Code

Extensions. Add option to choose dxf output units
[inkscape.git] / src / inkscape.cpp
index 8506f05de30e8cc0a96a51f1e9974916f5d5199c..4309775675cd95924f7bb72ee6b2affc72059513 100644 (file)
@@ -45,18 +45,16 @@ using Inkscape::Extension::Internal::PrintWin32;
 #include <gtkmm/messagedialog.h>
 #include <signal.h>
 #include <string>
-#include "application/application.h"
-#include "application/editor.h"
 #include "desktop.h"
 #include "desktop-handles.h"
-#include "dialogs/input.h"
+#include "device-manager.h"
 #include "document.h"
 #include "event-context.h"
 #include "extension/db.h"
 #include "extension/init.h"
 #include "extension/output.h"
 #include "extension/system.h"
-#include "helper/sp-marshal.h"
+//#include "helper/sp-marshal.h"
 #include "inkscape-private.h"
 #include "io/sys.h"
 #include "message-stack.h"
@@ -93,8 +91,6 @@ enum {
 # FORWARD DECLARATIONS
 ################################*/
 
-gboolean inkscape_app_use_gui( Inkscape::Application const * app );
-
 static void inkscape_class_init (Inkscape::ApplicationClass *klass);
 static void inkscape_init (SPObject *object);
 static void inkscape_dispose (GObject *object);
@@ -193,7 +189,7 @@ inkscape_class_init (Inkscape::ApplicationClass * klass)
                                G_SIGNAL_RUN_FIRST,
                                G_STRUCT_OFFSET (Inkscape::ApplicationClass, modify_selection),
                                NULL, NULL,
-                               sp_marshal_NONE__POINTER_UINT,
+                               g_cclosure_marshal_VOID__UINT_POINTER,
                                G_TYPE_NONE, 2,
                                G_TYPE_POINTER, G_TYPE_UINT);
     inkscape_signals[CHANGE_SELECTION] = g_signal_new ("change_selection",
@@ -201,7 +197,7 @@ inkscape_class_init (Inkscape::ApplicationClass * klass)
                                G_SIGNAL_RUN_FIRST,
                                G_STRUCT_OFFSET (Inkscape::ApplicationClass, change_selection),
                                NULL, NULL,
-                               sp_marshal_NONE__POINTER,
+                               g_cclosure_marshal_VOID__POINTER,
                                G_TYPE_NONE, 1,
                                G_TYPE_POINTER);
     inkscape_signals[CHANGE_SUBSELECTION] = g_signal_new ("change_subselection",
@@ -209,7 +205,7 @@ inkscape_class_init (Inkscape::ApplicationClass * klass)
                                G_SIGNAL_RUN_FIRST,
                                G_STRUCT_OFFSET (Inkscape::ApplicationClass, change_subselection),
                                NULL, NULL,
-                               sp_marshal_NONE__POINTER,
+                               g_cclosure_marshal_VOID__POINTER,
                                G_TYPE_NONE, 1,
                                G_TYPE_POINTER);
     inkscape_signals[SET_SELECTION] =    g_signal_new ("set_selection",
@@ -217,7 +213,7 @@ inkscape_class_init (Inkscape::ApplicationClass * klass)
                                G_SIGNAL_RUN_FIRST,
                                G_STRUCT_OFFSET (Inkscape::ApplicationClass, set_selection),
                                NULL, NULL,
-                               sp_marshal_NONE__POINTER,
+                               g_cclosure_marshal_VOID__POINTER,
                                G_TYPE_NONE, 1,
                                G_TYPE_POINTER);
     inkscape_signals[SET_EVENTCONTEXT] = g_signal_new ("set_eventcontext",
@@ -225,7 +221,7 @@ inkscape_class_init (Inkscape::ApplicationClass * klass)
                                G_SIGNAL_RUN_FIRST,
                                G_STRUCT_OFFSET (Inkscape::ApplicationClass, set_eventcontext),
                                NULL, NULL,
-                               sp_marshal_NONE__POINTER,
+                               g_cclosure_marshal_VOID__POINTER,
                                G_TYPE_NONE, 1,
                                G_TYPE_POINTER);
     inkscape_signals[ACTIVATE_DESKTOP] = g_signal_new ("activate_desktop",
@@ -233,7 +229,7 @@ inkscape_class_init (Inkscape::ApplicationClass * klass)
                                G_SIGNAL_RUN_FIRST,
                                G_STRUCT_OFFSET (Inkscape::ApplicationClass, activate_desktop),
                                NULL, NULL,
-                               sp_marshal_NONE__POINTER,
+                               g_cclosure_marshal_VOID__POINTER,
                                G_TYPE_NONE, 1,
                                G_TYPE_POINTER);
     inkscape_signals[DEACTIVATE_DESKTOP] = g_signal_new ("deactivate_desktop",
@@ -241,7 +237,7 @@ inkscape_class_init (Inkscape::ApplicationClass * klass)
                                G_SIGNAL_RUN_FIRST,
                                G_STRUCT_OFFSET (Inkscape::ApplicationClass, deactivate_desktop),
                                NULL, NULL,
-                               sp_marshal_NONE__POINTER,
+                               g_cclosure_marshal_VOID__POINTER,
                                G_TYPE_NONE, 1,
                                G_TYPE_POINTER);
     inkscape_signals[SHUTDOWN_SIGNAL] =        g_signal_new ("shut_down",
@@ -334,8 +330,8 @@ static gint inkscape_autosave(gpointer)
 
         ++docnum;
 
-        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)");
+        Inkscape::XML::Node *repr = doc->getReprRoot();
+        // g_debug("Document %d: \"%s\" %s", docnum, doc ? doc->getName() : "(null)", doc ? (doc->isModifiedSinceSave() ? "(dirty)" : "(clean)") : "(null)");
 
         if (doc->isModifiedSinceSave()) {
             gchar *oldest_autosave = 0;
@@ -534,7 +530,7 @@ inkscape_trackalt() {
 
 void inkscape_trackalt(guint trackvalue)
 {
-       inkscape->trackalt = trackvalue;
+    inkscape->trackalt = trackvalue;
 }
 
 
@@ -557,6 +553,13 @@ inkscape_deactivate_desktop_private (Inkscape::Application */*inkscape*/, SPDesk
 #define SP_INDENT 8
 
 
+static bool crashIsHappening = false;
+
+bool inkscapeIsCrashing()
+{
+    return crashIsHappening;
+}
+
 static void
 inkscape_crash_handler (int /*signum*/)
 {
@@ -584,6 +587,8 @@ inkscape_crash_handler (int /*signum*/)
     }
     recursion = TRUE;
 
+    crashIsHappening = true;
+
     EventTracker<SimpleEvent<Inkscape::Debug::Event::CORE> > tracker("crash");
     tracker.set<SimpleEvent<> >("emergency-save");
 
@@ -595,6 +600,8 @@ inkscape_crash_handler (int /*signum*/)
     strftime (sptstr, 256, "%Y_%m_%d_%H_%M_%S", sptm);
 
     gint count = 0;
+    gchar *curdir = g_get_current_dir(); // This one needs to be freed explicitly
+    gchar *inkscapedir = g_path_get_dirname(INKSCAPE->argv0); // Needs to be freed
     GSList *savednames = NULL;
     GSList *failednames = NULL;
     for (std::map<SPDocument*,int>::iterator iter = inkscape->document_set.begin();
@@ -602,67 +609,71 @@ inkscape_crash_handler (int /*signum*/)
           ++iter) {
         SPDocument *doc = iter->first;
         Inkscape::XML::Node *repr;
-        repr = sp_document_repr_root (doc);
+        repr = doc->getReprRoot();
         if (doc->isModifiedSinceSave()) {
-            const gchar *docname, *d0, *d;
-            gchar n[64], c[1024];
-            FILE *file;
+            const gchar *docname;
 
             /* originally, the document name was retrieved from
              * the sodipod:docname attribute */
-            docname = doc->name;
+            docname = doc->getName();
             if (docname) {
-                /* fixme: Quick hack to remove emergency file suffix */
-                d0 = strrchr ((char*)docname, '.');
+                /* Removes an emergency save suffix if present: /(.*)\.[0-9_]*\.[0-9_]*\.[~\.]*$/\1/ */
+                const char* d0 = strrchr ((char*)docname, '.');
                 if (d0 && (d0 > docname)) {
-                    d0 = strrchr ((char*)(d0 - 1), '.');
-                    if (d0 && (d0 > docname)) {
-                        d = d0;
-                        while (isdigit (*d) || (*d == '.') || (*d == '_')) d += 1;
-                        if (*d) {
-                            memcpy (n, docname, MIN (d0 - docname - 1, 64));
-                            n[63] = '\0';
-                            docname = n;
-                        }
+                    const char* d = d0;
+                    unsigned int dots = 0;
+                    while ((isdigit (*d) || *d=='_' || *d=='.') && d>docname && dots<2) {
+                        d -= 1;
+                        if (*d=='.') dots++;
+                    }
+                    if (*d=='.' && d>docname && dots==2) {
+                        char n[64];
+                        size_t len = MIN (d - docname, 63);
+                        memcpy (n, docname, len);
+                        n[len] = '\0';
+                        docname = n;
                     }
                 }
             }
-
             if (!docname || !*docname) docname = "emergency";
-            // try saving to the profile location
+
+            // Emergency filename
+            char c[1024];
             g_snprintf (c, 1024, "%.256s.%s.%d.svg", docname, sptstr, count);
-            gchar * location = homedir_path(c);
-            Inkscape::IO::dump_fopen_call(location, "E");
-            file = Inkscape::IO::fopen_utf8name(location, "w");
-            g_snprintf (c, 1024, "%s", location); // we want the complete path to be stored in c (for reporting purposes)
-            g_free(location);
-            if (!file) {
-                // try saving to /tmp
-                g_snprintf (c, 1024, "/tmp/inkscape-%.256s.%s.%d.svg", docname, sptstr, count);
-                Inkscape::IO::dump_fopen_call(c, "G");
-                file = Inkscape::IO::fopen_utf8name(c, "w");
-            }
-            if (!file) {
-                // try saving to the current directory
-                gchar *curdir = g_get_current_dir();
-                g_snprintf (c, 1024, "inkscape-%.256s.%s.%d.svg", docname, sptstr, count);
-                Inkscape::IO::dump_fopen_call(c, "F");
-                file = Inkscape::IO::fopen_utf8name(c, "w");
-                // store the complete path in c so that it can be reported later
-                gchar * location = g_build_filename(curdir, c, NULL);
-                g_snprintf (c, 1024, "%s", location);
-                g_free(location);
+
+            // Find a location
+            const char* locations[] = {
+                doc->getBase(),
+                g_get_home_dir(),
+                g_get_tmp_dir(),
+                curdir,
+                inkscapedir
+            };
+            FILE *file = 0;
+            for(size_t i=0; i<sizeof(locations)/sizeof(*locations); i++) {
+                if (!locations[i]) continue; // It seems to be okay, but just in case
+                gchar * filename = g_build_filename(locations[i], c, NULL);
+                Inkscape::IO::dump_fopen_call(filename, "E");
+                file = Inkscape::IO::fopen_utf8name(filename, "w");
+                if (file) {
+                    g_snprintf (c, 1024, "%s", filename); // we want the complete path to be stored in c (for reporting purposes)
+                    break;
+                }
             }
+
+            // Save
             if (file) {
                 sp_repr_save_stream (repr->document(), file, SP_SVG_NS_URI);
                 savednames = g_slist_prepend (savednames, g_strdup (c));
                 fclose (file);
             } else {
-                failednames = g_slist_prepend (failednames, (doc->name) ? g_strdup (doc->name) : g_strdup (_("Untitled document")));
+                failednames = g_slist_prepend (failednames, (doc->getName()) ? g_strdup(doc->getName()) : g_strdup (_("Untitled document")));
             }
             count++;
         }
     }
+    g_free(curdir);
+    g_free(inkscapedir);
 
     savednames = g_slist_reverse (savednames);
     failednames = g_slist_reverse (failednames);
@@ -735,7 +746,7 @@ inkscape_crash_handler (int /*signum*/)
     }
     *(b + pos) = '\0';
 
-    if ( inkscape_get_instance() && inkscape_app_use_gui( inkscape_get_instance() ) ) {
+    if ( inkscape_get_instance() && inkscape_use_gui() ) {
         GtkWidget *msgbox = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, "%s", b);
         gtk_dialog_run (GTK_DIALOG (msgbox));
         gtk_widget_destroy (msgbox);
@@ -807,7 +818,7 @@ inkscape_application_init (const gchar *argv0, gboolean use_gui)
 
     if (use_gui) {
         inkscape_load_menus(inkscape);
-        sp_input_load_from_preferences();
+        Inkscape::DeviceManager::getManager().loadConfig();
     }
 
     /* set language for user interface according setting in preferences */
@@ -855,9 +866,9 @@ inkscape_get_instance()
         return inkscape;
 }
 
-gboolean inkscape_app_use_gui( Inkscape::Application const * app )
+gboolean inkscape_use_gui()
 {
-    return app->use_gui;
+    return inkscape_get_instance()->use_gui;
 }
 
 /**
@@ -887,10 +898,6 @@ bool inkscape_load_menus (Inkscape::Application */*inkscape*/)
 void
 inkscape_selection_modified (Inkscape::Selection *selection, guint flags)
 {
-    if (Inkscape::NSApplication::Application::getNewGui()) {
-        Inkscape::NSApplication::Editor::selectionModified (selection, flags);
-        return;
-    }
     g_return_if_fail (selection != NULL);
 
     if (DESKTOP_IS_ACTIVE (selection->desktop())) {
@@ -902,10 +909,6 @@ inkscape_selection_modified (Inkscape::Selection *selection, guint flags)
 void
 inkscape_selection_changed (Inkscape::Selection * selection)
 {
-    if (Inkscape::NSApplication::Application::getNewGui()) {
-        Inkscape::NSApplication::Editor::selectionChanged (selection);
-        return;
-    }
     g_return_if_fail (selection != NULL);
 
     if (DESKTOP_IS_ACTIVE (selection->desktop())) {
@@ -916,10 +919,6 @@ inkscape_selection_changed (Inkscape::Selection * selection)
 void
 inkscape_subselection_changed (SPDesktop *desktop)
 {
-    if (Inkscape::NSApplication::Application::getNewGui()) {
-        Inkscape::NSApplication::Editor::subSelectionChanged (desktop);
-        return;
-    }
     g_return_if_fail (desktop != NULL);
 
     if (DESKTOP_IS_ACTIVE (desktop)) {
@@ -931,10 +930,6 @@ inkscape_subselection_changed (SPDesktop *desktop)
 void
 inkscape_selection_set (Inkscape::Selection * selection)
 {
-    if (Inkscape::NSApplication::Application::getNewGui()) {
-        Inkscape::NSApplication::Editor::selectionSet (selection);
-        return;
-    }
     g_return_if_fail (selection != NULL);
 
     if (DESKTOP_IS_ACTIVE (selection->desktop())) {
@@ -947,10 +942,6 @@ inkscape_selection_set (Inkscape::Selection * selection)
 void
 inkscape_eventcontext_set (SPEventContext * eventcontext)
 {
-    if (Inkscape::NSApplication::Application::getNewGui()) {
-        Inkscape::NSApplication::Editor::eventContextSet (eventcontext);
-        return;
-    }
     g_return_if_fail (eventcontext != NULL);
     g_return_if_fail (SP_IS_EVENT_CONTEXT (eventcontext));
 
@@ -964,12 +955,6 @@ void
 inkscape_add_desktop (SPDesktop * desktop)
 {
     g_return_if_fail (desktop != NULL);
-
-    if (Inkscape::NSApplication::Application::getNewGui())
-    {
-        Inkscape::NSApplication::Editor::addDesktop (desktop);
-        return;
-    }
     g_return_if_fail (inkscape != NULL);
 
     g_assert (!g_slist_find (inkscape->desktops, desktop));
@@ -988,11 +973,6 @@ void
 inkscape_remove_desktop (SPDesktop * desktop)
 {
     g_return_if_fail (desktop != NULL);
-    if (Inkscape::NSApplication::Application::getNewGui())
-    {
-        Inkscape::NSApplication::Editor::removeDesktop (desktop);
-        return;
-    }
     g_return_if_fail (inkscape != NULL);
 
     g_assert (g_slist_find (inkscape->desktops, desktop));
@@ -1028,11 +1008,6 @@ void
 inkscape_activate_desktop (SPDesktop * desktop)
 {
     g_return_if_fail (desktop != NULL);
-    if (Inkscape::NSApplication::Application::getNewGui())
-    {
-        Inkscape::NSApplication::Editor::activateDesktop (desktop);
-        return;
-    }
     g_return_if_fail (inkscape != NULL);
 
     if (DESKTOP_IS_ACTIVE (desktop)) {
@@ -1062,11 +1037,6 @@ void
 inkscape_reactivate_desktop (SPDesktop * desktop)
 {
     g_return_if_fail (desktop != NULL);
-    if (Inkscape::NSApplication::Application::getNewGui())
-    {
-        Inkscape::NSApplication::Editor::reactivateDesktop (desktop);
-        return;
-    }
     g_return_if_fail (inkscape != NULL);
 
     if (DESKTOP_IS_ACTIVE (desktop))
@@ -1180,13 +1150,8 @@ inkscape_switch_desktops_prev ()
 void
 inkscape_dialogs_hide ()
 {
-    if (Inkscape::NSApplication::Application::getNewGui())
-        Inkscape::NSApplication::Editor::hideDialogs();
-    else
-    {
-        g_signal_emit (G_OBJECT (inkscape), inkscape_signals[DIALOGS_HIDE], 0);
-        inkscape->dialogs_toggle = FALSE;
-    }
+    g_signal_emit (G_OBJECT (inkscape), inkscape_signals[DIALOGS_HIDE], 0);
+    inkscape->dialogs_toggle = FALSE;
 }
 
 
@@ -1194,13 +1159,8 @@ inkscape_dialogs_hide ()
 void
 inkscape_dialogs_unhide ()
 {
-    if (Inkscape::NSApplication::Application::getNewGui())
-        Inkscape::NSApplication::Editor::unhideDialogs();
-    else
-    {
-        g_signal_emit (G_OBJECT (inkscape), inkscape_signals[DIALOGS_UNHIDE], 0);
-        inkscape->dialogs_toggle = TRUE;
-    }
+    g_signal_emit (G_OBJECT (inkscape), inkscape_signals[DIALOGS_UNHIDE], 0);
+    inkscape->dialogs_toggle = TRUE;
 }
 
 
@@ -1231,24 +1191,17 @@ inkscape_add_document (SPDocument *document)
 {
     g_return_if_fail (document != NULL);
 
-    if (!Inkscape::NSApplication::Application::getNewGui())
-    {
-        // try to insert the pair into the list
-        if (!(inkscape->document_set.insert(std::make_pair(document, 1)).second)) {
-            //insert failed, this key (document) is already in the list
-            for (std::map<SPDocument*,int>::iterator iter = inkscape->document_set.begin();
-                   iter != inkscape->document_set.end();
-                   ++iter) {
-                if (iter->first == document) {
-                    // found this document in list, increase its count
-                    iter->second ++;
-                }
-           }
-        }
-    }
-    else
-    {
-        Inkscape::NSApplication::Editor::addDocument (document);
+    // try to insert the pair into the list
+    if (!(inkscape->document_set.insert(std::make_pair(document, 1)).second)) {
+        //insert failed, this key (document) is already in the list
+        for (std::map<SPDocument*,int>::iterator iter = inkscape->document_set.begin();
+               iter != inkscape->document_set.end();
+               ++iter) {
+            if (iter->first == document) {
+                // found this document in list, increase its count
+                iter->second ++;
+            }
+       }
     }
 }
 
@@ -1259,28 +1212,21 @@ inkscape_remove_document (SPDocument *document)
 {
     g_return_val_if_fail (document != NULL, false);
 
-    if (!Inkscape::NSApplication::Application::getNewGui())
-    {
-        for (std::map<SPDocument*,int>::iterator iter = inkscape->document_set.begin();
-                  iter != inkscape->document_set.end();
-                  ++iter) {
-            if (iter->first == document) {
-                // found this document in list, decrease its count
-                iter->second --;
-                if (iter->second < 1) {
-                    // this was the last one, remove the pair from list
-                    inkscape->document_set.erase (iter);
-                    return true;
-                } else {
-                    return false;
-                }
+    for (std::map<SPDocument*,int>::iterator iter = inkscape->document_set.begin();
+              iter != inkscape->document_set.end();
+              ++iter) {
+        if (iter->first == document) {
+            // found this document in list, decrease its count
+            iter->second --;
+            if (iter->second < 1) {
+                // this was the last one, remove the pair from list
+                inkscape->document_set.erase (iter);
+                return true;
+            } else {
+                return false;
             }
         }
     }
-    else
-    {
-        Inkscape::NSApplication::Editor::removeDocument (document);
-    }
 
     return false;
 }
@@ -1288,9 +1234,6 @@ inkscape_remove_document (SPDocument *document)
 SPDesktop *
 inkscape_active_desktop (void)
 {
-    if (Inkscape::NSApplication::Application::getNewGui())
-        return Inkscape::NSApplication::Editor::getActiveDesktop();
-
     if (inkscape->desktops == NULL) {
         return NULL;
     }
@@ -1301,9 +1244,6 @@ inkscape_active_desktop (void)
 SPDocument *
 inkscape_active_document (void)
 {
-    if (Inkscape::NSApplication::Application::getNewGui())
-        return Inkscape::NSApplication::Editor::getActiveDocument();
-
     if (SP_ACTIVE_DESKTOP) {
         return sp_desktop_document (SP_ACTIVE_DESKTOP);
     }