summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 12a29c6)
raw | patch | inline | side by side (parent: 12a29c6)
author | joncruz <joncruz@users.sourceforge.net> | |
Thu, 12 Jun 2008 09:53:24 +0000 (09:53 +0000) | ||
committer | joncruz <joncruz@users.sourceforge.net> | |
Thu, 12 Jun 2008 09:53:24 +0000 (09:53 +0000) |
diff --git a/src/inkscape.cpp b/src/inkscape.cpp
index b4f6808ce758d3b6df72a1f22e929824e2bfb566..e3667e1f3f66bdf7824d856d547fdb30046cf76a 100644 (file)
--- a/src/inkscape.cpp
+++ b/src/inkscape.cpp
#include <gtk/gtkmain.h>
#include <gtk/gtkmessagedialog.h>
+#include <glib.h>
+#include <glib/gstdio.h>
#include <glibmm/i18n.h>
#include <string>
#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;
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)
/* Initialize the extensions */
Inkscape::Extension::init();
+ inkscape_autosave_init();
+
return;
}
diff --git a/src/inkscape.h b/src/inkscape.h
index 12f101901873a7629d4303020f54a9e861e802ff..90737cc41b130550fcd3674b508190ed3d1049e0 100644 (file)
--- a/src/inkscape.h
+++ b/src/inkscape.h
#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);
index d16e24e4434ff2f4537f62f261a44025cd42fb40..3fcb7f56b96f6fc764317768bfa2e5a2b66ba2c4 100644 (file)
" 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\" "
index abea076412b355ca2d26373f38c4551ccf4856bd..82bde38346924ea1685f4b0b44dea11f8941bd31 100644 (file)
_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);
index ac378bf98e7c1d680c35fdaecbe5cbbb15026a34..22944d42a7b061dda43a1bf0cb17015fa0f4c83d 100644 (file)
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;