Code

Changed preference to use file chooser button
[inkscape.git] / src / inkscape.cpp
index 71c5d422fcb4217868ff36a7b6341b3933becf01..7e46efce6eb672e94fc91a195ff82bc2e9a5dc47 100644 (file)
@@ -18,6 +18,7 @@
 #endif
 
 
+#include <set>
 #include "debug/simple-event.h"
 #include "debug/event-tracker.h"
 
@@ -109,12 +110,14 @@ static bool inkscape_init_config (Inkscape::XML::Document *doc, const gchar *con
 struct Inkscape::Application {
     GObject object;
     Inkscape::XML::Document *menus;
+    std::multiset<SPDocument *> document_set;
     GSList *documents;
     GSList *desktops;
     gchar *argv0;
     gboolean dialogs_toggle;
     gboolean use_gui;         // may want to consider a virtual function
                               // for overriding things like the warning dlg's
+    guint mapalt;
 };
 
 struct Inkscape::ApplicationClass {
@@ -139,7 +142,11 @@ struct Inkscape::ApplicationClass {
 static GObjectClass * parent_class;
 static guint inkscape_signals[LAST_SIGNAL] = {0};
 
-static void (* segv_handler) (int) = NULL;
+static void (* segv_handler) (int) = SIG_DFL;
+static void (* abrt_handler) (int) = SIG_DFL;
+static void (* fpe_handler)  (int) = SIG_DFL;
+static void (* ill_handler)  (int) = SIG_DFL;
+static void (* bus_handler)  (int) = SIG_DFL;
 
 #ifdef WIN32
 #define INKSCAPE_PROFILE_DIR "Inkscape"
@@ -288,14 +295,17 @@ inkscape_init (SPObject * object)
         g_assert_not_reached ();
     }
 
+    new (&inkscape->document_set) std::multiset<SPDocument *>();
+
     inkscape->menus = sp_repr_read_mem (_(menus_skeleton), MENUS_SKELETON_SIZE, NULL);
 
     inkscape->documents = NULL;
     inkscape->desktops = NULL;
 
     inkscape->dialogs_toggle = TRUE;
-}
 
+    inkscape->mapalt=GDK_MOD1_MASK;    
+}
 
 static void
 inkscape_dispose (GObject *object)
@@ -317,6 +327,8 @@ inkscape_dispose (GObject *object)
         inkscape->menus = NULL;
     }
 
+    inkscape->document_set.~multiset();
+
     G_OBJECT_CLASS (parent_class)->dispose (object);
 
     gtk_main_quit ();
@@ -338,6 +350,22 @@ inkscape_unref (void)
         g_object_unref (G_OBJECT (inkscape));
 }
 
+/* returns the mask of the keyboard modifier to map to Alt, zero if no mapping */
+/* Needs to be a guint because gdktypes.h does not define a 'no-modifier' value */
+guint
+inkscape_mapalt() {
+    return inkscape->mapalt;
+}
+
+/* Sets the keyboard modifer to map to Alt. Zero switches off mapping, as does '1', which is the default */
+void inkscape_mapalt(guint maskvalue)
+{
+    if(maskvalue<2 || maskvalue> 5 ){  /* MOD5 is the highest defined in gdktypes.h */
+        inkscape->mapalt=0;
+    }else{
+        inkscape->mapalt=(GDK_MOD1_MASK << (maskvalue-1));
+    }
+}
 
 static void
 inkscape_activate_desktop_private (Inkscape::Application *inkscape, SPDesktop *desktop)
@@ -359,7 +387,7 @@ inkscape_deactivate_desktop_private (Inkscape::Application *inkscape, SPDesktop
 
 
 static void
-inkscape_segv_handler (int signum)
+inkscape_crash_handler (int signum)
 {
     using Inkscape::Debug::SimpleEvent;
     using Inkscape::Debug::EventTracker;
@@ -367,10 +395,19 @@ inkscape_segv_handler (int signum)
 
     static gint recursion = FALSE;
 
-    /* let any SIGABRTs seen from within this handler dump core */
-    signal(SIGABRT, SIG_DFL);
-
-    /* Kill loops */
+    /* 
+     * reset all signal handlers: any further crashes should just be allowed
+     * to crash normally.
+     * */
+    signal (SIGSEGV, segv_handler );
+    signal (SIGABRT, abrt_handler );
+    signal (SIGFPE,  fpe_handler  );
+    signal (SIGILL,  ill_handler  );
+#ifndef WIN32
+    signal (SIGBUS,  bus_handler  );
+#endif
+    
+    /* Stop bizarre loops */
     if (recursion) {
         abort ();
     }
@@ -439,7 +476,7 @@ inkscape_segv_handler (int signum)
                 file = Inkscape::IO::fopen_utf8name(c, "w");
             }
             if (file) {
-                sp_repr_save_stream (sp_repr_document (repr), file, SP_SVG_NS_URI);
+                sp_repr_save_stream (repr->document(), file, SP_SVG_NS_URI);
                 savednames = g_slist_prepend (savednames, g_strdup (c));
                 fclose (file);
             } else {
@@ -473,9 +510,9 @@ inkscape_segv_handler (int signum)
 
     /* Show nice dialog box */
 
-    char const *istr = N_("Inkscape encountered an internal error and will close now.\n");
-    char const *sstr = N_("Automatic backups of unsaved documents were done to the following locations:\n");
-    char const *fstr = N_("Automatic backup of the following documents failed:\n");
+    char const *istr = _("Inkscape encountered an internal error and will close now.\n");
+    char const *sstr = _("Automatic backups of unsaved documents were done to the following locations:\n");
+    char const *fstr = _("Automatic backup of the following documents failed:\n");
     gint nllen = strlen ("\n");
     gint len = strlen (istr) + strlen (sstr) + strlen (fstr);
     for (GSList *l = savednames; l != NULL; l = l->next) {
@@ -534,7 +571,7 @@ inkscape_segv_handler (int signum)
     tracker.clear();
     Logger::shutdown();
 
-    (* segv_handler) (signum);
+    /* on exit, allow restored signal handler to take over and crash us */
 }
 
 
@@ -545,13 +582,13 @@ inkscape_application_init (const gchar *argv0, gboolean use_gui)
     inkscape = (Inkscape::Application *)g_object_new (SP_TYPE_INKSCAPE, NULL);
     /* fixme: load application defaults */
 
-    segv_handler = signal (SIGSEGV, inkscape_segv_handler);
-    signal (SIGFPE,  inkscape_segv_handler);
-    signal (SIGILL,  inkscape_segv_handler);
+    segv_handler = signal (SIGSEGV, inkscape_crash_handler);
+    abrt_handler = signal (SIGABRT, inkscape_crash_handler);
+    fpe_handler  = signal (SIGFPE,  inkscape_crash_handler);
+    ill_handler  = signal (SIGILL,  inkscape_crash_handler);
 #ifndef WIN32
-    signal (SIGBUS,  inkscape_segv_handler);
+    bus_handler  = signal (SIGBUS,  inkscape_crash_handler);
 #endif
-    signal (SIGABRT, inkscape_segv_handler);
 
     inkscape->use_gui = use_gui;
     inkscape->argv0 = g_strdup(argv0);
@@ -561,16 +598,24 @@ inkscape_application_init (const gchar *argv0, gboolean use_gui)
     Inkscape::Preferences::load();
     inkscape_load_menus(inkscape);
 
-    /* DebugDialog redirection.  On Linux, default to OFF, on Win32, default to ON */
+    /* DebugDialog redirection.  On Linux, default to OFF, on Win32, default to ON.
+        * Use only if use_gui is enabled 
+        */
 #ifdef WIN32
 #define DEFAULT_LOG_REDIRECT true
 #else
 #define DEFAULT_LOG_REDIRECT false
 #endif
 
-    if (prefs_get_int_attribute("dialogs.debug", "redirect", DEFAULT_LOG_REDIRECT))
+    if (use_gui == TRUE && prefs_get_int_attribute("dialogs.debug", "redirect", DEFAULT_LOG_REDIRECT))
+    {
+               Inkscape::UI::Dialogs::DebugDialog::getInstance()->captureLogMessages();
+    }
+
+    /* Check for global remapping of Alt key */
+    if(use_gui)
     {
-        Inkscape::UI::Dialogs::DebugDialog::getInstance()->captureLogMessages();
+        inkscape_mapalt(guint(prefs_get_int_attribute("options.mapalt","value",0)));
     }
 
     /* Initialize the extensions */
@@ -643,7 +688,7 @@ inkscape_load_config (const gchar *filename, Inkscape::XML::Document *config, co
         return false;
     }
 
-    Inkscape::XML::Node *root = sp_repr_document_root (doc);
+    Inkscape::XML::Node *root = doc->root();
     if (strcmp (root->name(), "inkscape")) {
         gchar *safeFn = Inkscape::IO::sanitizeString(fn);
         GtkWidget *w = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, e_notsp, safeFn, warn);
@@ -706,11 +751,17 @@ inkscape_load_menus (Inkscape::Application *inkscape)
 Inkscape::XML::Node *
 inkscape_get_repr (Inkscape::Application *inkscape, const gchar *key)
 {
-    if (key == NULL) {
+    if ( (key == NULL) || (inkscape == NULL) ) {
         return NULL;
     }
 
-    Inkscape::XML::Node *repr = sp_repr_document_root (Inkscape::Preferences::get());
+    Inkscape::XML::Node *prefs = Inkscape::Preferences::get();
+    if ( !prefs ) {
+        return NULL;
+    }
+
+    Inkscape::XML::Node *repr = prefs->root();
+    if (!repr) return NULL;
     g_assert (!(strcmp (repr->name(), "inkscape")));
 
     gchar const *s = key;
@@ -839,9 +890,9 @@ inkscape_add_desktop (SPDesktop * desktop)
 
     if (DESKTOP_IS_ACTIVE (desktop)) {
         g_signal_emit (G_OBJECT (inkscape), inkscape_signals[ACTIVATE_DESKTOP], 0, desktop);
-        g_signal_emit (G_OBJECT (inkscape), inkscape_signals[SET_EVENTCONTEXT], 0, SP_DT_EVENTCONTEXT (desktop));
-        g_signal_emit (G_OBJECT (inkscape), inkscape_signals[SET_SELECTION], 0, SP_DT_SELECTION (desktop));
-        g_signal_emit (G_OBJECT (inkscape), inkscape_signals[CHANGE_SELECTION], 0, SP_DT_SELECTION (desktop));
+        g_signal_emit (G_OBJECT (inkscape), inkscape_signals[SET_EVENTCONTEXT], 0, sp_desktop_event_context (desktop));
+        g_signal_emit (G_OBJECT (inkscape), inkscape_signals[SET_SELECTION], 0, sp_desktop_selection (desktop));
+        g_signal_emit (G_OBJECT (inkscape), inkscape_signals[CHANGE_SELECTION], 0, sp_desktop_selection (desktop));
     }
 }
 
@@ -867,13 +918,13 @@ inkscape_remove_desktop (SPDesktop * desktop)
             inkscape->desktops = g_slist_remove (inkscape->desktops, new_desktop);
             inkscape->desktops = g_slist_prepend (inkscape->desktops, new_desktop);
             g_signal_emit (G_OBJECT (inkscape), inkscape_signals[ACTIVATE_DESKTOP], 0, new_desktop);
-            g_signal_emit (G_OBJECT (inkscape), inkscape_signals[SET_EVENTCONTEXT], 0, SP_DT_EVENTCONTEXT (new_desktop));
-            g_signal_emit (G_OBJECT (inkscape), inkscape_signals[SET_SELECTION], 0, SP_DT_SELECTION (new_desktop));
-            g_signal_emit (G_OBJECT (inkscape), inkscape_signals[CHANGE_SELECTION], 0, SP_DT_SELECTION (new_desktop));
+            g_signal_emit (G_OBJECT (inkscape), inkscape_signals[SET_EVENTCONTEXT], 0, sp_desktop_event_context (new_desktop));
+            g_signal_emit (G_OBJECT (inkscape), inkscape_signals[SET_SELECTION], 0, sp_desktop_selection (new_desktop));
+            g_signal_emit (G_OBJECT (inkscape), inkscape_signals[CHANGE_SELECTION], 0, sp_desktop_selection (new_desktop));
         } else {
             g_signal_emit (G_OBJECT (inkscape), inkscape_signals[SET_EVENTCONTEXT], 0, NULL);
-            if (SP_DT_SELECTION(desktop))
-                SP_DT_SELECTION(desktop)->clear();
+            if (sp_desktop_selection(desktop))
+                sp_desktop_selection(desktop)->clear();
         }
     }
 
@@ -912,9 +963,9 @@ inkscape_activate_desktop (SPDesktop * desktop)
     inkscape->desktops = g_slist_prepend (inkscape->desktops, desktop);
 
     g_signal_emit (G_OBJECT (inkscape), inkscape_signals[ACTIVATE_DESKTOP], 0, desktop);
-    g_signal_emit (G_OBJECT (inkscape), inkscape_signals[SET_EVENTCONTEXT], 0, SP_DT_EVENTCONTEXT (desktop));
-    g_signal_emit (G_OBJECT (inkscape), inkscape_signals[SET_SELECTION], 0, SP_DT_SELECTION (desktop));
-    g_signal_emit (G_OBJECT (inkscape), inkscape_signals[CHANGE_SELECTION], 0, SP_DT_SELECTION (desktop));
+    g_signal_emit (G_OBJECT (inkscape), inkscape_signals[SET_EVENTCONTEXT], 0, sp_desktop_event_context (desktop));
+    g_signal_emit (G_OBJECT (inkscape), inkscape_signals[SET_SELECTION], 0, sp_desktop_selection (desktop));
+    g_signal_emit (G_OBJECT (inkscape), inkscape_signals[CHANGE_SELECTION], 0, sp_desktop_selection (desktop));
 }
 
 
@@ -1096,8 +1147,11 @@ inkscape_add_document (SPDocument *document)
 
     if (!Inkscape::NSApplication::Application::getNewGui())
     {
-        g_assert (!g_slist_find (inkscape->documents, document));
-        inkscape->documents = g_slist_append (inkscape->documents, document);
+        if ( inkscape->document_set.find(document) != inkscape->document_set.end() ) {
+    
+            inkscape->documents = g_slist_append (inkscape->documents, document);
+        }
+        inkscape->document_set.insert(document);
     }
     else
     {
@@ -1114,8 +1168,10 @@ inkscape_remove_document (SPDocument *document)
 
     if (!Inkscape::NSApplication::Application::getNewGui())
     {
-        g_assert (g_slist_find (inkscape->documents, document));
-        inkscape->documents = g_slist_remove (inkscape->documents, document);
+        inkscape->document_set.erase(document);
+        if ( inkscape->document_set.find(document) == inkscape->document_set.end() ) {
+            inkscape->documents = g_slist_remove (inkscape->documents, document);
+        }
     }
     else
     {
@@ -1145,7 +1201,7 @@ inkscape_active_document (void)
         return Inkscape::NSApplication::Editor::getActiveDocument();
 
     if (SP_ACTIVE_DESKTOP) {
-        return SP_DT_DOCUMENT (SP_ACTIVE_DESKTOP);
+        return sp_desktop_document (SP_ACTIVE_DESKTOP);
     }
 
     return NULL;
@@ -1170,7 +1226,7 @@ SPEventContext *
 inkscape_active_event_context (void)
 {
     if (SP_ACTIVE_DESKTOP) {
-        return SP_DT_EVENTCONTEXT (SP_ACTIVE_DESKTOP);
+        return sp_desktop_event_context (SP_ACTIVE_DESKTOP);
     }
 
     return NULL;
@@ -1211,6 +1267,29 @@ inkscape_init_config (Inkscape::XML::Document *doc, const gchar *config_name, co
                 return false;
             }
         }
+
+        // Also create (empty for now) subdirectories for the user's stuff
+        {
+            gchar *temp_dn = profile_path("templates");
+            Inkscape::IO::mkdir_utf8name(temp_dn);
+        }
+        {
+            gchar *temp_dn = profile_path("keys");
+            Inkscape::IO::mkdir_utf8name(temp_dn);
+        }
+        {
+            gchar *temp_dn = profile_path("icons");
+            Inkscape::IO::mkdir_utf8name(temp_dn);
+        }
+        {
+            gchar *temp_dn = profile_path("extensions");
+            Inkscape::IO::mkdir_utf8name(temp_dn);
+        }
+        {
+            gchar *temp_dn = profile_path("palettes");
+            Inkscape::IO::mkdir_utf8name(temp_dn);
+        }
+
     } else if (!Inkscape::IO::file_test(dn, G_FILE_TEST_IS_DIR)) {
         if (use_gui) {
             // Not a directory
@@ -1394,11 +1473,19 @@ profile_path(const char *filename)
 Inkscape::XML::Node *
 inkscape_get_menus (Inkscape::Application * inkscape)
 {
-    Inkscape::XML::Node *repr = sp_repr_document_root (inkscape->menus);
+    Inkscape::XML::Node *repr = inkscape->menus->root();
     g_assert (!(strcmp (repr->name(), "inkscape")));
     return repr->firstChild();
 }
 
+void
+inkscape_get_all_desktops(std::list< SPDesktop* >& listbuf)
+{
+    for(GSList* l = inkscape->desktops; l != NULL; l = l->next) {
+        listbuf.push_back(static_cast< SPDesktop* >(l->data));
+    }
+}
+
 
 
 /*