Code

Merge and cleanup of GSoC C++-ification project.
[inkscape.git] / src / dialogs / export.cpp
index dc337ef8e841ea006d025334258262825ee0ffbd..7e99c2496efb96fb12b2de617fe2ca73db65cc7f 100644 (file)
@@ -1,14 +1,12 @@
-#define __SP_EXPORT_C__
-
-/** \file
- * \brief  PNG export dialog
+/** @file
+ * @brief  PNG export dialog
  */
-
-/*
- * Authors:
+/* Authors:
  *   Lauris Kaplinski <lauris@kaplinski.com>
  *   bulia byak <buliabyak@users.sf.net>
  *   Johan Engelen <j.b.c.engelen@ewi.utwente.nl>
+ *   Jon A. Cruz <jon@joncruz.org>
+ *   Abhishek Sharma
  *
  * Copyright (C) 1999-2007 Authors
  * Copyright (C) 2001-2002 Ximian, Inc.
@@ -20,6 +18,9 @@
 # include "config.h"
 #endif
 
+// This has to be included prior to anything that includes setjmp.h, it croaks otherwise
+#include <png.h>
+
 #include <gtk/gtk.h>
 #include <gtkmm/box.h>
 #include <gtkmm/buttonbox.h>
 #include "io/sys.h"
 
 #include "helper/png-write.h"
-#include <png.h>
 
+#ifdef WIN32
+#include <windows.h>
+#include <commdlg.h>
+#include <gdk/gdkwin32.h>
+#endif
+
+using Inkscape::DocumentUndo;
 
 #define SP_EXPORT_MIN_SIZE 1.0
 
@@ -169,7 +176,7 @@ sp_export_dialog_delete ( GtkObject */*object*/, GdkEvent */*event*/, gpointer /
 
     if (x<0) x=0;
     if (y<0) y=0;
-    
+
     Inkscape::Preferences *prefs = Inkscape::Preferences::get();
     prefs->setInt(prefs_path + "x", x);
     prefs->setInt(prefs_path + "y", y);
@@ -208,13 +215,13 @@ sp_export_spinbutton_new ( gchar const *key, float val, float min, float max,
                            int digits, unsigned int sensitive,
                            GCallback cb, GtkWidget *dlg )
 {
-    GtkObject *a = gtk_adjustment_new (val, min, max, step, page, page);
-    gtk_object_set_data (a, "key", const_cast<gchar *>(key));
-    gtk_object_set_data (GTK_OBJECT (dlg), (const gchar *)key, a);
+    GtkObject *adj = gtk_adjustment_new( val, min, max, step, page, 0 );
+    gtk_object_set_data( adj, "key", const_cast<gchar *>(key) );
+    gtk_object_set_data( GTK_OBJECT (dlg), (const gchar *)key, adj );
 
     if (us) {
         sp_unit_selector_add_adjustment ( SP_UNIT_SELECTOR (us),
-                                          GTK_ADJUSTMENT (a) );
+                                          GTK_ADJUSTMENT (adj) );
     }
 
     int pos = 0;
@@ -232,7 +239,7 @@ sp_export_spinbutton_new ( gchar const *key, float val, float min, float max,
 
     }
 
-    GtkWidget *sb = gtk_spin_button_new (GTK_ADJUSTMENT (a), 1.0, digits);
+    GtkWidget *sb = gtk_spin_button_new (GTK_ADJUSTMENT (adj), 1.0, digits);
     gtk_table_attach ( GTK_TABLE (t), sb, x + pos, x + pos + 1, y, y + 1,
                        (GtkAttachOptions)0, (GtkAttachOptions)0, 0, 0 );
     gtk_widget_set_size_request (sb, 80, -1);
@@ -254,7 +261,7 @@ sp_export_spinbutton_new ( gchar const *key, float val, float min, float max,
     }
 
     if (cb)
-        gtk_signal_connect (a, "value_changed", cb, dlg);
+        gtk_signal_connect (adj, "value_changed", cb, dlg);
 
     return;
 } // end of sp_export_spinbutton_new()
@@ -317,7 +324,7 @@ sp_export_dialog_area_box (GtkWidget * dlg)
                                dlg );
 
     sp_export_spinbutton_new ( "width", 0.0, 0.0, PNG_UINT_31_MAX, 0.1, 1.0,
-                               us->gobj(), GTK_WIDGET(t->gobj()), 4, 0, _("Width:"), NULL, EXPORT_COORD_PRECISION, 1,
+                               us->gobj(), GTK_WIDGET(t->gobj()), 4, 0, _("Wid_th:"), NULL, EXPORT_COORD_PRECISION, 1,
                                G_CALLBACK
                                    (sp_export_area_width_value_changed),
                                dlg );
@@ -333,7 +340,7 @@ sp_export_dialog_area_box (GtkWidget * dlg)
                                dlg );
 
     sp_export_spinbutton_new ( "height", 0.0, 0.0, PNG_UINT_31_MAX, 0.1, 1.0,
-                               us->gobj(), GTK_WIDGET(t->gobj()), 4, 1, _("Height:"), NULL, EXPORT_COORD_PRECISION, 1,
+                               us->gobj(), GTK_WIDGET(t->gobj()), 4, 1, _("Hei_ght:"), NULL, EXPORT_COORD_PRECISION, 1,
                                G_CALLBACK (sp_export_area_height_value_changed),
                                dlg );
 
@@ -359,9 +366,9 @@ gchar* create_filepath_from_id (const gchar *id, const gchar *file_entry_text) {
 
     if (directory == NULL) {
         /* Grab document directory */
-        if (SP_DOCUMENT_URI(SP_ACTIVE_DOCUMENT)) {
+        if ( SP_ACTIVE_DOCUMENT->getURI() ) {
             // std::cout << "Directory from document" << std::endl;
-            directory = g_dirname(SP_DOCUMENT_URI(SP_ACTIVE_DOCUMENT));
+            directory = g_dirname( SP_ACTIVE_DOCUMENT->getURI() );
         }
     }
 
@@ -492,7 +499,7 @@ sp_export_dialog (void)
 
             sp_export_spinbutton_new ( "bmheight", 16.0, 1.0, 1000000.0, 1.0, 10.0,
                                        NULL, GTK_WIDGET(t->gobj()), 0, 1,
-                                       _("Height:"), _("pixels at"), 0, 1,
+                                       _("_Height:"), _("pixels at"), 0, 1,
                                        G_CALLBACK
                                        (sp_export_bitmap_height_value_changed),
                                        dlg );
@@ -532,13 +539,12 @@ sp_export_dialog (void)
              * this code sets the name first, it may not be the one users
              * really see.
              */
-            if (SP_ACTIVE_DOCUMENT && SP_DOCUMENT_URI (SP_ACTIVE_DOCUMENT))
+            if ( SP_ACTIVE_DOCUMENT && SP_ACTIVE_DOCUMENT->getURI() )
             {
                 gchar *name;
                 SPDocument * doc = SP_ACTIVE_DOCUMENT;
-                const gchar *uri = SP_DOCUMENT_URI (doc);
-                Inkscape::XML::Node * repr = sp_document_repr_root(doc);
-                const gchar * text_extension = repr->attribute("inkscape:output_extension");
+                const gchar *uri = doc->getURI();
+                const gchar *text_extension = get_file_save_extension (Inkscape::Extension::FILE_SAVE_METHOD_SAVE_AS).c_str();
                 Inkscape::Extension::Output * oextension = NULL;
 
                 if (text_extension != NULL) {
@@ -778,7 +784,7 @@ sp_export_selection_modified ( Inkscape::Application */*inkscape*/,
             if ( SP_ACTIVE_DESKTOP ) {
                 SPDocument *doc;
                 doc = sp_desktop_document (SP_ACTIVE_DESKTOP);
-                boost::optional<Geom::Rect> bbox = sp_item_bbox_desktop (SP_ITEM (SP_DOCUMENT_ROOT (doc)));
+                Geom::OptRect bbox = SP_ITEM(doc->root)->getBboxDesktop(SPItem::RENDERING_BBOX);
                 if (bbox) {
                     sp_export_set_area (base, bbox->min()[Geom::X],
                                               bbox->min()[Geom::Y],
@@ -790,7 +796,7 @@ sp_export_selection_modified ( Inkscape::Application */*inkscape*/,
         case SELECTION_SELECTION:
             if ((sp_desktop_selection(SP_ACTIVE_DESKTOP))->isEmpty() == false) {
                 NRRect bbox;
-                (sp_desktop_selection (SP_ACTIVE_DESKTOP))->bounds(&bbox);
+                (sp_desktop_selection (SP_ACTIVE_DESKTOP))->bounds(&bbox, SPItem::RENDERING_BBOX);
                 sp_export_set_area (base, bbox.x0, bbox.y0, bbox.x1, bbox.y1);
             }
             break;
@@ -837,7 +843,7 @@ sp_export_area_toggled (GtkToggleButton *tb, GtkObject *base)
     if ( SP_ACTIVE_DESKTOP )
     {
         SPDocument *doc;
-        boost::optional<Geom::Rect> bbox;
+        Geom::OptRect bbox;
         doc = sp_desktop_document (SP_ACTIVE_DESKTOP);
 
         /* Notice how the switch is used to 'fall through' here to get
@@ -847,7 +853,7 @@ sp_export_area_toggled (GtkToggleButton *tb, GtkObject *base)
             case SELECTION_SELECTION:
                 if ((sp_desktop_selection(SP_ACTIVE_DESKTOP))->isEmpty() == false)
                 {
-                    bbox = sp_desktop_selection (SP_ACTIVE_DESKTOP)->bounds();
+                    bbox = sp_desktop_selection (SP_ACTIVE_DESKTOP)->bounds(SPItem::RENDERING_BBOX);
                     /* Only if there is a selection that we can set
                        do we break, otherwise we fall through to the
                        drawing */
@@ -859,7 +865,7 @@ sp_export_area_toggled (GtkToggleButton *tb, GtkObject *base)
                 /** \todo
                  * This returns wrong values if the document has a viewBox.
                  */
-                bbox = sp_item_bbox_desktop (SP_ITEM (SP_DOCUMENT_ROOT (doc)));
+                bbox = SP_ITEM(doc->root)->getBboxDesktop(SPItem::RENDERING_BBOX);
                 /* If the drawing is valid, then we'll use it and break
                    otherwise we drop through to the page settings */
                 if (bbox) {
@@ -869,7 +875,7 @@ sp_export_area_toggled (GtkToggleButton *tb, GtkObject *base)
                 }
             case SELECTION_PAGE:
                 bbox = Geom::Rect(Geom::Point(0.0, 0.0),
-                                  Geom::Point(sp_document_width(doc), sp_document_height(doc)));
+                                  Geom::Point(doc->getWidth(), doc->getHeight()));
 
                 // std::cout << "Using selection: PAGE" << std::endl;
                 key = SELECTION_PAGE;
@@ -1038,7 +1044,7 @@ create_progress_dialog (GtkObject *base, gchar *progress_text) {
 static gchar *
 filename_add_extension (const gchar *filename, const gchar *extension)
 {
-  gchar *dot;
+  const gchar *dot;
 
   dot = strrchr (filename, '.');
   if ( !dot )
@@ -1058,6 +1064,23 @@ filename_add_extension (const gchar *filename, const gchar *extension)
   }
 }
 
+gchar *absolutize_path_from_document_location (SPDocument *doc, const gchar *filename)
+{
+    gchar *path = 0;
+    //Make relative paths go from the document location, if possible:
+    if (!g_path_is_absolute(filename) && doc->getURI()) {
+        gchar *dirname = g_path_get_dirname(doc->getURI());
+        if (dirname) {
+            path = g_build_filename(dirname, filename, NULL);
+            g_free(dirname);
+        }
+    }
+    if (!path) {
+        path = g_strdup(filename);
+    }
+    return path;
+}
+
 /// Called when export button is clicked
 static void
 sp_export_export_clicked (GtkButton */*button*/, GtkObject *base)
@@ -1065,6 +1088,7 @@ sp_export_export_clicked (GtkButton */*button*/, GtkObject *base)
     if (!SP_ACTIVE_DESKTOP) return;
 
     SPNamedView *nv = sp_desktop_namedview(SP_ACTIVE_DESKTOP);
+    SPDocument *doc = sp_desktop_document (SP_ACTIVE_DESKTOP);
 
     GtkWidget *be = (GtkWidget *)gtk_object_get_data(base, "batch_checkbox");
     GtkWidget *he = (GtkWidget *)gtk_object_get_data(base, "hide_checkbox");
@@ -1085,15 +1109,19 @@ sp_export_export_clicked (GtkButton */*button*/, GtkObject *base)
         for (GSList *i = (GSList *) sp_desktop_selection(SP_ACTIVE_DESKTOP)->itemList();
              i != NULL;
              i = i->next) {
-            SPItem *item = (SPItem *) i->data;
+            SPItem *item = reinterpret_cast<SPItem *>(i->data);
+
             // retrieve export filename hint
-            const gchar *fn = SP_OBJECT_REPR(item)->attribute("inkscape:export-filename");
-            if (!fn) {
-                fn = create_filepath_from_id (SP_OBJECT_ID(item), NULL);
+            const gchar *filename = item->getRepr()->attribute("inkscape:export-filename");
+            gchar *path = 0;
+            if (!filename) {
+                path = create_filepath_from_id(item->getId(), NULL);
+            } else {
+                path = absolutize_path_from_document_location(doc, filename);
             }
 
             // retrieve export dpi hints
-            const gchar *dpi_hint = SP_OBJECT_REPR(item)->attribute("inkscape:export-xdpi"); // only xdpi, ydpi is always the same now
+            const gchar *dpi_hint = item->getRepr()->attribute("inkscape:export-xdpi"); // only xdpi, ydpi is always the same now
             gdouble dpi = 0.0;
             if (dpi_hint) {
                 dpi = atof(dpi_hint);
@@ -1102,29 +1130,31 @@ sp_export_export_clicked (GtkButton */*button*/, GtkObject *base)
                 dpi = DPI_BASE;
             }
 
-            NRRect area;
-            sp_item_invoke_bbox(item, &area, sp_item_i2r_affine((SPItem *) item), TRUE);
-
-            gint width = (gint) ((area.x1 - area.x0) * dpi / PX_PER_IN + 0.5);
-            gint height = (gint) ((area.y1 - area.y0) * dpi / PX_PER_IN + 0.5);
-
-            if (width > 1 && height > 1) {
-                /* Do export */
-                if (!sp_export_png_file (sp_desktop_document (SP_ACTIVE_DESKTOP), fn,
-                                         area.x0, area.y0, area.x1, area.y1, width, height, dpi, dpi,
-                                         nv->pagecolor,
-                                         NULL, NULL, TRUE,  // overwrite without asking
-                                         hide ? (GSList *) sp_desktop_selection(SP_ACTIVE_DESKTOP)->itemList() : NULL
-                        )) {
-                    gchar * error;
-                    gchar * safeFile = Inkscape::IO::sanitizeString(fn);
-                    error = g_strdup_printf(_("Could not export to filename %s.\n"), safeFile);
-                    sp_ui_error_dialog(error);
-                    g_free(safeFile);
-                    g_free(error);
+            Geom::OptRect area;
+            item->invoke_bbox( area, item->i2d_affine(), TRUE );
+            if (area) {
+                gint width = (gint) (area->width() * dpi / PX_PER_IN + 0.5);
+                gint height = (gint) (area->height() * dpi / PX_PER_IN + 0.5);
+
+                if (width > 1 && height > 1) {
+                    /* Do export */
+                    if (!sp_export_png_file (doc, path,
+                                             *area, width, height, dpi, dpi,
+                                             nv->pagecolor,
+                                             NULL, NULL, TRUE,  // overwrite without asking
+                                             hide ? (GSList *) sp_desktop_selection(SP_ACTIVE_DESKTOP)->itemList() : NULL
+                            )) {
+                        gchar * error;
+                        gchar * safeFile = Inkscape::IO::sanitizeString(path);
+                        error = g_strdup_printf(_("Could not export to filename %s.\n"), safeFile);
+                        sp_ui_error_dialog(error);
+                        g_free(safeFile);
+                        g_free(error);
+                    }
                 }
             }
             n++;
+            g_free(path);
             sp_export_progress_callback((float)n/num, base);
         }
 
@@ -1155,7 +1185,13 @@ sp_export_export_clicked (GtkButton */*button*/, GtkObject *base)
         return;
     }
 
-    gchar *dirname = g_path_get_dirname(filename);
+    // make sure that .png is the extension of the file:
+    gchar * filename_ext = filename_add_extension(filename, "png");
+    gtk_entry_set_text(GTK_ENTRY(fe), filename_ext);
+
+    gchar *path = absolutize_path_from_document_location(doc, filename_ext);
+
+    gchar *dirname = g_path_get_dirname(path);
     if ( dirname == NULL
          || !Inkscape::IO::file_test(dirname, (GFileTest)(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) )
     {
@@ -1166,30 +1202,27 @@ sp_export_export_clicked (GtkButton */*button*/, GtkObject *base)
         g_free(safeDir);
         g_free(error);
         g_free(dirname);
+        g_free(path);
         return;
     }
     g_free(dirname);
 
-    // make sure that .png is the extension of the file:
-    gchar * filename_ext = filename_add_extension(filename, "png");
-    gtk_entry_set_text(GTK_ENTRY(fe), filename_ext);
-
-    gchar *fn = g_path_get_basename (filename_ext);
-
+    gchar *fn = g_path_get_basename (path);
     gchar *progress_text = g_strdup_printf (_("Exporting %s (%lu x %lu)"), fn, width, height);
     g_free (fn);
+
     GtkWidget *prog_dlg = create_progress_dialog (base, progress_text);
     g_free (progress_text);
 
     /* Do export */
-    if (!sp_export_png_file (sp_desktop_document (SP_ACTIVE_DESKTOP), filename_ext,
-                             x0, y0, x1, y1, width, height, xdpi, ydpi,
+    if (!sp_export_png_file (sp_desktop_document (SP_ACTIVE_DESKTOP), path,
+                             Geom::Rect(Geom::Point(x0, y0), Geom::Point(x1, y1)), width, height, xdpi, ydpi,
                              nv->pagecolor,
                              sp_export_progress_callback, base, FALSE,
                              hide ? (GSList *) sp_desktop_selection(SP_ACTIVE_DESKTOP)->itemList() : NULL
             )) {
         gchar * error;
-        gchar * safeFile = Inkscape::IO::sanitizeString(filename);
+        gchar * safeFile = Inkscape::IO::sanitizeString(path);
         error = g_strdup_printf(_("Could not export to filename %s.\n"), safeFile);
         sp_ui_error_dialog(error);
         g_free(safeFile);
@@ -1210,14 +1243,13 @@ sp_export_export_clicked (GtkButton */*button*/, GtkObject *base)
         case SELECTION_PAGE:
         case SELECTION_DRAWING: {
             SPDocument * doc = SP_ACTIVE_DOCUMENT;
-            Inkscape::XML::Node * repr = sp_document_repr_root(doc);
+            Inkscape::XML::Node * repr = doc->getReprRoot();
             bool modified = false;
-            const gchar * temp_string;
 
-            bool saved = sp_document_get_undo_sensitive(doc);
-            sp_document_set_undo_sensitive(doc, false);
+            bool saved = DocumentUndo::getUndoSensitive(doc);
+            DocumentUndo::setUndoSensitive(doc, false);
 
-            temp_string = repr->attribute("inkscape:export-filename");
+            gchar const *temp_string = repr->attribute("inkscape:export-filename");
             if (temp_string == NULL || strcmp(temp_string, filename_ext)) {
                 repr->setAttribute("inkscape:export-filename", filename_ext);
                 modified = true;
@@ -1232,7 +1264,7 @@ sp_export_export_clicked (GtkButton */*button*/, GtkObject *base)
                 sp_repr_set_svg_double(repr, "inkscape:export-ydpi", ydpi);
                 modified = true;
             }
-            sp_document_set_undo_sensitive(doc, saved);
+            DocumentUndo::setUndoSensitive(doc, saved);
 
             if (modified) {
                 doc->setModifiedSinceSave();
@@ -1244,8 +1276,8 @@ sp_export_export_clicked (GtkButton */*button*/, GtkObject *base)
             SPDocument * doc = SP_ACTIVE_DOCUMENT;
             bool modified = false;
 
-            bool saved = sp_document_get_undo_sensitive(doc);
-            sp_document_set_undo_sensitive(doc, false);
+            bool saved = DocumentUndo::getUndoSensitive(doc);
+            DocumentUndo::setUndoSensitive(doc, false);
             reprlst = sp_desktop_selection(SP_ACTIVE_DESKTOP)->reprList();
 
             for(; reprlst != NULL; reprlst = reprlst->next) {
@@ -1254,8 +1286,8 @@ sp_export_export_clicked (GtkButton */*button*/, GtkObject *base)
 
                 if (repr->attribute("id") == NULL ||
                         !(g_strrstr(filename_ext, repr->attribute("id")) != NULL &&
-                          (!SP_DOCUMENT_URI(SP_ACTIVE_DOCUMENT) ||
-                            strcmp(g_dirname(filename), g_dirname(SP_DOCUMENT_URI(SP_ACTIVE_DOCUMENT))) == 0))) {
+                          ( !SP_ACTIVE_DOCUMENT->getURI() ||
+                            strcmp(g_dirname(filename), g_dirname(SP_ACTIVE_DOCUMENT->getURI())) == 0))) {
                     temp_string = repr->attribute("inkscape:export-filename");
                     if (temp_string == NULL || strcmp(temp_string, filename_ext)) {
                         repr->setAttribute("inkscape:export-filename", filename_ext);
@@ -1273,7 +1305,7 @@ sp_export_export_clicked (GtkButton */*button*/, GtkObject *base)
                     modified = true;
                 }
             }
-            sp_document_set_undo_sensitive(doc, saved);
+            DocumentUndo::setUndoSensitive(doc, saved);
 
             if (modified) {
                 doc->setModifiedSinceSave();
@@ -1285,12 +1317,14 @@ sp_export_export_clicked (GtkButton */*button*/, GtkObject *base)
     }
 
     g_free (filename_ext);
+    g_free (path);
 
     }
 
 } // end of sp_export_export_clicked()
 
 /// Called when Browse button is clicked
+/// @todo refactor this code to use ui/dialogs/filedialog.cpp
 static void
 sp_export_browse_clicked (GtkButton */*button*/, gpointer /*userdata*/)
 {
@@ -1319,11 +1353,59 @@ sp_export_browse_clicked (GtkButton */*button*/, gpointer /*userdata*/)
     filename = gtk_entry_get_text (GTK_ENTRY (fe));
 
     if (*filename == '\0') {
-        filename = homedir_path(NULL);
+        filename = create_filepath_from_id(NULL, NULL);
     }
 
     gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (fs), filename);
 
+#ifdef WIN32
+    // code in this section is borrowed from ui/dialogs/filedialogimpl-win32.cpp
+    OPENFILENAMEW opf;
+    WCHAR filter_string[20];
+    wcsncpy(filter_string, L"PNG#*.png##", 11);
+    filter_string[3] = L'\0';
+    filter_string[9] = L'\0';
+    filter_string[10] = L'\0';
+    WCHAR* title_string = (WCHAR*)g_utf8_to_utf16(_("Select a filename for exporting"), -1, NULL, NULL, NULL);
+    WCHAR* extension_string = (WCHAR*)g_utf8_to_utf16("*.png", -1, NULL, NULL, NULL);
+    // Copy the selected file name, converting from UTF-8 to UTF-16
+    WCHAR _filename[_MAX_PATH + 1];
+    memset(_filename, 0, sizeof(_filename));
+    gunichar2* utf16_path_string = g_utf8_to_utf16(filename, -1, NULL, NULL, NULL);
+    wcsncpy(_filename, (wchar_t*)utf16_path_string, _MAX_PATH);
+    g_free(utf16_path_string);
+
+    opf.hwndOwner = (HWND)(GDK_WINDOW_HWND(GTK_WIDGET(dlg)->window));
+    opf.lpstrFilter = filter_string;
+    opf.lpstrCustomFilter = 0;
+    opf.nMaxCustFilter = 0L;
+    opf.nFilterIndex = 1L;
+    opf.lpstrFile = _filename;
+    opf.nMaxFile = _MAX_PATH;
+    opf.lpstrFileTitle = NULL;
+    opf.nMaxFileTitle=0;
+    opf.lpstrInitialDir = 0;
+    opf.lpstrTitle = title_string;
+    opf.nFileOffset = 0;
+    opf.nFileExtension = 2;
+    opf.lpstrDefExt = extension_string;
+    opf.lpfnHook = NULL;
+    opf.lCustData = 0;
+    opf.Flags = OFN_PATHMUSTEXIST;
+    opf.lStructSize = sizeof(OPENFILENAMEW);
+    if (GetSaveFileNameW(&opf) != 0)
+    {
+        // Copy the selected file name, converting from UTF-16 to UTF-8
+        gchar *utf8string = g_utf16_to_utf8((const gunichar2*)opf.lpstrFile, _MAX_PATH, NULL, NULL, NULL);
+        gtk_entry_set_text (GTK_ENTRY (fe), utf8string);
+        g_object_set_data (G_OBJECT (dlg), "filename", fe);
+        g_free(utf8string);
+
+    }
+    g_free(extension_string);
+    g_free(title_string);
+
+#else
     if (gtk_dialog_run (GTK_DIALOG (fs)) == GTK_RESPONSE_ACCEPT)
     {
         gchar *file;
@@ -1338,6 +1420,7 @@ sp_export_browse_clicked (GtkButton */*button*/, gpointer /*userdata*/)
         g_free(utf8file);
         g_free(file);
     }
+#endif
 
     gtk_widget_destroy (fs);
 
@@ -1407,7 +1490,7 @@ sp_export_detect_size(GtkObject * base) {
         switch (this_test[i]) {
             case SELECTION_SELECTION:
                 if ((sp_desktop_selection(SP_ACTIVE_DESKTOP))->isEmpty() == false) {
-                    boost::optional<Geom::Rect> bbox = (sp_desktop_selection (SP_ACTIVE_DESKTOP))->bounds();
+                    Geom::OptRect bbox = (sp_desktop_selection (SP_ACTIVE_DESKTOP))->bounds(SPItem::RENDERING_BBOX);
 
                     //std::cout << "Selection " << bbox;
                     if ( bbox && sp_export_bbox_equal(*bbox,current_bbox)) {
@@ -1418,7 +1501,7 @@ sp_export_detect_size(GtkObject * base) {
             case SELECTION_DRAWING: {
                 SPDocument *doc = sp_desktop_document (SP_ACTIVE_DESKTOP);
 
-                boost::optional<Geom::Rect> bbox = sp_item_bbox_desktop (SP_ITEM (SP_DOCUMENT_ROOT (doc)));
+                Geom::OptRect bbox = SP_ITEM(doc->root)->getBboxDesktop(SPItem::RENDERING_BBOX);
 
                 // std::cout << "Drawing " << bbox2;
                 if ( bbox && sp_export_bbox_equal(*bbox,current_bbox) ) {
@@ -1433,8 +1516,8 @@ sp_export_detect_size(GtkObject * base) {
                 doc = sp_desktop_document (SP_ACTIVE_DESKTOP);
 
                 Geom::Point x(0.0, 0.0);
-                Geom::Point y(sp_document_width(doc),
-                              sp_document_height(doc));
+                Geom::Point y(doc->getWidth(),
+                              doc->getHeight());
                 Geom::Rect bbox(x, y);
 
                 // std::cout << "Page " << bbox;
@@ -1969,9 +2052,9 @@ sp_export_filename_modified (GtkObject * object, gpointer data)
   Local Variables:
   mode:c++
   c-file-style:"stroustrup"
-  c-file-offsets:((innamespace . 0)(inline-open . 0))
+  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
   indent-tabs-mode:nil
   fill-column:99
   End:
 */
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :