yakov pushed a commit to branch master.

http://git.enlightenment.org/tools/erigo.git/commit/?id=12445b31747d5f2369707b261b4293f325d3a809

commit 12445b31747d5f2369707b261b4293f325d3a809
Author: Yakov Goldberg <yako...@samsung.com>
Date:   Sun Nov 15 14:09:29 2015 +0200

    Autosave implemented
    
    Implemented autosave feature.
    Project is automatically saved every 10 seconds into file
    ".project.swp_erigo"
    When user opens a project and swap file exists, user will be asked
    what he wants to open: swap or original file.
---
 src/bin/gui/CMakeLists.txt |  1 +
 src/bin/gui/autosave.c     | 99 ++++++++++++++++++++++++++++++++++++++++++++++
 src/bin/gui/autosave.h     | 23 +++++++++++
 src/bin/gui/editor.c       |  6 +++
 src/bin/gui/egui_logic.c   | 57 +++++++++++++++++++++++++-
 5 files changed, 185 insertions(+), 1 deletion(-)

diff --git a/src/bin/gui/CMakeLists.txt b/src/bin/gui/CMakeLists.txt
index e1abcf8..8b17ca7 100644
--- a/src/bin/gui/CMakeLists.txt
+++ b/src/bin/gui/CMakeLists.txt
@@ -70,6 +70,7 @@ add_executable(${TARGET}
    dnd.c
    key_bindings.c
    popup.c
+   autosave.c
    )
 
 add_dependencies(${TARGET} erigo_cmd)
diff --git a/src/bin/gui/autosave.c b/src/bin/gui/autosave.c
new file mode 100644
index 0000000..0836719
--- /dev/null
+++ b/src/bin/gui/autosave.c
@@ -0,0 +1,99 @@
+
+#include "autosave.h"
+#include "gui_widget.h"
+#include "json_generator.h"
+#include "egui_log.h"
+
+
+static int _init_counter = 0;
+static Eina_List *_ctxs_to_save = NULL;
+
+typedef struct
+{
+   const Gui_Context *ctx;
+   const Memento *mem_autosaved;
+} Autosave_Info;
+
+static Ecore_Timer *_autosave_timer;
+
+void
+autosave_context_add(const Gui_Context *ctx)
+{
+   if (!_init_counter)
+     {
+        ERR("Autosave module was not initialized");
+        return;
+     }
+   Autosave_Info *ai = calloc(1, sizeof(Autosave_Info));
+   ai->ctx = ctx;
+   _ctxs_to_save = eina_list_append(_ctxs_to_save, ai);
+}
+
+void
+autosave_context_remove(const Gui_Context *ctx)
+{
+   if (!_init_counter)
+     {
+        ERR("Autosave module was not initialized");
+        return;
+     }
+   Eina_List *itr;
+   Autosave_Info *ai;
+   EINA_LIST_FOREACH(_ctxs_to_save, itr, ai)
+     {
+        if (ai->ctx == ctx) break;
+     }
+   _ctxs_to_save = eina_list_remove(_ctxs_to_save, ai);
+   free(ai);
+}
+
+static Eina_Bool
+_autosave_cb(void *data EINA_UNUSED)
+{
+   Eina_List *itr;
+   Autosave_Info *ai;
+   EINA_LIST_FOREACH(_ctxs_to_save, itr, ai)
+     {
+        if (context_current_memento_get(ai->ctx) == 
context_saved_memento_get(ai->ctx) ||
+            context_current_memento_get(ai->ctx) == ai->mem_autosaved) 
continue;
+
+        ai->mem_autosaved = context_current_memento_get(ai->ctx);
+
+        const char *path = gui_context_project_path_get(ai->ctx);
+        const char *filename = gui_context_project_filename_get(ai->ctx);
+        char swap_file[PATH_MAX];
+
+        sprintf(swap_file, "%s/.%s.erigo_swp", path, filename);
+        json_file_generate(ai->ctx, swap_file);
+     }
+   return ECORE_CALLBACK_RENEW;
+}
+
+char *
+autosave_ctx_swapfile_name_get(const char *filename)
+{
+   char *path = ecore_file_dir_get(filename);
+   const char *name = ecore_file_file_get(filename);
+   char *swap_file = calloc(strlen(path) + strlen(name) + 13, 1);
+   sprintf(swap_file, "%s/.%s.erigo_swp", path, name);
+   free(path);
+   return swap_file;
+}
+
+Eina_Bool
+autosave_init()
+{
+   if (_init_counter++) return EINA_TRUE;
+   _autosave_timer = ecore_timer_add(10, _autosave_cb, NULL);
+   return EINA_TRUE;
+}
+
+void
+autosave_shutdown()
+{
+   if (--_init_counter)
+     {
+        ecore_timer_del(_autosave_timer);
+        _autosave_timer = NULL;
+     }
+}
diff --git a/src/bin/gui/autosave.h b/src/bin/gui/autosave.h
new file mode 100644
index 0000000..7f84ff4
--- /dev/null
+++ b/src/bin/gui/autosave.h
@@ -0,0 +1,23 @@
+
+#ifndef _AUTOSAVE_H
+#define _AUTOSAVE_H
+
+#include "gui_widget.h"
+
+Eina_Bool
+autosave_init();
+
+void
+autosave_shutdown();
+
+void
+autosave_context_add(const Gui_Context *ctx);
+
+void
+autosave_context_remove(const Gui_Context *ctx);
+
+char *
+autosave_ctx_swapfile_name_get(const char *filename);
+
+
+#endif
diff --git a/src/bin/gui/editor.c b/src/bin/gui/editor.c
index b659758..b8a6ba9 100644
--- a/src/bin/gui/editor.c
+++ b/src/bin/gui/editor.c
@@ -15,6 +15,8 @@
 #include "key_bindings.h"
 #include "settings.h"
 #include "updater.h"
+#include "autosave.h"
+#include "popup.h"
 
 #include "dnd.h"
 
@@ -2888,6 +2890,7 @@ editor_shutdown()
    target_db_shutdown();
    proplayout_shutdown();
    objtree_shutdown();
+   autosave_shutdown();
 
    void *p = (void *) propview_cbs_get();
    free(p);
@@ -3909,6 +3912,7 @@ _project_close(const Gui_Context *ctx)
           }
 
         session_del(editor_session);
+        autosave_context_remove(ctx);
         gui_context_del((Gui_Context *) ctx);
      }
 }
@@ -3973,6 +3977,7 @@ _project_new(const char *filename)
    /* FIXME: handle return values */
    _active_context_set(ctx);
    objtree_context_set(ctx);
+   autosave_context_add(ctx);
 
    /* Assign new editor session to context */
    Gui_Session *session = session_new(MODE_EDITOR, EINA_TRUE);
@@ -4304,6 +4309,7 @@ editor_init(GuiLogicCbs *_guilogic_cbs)
    objtree_init();
    proplayout_init();
    target_db_init();
+   autosave_init();
    ecore_idle_enterer_add(_wdg_border_draw_on_idle, NULL);
 
    DnD_Main_Obj_Info *di = calloc (1, sizeof(DnD_Main_Obj_Info));
diff --git a/src/bin/gui/egui_logic.c b/src/bin/gui/egui_logic.c
index 879812b..02a1a40 100644
--- a/src/bin/gui/egui_logic.c
+++ b/src/bin/gui/egui_logic.c
@@ -20,6 +20,7 @@
 #include "key_bindings.h"
 #include "settings.h"
 #include "simulator.h"
+#include "autosave.h"
 
 /*FIXME: remove this include */
 #include "objtree.h"
@@ -149,6 +150,21 @@ static void
 _context_save(const Gui_Context *ctx)
 {
    generator_ctx_source_generate(ctx, GENERATE_JSON, EINA_FALSE);
+
+   const char *path = gui_context_project_path_get(ctx);
+   const char *filename = gui_context_project_filename_get(ctx);
+   char full_path[PATH_MAX];
+   sprintf(full_path, "%s/%s", path, filename);
+
+   char *swap_file = autosave_ctx_swapfile_name_get(full_path);
+   if (swap_file)
+     {
+        if (ecore_file_exists(swap_file))
+          {
+             ecore_file_remove(swap_file);
+          }
+        free(swap_file);
+     }
    context_saved_memento_set((Gui_Context *) ctx, 
context_current_memento_get(ctx));
    _canvas_name_update(ctx, EINA_FALSE);
 }
@@ -221,12 +237,51 @@ _project_open_create_internal(const char *filename, int 
fs_mode, const char *dir
    return ctx;
 }
 
+/* Callback for swapfile popup window */
+static void
+_swapfile_popup_cb(Popup_Button_Type button_type, void *data)
+{
+   char *path = data;
+   /* If OK button pressed open swapped file */
+   if (button_type == POPUP_OK_BUTTON)
+     {
+        char *swap_file = autosave_ctx_swapfile_name_get(path);
+        Gui_Context *ctx = _project_open_create_internal(swap_file, ITEM_OPEN, 
NULL, NULL, NULL);
+        free(swap_file);
+
+        /* After openning swap file, apply original filename to context
+         * and update canvas name to show star*/
+        const char *original_filename = ecore_file_file_get(path);
+        gui_context_project_filename_set(ctx, original_filename);
+
+        _canvas_name_update(ctx, EINA_TRUE);
+     }
+   else
+     {
+        _project_open_create_internal(path, ITEM_OPEN, NULL, NULL, NULL);
+     }
+   free(path);
+}
+
+/* Wrapper for _project_open_create_internal() func.
+ * Has to check if swap file exists and show popup if needed. */
 void
 project_open_create(const char *filename, int fs_mode, const char *dir, const 
char *file_name, const char *project_name)
 {
+   Eina_Bool ret = EINA_FALSE;
    if (fs_mode == ITEM_OPEN)
      {
-        _project_new_mode_internal(filename, fs_mode, NULL, NULL, NULL);
+        char *swap_file = autosave_ctx_swapfile_name_get(filename);
+        if (swap_file && ecore_file_exists(swap_file))
+          {
+             const char *title = "Warning";
+             const char *text = "Swap file exists for current project. Looks 
like file was not properly saved. Do you want to open swap file instead of 
original ?";
+             popup_show(g_main_wdgs->main_win->main_win, title, text, 
POPUP_OK_BUTTON | POPUP_CANCEL_BUTTON, _swapfile_popup_cb, strdup(filename));
+             free(swap_file);
+             ret = EINA_TRUE;
+          }
+        if (ret) return;
+        _project_open_create_internal(filename, fs_mode, NULL, NULL, NULL);
      }
    else if (fs_mode == ITEM_NEW)
      {

-- 


Reply via email to