Code

Merge and cleanup of GSoC C++-ification project.
[inkscape.git] / src / file.cpp
index 58ca463bf0eff55ea4e1666a48bf6c8fc87f31e7..bde985ea56c2e3f670d6d41eafac6358b7ccd8f7 100644 (file)
@@ -1,24 +1,25 @@
-#define __SP_FILE_C__
-
-/*
- * File/Print operations
- *
- * Authors:
+/** @file
+ * @brief File/Print operations
+ */
+/* Authors:
  *   Lauris Kaplinski <lauris@kaplinski.com>
  *   Chema Celorio <chema@celorio.com>
  *   bulia byak <buliabyak@users.sf.net>
  *   Bruno Dilly <bruno.dilly@gmail.com>
+ *   Stephen Silver <sasilver@users.sourceforge.net>
+ *   Jon A. Cruz <jon@joncruz.org>
+ *   Abhishek Sharma
  *
  * Copyright (C) 2006 Johan Engelen <johan@shouraizou.nl>
- * Copyright (C) 1999-2005 Authors
+ * Copyright (C) 1999-2008 Authors
  * Copyright (C) 2004 David Turner
  * Copyright (C) 2001-2002 Ximian, Inc.
  *
  * Released under GNU GPL, read the file 'COPYING' for more information
  */
 
-/**
- * Note: This file needs to be cleaned up extensively.
+/** @file
+ * @note This file needs to be cleaned up extensively.
  * What it probably needs is to have one .h file for
  * the API, and two or more .cpp files for the implementations.
  */
 # include "config.h"
 #endif
 
+#include <gtk/gtk.h>
 #include <glib/gmem.h>
+#include <glibmm/i18n.h>
 #include <libnr/nr-pixops.h>
 
-#include "document-private.h"
-#include "selection-chemistry.h"
-#include "ui/view/view-widget.h"
+#include "desktop.h"
+#include "desktop-handles.h"
+#include "dialogs/export.h"
 #include "dir-util.h"
+#include "document-private.h"
+#include "extension/db.h"
+#include "extension/input.h"
+#include "extension/output.h"
+#include "extension/system.h"
+#include "file.h"
 #include "helper/png-write.h"
-#include "dialogs/export.h"
-#include <glibmm/i18n.h>
+#include "id-clash.h"
+#include "inkscape.h"
 #include "inkscape.h"
-#include "desktop.h"
-#include "selection.h"
 #include "interface.h"
-#include "style.h"
-#include "print.h"
-#include "file.h"
+#include "io/sys.h"
 #include "message.h"
 #include "message-stack.h"
-#include "ui/dialog/filedialog.h"
-#include "ui/dialog/ocaldialogs.h"
-#include "prefs-utils.h"
 #include "path-prefix.h"
-
+#include "preferences.h"
+#include "print.h"
+#include "rdf.h"
+#include "selection-chemistry.h"
+#include "selection.h"
 #include "sp-namedview.h"
-#include "desktop-handles.h"
-
-#include "extension/db.h"
-#include "extension/input.h"
-#include "extension/output.h"
-/* #include "extension/menu.h"  */
-#include "extension/system.h"
-
-#include "io/sys.h"
-#include "application/application.h"
-#include "application/editor.h"
-#include "inkscape.h"
+#include "style.h"
+#include "ui/dialog/ocaldialogs.h"
+#include "ui/view/view-widget.h"
 #include "uri.h"
+#include "xml/rebase-hrefs.h"
+
+using Inkscape::DocumentUndo;
 
 #ifdef WITH_GNOME_VFS
 # include <libgnomevfs/gnome-vfs.h>
 #endif
 
-#ifdef WITH_INKBOARD
-#include "jabber_whiteboard/session-manager.h"
+#ifdef WITH_DBUS
+#include "extension/dbus/dbus-init.h"
 #endif
 
+//#ifdef WITH_INKBOARD
+//#include "jabber_whiteboard/session-manager.h"
+//#endif
+
+#ifdef WIN32
+#include <windows.h>
+#endif
 
 //#define INK_DUMP_FILENAME_CONV 1
 #undef INK_DUMP_FILENAME_CONV
 void dump_str(gchar const *str, gchar const *prefix);
 void dump_ustr(Glib::ustring const &ustr);
 
+// what gets passed here is not actually an URI... it is an UTF-8 encoded filename (!)
+static void sp_file_add_recent(gchar const *uri)
+{
+    if(uri == NULL) {
+        g_warning("sp_file_add_recent: uri == NULL");
+        return;
+    }
+    GtkRecentManager *recent = gtk_recent_manager_get_default();
+    gchar *fn = g_filename_from_utf8(uri, -1, NULL, NULL, NULL);
+    if (fn) {
+        gchar *uri_to_add = g_filename_to_uri(fn, NULL, NULL);
+        if (uri_to_add) {
+            gtk_recent_manager_add_item(recent, uri_to_add);
+            g_free(uri_to_add);
+        }
+        g_free(fn);
+    }
+}
+
 
 /*######################
 ## N E W
@@ -92,57 +118,69 @@ void dump_ustr(Glib::ustring const &ustr);
 /**
  * Create a blank document and add it to the desktop
  */
-SPDesktop*
-sp_file_new(const Glib::ustring &templ)
+SPDesktop *sp_file_new(const Glib::ustring &templ)
 {
-    char *templName = NULL;
-    if (templ.size()>0)
-        templName = (char *)templ.c_str();
-    SPDocument *doc = sp_document_new(templName, TRUE, true);
+    SPDocument *doc = SPDocument::createNewDoc( !templ.empty() ? templ.c_str() : 0 , TRUE, true );
     g_return_val_if_fail(doc != NULL, NULL);
 
-    SPDesktop *dt;
-    if (Inkscape::NSApplication::Application::getNewGui())
-    {
-        dt = Inkscape::NSApplication::Editor::createDesktop (doc);
-    } else {
-        SPViewWidget *dtw = sp_desktop_widget_new(sp_document_namedview(doc, NULL));
-        g_return_val_if_fail(dtw != NULL, NULL);
-        sp_document_unref(doc);
-
-        sp_create_window(dtw, TRUE);
-        dt = static_cast<SPDesktop*>(dtw->view);
-        sp_namedview_window_from_document(dt);
-        sp_namedview_update_layers_from_document(dt);
-    }
+    SPViewWidget *dtw = sp_desktop_widget_new(sp_document_namedview(doc, NULL));
+    g_return_val_if_fail(dtw != NULL, NULL);
+    doc->doUnref();
+
+    sp_create_window(dtw, TRUE);
+    SPDesktop *dt = static_cast<SPDesktop *>(dtw->view);
+    sp_namedview_window_from_document(dt);
+    sp_namedview_update_layers_from_document(dt);
+
+#ifdef WITH_DBUS
+    Inkscape::Extension::Dbus::dbus_init_desktop_interface(dt);
+#endif
+
     return dt;
 }
 
-SPDesktop*
-sp_file_new_default()
+SPDesktop* sp_file_new_default()
 {
     std::list<gchar *> sources;
     sources.push_back( profile_path("templates") ); // first try user's local dir
     sources.push_back( g_strdup(INKSCAPE_TEMPLATESDIR) ); // then the system templates dir
-
-    while (!sources.empty()) {
-        gchar *dirname = sources.front();
-        if ( Inkscape::IO::file_test( dirname, (GFileTest)(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR) ) ) {
-
-            // TRANSLATORS: default.svg is localizable - this is the name of the default document
-            //  template. This way you can localize the default pagesize, translate the name of
-            //  the default layer, etc. If you wish to localize this file, please create a
-            //  localized share/templates/default.xx.svg file, where xx is your language code.
-            char *default_template = g_build_filename(dirname, _("default.svg"), NULL);
-            if (Inkscape::IO::file_test(default_template, G_FILE_TEST_IS_REGULAR)) {
-                return sp_file_new(default_template);
+    std::list<gchar const*> baseNames;
+    gchar const* localized = _("default.svg");
+    if (strcmp("default.svg", localized) != 0) {
+        baseNames.push_back(localized);
+    }
+    baseNames.push_back("default.svg");
+    gchar *foundTemplate = 0;
+
+    for (std::list<gchar const*>::iterator nameIt = baseNames.begin(); (nameIt != baseNames.end()) && !foundTemplate; ++nameIt) {
+        for (std::list<gchar *>::iterator it = sources.begin(); (it != sources.end()) && !foundTemplate; ++it) {
+            gchar *dirname = *it;
+            if ( Inkscape::IO::file_test( dirname, (GFileTest)(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR) ) ) {
+
+                // TRANSLATORS: default.svg is localizable - this is the name of the default document
+                //  template. This way you can localize the default pagesize, translate the name of
+                //  the default layer, etc. If you wish to localize this file, please create a
+                //  localized share/templates/default.xx.svg file, where xx is your language code.
+                char *tmp = g_build_filename(dirname, *nameIt, NULL);
+                if (Inkscape::IO::file_test(tmp, G_FILE_TEST_IS_REGULAR)) {
+                    foundTemplate = tmp;
+                } else {
+                    g_free(tmp);
+                }
             }
         }
-        g_free(dirname);
-        sources.pop_front();
     }
 
-    return sp_file_new("");
+    for (std::list<gchar *>::iterator it = sources.begin(); it != sources.end(); ++it) {
+        g_free(*it);
+    }
+
+    SPDesktop* desk = sp_file_new(foundTemplate ? foundTemplate : "");
+    if (foundTemplate) {
+        g_free(foundTemplate);
+        foundTemplate = 0;
+    }
+    return desk;
 }
 
 
@@ -176,6 +214,10 @@ sp_file_open(const Glib::ustring &uri,
              Inkscape::Extension::Extension *key,
              bool add_to_recent, bool replace_empty)
 {
+    SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+    if (desktop)
+        desktop->setWaitingCursor();
+
     SPDocument *doc = NULL;
     try {
         doc = Inkscape::Extension::open(key, uri.c_str());
@@ -185,35 +227,33 @@ sp_file_open(const Glib::ustring &uri,
         doc = NULL;
     }
 
+    if (desktop)
+        desktop->clearWaitingCursor();
+
     if (doc) {
-        SPDesktop *desktop = SP_ACTIVE_DESKTOP;
         SPDocument *existing = desktop ? sp_desktop_document(desktop) : NULL;
 
         if (existing && existing->virgin && replace_empty) {
             // If the current desktop is empty, open the document there
-            sp_document_ensure_up_to_date (doc);
+            doc->ensureUpToDate();
             desktop->change_document(doc);
-            sp_document_resized_signal_emit (doc, sp_document_width(doc), sp_document_height(doc));
+            doc->emitResizedSignal(doc->getWidth(), doc->getHeight());
         } else {
-            if (!Inkscape::NSApplication::Application::getNewGui()) {
-                // create a whole new desktop and window
-                SPViewWidget *dtw = sp_desktop_widget_new(sp_document_namedview(doc, NULL));
-                sp_create_window(dtw, TRUE);
-                desktop = static_cast<SPDesktop*>(dtw->view);
-            } else {
-                desktop = Inkscape::NSApplication::Editor::createDesktop (doc);
-            }
+            // create a whole new desktop and window
+            SPViewWidget *dtw = sp_desktop_widget_new(sp_document_namedview(doc, NULL));
+            sp_create_window(dtw, TRUE);
+            desktop = static_cast<SPDesktop*>(dtw->view);
         }
 
         doc->virgin = FALSE;
         // everyone who cares now has a reference, get rid of ours
-        sp_document_unref(doc);
+        doc->doUnref();
         // resize the window to match the document properties
         sp_namedview_window_from_document(desktop);
         sp_namedview_update_layers_from_document(desktop);
 
         if (add_to_recent) {
-            prefs_set_recent_file(SP_DOCUMENT_URI(doc), SP_DOCUMENT_NAME(doc));
+            sp_file_add_recent( doc->getURI() );
         }
 
         return TRUE;
@@ -230,8 +270,7 @@ sp_file_open(const Glib::ustring &uri,
 /**
  *  Handle prompting user for "do you want to revert"?  Revert on "OK"
  */
-void
-sp_file_revert_dialog()
+void sp_file_revert_dialog()
 {
     SPDesktop  *desktop = SP_ACTIVE_DESKTOP;
     g_assert(desktop != NULL);
@@ -239,17 +278,17 @@ sp_file_revert_dialog()
     SPDocument *doc = sp_desktop_document(desktop);
     g_assert(doc != NULL);
 
-    Inkscape::XML::Node     *repr = sp_document_repr_root(doc);
+    Inkscape::XML::Node *repr = doc->getReprRoot();
     g_assert(repr != NULL);
 
-    gchar const *uri = doc->uri;
+    gchar const *uri = doc->getURI();
     if (!uri) {
         desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("Document not saved yet.  Cannot revert."));
         return;
     }
 
     bool do_revert = true;
-    if (doc->isModified()) {
+    if (doc->isModifiedSinceSave()) {
         gchar *text = g_strdup_printf(_("Changes will be lost!  Are you sure you want to reload document %s?"), uri);
 
         bool response = desktop->warnDialog (text);
@@ -267,12 +306,12 @@ sp_file_revert_dialog()
 
         // remember current zoom and view
         double zoom = desktop->current_zoom();
-        NR::Point c = desktop->get_display_area().midpoint();
+        Geom::Point c = desktop->get_display_area().midpoint();
 
         reverted = sp_file_open(uri,NULL);
         if (reverted) {
             // restore zoom and view
-            desktop->zoom_absolute(c[NR::X], c[NR::Y], zoom);
+            desktop->zoom_absolute(c[Geom::X], c[Geom::Y], zoom);
         }
     } else {
         reverted = false;
@@ -367,8 +406,6 @@ void dump_ustr(Glib::ustring const &ustr)
     g_message("---------------");
 }
 
-static Inkscape::UI::Dialog::FileOpenDialog *openDialogInstance = NULL;
-
 /**
  *  Display an file Open selector.  Open a document if OK is pressed.
  *  Can select single or multiple files for opening.
@@ -376,76 +413,115 @@ static Inkscape::UI::Dialog::FileOpenDialog *openDialogInstance = NULL;
 void
 sp_file_open_dialog(Gtk::Window &parentWindow, gpointer /*object*/, gpointer /*data*/)
 {
-
     //# Get the current directory for finding files
-    Glib::ustring open_path;
-    char *attr = (char *)prefs_get_string_attribute("dialogs.open", "path");
-    if (attr)
-        open_path = attr;
+    static Glib::ustring open_path;
+    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
 
+    if(open_path.empty())
+    {
+        Glib::ustring attr = prefs->getString("/dialogs/open/path");
+        if (!attr.empty()) open_path = attr;
+    }
 
     //# Test if the open_path directory exists
     if (!Inkscape::IO::file_test(open_path.c_str(),
               (GFileTest)(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)))
         open_path = "";
 
-    //# If no open path, default to our home directory
-    if (open_path.size() < 1)
+#ifdef WIN32
+    //# If no open path, default to our win32 documents folder
+    if (open_path.empty())
+    {
+        // The path to the My Documents folder is read from the
+        // value "HKEY_CURRENT_USER\Software\Windows\CurrentVersion\Explorer\Shell Folders\Personal"
+        HKEY key = NULL;
+        if(RegOpenKeyExA(HKEY_CURRENT_USER,
+            "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders",
+            0, KEY_QUERY_VALUE, &key) == ERROR_SUCCESS)
         {
+            WCHAR utf16path[_MAX_PATH];
+            DWORD value_type;
+            DWORD data_size = sizeof(utf16path);
+            if(RegQueryValueExW(key, L"Personal", NULL, &value_type,
+                (BYTE*)utf16path, &data_size) == ERROR_SUCCESS)
+            {
+                g_assert(value_type == REG_SZ);
+                gchar *utf8path = g_utf16_to_utf8(
+                    (const gunichar2*)utf16path, -1, NULL, NULL, NULL);
+                if(utf8path)
+                {
+                    open_path = Glib::ustring(utf8path);
+                    g_free(utf8path);
+                }
+            }
+        }
+    }
+#endif
+
+    //# If no open path, default to our home directory
+    if (open_path.empty())
+    {
         open_path = g_get_home_dir();
         open_path.append(G_DIR_SEPARATOR_S);
-        }
+    }
 
-    //# Create a dialog if we don't already have one
-    if (!openDialogInstance) {
-        openDialogInstance =
+    //# Create a dialog
+    Inkscape::UI::Dialog::FileOpenDialog *openDialogInstance =
               Inkscape::UI::Dialog::FileOpenDialog::create(
-                 parentWindow,
-                 open_path,
+                 parentWindow, open_path,
                  Inkscape::UI::Dialog::SVG_TYPES,
-                 (char const *)_("Select file to open"));
-    }
-
+                 _("Select file to open"));
 
     //# Show the dialog
     bool const success = openDialogInstance->show();
+
+    //# Save the folder the user selected for later
+    open_path = openDialogInstance->getCurrentDirectory();
+
     if (!success)
+    {
+        delete openDialogInstance;
         return;
+    }
 
     //# User selected something.  Get name and type
     Glib::ustring fileName = openDialogInstance->getFilename();
+
     Inkscape::Extension::Extension *selection =
             openDialogInstance->getSelectionType();
 
-    //# Code to check & open iff multiple files.
-    std::vector<Glib::ustring> flist=openDialogInstance->getFilenames();
+    //# Code to check & open if multiple files.
+    std::vector<Glib::ustring> flist = openDialogInstance->getFilenames();
+
+    //# We no longer need the file dialog object - delete it
+    delete openDialogInstance;
+    openDialogInstance = NULL;
 
     //# Iterate through filenames if more than 1
     if (flist.size() > 1)
+    {
+        for (unsigned int i = 0; i < flist.size(); i++)
         {
-        for (unsigned int i=1 ; i<flist.size() ; i++)
-            {
-            Glib::ustring fName = flist[i];
+            fileName = flist[i];
 
-            if (Glib::file_test(fileName, Glib::FILE_TEST_IS_DIR)) {
-            Glib::ustring newFileName = Glib::filename_to_utf8(fName);
+            Glib::ustring newFileName = Glib::filename_to_utf8(fileName);
             if ( newFileName.size() > 0 )
-                fName = newFileName;
+                fileName = newFileName;
             else
                 g_warning( "ERROR CONVERTING OPEN FILENAME TO UTF-8" );
 
 #ifdef INK_DUMP_FILENAME_CONV
-            g_message("Opening File %s\n",fileName);
+            g_message("Opening File %s\n", fileName.c_str());
 #endif
             sp_file_open(fileName, selection);
-            }
         }
+
         return;
     }
 
 
-    if (fileName.size() > 0) {
-
+    if (!fileName.empty())
+    {
         Glib::ustring newFileName = Glib::filename_to_utf8(fileName);
 
         if ( newFileName.size() > 0)
@@ -453,9 +529,9 @@ sp_file_open_dialog(Gtk::Window &parentWindow, gpointer /*object*/, gpointer /*d
         else
             g_warning( "ERROR CONVERTING OPEN FILENAME TO UTF-8" );
 
-        open_path = fileName;
+        open_path = Glib::path_get_dirname (fileName);
         open_path.append(G_DIR_SEPARATOR_S);
-        prefs_set_string_attribute("dialogs.open", "path", open_path.c_str());
+        prefs->setString("/dialogs/open/path", open_path);
 
         sp_file_open(fileName, selection);
     }
@@ -471,17 +547,14 @@ sp_file_open_dialog(Gtk::Window &parentWindow, gpointer /*object*/, gpointer /*d
 /**
  * Remove unreferenced defs from the defs section of the document.
  */
-
-
-void
-sp_file_vacuum()
+void sp_file_vacuum()
 {
     SPDocument *doc = SP_ACTIVE_DOCUMENT;
 
-    unsigned int diff = vacuum_document (doc);
+    unsigned int diff = doc->vacuumDocument();
 
-    sp_document_done(doc, SP_VERB_FILE_VACUUM,
-                     _("Vacuum &lt;defs&gt;"));
+    DocumentUndo::done(doc, SP_VERB_FILE_VACUUM,
+                       _("Vacuum &lt;defs&gt;"));
 
     SPDesktop *dt = SP_ACTIVE_DESKTOP;
     if (diff > 0) {
@@ -509,15 +582,17 @@ sp_file_vacuum()
  */
 static bool
 file_save(Gtk::Window &parentWindow, SPDocument *doc, const Glib::ustring &uri,
-          Inkscape::Extension::Extension *key, bool saveas, bool official)
+          Inkscape::Extension::Extension *key, bool checkoverwrite, bool official,
+          Inkscape::Extension::FileSaveMethod save_method)
 {
     if (!doc || uri.size()<1) //Safety check
         return false;
 
     try {
         Inkscape::Extension::save(key, doc, uri.c_str(),
-                 false,
-                 saveas, official);
+                                  false,
+                                  checkoverwrite, official,
+                                  save_method);
     } catch (Inkscape::Extension::Output::no_extension_found &e) {
         gchar *safeUri = Inkscape::IO::sanitizeString(uri.c_str());
         gchar *text = g_strdup_printf(_("No Inkscape extension found to save document (%s).  This may have been caused by an unknown filename extension."), safeUri);
@@ -526,6 +601,14 @@ file_save(Gtk::Window &parentWindow, SPDocument *doc, const Glib::ustring &uri,
         g_free(text);
         g_free(safeUri);
         return FALSE;
+    } catch (Inkscape::Extension::Output::file_read_only &e) {
+        gchar *safeUri = Inkscape::IO::sanitizeString(uri.c_str());
+        gchar *text = g_strdup_printf(_("File %s is write protected. Please remove write protection and try again."), safeUri);
+        SP_ACTIVE_DESKTOP->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("Document not saved."));
+        sp_ui_error_dialog(text);
+        g_free(text);
+        g_free(safeUri);
+        return FALSE;
     } catch (Inkscape::Extension::Output::save_failed &e) {
         gchar *safeUri = Inkscape::IO::sanitizeString(uri.c_str());
         gchar *text = g_strdup_printf(_("File %s could not be saved."), safeUri);
@@ -534,8 +617,14 @@ file_save(Gtk::Window &parentWindow, SPDocument *doc, const Glib::ustring &uri,
         g_free(text);
         g_free(safeUri);
         return FALSE;
+    } catch (Inkscape::Extension::Output::save_cancelled &e) {
+        SP_ACTIVE_DESKTOP->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("Document not saved."));
+        return FALSE;
     } catch (Inkscape::Extension::Output::no_overwrite &e) {
-        return sp_file_save_dialog(parentWindow, doc);
+        return sp_file_save_dialog(parentWindow, doc, Inkscape::Extension::FILE_SAVE_METHOD_SAVE_AS);
+    } catch (...) {
+        SP_ACTIVE_DESKTOP->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("Document not saved."));
+        return FALSE;
     }
 
     SP_ACTIVE_DESKTOP->event_log->rememberFileSave();
@@ -622,8 +711,8 @@ file_save_remote(SPDocument */*doc*/,
     }
     return true;
 #else
-       // in case we do not have GNOME_VFS
-       return false;
+    // in case we do not have GNOME_VFS
+    return false;
 #endif
 
 }
@@ -631,53 +720,47 @@ file_save_remote(SPDocument */*doc*/,
 
 /**
  *  Display a SaveAs dialog.  Save the document if OK pressed.
- *
- * \param    ascopy  (optional) wether to set the documents->uri to the new filename or not
  */
 bool
-sp_file_save_dialog(Gtk::Window &parentWindow, SPDocument *doc, bool is_copy)
+sp_file_save_dialog(Gtk::Window &parentWindow, SPDocument *doc, Inkscape::Extension::FileSaveMethod save_method)
 {
-
-    Inkscape::XML::Node *repr = sp_document_repr_root(doc);
-
     Inkscape::Extension::Output *extension = 0;
+    bool is_copy = (save_method == Inkscape::Extension::FILE_SAVE_METHOD_SAVE_COPY);
 
-    //# Get the default extension name
+    // Note: default_extension has the format "org.inkscape.output.svg.inkscape", whereas
+    //       filename_extension only uses ".svg"
     Glib::ustring default_extension;
-    char *attr = (char *)repr->attribute("inkscape:output_extension");
-    if (!attr)
-        attr = (char *)prefs_get_string_attribute("dialogs.save_as", "default");
-    if (attr)
-        default_extension = attr;
+    Glib::ustring filename_extension = ".svg";
+
+    default_extension= Inkscape::Extension::get_file_save_extension(save_method);
     //g_message("%s: extension name: '%s'", __FUNCTION__, default_extension);
 
+    extension = dynamic_cast<Inkscape::Extension::Output *>
+        (Inkscape::Extension::db.get(default_extension.c_str()));
+
+    if (extension)
+        filename_extension = extension->get_extension();
+
     Glib::ustring save_path;
     Glib::ustring save_loc;
 
-    if (doc->uri == NULL) {
-        char formatBuf[256];
-        int i = 1;
+    save_path = Inkscape::Extension::get_file_save_path(doc, save_method);
 
-        Glib::ustring filename_extension = ".svg";
-        extension = dynamic_cast<Inkscape::Extension::Output *>
-              (Inkscape::Extension::db.get(default_extension.c_str()));
-        //g_warning("%s: extension ptr: 0x%x", __FUNCTION__, (unsigned int)extension);
-        if (extension)
-            filename_extension = extension->get_extension();
+    if (!Inkscape::IO::file_test(save_path.c_str(),
+          (GFileTest)(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)))
+        save_path = "";
 
-        attr = (char *)prefs_get_string_attribute("dialogs.save_as", "path");
-        if (attr)
-            save_path = attr;
+    if (save_path.size()<1)
+        save_path = g_get_home_dir();
 
-        if (!Inkscape::IO::file_test(save_path.c_str(),
-              (GFileTest)(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)))
-            save_path = "";
-
-        if (save_path.size()<1)
-            save_path = g_get_home_dir();
+    save_loc = save_path;
+    save_loc.append(G_DIR_SEPARATOR_S);
 
-        save_loc = save_path;
-        save_loc.append(G_DIR_SEPARATOR_S);
+    // TODO fixed buffer is bad:
+    char formatBuf[256];
+    int i = 1;
+    if ( !doc->getURI() ) {
+        // We are saving for the first time; create a unique default filename
         snprintf(formatBuf, 255, _("drawing%s"), filename_extension.c_str());
         save_loc.append(formatBuf);
 
@@ -688,8 +771,8 @@ sp_file_save_dialog(Gtk::Window &parentWindow, SPDocument *doc, bool is_copy)
             save_loc.append(formatBuf);
         }
     } else {
-        save_loc = Glib::build_filename(Glib::path_get_dirname(doc->uri),
-                                        Glib::path_get_basename(doc->uri));
+        snprintf(formatBuf, 255, _("%s"), Glib::path_get_basename(doc->getURI()).c_str());
+        save_loc.append(formatBuf);
     }
 
     // convert save_loc from utf-8 to locale
@@ -707,31 +790,31 @@ sp_file_save_dialog(Gtk::Window &parentWindow, SPDocument *doc, bool is_copy)
     } else {
         dialog_title = (char const *) _("Select file to save to");
     }
+    gchar* doc_title = doc->root->title();
     Inkscape::UI::Dialog::FileSaveDialog *saveDialog =
         Inkscape::UI::Dialog::FileSaveDialog::create(
-               parentWindow,
+            parentWindow,
             save_loc,
             Inkscape::UI::Dialog::SVG_TYPES,
-            (char const *) _("Select file to save to"),
-            default_extension
+            dialog_title,
+            default_extension,
+            doc_title ? doc_title : "",
+            save_method
             );
 
-    saveDialog->change_title(dialog_title);
     saveDialog->setSelectionType(extension);
 
-    // allow easy access to the user's own templates folder
-    gchar *templates = profile_path ("templates");
-    if (Inkscape::IO::file_test(templates, (GFileTest)(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) {
-        dynamic_cast<Gtk::FileChooser *>(saveDialog)->add_shortcut_folder(templates);
-    }
-    g_free (templates);
-
     bool success = saveDialog->show();
     if (!success) {
         delete saveDialog;
         return success;
     }
 
+    // set new title here (call RDF to ensure metadata and title element are updated)
+    rdf_set_work_entity(doc, rdf_find_entity("title"), saveDialog->getDocTitle().c_str());
+    // free up old string
+    if(doc_title) g_free(doc_title);
+
     Glib::ustring fileName = saveDialog->getFilename();
     Inkscape::Extension::Extension *selectionType = saveDialog->getSelectionType();
 
@@ -747,13 +830,15 @@ sp_file_save_dialog(Gtk::Window &parentWindow, SPDocument *doc, bool is_copy)
         else
             g_warning( "Error converting save filename to UTF-8." );
 
-        success = file_save(parentWindow, doc, fileName, selectionType, TRUE, !is_copy);
+        // FIXME: does the argument !is_copy really convey the correct meaning here?
+        success = file_save(parentWindow, doc, fileName, selectionType, TRUE, !is_copy, save_method);
 
-        if (success)
-            prefs_set_recent_file(SP_DOCUMENT_URI(doc), SP_DOCUMENT_NAME(doc));
+        if (success && doc->getURI()) {
+            sp_file_add_recent( doc->getURI() );
+        }
 
         save_path = Glib::path_get_dirname(fileName);
-        prefs_set_string_attribute("dialogs.save_as", "path", save_path.c_str());
+        Inkscape::Extension::store_save_path_in_prefs(save_path, save_method);
 
         return success;
     }
@@ -771,17 +856,31 @@ sp_file_save_document(Gtk::Window &parentWindow, SPDocument *doc)
 {
     bool success = true;
 
-    if (doc->isModified()) {
-        Inkscape::XML::Node *repr = sp_document_repr_root(doc);
-        if ( doc->uri == NULL
-            || repr->attribute("inkscape:output_extension") == NULL )
+    if (doc->isModifiedSinceSave()) {
+        if ( doc->getURI() == NULL )
         {
-            return sp_file_save_dialog(parentWindow, doc, FALSE);
+            // Hier sollte in Argument mitgegeben werden, das anzeigt, da� das Dokument das erste
+            // Mal gespeichert wird, so da� als default .svg ausgew�hlt wird und nicht die zuletzt
+            // benutzte "Save as ..."-Endung
+            return sp_file_save_dialog(parentWindow, doc, Inkscape::Extension::FILE_SAVE_METHOD_INKSCAPE_SVG);
         } else {
-            gchar const *fn = g_strdup(doc->uri);
-            gchar const *ext = repr->attribute("inkscape:output_extension");
-            success = file_save(parentWindow, doc, fn, Inkscape::Extension::db.get(ext), FALSE, TRUE);
-            g_free((void *) fn);
+            Glib::ustring extension = Inkscape::Extension::get_file_save_extension(Inkscape::Extension::FILE_SAVE_METHOD_SAVE_AS);
+            Glib::ustring fn = g_strdup(doc->getURI());
+            // Try to determine the extension from the uri; this may not lead to a valid extension,
+            // but this case is caught in the file_save method below (or rather in Extension::save()
+            // further down the line).
+            Glib::ustring ext = "";
+            Glib::ustring::size_type pos = fn.rfind('.');
+            if (pos != Glib::ustring::npos) {
+                // FIXME: this could/should be more sophisticated (see FileSaveDialog::appendExtension()),
+                // but hopefully it's a reasonable workaround for now
+                ext = fn.substr( pos );
+            }
+            success = file_save(parentWindow, doc, fn, Inkscape::Extension::db.get(ext.c_str()), FALSE, TRUE, Inkscape::Extension::FILE_SAVE_METHOD_SAVE_AS);
+            if (success == false) {
+                // give the user the chance to change filename or extension
+                return sp_file_save_dialog(parentWindow, doc, Inkscape::Extension::FILE_SAVE_METHOD_INKSCAPE_SVG);
+            }
         }
     } else {
         SP_ACTIVE_DESKTOP->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("No changes need to be saved."));
@@ -817,7 +916,7 @@ sp_file_save_as(Gtk::Window &parentWindow, gpointer /*object*/, gpointer /*data*
     if (!SP_ACTIVE_DOCUMENT)
         return false;
     sp_namedview_document_from_window(SP_ACTIVE_DESKTOP);
-    return sp_file_save_dialog(parentWindow, SP_ACTIVE_DOCUMENT, FALSE);
+    return sp_file_save_dialog(parentWindow, SP_ACTIVE_DOCUMENT, Inkscape::Extension::FILE_SAVE_METHOD_SAVE_AS);
 }
 
 
@@ -831,7 +930,7 @@ sp_file_save_a_copy(Gtk::Window &parentWindow, gpointer /*object*/, gpointer /*d
     if (!SP_ACTIVE_DOCUMENT)
         return false;
     sp_namedview_document_from_window(SP_ACTIVE_DESKTOP);
-    return sp_file_save_dialog(parentWindow, SP_ACTIVE_DOCUMENT, TRUE);
+    return sp_file_save_dialog(parentWindow, SP_ACTIVE_DOCUMENT, Inkscape::Extension::FILE_SAVE_METHOD_SAVE_COPY);
 }
 
 
@@ -859,104 +958,104 @@ file_import(SPDocument *in_doc, const Glib::ustring &uri,
     }
 
     if (doc != NULL) {
-        // move imported defs to our document's defs
-        SPObject *in_defs = SP_DOCUMENT_DEFS(in_doc);
-        SPObject *defs = SP_DOCUMENT_DEFS(doc);
+        Inkscape::XML::rebase_hrefs(doc, in_doc->getBase(), true);
+        Inkscape::XML::Document *xml_in_doc = in_doc->getReprDoc();
 
-        Inkscape::IO::fixupHrefs(doc, in_doc->base, true);
-        Inkscape::XML::Document *xml_doc = sp_document_repr_doc(doc);
+        prevent_id_clashes(doc, in_doc);
 
+        SPObject *in_defs = SP_DOCUMENT_DEFS(in_doc);
         Inkscape::XML::Node *last_def = SP_OBJECT_REPR(in_defs)->lastChild();
-        for (SPObject *child = sp_object_first_child(defs);
-             child != NULL; child = SP_OBJECT_NEXT(child))
-        {
-            // FIXME: in case of id conflict, newly added thing will be re-ided and thus likely break a reference to it from imported stuff
-            SP_OBJECT_REPR(in_defs)->addChild(SP_OBJECT_REPR(child)->duplicate(xml_doc), last_def);
-        }
 
+        SPCSSAttr *style = sp_css_attr_from_object(doc->getRoot());
+
+        // Count the number of top-level items in the imported document.
         guint items_count = 0;
-        for (SPObject *child = sp_object_first_child(SP_DOCUMENT_ROOT(doc));
-             child != NULL; child = SP_OBJECT_NEXT(child)) {
-            if (SP_IS_ITEM(child))
-                items_count ++;
+        for ( SPObject *child = doc->getRoot()->firstChild(); child; child = child->getNext()) {
+            if (SP_IS_ITEM(child)) {
+                items_count++;
+            }
         }
-        SPCSSAttr *style = sp_css_attr_from_object (SP_DOCUMENT_ROOT (doc));
-
-        SPObject *new_obj = NULL;
 
+        // Create a new group if necessary.
+        Inkscape::XML::Node *newgroup = NULL;
         if ((style && style->firstChild()) || items_count > 1) {
-            // create group
-            Inkscape::XML::Document *xml_doc = sp_document_repr_doc(in_doc);
-            Inkscape::XML::Node *newgroup = xml_doc->createElement("svg:g");
-            sp_repr_css_set (newgroup, style, "style");
-
-            for (SPObject *child = sp_object_first_child(SP_DOCUMENT_ROOT(doc)); child != NULL; child = SP_OBJECT_NEXT(child) ) {
-                if (SP_IS_ITEM(child)) {
-                    Inkscape::XML::Node *newchild = SP_OBJECT_REPR(child)->duplicate(xml_doc);
-
-                    // convert layers to groups; FIXME: add "preserve layers" mode where each layer
-                    // from impot is copied to the same-named layer in host
-                    newchild->setAttribute("inkscape:groupmode", NULL);
+            newgroup = xml_in_doc->createElement("svg:g");
+            sp_repr_css_set(newgroup, style, "style");
+        }
 
-                    newgroup->appendChild(newchild);
-                }
-            }
+        // Determine the place to insert the new object.
+        // This will be the current layer, if possible.
+        // FIXME: If there's no desktop (command line run?) we need
+        //        a document:: method to return the current layer.
+        //        For now, we just use the root in this case.
+        SPObject *place_to_insert;
+        if (desktop) {
+            place_to_insert = desktop->currentLayer();
+        } else {
+            place_to_insert = in_doc->getRoot();
+        }
 
-            if (desktop) {
-                // Add it to the current layer
-                new_obj = desktop->currentLayer()->appendChildRepr(newgroup);
-            } else {
-                // There's no desktop (command line run?)
-                // FIXME: For such cases we need a document:: method to return the current layer
-                new_obj = SP_DOCUMENT_ROOT(in_doc)->appendChildRepr(newgroup);
+        // Construct a new object representing the imported image,
+        // and insert it into the current document.
+        SPObject *new_obj = NULL;
+        for ( SPObject *child = doc->getRoot()->firstChild(); child; child = child->getNext() ) {
+            if (SP_IS_ITEM(child)) {
+                Inkscape::XML::Node *newitem = SP_OBJECT_REPR(child)->duplicate(xml_in_doc);
+
+                // convert layers to groups, and make sure they are unlocked
+                // FIXME: add "preserve layers" mode where each layer from
+                //        import is copied to the same-named layer in host
+                newitem->setAttribute("inkscape:groupmode", NULL);
+                newitem->setAttribute("sodipodi:insensitive", NULL);
+
+                if (newgroup) newgroup->appendChild(newitem);
+                else new_obj = place_to_insert->appendChildRepr(newitem);
             }
 
-            Inkscape::GC::release(newgroup);
-        } else {
-            // just add one item
-            for (SPObject *child = sp_object_first_child(SP_DOCUMENT_ROOT(doc)); child != NULL; child = SP_OBJECT_NEXT(child) ) {
-                if (SP_IS_ITEM(child)) {
-                    Inkscape::XML::Node *newitem = SP_OBJECT_REPR(child)->duplicate(xml_doc);
-                    newitem->setAttribute("inkscape:groupmode", NULL);
-
-                    if (desktop) {
-                        // Add it to the current layer
-                        new_obj = desktop->currentLayer()->appendChildRepr(newitem);
-                    } else {
-                        // There's no desktop (command line run?)
-                        // FIXME: For such cases we need a document:: method to return the current layer
-                        new_obj = SP_DOCUMENT_ROOT(in_doc)->appendChildRepr(newitem);
+            // don't lose top-level defs or style elements
+            else if (SP_OBJECT_REPR(child)->type() == Inkscape::XML::ELEMENT_NODE) {
+                const gchar *tag = SP_OBJECT_REPR(child)->name();
+                if (!strcmp(tag, "svg:defs")) {
+                    for ( SPObject *x = child->firstChild(); x; x = x->getNext() ) {
+                        SP_OBJECT_REPR(in_defs)->addChild(SP_OBJECT_REPR(x)->duplicate(xml_in_doc), last_def);
                     }
-
+                }
+                else if (!strcmp(tag, "svg:style")) {
+                    in_doc->getRoot()->appendChildRepr(SP_OBJECT_REPR(child)->duplicate(xml_in_doc));
                 }
             }
         }
+        if (newgroup) new_obj = place_to_insert->appendChildRepr(newgroup);
 
-        if (style) sp_repr_css_attr_unref (style);
+        // release some stuff
+        if (newgroup) Inkscape::GC::release(newgroup);
+        if (style) sp_repr_css_attr_unref(style);
 
         // select and move the imported item
         if (new_obj && SP_IS_ITEM(new_obj)) {
             Inkscape::Selection *selection = sp_desktop_selection(desktop);
             selection->set(SP_ITEM(new_obj));
 
-            // To move the imported object, we must temporarily set the "transform pattern with
-            // object" option.
+            // preserve parent and viewBox transformations
+            // c2p is identity matrix at this point unless ensureUpToDate is called
+            doc->ensureUpToDate();
+            Geom::Matrix affine = SP_ROOT(doc->getRoot())->c2p * SP_ITEM(place_to_insert)->i2doc_affine().inverse();
+            sp_selection_apply_affine(selection, desktop->dt2doc() * affine * desktop->doc2dt(), true, false);
+
+            // move to mouse pointer
             {
-                int const saved_pref = prefs_get_int_attribute("options.transform", "pattern", 1);
-                prefs_set_int_attribute("options.transform", "pattern", 1);
-                sp_document_ensure_up_to_date(sp_desktop_document(desktop));
-                NR::Maybe<NR::Rect> sel_bbox = selection->bounds();
+                sp_desktop_document(desktop)->ensureUpToDate();
+                Geom::OptRect sel_bbox = selection->bounds();
                 if (sel_bbox) {
-                    NR::Point m( desktop->point() - sel_bbox->midpoint() );
-                    sp_selection_move_relative(selection, m);
+                    Geom::Point m( desktop->point() - sel_bbox->midpoint() );
+                    sp_selection_move_relative(selection, m, false);
                 }
-                prefs_set_int_attribute("options.transform", "pattern", saved_pref);
             }
         }
 
-        sp_document_unref(doc);
-        sp_document_done(in_doc, SP_VERB_FILE_IMPORT,
-                         _("Import"));
+        doc->doUnref();
+        DocumentUndo::done(in_doc, SP_VERB_FILE_IMPORT,
+                           _("Import"));
 
     } else {
         gchar *text = g_strdup_printf(_("Failed to load the requested file %s"), uri.c_str());
@@ -968,8 +1067,6 @@ file_import(SPDocument *in_doc, const Glib::ustring &uri,
 }
 
 
-static Inkscape::UI::Dialog::FileOpenDialog *importDialogInstance = NULL;
-
 /**
  *  Display an Open dialog, import a resource if OK pressed.
  */
@@ -982,24 +1079,46 @@ sp_file_import(Gtk::Window &parentWindow)
     if (!doc)
         return;
 
-    if (!importDialogInstance) {
-        importDialogInstance =
+    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+
+    if(import_path.empty())
+    {
+        Glib::ustring attr = prefs->getString("/dialogs/import/path");
+        if (!attr.empty()) import_path = attr;
+    }
+
+    //# Test if the import_path directory exists
+    if (!Inkscape::IO::file_test(import_path.c_str(),
+              (GFileTest)(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)))
+        import_path = "";
+
+    //# If no open path, default to our home directory
+    if (import_path.empty())
+    {
+        import_path = g_get_home_dir();
+        import_path.append(G_DIR_SEPARATOR_S);
+    }
+
+    // Create new dialog (don't use an old one, because parentWindow has probably changed)
+    Inkscape::UI::Dialog::FileOpenDialog *importDialogInstance =
              Inkscape::UI::Dialog::FileOpenDialog::create(
                  parentWindow,
-                import_path,
+                 import_path,
                  Inkscape::UI::Dialog::IMPORT_TYPES,
                  (char const *)_("Select file to import"));
-    }
 
     bool success = importDialogInstance->show();
-    if (!success)
+    if (!success) {
+        delete importDialogInstance;
         return;
+    }
 
     //# Get file name and extension type
     Glib::ustring fileName = importDialogInstance->getFilename();
-    Inkscape::Extension::Extension *selection =
-        importDialogInstance->getSelectionType();
+    Inkscape::Extension::Extension *selection = importDialogInstance->getSelectionType();
 
+    delete importDialogInstance;
+    importDialogInstance = NULL;
 
     if (fileName.size() > 0) {
 
@@ -1010,10 +1129,9 @@ sp_file_import(Gtk::Window &parentWindow)
         else
             g_warning( "ERROR CONVERTING OPEN FILENAME TO UTF-8" );
 
-
-        import_path = fileName;
-        if (import_path.size()>0)
-            import_path.append(G_DIR_SEPARATOR_S);
+        import_path = Glib::path_get_dirname (fileName);
+        import_path.append(G_DIR_SEPARATOR_S);
+        prefs->setString("/dialogs/import/path", import_path);
 
         file_import(doc, fileName, selection);
     }
@@ -1027,19 +1145,14 @@ sp_file_import(Gtk::Window &parentWindow)
 ## E X P O R T
 ######################*/
 
-//#define NEW_EXPORT_DIALOG
-
-
 
 #ifdef NEW_EXPORT_DIALOG
 
-static Inkscape::UI::Dialog::FileExportDialog *exportDialogInstance = NULL;
-
 /**
  *  Display an Export dialog, export as the selected type if OK pressed
  */
 bool
-sp_file_export_dialog(void *widget)
+sp_file_export_dialog(Gtk::Window &parentWindow)
 {
     //# temp hack for 'doc' until we can switch to this dialog
     SPDocument *doc = SP_ACTIVE_DOCUMENT;
@@ -1047,17 +1160,15 @@ sp_file_export_dialog(void *widget)
     Glib::ustring export_path;
     Glib::ustring export_loc;
 
-    Inkscape::XML::Node *repr = sp_document_repr_root(doc);
-
+    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
     Inkscape::Extension::Output *extension;
 
     //# Get the default extension name
-    Glib::ustring default_extension;
-    char *attr = (char *)repr->attribute("inkscape:output_extension");
-    if (!attr)
-        attr = (char *)prefs_get_string_attribute("dialogs.save_as", "default");
-    if (attr)
-        default_extension = attr;
+    Glib::ustring default_extension = prefs->getString("/dialogs/save_export/default");
+    if(default_extension.empty()) {
+        // FIXME: Is this a good default? Should there be a macro for the string?
+        default_extension = "org.inkscape.output.png.cairo";
+    }
     //g_message("%s: extension name: '%s'", __FUNCTION__, default_extension);
 
     if (doc->uri == NULL)
@@ -1071,9 +1182,9 @@ sp_file_export_dialog(void *widget)
         if (extension)
             filename_extension = extension->get_extension();
 
-        attr = (char *)prefs_get_string_attribute("dialogs.save_as", "path");
-        if (attr)
-            export_path = attr;
+        Glib::ustring attr3 = prefs->getString("/dialogs/save_export/path");
+        if (!attr3.empty())
+            export_path = attr3;
 
         if (!Inkscape::IO::file_test(export_path.c_str(),
               (GFileTest)(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)))
@@ -1100,25 +1211,29 @@ sp_file_export_dialog(void *widget)
     if ( export_path_local.size() > 0)
         export_path = export_path_local;
 
-    //# Show the SaveAs dialog
-    if (!exportDialogInstance)
-        exportDialogInstance =
-             Inkscape::UI::Dialog::FileExportDialog::create(
-                 export_path,
-                 Inkscape::UI::Dialog::EXPORT_TYPES,
-                 (char const *) _("Select file to export to"),
-                 default_extension
-            );
+    //# Show the Export dialog
+    Inkscape::UI::Dialog::FileExportDialog *exportDialogInstance =
+        Inkscape::UI::Dialog::FileExportDialog::create(
+            parentWindow,
+            export_path,
+            Inkscape::UI::Dialog::EXPORT_TYPES,
+            (char const *) _("Select file to export to"),
+            default_extension
+        );
 
     bool success = exportDialogInstance->show();
-    if (!success)
+    if (!success) {
+        delete exportDialogInstance;
         return success;
+    }
 
     Glib::ustring fileName = exportDialogInstance->getFilename();
 
     Inkscape::Extension::Extension *selectionType =
         exportDialogInstance->getSelectionType();
 
+    delete exportDialogInstance;
+    exportDialogInstance = NULL;
 
     if (fileName.size() > 0) {
         Glib::ustring newFileName = Glib::filename_to_utf8(fileName);
@@ -1128,13 +1243,15 @@ sp_file_export_dialog(void *widget)
         else
             g_warning( "Error converting save filename to UTF-8." );
 
-        success = file_save(doc, fileName, selectionType, TRUE, FALSE);
+        success = file_save(parentWindow, doc, fileName, selectionType, TRUE, FALSE, Inkscape::Extension::FILE_SAVE_METHOD_EXPORT);
 
-        if (success)
-            prefs_set_recent_file(SP_DOCUMENT_URI(doc), SP_DOCUMENT_NAME(doc));
+        if (success) {
+            Glib::RefPtr<Gtk::RecentManager> recent = Gtk::RecentManager::get_default();
+            recent->add_item( doc->getURI() );
+        }
 
         export_path = fileName;
-        prefs_set_string_attribute("dialogs.save_as", "path", export_path.c_str());
+        prefs->setString("/dialogs/save_export/path", export_path);
 
         return success;
     }
@@ -1149,7 +1266,7 @@ sp_file_export_dialog(void *widget)
  *
  */
 bool
-sp_file_export_dialog(void */*widget*/)
+sp_file_export_dialog(Gtk::Window &/*parentWindow*/)
 {
     sp_export_dialog();
     return true;
@@ -1164,6 +1281,7 @@ sp_file_export_dialog(void */*widget*/)
 /**
  *  Display an Export dialog, export as the selected type if OK pressed
  */
+/*
 bool
 sp_file_export_to_ocal_dialog(Gtk::Window &parentWindow)
 {
@@ -1180,13 +1298,12 @@ sp_file_export_to_ocal_dialog(Gtk::Window &parentWindow)
 
     bool success = false;
 
-    static Inkscape::UI::Dialog::FileExportToOCALDialog *exportDialogInstance = NULL;
-    static Inkscape::UI::Dialog::FileExportToOCALPasswordDialog *exportPasswordDialogInstance = NULL;
     static bool gotSuccess = false;
 
-    Inkscape::XML::Node *repr = sp_document_repr_root(doc);
+    Inkscape::XML::Node *repr = doc->getReprRoot();
+    (void)repr;
 
-    if (!doc->uri && !doc->isModified())
+    if (!doc->uri && !doc->isModifiedSinceSave())
         return false;
 
     //  Get the default extension name
@@ -1211,19 +1328,24 @@ sp_file_export_to_ocal_dialog(Gtk::Window &parentWindow)
         export_path = export_path_local;
 
     // Show the Export To OCAL dialog
-    if (!exportDialogInstance)
-        exportDialogInstance = new Inkscape::UI::Dialog::FileExportToOCALDialog(
+    Inkscape::UI::Dialog::FileExportToOCALDialog *exportDialogInstance =
+        new Inkscape::UI::Dialog::FileExportToOCALDialog(
                 parentWindow,
                 Inkscape::UI::Dialog::EXPORT_TYPES,
                 (char const *) _("Select file to export to")
                 );
 
     success = exportDialogInstance->show();
-    if (!success)
+    if (!success) {
+        delete exportDialogInstance;
         return success;
+    }
 
     fileName = exportDialogInstance->getFilename();
 
+    delete exportDialogInstance;
+    exportDialogInstance = NULL;;
+
     fileName.append(filename_extension.c_str());
     if (fileName.size() > 0) {
         Glib::ustring newFileName = Glib::filename_to_utf8(fileName);
@@ -1239,7 +1361,7 @@ sp_file_export_to_ocal_dialog(Gtk::Window &parentWindow)
 
     fileName = filePath;
 
-    success = file_save(parentWindow, doc, filePath, selectionType, FALSE, FALSE);
+    success = file_save(parentWindow, doc, filePath, selectionType, FALSE, FALSE, Inkscape::Extension::FILE_SAVE_METHOD_EXPORT);
 
     if (!success){
         gchar *text = g_strdup_printf(_("Error saving a temporary copy"));
@@ -1251,29 +1373,35 @@ sp_file_export_to_ocal_dialog(Gtk::Window &parentWindow)
     // Start now the submition
 
     // Create the uri
+    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
     Glib::ustring uri = "dav://";
-    char *username = (char *)prefs_get_string_attribute("options.ocalusername", "str");
-    char *password = (char *)prefs_get_string_attribute("options.ocalpassword", "str");
-    if ((username == NULL) || (!strcmp(username, "")) || (password == NULL) || (!strcmp(password, "")))
+    Glib::ustring username = prefs->getString("/options/ocalusername/str");
+    Glib::ustring password = prefs->getString("/options/ocalpassword/str");
+    if (username.empty() || password.empty())
     {
+        Inkscape::UI::Dialog::FileExportToOCALPasswordDialog *exportPasswordDialogInstance = NULL;
         if(!gotSuccess)
         {
-            if (!exportPasswordDialogInstance)
-                exportPasswordDialogInstance = new Inkscape::UI::Dialog::FileExportToOCALPasswordDialog(
+            exportPasswordDialogInstance = new Inkscape::UI::Dialog::FileExportToOCALPasswordDialog(
                     parentWindow,
                     (char const *) _("Open Clip Art Login"));
             success = exportPasswordDialogInstance->show();
-            if (!success)
+            if (!success) {
+                delete exportPasswordDialogInstance;
                 return success;
+            }
         }
-        username = (char *)exportPasswordDialogInstance->getUsername().c_str();
-        password = (char *)exportPasswordDialogInstance->getPassword().c_str();
+        username = exportPasswordDialogInstance->getUsername();
+        password = exportPasswordDialogInstance->getPassword();
+
+        delete exportPasswordDialogInstance;
+        exportPasswordDialogInstance = NULL;
     }
     uri.append(username);
     uri.append(":");
     uri.append(password);
     uri.append("@");
-    uri.append(prefs_get_string_attribute("options.ocalurl", "str"));
+    uri.append(prefs->getString("/options/ocalurl/str"));
     uri.append("/dav.php/");
     uri.append(Glib::path_get_basename(fileName));
 
@@ -1282,7 +1410,7 @@ sp_file_export_to_ocal_dialog(Gtk::Window &parentWindow)
     remove(fileName.c_str());
     if (!success)
     {
-        gchar *text = g_strdup_printf(_("Error exporting the document. Verify if the server name, username and password are correct. If the server have support for webdav and verify if you didn't forget to choose a license too."));
+        gchar *text = g_strdup_printf(_("Error exporting the document. Verify if the server name, username and password are correct, if the server has support for webdav and verify if you didn't forget to choose a license."));
         sp_ui_error_dialog(text);
     }
     else
@@ -1290,10 +1418,11 @@ sp_file_export_to_ocal_dialog(Gtk::Window &parentWindow)
 
     return success;
 }
-
+*/
 /**
  * Export the current document to OCAL
  */
+/*
 void
 sp_file_export_to_ocal(Gtk::Window &parentWindow)
 {
@@ -1305,7 +1434,7 @@ sp_file_export_to_ocal(Gtk::Window &parentWindow)
     if (success)
         SP_ACTIVE_DESKTOP->messageStack()->flash(Inkscape::IMMEDIATE_MESSAGE, _("Document exported..."));
 }
-
+*/
 
 /*######################
 ## I M P O R T  F R O M  O C A L
@@ -1323,7 +1452,7 @@ sp_file_import_from_ocal(Gtk::Window &parentWindow)
     if (!doc)
         return;
 
-    static Inkscape::UI::Dialog::FileImportFromOCALDialog *importDialogInstance = NULL;
+    Inkscape::UI::Dialog::FileImportFromOCALDialog *importDialogInstance = NULL;
 
     if (!importDialogInstance) {
         importDialogInstance = new
@@ -1335,13 +1464,17 @@ sp_file_import_from_ocal(Gtk::Window &parentWindow)
     }
 
     bool success = importDialogInstance->show();
-    if (!success)
+    if (!success) {
+        delete importDialogInstance;
         return;
+    }
 
     // Get file name and extension type
     Glib::ustring fileName = importDialogInstance->getFilename();
-    Inkscape::Extension::Extension *selection =
-        importDialogInstance->getSelectionType();
+    Inkscape::Extension::Extension *selection = importDialogInstance->getSelectionType();
+
+    delete importDialogInstance;
+    importDialogInstance = NULL;
 
     if (fileName.size() > 0) {
 
@@ -1392,102 +1525,6 @@ sp_file_print_preview(gpointer /*object*/, gpointer /*data*/)
 
 }
 
-void Inkscape::IO::fixupHrefs( SPDocument *doc, const gchar *base, gboolean spns )
-{
-    //g_message("Inkscape::IO::fixupHrefs( , [%s], )", base );
-
-    if ( 0 ) {
-        gchar const* things[] = {
-            "data:foo,bar",
-            "http://www.google.com/image.png",
-            "ftp://ssd.com/doo",
-            "/foo/dee/bar.svg",
-            "foo.svg",
-            "file:/foo/dee/bar.svg",
-            "file:///foo/dee/bar.svg",
-            "file:foo.svg",
-            "/foo/bar\xe1\x84\x92.svg",
-            "file:///foo/bar\xe1\x84\x92.svg",
-            "file:///foo/bar%e1%84%92.svg",
-            "/foo/bar%e1%84%92.svg",
-            "bar\xe1\x84\x92.svg",
-            "bar%e1%84%92.svg",
-            NULL
-        };
-        g_message("+------");
-        for ( int i = 0; things[i]; i++ )
-        {
-            try
-            {
-                URI uri(things[i]);
-                gboolean isAbs = g_path_is_absolute( things[i] );
-                gchar *str = uri.toString();
-                g_message( "abs:%d  isRel:%d  scheme:[%s]  path:[%s][%s]   uri[%s] / [%s]", (int)isAbs,
-                           (int)uri.isRelative(),
-                           uri.getScheme(),
-                           uri.getPath(),
-                           uri.getOpaque(),
-                           things[i],
-                           str );
-                g_free(str);
-            }
-            catch ( MalformedURIException err )
-            {
-                dump_str( things[i], "MalformedURIException" );
-                xmlChar *redo = xmlURIEscape((xmlChar const *)things[i]);
-                g_message("    gone from [%s] to [%s]", things[i], redo );
-                if ( redo == NULL )
-                {
-                    URI again = URI::fromUtf8( things[i] );
-                    gboolean isAbs = g_path_is_absolute( things[i] );
-                    gchar *str = again.toString();
-                    g_message( "abs:%d  isRel:%d  scheme:[%s]  path:[%s][%s]   uri[%s] / [%s]", (int)isAbs,
-                               (int)again.isRelative(),
-                               again.getScheme(),
-                               again.getPath(),
-                               again.getOpaque(),
-                               things[i],
-                               str );
-                    g_free(str);
-                    g_message("    ----");
-                }
-            }
-        }
-        g_message("+------");
-    }
-
-    GSList const *images = sp_document_get_resource_list(doc, "image");
-    for (GSList const *l = images; l != NULL; l = l->next) {
-        Inkscape::XML::Node *ir = SP_OBJECT_REPR(l->data);
-
-        const gchar *href = ir->attribute("xlink:href");
-
-        // First try to figure out an absolute path to the asset
-        //g_message("image href [%s]", href );
-        if (spns && !g_path_is_absolute(href)) {
-            const gchar *absref = ir->attribute("sodipodi:absref");
-            const gchar *base_href = g_build_filename(base, href, NULL);
-            //g_message("      absr [%s]", absref );
-
-            if ( absref && Inkscape::IO::file_test(absref, G_FILE_TEST_EXISTS) && !Inkscape::IO::file_test(base_href, G_FILE_TEST_EXISTS))
-            {
-                // only switch over if the absref is valid while href is not
-                href = absref;
-                //g_message("     copied absref to href");
-            }
-        }
-
-        // Once we have an absolute path, convert it relative to the new location
-        if (href && g_path_is_absolute(href)) {
-            const gchar *relname = sp_relative_path_from_path(href, base);
-            //g_message("     setting to [%s]", relname );
-            ir->setAttribute("xlink:href", relname);
-        }
-// TODO next refinement is to make the first choice keeping the relative path as-is if
-//      based on the new location it gives us a valid file.
-    }
-}
-
 
 /*
   Local Variables: