core: switch to single-project implementation

This has never worked right, it's caused a number of complexities within the code, and I think there are better ways to do this.
This commit is contained in:
itsmattkc
2023-02-08 12:15:05 -08:00
parent c322bb6463
commit 70d34c674b
6 changed files with 129 additions and 391 deletions
+54 -241
View File
@@ -83,6 +83,7 @@ Core* Core::instance_ = nullptr;
Core::Core(const CoreParams& params) :
main_window_(nullptr),
open_project_(nullptr),
tool_(Tool::kPointer),
addable_object_(Tool::kAddableEmpty),
snapping_(true),
@@ -291,15 +292,10 @@ void Core::ClearOpenRecentList()
void Core::CreateNewProject()
{
// If we already have an empty/new project, switch to it
foreach (Project* already_open, open_projects_) {
if (already_open->is_new()) {
AddOpenProject(already_open);
return;
}
}
if (CloseProject(false)) {
AddOpenProject(new Project());
}
}
const bool &Core::snapping() const
{
@@ -471,21 +467,19 @@ void Core::CreateNewSequence()
void Core::AddOpenProject(Project* p, bool add_to_recents)
{
// Ensure project is not open at the moment
foreach (Project* already_open, open_projects_) {
if (already_open == p) {
if (open_project_ == p) {
// Signal UI to switch to this project
emit ProjectOpened(p);
return;
}
}
// If we currently have an empty project, close it first
if (!open_projects_.isEmpty() && open_projects_.last()->is_new()) {
CloseProject(open_projects_.last(), false);
if (open_project_) {
CloseProject(false);
}
connect(p, &Project::ModifiedChanged, this, &Core::ProjectWasModified);
open_projects_.append(p);
open_project_ = p;
if (!p->filename().isEmpty() && add_to_recents) {
PushRecentlyOpenedProject(p->filename());
@@ -508,11 +502,9 @@ bool Core::AddOpenProjectFromTask(Task *task, bool add_to_recents)
return true;
} else {
delete project;
if (open_projects_.empty()) {
CreateNewProject();
}
}
}
return false;
}
@@ -593,23 +585,7 @@ bool Core::ConfirmImageSequence(const QString& filename)
void Core::ProjectWasModified(bool e)
{
//Project* p = static_cast<Project*>(sender());
if (e) {
// If this project is modified, we know for sure the window should show a "modified" flag (the * in the titlebar)
main_window_->setWindowModified(true);
} else {
// If we just set this project to "not modified", see if all projects are not modified in which case we can hide
// the modified flag
foreach (Project* open, open_projects_) {
if (open->is_modified()) {
main_window_->setWindowModified(true);
return;
}
}
main_window_->setWindowModified(false);
}
main_window_->setWindowModified(e);
}
bool Core::StartHeadlessExport()
@@ -805,15 +781,15 @@ void Core::StartGUI(bool full_screen)
}
}
void Core::SaveProjectInternal(Project* project, const QString& override_filename)
void Core::SaveProjectInternal(const QString& override_filename)
{
// Create save manager
Task* psm;
// Put layout into project
project->SetLayoutInfo(main_window_->SaveLayout());
open_project_->SetLayoutInfo(main_window_->SaveLayout());
if (project->filename().endsWith(QStringLiteral(".otio"), Qt::CaseInsensitive)) {
if (open_project_->filename().endsWith(QStringLiteral(".otio"), Qt::CaseInsensitive)) {
#ifdef USE_OTIO
psm = new SaveOTIOTask(project);
#else
@@ -824,8 +800,8 @@ void Core::SaveProjectInternal(Project* project, const QString& override_filenam
return;
#endif
} else {
bool use_compression = !project->filename().endsWith(QStringLiteral(".ovexml"), Qt::CaseInsensitive);
psm = new ProjectSaveTask(project, use_compression);
bool use_compression = !open_project_->filename().endsWith(QStringLiteral(".ovexml"), Qt::CaseInsensitive);
psm = new ProjectSaveTask(open_project_, use_compression);
if (!override_filename.isEmpty()) {
// Set override filename if provided
@@ -915,9 +891,9 @@ void Core::SaveUnrecoveredList()
}
}
bool Core::RevertProjectInternal(Project *p, bool by_opening_existing)
bool Core::RevertProjectInternal(bool by_opening_existing)
{
if (p->filename().isEmpty()) {
if (open_project_->filename().isEmpty()) {
QMessageBox::critical(main_window_, tr("Revert"),
tr("This project has not yet been saved, therefore there is no last saved state to revert to."));
} else {
@@ -925,21 +901,20 @@ bool Core::RevertProjectInternal(Project *p, bool by_opening_existing)
if (by_opening_existing) {
msg = tr("The project \"%1\" is already open. By re-opening it, the project will revert to "
"its last saved state. Any unsaved changes will be lost. Do you wish to continue?").arg(p->filename());
"its last saved state. Any unsaved changes will be lost. Do you wish to continue?").arg(open_project_->filename());
} else {
msg = tr("This will revert the project \"%1\" back to its last saved state. "
"All unsaved changes will be lost. Do you wish to continue?").arg(p->name());
"All unsaved changes will be lost. Do you wish to continue?").arg(open_project_->name());
}
if (QMessageBox::question(main_window_, tr("Revert"), msg, QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok) {
// Copy filename because CloseProject is going to delete `p`
QString filename = p->filename();
QString filename = open_project_->filename();
// Close project without prompting to save it
CloseProjectBehavior b = kCloseProjectDontSave;
CloseProject(p, false, b);
CloseProject(false, true);
// NOTE: `p` will be deleted now, so don't try accessing it
// NOTE: `open_project_` will be deleted now, so don't try accessing it
// Re-open project at the filename
OpenProjectInternal(filename);
@@ -964,19 +939,18 @@ void Core::SaveRecentProjectsList()
void Core::SaveAutorecovery()
{
if (OLIVE_CONFIG("AutorecoveryEnabled").toBool()) {
foreach (Project* p, open_projects_) {
if (!p->has_autorecovery_been_saved()) {
QDir project_autorecovery_dir(QDir(FileFunctions::GetAutoRecoveryRoot()).filePath(p->GetUuid().toString()));
if (!open_project_->has_autorecovery_been_saved()) {
QDir project_autorecovery_dir(QDir(FileFunctions::GetAutoRecoveryRoot()).filePath(open_project_->GetUuid().toString()));
if (FileFunctions::DirectoryIsValid(project_autorecovery_dir)) {
QString this_autorecovery_path = project_autorecovery_dir.filePath(QStringLiteral("%1.ove").arg(QString::number(QDateTime::currentSecsSinceEpoch())));
SaveProjectInternal(p, this_autorecovery_path);
SaveProjectInternal(this_autorecovery_path);
p->set_autorecovery_saved(true);
open_project_->set_autorecovery_saved(true);
// Keep track of projects that where the "newest" save is the recovery project
if (!autorecovered_projects_.contains(p->GetUuid())) {
autorecovered_projects_.append(p->GetUuid());
if (!autorecovered_projects_.contains(open_project_->GetUuid())) {
autorecovered_projects_.append(open_project_->GetUuid());
}
qDebug() << "Saved auto-recovery to:" << this_autorecovery_path;
@@ -985,7 +959,7 @@ void Core::SaveAutorecovery()
{
QFile realname_file(project_autorecovery_dir.filePath(QStringLiteral("realname.txt")));
realname_file.open(QFile::WriteOnly);
realname_file.write(p->pretty_filename().toUtf8());
realname_file.write(open_project_->pretty_filename().toUtf8());
realname_file.close();
}
@@ -1024,7 +998,6 @@ void Core::SaveAutorecovery()
.arg(project_autorecovery_dir.absolutePath()));
}
}
}
// Save index
SaveUnrecoveredList();
@@ -1047,24 +1020,7 @@ void Core::ProjectSaveSucceeded(Task* task)
Project* Core::GetActiveProject() const
{
ProjectPanel* active_project_panel = PanelManager::instance()->MostRecentlyFocused<ProjectPanel>();
if (active_project_panel && active_project_panel->project()) {
return active_project_panel->project();
}
return nullptr;
}
ProjectViewModel *Core::GetActiveProjectModel() const
{
ProjectPanel* active_project_panel = PanelManager::instance()->MostRecentlyFocused<ProjectPanel>();
if (active_project_panel) {
return active_project_panel->model();
} else {
return nullptr;
}
return open_project_;
}
Folder *Core::GetSelectedFolderInActiveProject() const
@@ -1106,69 +1062,6 @@ QString Core::PasteStringFromClipboard()
return QGuiApplication::clipboard()->text();
}
bool Core::SaveActiveProject()
{
Project* active_project = GetActiveProject();
if (active_project) {
return SaveProject(active_project);
}
return false;
}
bool Core::SaveActiveProjectAs()
{
Project* active_project = GetActiveProject();
if (active_project) {
return SaveProjectAs(active_project);
}
return false;
}
bool Core::SaveAllProjects()
{
foreach (Project* p, open_projects_) {
if (!SaveProject(p)) {
return false;
}
}
return true;
}
void Core::RevertActiveProject()
{
Project *p = GetActiveProject();
if (p) {
RevertProjectInternal(p, false);
}
}
bool Core::CloseActiveProject()
{
return CloseProject(GetActiveProject(), true);
}
bool Core::CloseAllExceptActiveProject()
{
Project* active_proj = GetActiveProject();
QList<Project*> copy = open_projects_;
foreach (Project* p, copy) {
if (p != active_proj) {
if (!CloseProject(p, true)) {
return false;
}
}
}
return true;
}
QString Core::GetProjectFilter(bool include_any_filter)
{
static const QVector< QPair<QString, QString> > FILTERS = {
@@ -1230,12 +1123,12 @@ void Core::SetStartupLocale()
}
}
bool Core::SaveProject(Project* p)
bool Core::SaveProject()
{
if (p->filename().isEmpty()) {
return SaveProjectAs(p);
if (open_project_->filename().isEmpty()) {
return SaveProjectAs();
} else {
SaveProjectInternal(p);
SaveProjectInternal();
return true;
}
@@ -1339,7 +1232,7 @@ void Core::WarnCacheFull()
}
}
bool Core::SaveProjectAs(Project* p)
bool Core::SaveProjectAs()
{
QFileDialog fd(main_window_, tr("Save Project As"));
@@ -1356,9 +1249,9 @@ bool Core::SaveProjectAs(Project* p)
fn = FileFunctions::EnsureFilenameExtension(fn, extension);
p->set_filename(fn);
open_project_->set_filename(fn);
SaveProjectInternal(p);
SaveProjectInternal();
return true;
}
@@ -1366,6 +1259,11 @@ bool Core::SaveProjectAs(Project* p)
return false;
}
void Core::RevertProject()
{
RevertProjectInternal(false);
}
void Core::PushRecentlyOpenedProject(const QString& s)
{
if (s.isEmpty()) {
@@ -1392,17 +1290,16 @@ void Core::PushRecentlyOpenedProject(const QString& s)
void Core::OpenProjectInternal(const QString &filename, bool recovery_project)
{
// See if this project is open already
foreach (Project* p, open_projects_) {
if (open_project_) {
// Comparing QFileInfos will handle case insensitivity and both slash directions on platforms
// where this is necessary (not naming any names *cough* Windows)
if (QFileInfo(p->filename()) == QFileInfo(filename)) {
if (QFileInfo(open_project_->filename()) == QFileInfo(filename)) {
// This project is already open
bool reverted = RevertProjectInternal(p, true);
bool reverted = RevertProjectInternal(true);
if (!reverted) {
// Calling this will focus attention to the project that the user just tried to re-open
AddOpenProject(p);
AddOpenProject(open_project_);
}
// Don't do anything else
@@ -1544,48 +1441,22 @@ void Core::OpenProjectFromRecentList(int index)
}
}
bool Core::CloseProject(Project *p, bool auto_open_new)
bool Core::CloseProject(bool auto_open_new, bool ignore_modified)
{
CloseProjectBehavior b = kCloseProjectOnlyOne;
return CloseProject(p, auto_open_new, b);
}
bool Core::CloseProject(Project* p, bool auto_open_new, CloseProjectBehavior &confirm_behavior)
{
for (int i=0;i<open_projects_.size();i++) {
if (open_projects_.at(i) == p) {
if (p->is_modified() && confirm_behavior != kCloseProjectDontSave) {
bool save_this_project;
if (confirm_behavior == kCloseProjectAsk || confirm_behavior == kCloseProjectOnlyOne) {
if (open_project_) {
if (open_project_->is_modified() && !ignore_modified) {
QMessageBox mb(main_window_);
mb.setWindowModality(Qt::WindowModal);
mb.setIcon(QMessageBox::Question);
mb.setWindowTitle(tr("Unsaved Changes"));
mb.setText(tr("The project '%1' has unsaved changes. Would you like to save them?")
.arg(p->name()));
.arg(open_project_->name()));
QPushButton* yes_btn = mb.addButton(tr("Save"), QMessageBox::YesRole);
QPushButton* yes_to_all_btn;
if (confirm_behavior == kCloseProjectOnlyOne) {
yes_to_all_btn = nullptr;
} else {
yes_to_all_btn = mb.addButton(tr("Save All"), QMessageBox::YesRole);
}
mb.addButton(tr("Don't Save"), QMessageBox::NoRole);
QPushButton* no_to_all_btn;
if (confirm_behavior == kCloseProjectOnlyOne) {
no_to_all_btn = nullptr;
} else {
no_to_all_btn = mb.addButton(tr("Don't Save All"), QMessageBox::NoRole);
}
QPushButton* cancel_btn = mb.addButton(QMessageBox::Cancel);
mb.exec();
@@ -1593,84 +1464,31 @@ bool Core::CloseProject(Project* p, bool auto_open_new, CloseProjectBehavior &co
if (mb.clickedButton() == cancel_btn) {
// Stop closing projects if the user clicked cancel
return false;
} else if (mb.clickedButton() == yes_to_all_btn) {
// Set flag that other CloseProject commands are going to use
confirm_behavior = kCloseProjectSave;
} else if (mb.clickedButton() == no_to_all_btn) {
// Set flag that other CloseProject commands are going to use
confirm_behavior = kCloseProjectDontSave;
}
save_this_project = (mb.clickedButton() == yes_btn || mb.clickedButton() == yes_to_all_btn);
} else {
// We must be saving this project
save_this_project = true;
}
if (save_this_project && !SaveProject(p)) {
if (mb.clickedButton() == yes_btn && !SaveProject()) {
// The save failed, stop closing projects
return false;
}
}
// For safety, the undo stack is cleared so no commands try to affect a freed project
undo_stack_.clear();
disconnect(p, &Project::ModifiedChanged, this, &Core::ProjectWasModified);
emit ProjectClosed(p);
open_projects_.removeAt(i);
delete p;
break;
}
disconnect(open_project_, &Project::ModifiedChanged, this, &Core::ProjectWasModified);
emit ProjectClosed(open_project_);
delete open_project_;
open_project_ = nullptr;
}
// Ensure a project is always active
if (auto_open_new && open_projects_.isEmpty()) {
if (auto_open_new) {
CreateNewProject();
}
return true;
}
bool Core::CloseAllProjects(bool auto_open_new)
{
QList<Project*> copy = open_projects_;
// See how many projects are modified so we can set "behavior" correctly
// (i.e. whether to show "Yes/No To All" buttons or not)
int modified_count = 0;
foreach (Project* p, copy) {
if (p->is_modified()) {
modified_count++;
}
}
CloseProjectBehavior behavior;
if (modified_count > 1) {
behavior = kCloseProjectAsk;
} else {
behavior = kCloseProjectOnlyOne;
}
foreach (Project* p, copy) {
// If this is the only remaining project and the user hasn't chose "yes/no to all", hide those buttons
if (modified_count == 1 && behavior == kCloseProjectAsk) {
behavior = kCloseProjectOnlyOne;
}
if (!CloseProject(p, auto_open_new, behavior)) {
return false;
}
modified_count--;
}
return true;
}
void Core::CacheActiveSequence(bool in_out_only)
{
TimeBasedPanel* p = PanelManager::instance()->MostRecentlyFocused<TimeBasedPanel>();
@@ -1787,11 +1605,6 @@ bool Core::SetLanguage(const QString &locale)
return false;
}
bool Core::CloseAllProjects()
{
return CloseAllProjects(true);
}
void Core::OpenProject()
{
QString file = QFileDialog::getOpenFileName(main_window_,
+9 -63
View File
@@ -219,7 +219,6 @@ public:
* The active Project file, or nullptr if the heuristic couldn't find one.
*/
Project* GetActiveProject() const;
ProjectViewModel* GetActiveProjectModel() const;
Folder* GetSelectedFolderInActiveProject() const;
/**
@@ -265,23 +264,10 @@ public:
*/
void OpenProjectFromRecentList(int index);
enum CloseProjectBehavior {
kCloseProjectOnlyOne,
kCloseProjectAsk,
kCloseProjectSave,
kCloseProjectDontSave
};
/**
* @brief Closes a project
*/
bool CloseProject(Project* p, bool auto_open_new, CloseProjectBehavior& confirm_behavior);
bool CloseProject(Project* p, bool auto_open_new);
/**
* @brief Closes all open projects
*/
bool CloseAllProjects(bool auto_open_new);
bool CloseProject(bool auto_open_new, bool ignore_modified = false);
/**
* @brief Runs a modal cache task on the currently active sequence
@@ -298,11 +284,6 @@ public:
*/
bool SetLanguage(const QString& locale);
/**
* @brief Saves a specific project
*/
bool SaveProject(Project *p);
/**
* @brief Show message in main window's status bar
*
@@ -327,46 +308,16 @@ public slots:
void OpenProject();
/**
* @brief Save the currently active project
*
* If the project hasn't been saved before, this will be equivalent to calling SaveActiveProjectAs().
* @brief Saves the current project
*/
bool SaveActiveProject();
bool SaveProject();
/**
* @brief Save the currently active project with a new filename
* @brief Performs a "save as" on the current project
*/
bool SaveActiveProjectAs();
bool SaveProjectAs();
/**
* @brief Save all currently open projects
*/
bool SaveAllProjects();
/**
* @brief Revert project to last saved state (basically close and open it)
*/
void RevertActiveProject();
/**
* @brief Closes the active project
*
* If no other projects are open, a new one is created automatically.
*/
bool CloseActiveProject();
/**
* @brief Closes all projects except the active project
*/
bool CloseAllExceptActiveProject();
/**
* @brief Closes all open projects
*
* Equivalent to `CloseAllProjects(true)`, but useful for the signal/slot system where you may not be able to specify
* parameters.
*/
bool CloseAllProjects();
void RevertProject();
/**
* @brief Set the current application-wide tool
@@ -523,11 +474,6 @@ private:
*/
void SetStartupLocale();
/**
* @brief Performs a "save as" on a specific project
*/
bool SaveProjectAs(Project *p);
/**
* @brief Adds a filename to the top of the recently opened projects list (or moves it if it already exists)
*/
@@ -552,7 +498,7 @@ private:
/**
* @brief Internal function for saving a project to a file
*/
void SaveProjectInternal(Project *project, const QString &override_filename = QString());
void SaveProjectInternal(const QString &override_filename = QString());
/**
* @brief Retrieves the currently most active sequence for exporting
@@ -563,7 +509,7 @@ private:
void SaveUnrecoveredList();
bool RevertProjectInternal(Project *p, bool by_opening_existing);
bool RevertProjectInternal(bool by_opening_existing);
void SaveRecentProjectsList();
@@ -582,7 +528,7 @@ private:
/**
* @brief List of currently open projects
*/
QList<Project*> open_projects_;
Project *open_project_;
/**
* @brief Currently active tool
+1 -1
View File
@@ -221,7 +221,7 @@ void ProjectPanel::UpdateSubtitle()
void ProjectPanel::SaveConnectedProject()
{
Core::instance()->SaveProject(this->project());
Core::instance()->SaveProject();
}
QVector<ViewerOutput *> ProjectPanel::GetSelectedFootage() const
+3 -17
View File
@@ -52,21 +52,16 @@ MainMenu::MainMenu(MainWindow *parent) :
file_open_recent_menu_ = new Menu(file_menu_);
file_open_recent_separator_ = file_open_recent_menu_->addSeparator();
file_open_recent_clear_item_ = file_open_recent_menu_->AddItem("clearopenrecent", Core::instance(), &Core::ClearOpenRecentList);
file_save_item_ = file_menu_->AddItem("saveproj", Core::instance(), &Core::SaveActiveProject, tr("Ctrl+S"));
file_save_as_item_ = file_menu_->AddItem("saveprojas", Core::instance(), &Core::SaveActiveProjectAs, tr("Ctrl+Shift+S"));
file_save_all_item_ = file_menu_->AddItem("saveallproj", Core::instance(), &Core::SaveAllProjects);
file_save_item_ = file_menu_->AddItem("saveproj", Core::instance(), &Core::SaveProject, tr("Ctrl+S"));
file_save_as_item_ = file_menu_->AddItem("saveprojas", Core::instance(), &Core::SaveProjectAs, tr("Ctrl+Shift+S"));
file_menu_->addSeparator();
file_revert_item_ = file_menu_->AddItem("revert", Core::instance(), &Core::RevertActiveProject, tr("F12"));
file_revert_item_ = file_menu_->AddItem("revert", Core::instance(), &Core::RevertProject, tr("F12"));
file_menu_->addSeparator();
file_import_item_ = file_menu_->AddItem("import", Core::instance(), &Core::DialogImportShow, tr("Ctrl+I"));
file_menu_->addSeparator();
file_export_menu_ = new Menu(file_menu_);
file_export_media_item_ = file_export_menu_->AddItem("export", Core::instance(), &Core::DialogExportShow, tr("Ctrl+M"));
file_menu_->addSeparator();
file_close_project_item_ = file_menu_->AddItem("closeproj", Core::instance(), &Core::CloseActiveProject);
file_close_all_projects_item_ = file_menu_->AddItem("closeallproj", Core::instance(), static_cast<bool(Core::*)()>(&Core::CloseAllProjects));
file_close_all_except_item_ = file_menu_->AddItem("closeallexcept", Core::instance(), &Core::CloseAllExceptActiveProject);
file_menu_->addSeparator();
file_project_properties_item_ = file_menu_->AddItem("projectproperties", Core::instance(), &Core::DialogProjectPropertiesShow, tr("Shift+F10"));
file_menu_->addSeparator();
file_exit_item_ = file_menu_->AddItem("exit", parent, &MainWindow::close);
@@ -328,20 +323,13 @@ void MainMenu::FileMenuAboutToShow()
file_save_item_->setEnabled(active_project);
file_save_as_item_->setEnabled(active_project);
file_close_project_item_->setEnabled(active_project);
file_close_all_projects_item_->setEnabled(active_project);
file_close_all_except_item_->setEnabled(active_project);
if (active_project) {
file_save_item_->setText(tr("&Save '%1'").arg(active_project->name()));
file_save_as_item_->setText(tr("Save '%1' &As").arg(active_project->name()));
file_close_project_item_->setText(tr("Close '%1'").arg(active_project->name()));
file_close_all_except_item_->setText(tr("Close All Except '%1'").arg(active_project->name()));
} else {
file_save_item_->setText(tr("&Save Project"));
file_save_as_item_->setText(tr("Save Project &As"));
file_close_project_item_->setText(tr("Close Project"));
file_close_all_except_item_->setText(tr("Close All Except Current Project"));
}
}
@@ -704,12 +692,10 @@ void MainMenu::Retranslate()
file_open_item_->setText(tr("&Open Project"));
file_open_recent_menu_->setTitle(tr("Open &Recent"));
file_open_recent_clear_item_->setText(tr("&Clear Recent List"));
file_save_all_item_->setText(tr("Sa&ve All Projects"));
file_revert_item_->setText(tr("Revert"));
file_import_item_->setText(tr("&Import..."));
file_export_menu_->setTitle(tr("&Export"));
file_export_media_item_->setText(tr("&Media..."));
file_close_all_projects_item_->setText(tr("Close All Projects"));
file_project_properties_item_->setText(tr("Project Properties"));
file_exit_item_->setText(tr("E&xit"));
-4
View File
@@ -202,14 +202,10 @@ private:
QAction* file_open_recent_clear_item_;
QAction* file_save_item_;
QAction* file_save_as_item_;
QAction* file_save_all_item_;
QAction* file_revert_item_;
QAction* file_import_item_;
Menu* file_export_menu_;
QAction* file_export_media_item_;
QAction* file_close_project_item_;
QAction* file_close_all_projects_item_;
QAction* file_close_all_except_item_;
QAction* file_project_properties_item_;
QAction* file_exit_item_;
+2 -5
View File
@@ -431,7 +431,7 @@ void MainWindow::SelectFootage(const QVector<Footage *> &e)
void MainWindow::closeEvent(QCloseEvent *e)
{
// Try to close all projects (this will return false if the user chooses not to close)
if (!Core::instance()->CloseAllProjects(false)) {
if (!Core::instance()->CloseProject(false)) {
e->ignore();
return;
}
@@ -555,10 +555,7 @@ void MainWindow::TimelineCloseRequested()
void MainWindow::ProjectCloseRequested()
{
ProjectPanel* panel = static_cast<ProjectPanel*>(sender());
Project* p = panel->project();
Core::instance()->CloseProject(p, true);
Core::instance()->CloseProject(true);
}
void MainWindow::ViewerCloseRequested()