diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6ae2fcadf..345a951e6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -173,9 +173,11 @@ add_library(aseprite-library ui_context.cpp undo_transaction.cpp xml_exception.cpp + app/backup.cpp app/check_update.cpp app/color.cpp app/color_utils.cpp + app/data_recovery.cpp app/file_selector.cpp app/widget_loader.cpp commands/cmd_about.cpp diff --git a/src/app.cpp b/src/app.cpp index 7bcf38c2b..2b5d307fc 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -22,6 +22,7 @@ #include "app/check_update.h" #include "app/color_utils.h" +#include "app/data_recovery.h" #include "app/find_widget.h" #include "app/load_widget.h" #include "base/exception.h" @@ -78,18 +79,19 @@ using namespace ui; -/** - * ASEPRITE modules. - */ class App::Modules { public: - // ASEPRITE Modules FileSystemModule m_file_system_module; tools::ToolBox m_toolbox; CommandsModule m_commands_modules; UIContext m_ui_context; RecentFiles m_recent_files; + app::DataRecovery m_recovery; + + App::Modules() + : m_recovery(&m_ui_context) { + } }; App* App::m_instance = NULL; @@ -144,8 +146,6 @@ App::App(int argc, char* argv[]) set_current_palette(NULL, true); } - - int App::run() { #ifdef ENABLE_UPDATER @@ -248,10 +248,10 @@ App::~App() // Remove ASEPRITE handlers PRINTF("ASE: Uninstalling\n"); - // Fire App Exit signal + // Fire App Exit signal. App::instance()->Exit(); - // Finalize modules, configuration and core + // Finalize modules, configuration and core. Editor::editor_cursor_exit(); boundary_exit(); diff --git a/src/app/backup.cpp b/src/app/backup.cpp new file mode 100644 index 000000000..5db8335d7 --- /dev/null +++ b/src/app/backup.cpp @@ -0,0 +1,39 @@ +/* ASEPRITE + * Copyright (C) 2001-2012 David Capello + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "config.h" + +#include "app/backup.h" + +namespace app { + +Backup::Backup(const base::string& path) + : m_path(path) +{ +} + +Backup::~Backup() +{ +} + +bool Backup::hasDataToRestore() +{ + return false; +} + +} // namespace app diff --git a/src/app/backup.h b/src/app/backup.h new file mode 100644 index 000000000..e8c7f8637 --- /dev/null +++ b/src/app/backup.h @@ -0,0 +1,44 @@ +/* ASEPRITE + * Copyright (C) 2001-2012 David Capello + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef APP_BACKUP_H_INCLUDED +#define APP_BACKUP_H_INCLUDED + +#include "base/disable_copying.h" +#include "base/string.h" + +namespace app { + + // A class to record/restore backup information. + class Backup { + public: + Backup(const base::string& path); + ~Backup(); + + // Returns true if there are items that can be restored. + bool hasDataToRestore(); + + private: + DISABLE_COPYING(Backup); + + base::string m_path; + }; + +} // namespace app + +#endif diff --git a/src/app/data_recovery.cpp b/src/app/data_recovery.cpp new file mode 100644 index 000000000..9f8282a14 --- /dev/null +++ b/src/app/data_recovery.cpp @@ -0,0 +1,82 @@ +/* ASEPRITE + * Copyright (C) 2001-2012 David Capello + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "config.h" + +#include "app/data_recovery.h" + +#include "app/backup.h" +#include "base/fs.h" +#include "base/path.h" +#include "base/temp_dir.h" +#include "document.h" +#include "ui_context.h" + +#include + +namespace app { + +DataRecovery::DataRecovery(Context* context) + : m_tempDir(NULL) + , m_backup(NULL) + , m_context(context) +{ + // Check if there is already data to recover + const base::string existent_data_path = get_config_string("DataRecovery", "Path", ""); + if (!existent_data_path.empty() && + base::directory_exists(existent_data_path)) { + // Load the backup data. + m_tempDir = new base::TempDir(); + m_tempDir->attach(existent_data_path); + m_backup = new Backup(existent_data_path); + } + else { + // Create a new directory to save the backup information. + m_tempDir = new base::TempDir(PACKAGE); + m_backup = new Backup(m_tempDir->path()); + + set_config_string("DataRecovery", "Path", m_tempDir->path().c_str()); + flush_config_file(); + } + + m_context->addObserver(this); +} + +DataRecovery::~DataRecovery() +{ + m_context->removeObserver(this); + + delete m_backup; + + if (m_tempDir) { + delete m_tempDir; + set_config_string("DataRecovery", "Path", ""); + } +} + +void DataRecovery::onAddDocument(Context* context, Document* document) +{ + document->addObserver(this); +} + +void DataRecovery::onRemoveDocument(Context* context, Document* document) +{ + document->removeObserver(this); +} + +} // namespace app diff --git a/src/app/data_recovery.h b/src/app/data_recovery.h new file mode 100644 index 000000000..2cdd4e389 --- /dev/null +++ b/src/app/data_recovery.h @@ -0,0 +1,59 @@ +/* ASEPRITE + * Copyright (C) 2001-2012 David Capello + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef DATA_RECOVERY_H_INCLUDED +#define DATA_RECOVERY_H_INCLUDED + +#include "base/compiler_specific.h" +#include "base/disable_copying.h" +#include "base/slot.h" +#include "context_observer.h" +#include "document_observer.h" +#include "documents.h" + +namespace base { class TempDir; } + +namespace app { + + class Backup; + + class DataRecovery : public ContextObserver + , public DocumentObserver { + public: + DataRecovery(Context* context); + ~DataRecovery(); + + // Returns a backup if there are data to be restored from a + // crash. Or null if the program didn't crash in its previous + // execution. + Backup* getBackup() { return m_backup; } + + private: + void onAddDocument(Context* context, Document* document) OVERRIDE; + void onRemoveDocument(Context* context, Document* document) OVERRIDE; + + base::TempDir* m_tempDir; + Backup* m_backup; + Context* m_context; + + DISABLE_COPYING(DataRecovery); + }; + +} // namespace app + +#endif diff --git a/src/context_observer.h b/src/context_observer.h index e4759c7b7..148571736 100644 --- a/src/context_observer.h +++ b/src/context_observer.h @@ -20,6 +20,7 @@ #define CONTEXT_OBSERVER_H_INCLUDED class Context; +class Document; // Observer of context events. The default implementation does nothing // in each handler, so you can override the required events. @@ -31,6 +32,8 @@ public: virtual void onActiveDocumentAfterChange(Context* context) { } virtual void onCommandBeforeExecution(Context* context) { } virtual void onCommandAfterExecution(Context* context) { } + virtual void onAddDocument(Context* context, Document* document) { } + virtual void onRemoveDocument(Context* context, Document* document) { } }; #endif diff --git a/src/context_observer_list.cpp b/src/context_observer_list.cpp index dc43389cc..6b42b90b2 100644 --- a/src/context_observer_list.cpp +++ b/src/context_observer_list.cpp @@ -68,3 +68,17 @@ void ContextObserverList::notifyCommandAfterExecution(Context* context) std::for_each(copy.begin(), copy.end(), std::bind2nd(std::mem_fun(&ContextObserver::onCommandAfterExecution), context)); } + +void ContextObserverList::notifyAddDocument(Context* context, Document* document) +{ + list_type copy = m_observer; + for (iterator it=copy.begin(), end=copy.end(); it!=end; ++it) + (*it)->onAddDocument(context, document); +} + +void ContextObserverList::notifyRemoveDocument(Context* context, Document* document) +{ + list_type copy = m_observer; + for (iterator it=copy.begin(), end=copy.end(); it!=end; ++it) + (*it)->onRemoveDocument(context, document); +} diff --git a/src/context_observer_list.h b/src/context_observer_list.h index 750db8866..c5e651f4a 100644 --- a/src/context_observer_list.h +++ b/src/context_observer_list.h @@ -23,6 +23,7 @@ class Context; class ContextObserver; +class Document; class ContextObserverList { @@ -40,6 +41,8 @@ public: void notifyActiveDocumentAfterChange(Context* context); void notifyCommandBeforeExecution(Context* context); void notifyCommandAfterExecution(Context* context); + void notifyAddDocument(Context* context, Document* document); + void notifyRemoveDocument(Context* context, Document* document); private: list_type m_observer;