summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJon A. Cruz <jon@joncruz.org>2008-06-12 09:53:24 +0000
committerjoncruz <joncruz@users.sourceforge.net>2008-06-12 09:53:24 +0000
commit33c6e6fa672c388c540250d86c5c23f571338d11 (patch)
treefe79929f27051662c64670630925b28254568133 /src
parentFixed uninitialized variables, including modified-since-save. (diff)
downloadinkscape-33c6e6fa672c388c540250d86c5c23f571338d11.tar.gz
inkscape-33c6e6fa672c388c540250d86c5c23f571338d11.zip
Committing fixed patch for autosave. Fixes bug #171092.
(bzr r5898)
Diffstat (limited to 'src')
-rw-r--r--src/inkscape.cpp169
-rw-r--r--src/inkscape.h2
-rw-r--r--src/preferences-skeleton.h1
-rw-r--r--src/ui/dialog/inkscape-preferences.cpp24
-rw-r--r--src/ui/dialog/inkscape-preferences.h4
5 files changed, 200 insertions, 0 deletions
diff --git a/src/inkscape.cpp b/src/inkscape.cpp
index b4f6808ce..e3667e1f3 100644
--- a/src/inkscape.cpp
+++ b/src/inkscape.cpp
@@ -41,6 +41,8 @@ using Inkscape::Extension::Internal::PrintWin32;
#include <gtk/gtkmain.h>
#include <gtk/gtkmessagedialog.h>
+#include <glib.h>
+#include <glib/gstdio.h>
#include <glibmm/i18n.h>
#include <string>
@@ -61,8 +63,12 @@ using Inkscape::Extension::Internal::PrintWin32;
#include "prefs-utils.h"
#include "xml/repr.h"
#include "io/sys.h"
+#include "message-stack.h"
#include "extension/init.h"
+#include "extension/db.h"
+#include "extension/output.h"
+#include "extension/system.h"
static Inkscape::Application *inkscape = NULL;
@@ -287,6 +293,167 @@ inkscape_class_init (Inkscape::ApplicationClass * klass)
klass->deactivate_desktop = inkscape_deactivate_desktop_private;
}
+#ifdef WIN32
+typedef int uid_t;
+#define getuid() 0
+#endif
+
+/**
+ * static gint inkscape_autosave(gpointer);
+ *
+ * Callback passed to g_timeout_add_seconds()
+ * Responsible for autosaving all open documents
+ */
+static gint inkscape_autosave(gpointer)
+{
+ // Use UID for separating autosave-documents between users if directory is multiuser
+ uid_t uid = getuid();
+
+ Glib::ustring autosave_dir;
+ {
+ gchar const* tmp = prefs_get_string_attribute("options.autosave", "path");
+ if ( tmp ) {
+ autosave_dir = tmp;
+ } else {
+ autosave_dir = Glib::get_tmp_dir();
+ }
+ }
+
+ GDir *autosave_dir_ptr = g_dir_open(autosave_dir.c_str(), 0, NULL);
+ if( !autosave_dir_ptr ){
+ g_warning("Cannot open autosave directory!");
+ return TRUE;
+ }
+
+ time_t sptime = time(NULL);
+ struct tm *sptm = localtime(&sptime);
+ gchar sptstr[256];
+ strftime(sptstr, 256, "%Y_%m_%d_%H_%M_%S", sptm);
+
+ gint autosave_max = prefs_get_int_attribute("options.autosave", "max", 10);
+
+ gint docnum = 0;
+
+ SP_ACTIVE_DESKTOP->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Autosaving documents..."));
+ for (GSList *docList = inkscape->documents; docList; docList = docList->next) {
+ ++docnum;
+
+ // TODO replace this with SP_DOCUMENT() when linking issues are addressed:
+ SPDocument *doc = static_cast<SPDocument *>(docList->data);
+ Inkscape::XML::Node *repr = sp_document_repr_root(doc);
+ // g_debug("Document %d: \"%s\" %s", docnum, doc ? doc->name : "(null)", doc ? (doc->isModifiedSinceSave() ? "(dirty)" : "(clean)") : "(null)");
+
+ if (doc->isModifiedSinceSave()) {
+ gchar *oldest_autosave = 0;
+ const gchar *filename = 0;
+ struct stat sb;
+ time_t min_time = 0;
+ gint count = 0;
+
+ // Look for previous autosaves
+ gchar* baseName = g_strdup_printf( "inkscape-autosave-%d", uid );
+ g_dir_rewind(autosave_dir_ptr);
+ while( (filename = g_dir_read_name(autosave_dir_ptr)) != NULL ){
+ if ( strncmp(filename, baseName, strlen(baseName)) == 0 ){
+ gchar* full_path = g_build_filename( autosave_dir.c_str(), filename, NULL );
+ if ( g_stat(full_path, &sb) != -1 ) {
+ if ( difftime(sb.st_ctime, min_time) < 0 || min_time == 0 ){
+ min_time = sb.st_ctime;
+ if ( oldest_autosave ) {
+ g_free(oldest_autosave);
+ }
+ oldest_autosave = g_strdup(full_path);
+ }
+ count ++;
+ }
+ g_free(full_path);
+ }
+ }
+
+ // g_debug("%d previous autosaves exists. Max = %d", count, autosave_max);
+
+ // Have we reached the limit for number of autosaves?
+ if ( count >= autosave_max ){
+ // Remove the oldest file
+ if ( oldest_autosave ) {
+ unlink(oldest_autosave);
+ }
+ }
+
+ if ( oldest_autosave ) {
+ g_free(oldest_autosave);
+ oldest_autosave = 0;
+ }
+
+
+ // Set the filename we will actually save to
+ g_free(baseName);
+ baseName = g_strdup_printf("inkscape-autosave-%d-%s-%03d.svg", uid, sptstr, docnum);
+ gchar* full_path = g_build_filename(autosave_dir.c_str(), baseName, NULL);
+ g_free(baseName);
+ baseName = 0;
+
+ // g_debug("Filename: %s", full_path);
+
+ // Try to save the file
+ FILE *file = Inkscape::IO::fopen_utf8name(full_path, "w");
+ gchar *errortext = 0;
+ if (file) {
+ try{
+ sp_repr_save_stream(repr->document(), file, SP_SVG_NS_URI);
+ } catch (Inkscape::Extension::Output::no_extension_found &e) {
+ errortext = g_strdup(_("Autosave failed! Could not find inkscape extension to save document."));
+ } catch (Inkscape::Extension::Output::save_failed &e) {
+ gchar *safeUri = Inkscape::IO::sanitizeString(full_path);
+ errortext = g_strdup_printf(_("Autosave failed! File %s could not be saved."), safeUri);
+ g_free(safeUri);
+ }
+ fclose(file);
+ }
+ else {
+ gchar *safeUri = Inkscape::IO::sanitizeString(full_path);
+ errortext = g_strdup_printf(_("Autosave failed! File %s could not be saved."), safeUri);
+ g_free(safeUri);
+ }
+
+ if (errortext) {
+ SP_ACTIVE_DESKTOP->messageStack()->flash(Inkscape::ERROR_MESSAGE, errortext);
+ g_warning("%s", errortext);
+ g_free(errortext);
+ }
+
+ g_free(full_path);
+ }
+ }
+ g_dir_close(autosave_dir_ptr);
+
+ SP_ACTIVE_DESKTOP->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Autosave complete."));
+
+ return TRUE;
+}
+
+void inkscape_autosave_init()
+{
+ static guint32 autosave_timeout_id = 0;
+
+ // Turn off any previously initiated timeouts
+ if ( autosave_timeout_id ) {
+ g_source_remove(autosave_timeout_id);
+ autosave_timeout_id = 0;
+ }
+
+ // g_debug("options.autosave.enable = %lld", prefs_get_int_attribute_limited("options.autosave", "enable", 1, 0, 1));
+ // Is autosave enabled?
+ if( prefs_get_int_attribute_limited("options.autosave", "enable", 1, 0, 1) != 1 ){
+ autosave_timeout_id = 0;
+ } else {
+ // Turn on autosave
+ guint32 timeout = prefs_get_int_attribute("options.autosave", "interval", 10) * 60;
+ // g_debug("options.autosave.interval = %lld", prefs_get_int_attribute("options.autosave", "interval", 10));
+ autosave_timeout_id = g_timeout_add_seconds(timeout, inkscape_autosave, NULL);
+ }
+}
+
static void
inkscape_init (SPObject * object)
@@ -623,6 +790,8 @@ inkscape_application_init (const gchar *argv0, gboolean use_gui)
/* Initialize the extensions */
Inkscape::Extension::init();
+ inkscape_autosave_init();
+
return;
}
diff --git a/src/inkscape.h b/src/inkscape.h
index 12f101901..90737cc41 100644
--- a/src/inkscape.h
+++ b/src/inkscape.h
@@ -29,6 +29,8 @@ namespace Inkscape {
#define INKSCAPE inkscape_get_instance()
+void inkscape_autosave_init();
+
void inkscape_application_init (const gchar *argv0, gboolean use_gui);
bool inkscape_load_config (const gchar *filename, Inkscape::XML::Document *config, const gchar *skeleton, unsigned int skel_size, const gchar *e_notreg, const gchar *e_notxml, const gchar *e_notsp, const gchar *warn);
diff --git a/src/preferences-skeleton.h b/src/preferences-skeleton.h
index d16e24e44..3fcb7f56b 100644
--- a/src/preferences-skeleton.h
+++ b/src/preferences-skeleton.h
@@ -264,6 +264,7 @@ static char const preferences_skeleton[] =
" masks=\"65535\"/>\n" // 0x0000ffff
" <group id=\"svgoutput\" usenamedcolors=\"0\" numericprecision=\"8\" minimumexponent=\"-8\" inlineattrs=\"0\" indent=\"2\" allowrelativecoordinates=\"1\" allowshorthands=\"1\" forcerepeatcommands=\"0\"/>\n"
" <group id=\"forkgradientvectors\" value=\"1\"/>\n"
+" <group id=\"autosave\" enable=\"0\" interval=\"10\" path=\"\" max=\"10\"/>\n"
" <group id=\"grids\""
" no_emphasize_when_zoomedout=\"0\">\n"
" <group id=\"xy\" "
diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp
index abea07641..82bde3834 100644
--- a/src/ui/dialog/inkscape-preferences.cpp
+++ b/src/ui/dialog/inkscape-preferences.cpp
@@ -986,6 +986,30 @@ void InkscapePreferences::initPageMisc()
_misc_simpl.init("options.simplifythreshold", "value", 0.0001, 1.0, 0.0001, 0.0010, 0.0010, false, false);
+ // Autosave options
+ _misc_autosave_enable.init( _("Enable auto-save of document"), "options.autosave", "enable", false);
+ _page_misc.add_line(false, "", _misc_autosave_enable, "", _("Automatically saves the current document to disk at a given interval, thus minimizing loss at a crash"), false);
+ _misc_autosave_interval.init("options.autosave", "interval", 1.0, 10800.0, 1.0, 10.0, 10.0, true, false);
+ _page_misc.add_line(true, _("Interval (in minutes):"), _misc_autosave_interval, "", _("Sets the interval (in minutes) at which a workspace will be automatically saved to disk"), false);
+ _misc_autosave_path.init("options.autosave", "path", true);
+ _page_misc.add_line(true, _("Path:"), _misc_autosave_path, "", _("Sets the directory where autosaves will be written"), false);
+ _misc_autosave_max.init("options.autosave", "max", 1.0, 100.0, 1.0, 10.0, 10.0, true, false);
+ _page_misc.add_line(true, _("Maximum number of autosaves"), _misc_autosave_max, "", _("Allows for limiting the space used by autosaves, by setting a maximum number of allowed files"), false);
+
+ /* When changing the interval or enabling/disabling the autosave function,
+ * update our running configuration
+ *
+ * FIXME!
+ * the inkscape_autosave_init should be called AFTER the values have been changed
+ * (which cannot be guaranteed from here)
+ *
+ * For now, autosave-settings will not change until restart
+ */
+ /*
+ _misc_autosave_enable.signal_toggled().connect( sigc::ptr_fun(inkscape_autosave_init), TRUE );
+ _misc_autosave_interval.signal_changed().connect( sigc::ptr_fun(inkscape_autosave_init), TRUE );
+ */
+
// -----------
_misc_bitmap_autoreload.init(_("Automatically reload bitmaps"), "options.bitmapautoreload", "value", true);
diff --git a/src/ui/dialog/inkscape-preferences.h b/src/ui/dialog/inkscape-preferences.h
index ac378bf98..22944d42a 100644
--- a/src/ui/dialog/inkscape-preferences.h
+++ b/src/ui/dialog/inkscape-preferences.h
@@ -169,6 +169,10 @@ protected:
PrefCombo _misc_overs_bitmap;
PrefCombo _misc_bitmap_editor;
PrefCheckButton _misc_bitmap_autoreload;
+ PrefCheckButton _misc_autosave_enable;
+ PrefSpinButton _misc_autosave_interval;
+ PrefEntry _misc_autosave_path;
+ PrefSpinButton _misc_autosave_max;
Gtk::ComboBoxText _cms_display_profile;
PrefCheckButton _cms_from_display;