Code

Merge and cleanup of GSoC C++-ification project.
[inkscape.git] / src / dialogs / export.cpp
index 372430bcd04c53b028d9ba75cca76a0c4bb73858..7e99c2496efb96fb12b2de617fe2ca73db65cc7f 100644 (file)
@@ -1,15 +1,14 @@
-#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-2005 Authors
+ * Copyright (C) 1999-2007 Authors
  * Copyright (C) 2001-2002 Ximian, Inc.
  *
  * Released under GNU GPL, read the file 'COPYING' for more information
 # 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 <gtkmm/label.h>
+#include <gtkmm/widget.h>
+#include <gtkmm/togglebutton.h>
+#include <gtkmm/entry.h>
+#include <gtkmm/image.h>
+#include <gtkmm/stockid.h>
+#include <gtkmm/stock.h>
+#ifdef WITH_GNOME_VFS
+# include <libgnomevfs/gnome-vfs-init.h>  // gnome_vfs_initialized
+#endif
 
 #include <glibmm/i18n.h>
 #include "helper/unit-menu.h"
 #include "file.h"
 #include "macros.h"
 #include "sp-namedview.h"
+#include "selection-chemistry.h"
 
 #include "dialog-events.h"
-#include "../prefs-utils.h"
-#include "../verbs.h"
-#include "../interface.h"
+#include "preferences.h"
+#include "verbs.h"
+#include "interface.h"
 
 #include "extension/output.h"
 #include "extension/db.h"
 
 #include "io/sys.h"
 
+#include "helper/png-write.h"
+
+#ifdef WIN32
+#include <windows.h>
+#include <commdlg.h>
+#include <gdk/gdkwin32.h>
+#endif
+
+using Inkscape::DocumentUndo;
 
 #define SP_EXPORT_MIN_SIZE 1.0
 
 
 #define EXPORT_COORD_PRECISION 3
 
+#define MIN_ONSCREEN_DISTANCE 50
+
 static void sp_export_area_toggled   ( GtkToggleButton *tb, GtkObject *base );
 static void sp_export_export_clicked ( GtkButton *button, GtkObject *base );
 static void sp_export_browse_clicked ( GtkButton *button, gpointer userdata );
-static void sp_export_browse_store   ( GtkButton *button, gpointer userdata );
 
-
-static void sp_export_area_x_value_changed       ( GtkAdjustment *adj, 
+static void sp_export_area_x_value_changed       ( GtkAdjustment *adj,
                                                    GtkObject *base);
-                                             
-static void sp_export_area_y_value_changed       ( GtkAdjustment *adj, 
+
+static void sp_export_area_y_value_changed       ( GtkAdjustment *adj,
                                                    GtkObject *base);
-                                             
-static void sp_export_area_width_value_changed   ( GtkAdjustment *adj, 
+
+static void sp_export_area_width_value_changed   ( GtkAdjustment *adj,
                                                    GtkObject *base);
-                                                 
-static void sp_export_area_height_value_changed  ( GtkAdjustment *adj, 
+
+static void sp_export_area_height_value_changed  ( GtkAdjustment *adj,
                                                    GtkObject *base);
-                                                  
-static void sp_export_bitmap_width_value_changed ( GtkAdjustment *adj, 
+
+static void sp_export_bitmap_width_value_changed ( GtkAdjustment *adj,
                                                    GtkObject *base);
-                                                   
-static void sp_export_bitmap_height_value_changed ( GtkAdjustment *adj, 
+
+static void sp_export_bitmap_height_value_changed ( GtkAdjustment *adj,
                                                    GtkObject *base);
-                                                   
-static void sp_export_xdpi_value_changed         ( GtkAdjustment *adj, 
+
+static void sp_export_xdpi_value_changed         ( GtkAdjustment *adj,
                                                    GtkObject *base);
-                                           
-static void sp_export_selection_changed ( Inkscape::Application *inkscape, 
-                                          Inkscape::Selection *selection, 
+
+static void sp_export_selection_changed ( Inkscape::Application *inkscape,
+                                          Inkscape::Selection *selection,
                                           GtkObject *base);
-static void sp_export_selection_modified ( Inkscape::Application *inkscape, 
-                                           Inkscape::Selection *selection, 
+static void sp_export_selection_modified ( Inkscape::Application *inkscape,
+                                           Inkscape::Selection *selection,
                                            guint flags,
                                            GtkObject *base );
 
@@ -97,7 +121,7 @@ static void sp_export_filename_modified (GtkObject * object, gpointer data);
 static inline void sp_export_find_default_selection(GtkWidget * dlg);
 static void sp_export_detect_size(GtkObject * base);
 
-static const gchar *prefs_path = "dialogs.export";
+static Glib::ustring const prefs_path = "/dialogs/export/";
 
 // these all need to be reinitialized to their defaults during dialog_destroy
 static GtkWidget *dlg = NULL;
@@ -126,7 +150,7 @@ static const char * selection_labels[SELECTION_NUMBER_OF] = {
     N_("_Page"), N_("_Drawing"), N_("_Selection"), N_("_Custom")};
 
 static void
-sp_export_dialog_destroy ( GtkObject *object, gpointer data )
+sp_export_dialog_destroy ( GtkObject */*object*/, gpointer /*data*/ )
 {
     sp_signal_disconnect_by_data (INKSCAPE, dlg);
 
@@ -144,7 +168,7 @@ sp_export_dialog_destroy ( GtkObject *object, gpointer data )
 
 /// Called when dialog is closed or inkscape is shut down.
 static bool
-sp_export_dialog_delete ( GtkObject *object, GdkEvent *event, gpointer data )
+sp_export_dialog_delete ( GtkObject */*object*/, GdkEvent */*event*/, gpointer /*data*/ )
 {
 
     gtk_window_get_position ((GtkWindow *) dlg, &x, &y);
@@ -153,10 +177,11 @@ sp_export_dialog_delete ( GtkObject *object, GdkEvent *event, gpointer data )
     if (x<0) x=0;
     if (y<0) y=0;
 
-    prefs_set_int_attribute (prefs_path, "x", x);
-    prefs_set_int_attribute (prefs_path, "y", y);
-    prefs_set_int_attribute (prefs_path, "w", w);
-    prefs_set_int_attribute (prefs_path, "h", h);
+    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+    prefs->setInt(prefs_path + "x", x);
+    prefs->setInt(prefs_path + "y", y);
+    prefs->setInt(prefs_path + "w", w);
+    prefs->setInt(prefs_path + "h", h);
 
     return FALSE; // which means, go ahead and destroy it
 
@@ -183,20 +208,20 @@ sp_export_dialog_delete ( GtkObject *object, GdkEvent *event, gpointer data )
 
 */
 static void
-sp_export_spinbutton_new ( gchar *key, float val, float min, float max,
+sp_export_spinbutton_new ( gchar const *key, float val, float min, float max,
                            float step, float page, GtkWidget *us,
                            GtkWidget *t, int x, int y,
                            const gchar *ll, const gchar *lr,
                            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", 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;
@@ -214,7 +239,7 @@ sp_export_spinbutton_new ( gchar *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);
@@ -236,105 +261,145 @@ sp_export_spinbutton_new ( gchar *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()
 
 
-static GtkWidget *
-sp_export_dialog_area_frame (GtkWidget * dlg)
+static Gtk::VBox *
+sp_export_dialog_area_box (GtkWidget * dlg)
 {
-    GtkWidget * f, * t, * hb, * b, * us, * l, * vb, * unitbox;
+    Gtk::VBox* vb = new Gtk::VBox(false, 3);
 
-    f = gtk_frame_new (_("Export area"));
-    vb = gtk_vbox_new (FALSE, 2);
-    gtk_container_add (GTK_CONTAINER (f), vb);
+    Gtk::Label* lbl = new Gtk::Label(_("<big><b>Export area</b></big>"), Gtk::ALIGN_LEFT);
+    lbl->set_use_markup(true);
+    vb->pack_start(*lbl);
 
     /* Units box */
-    unitbox = gtk_hbox_new (FALSE, 0);
-    gtk_container_set_border_width (GTK_CONTAINER (unitbox), 4);
+    Gtk::HBox* unitbox = new Gtk::HBox(false, 0);
     /* gets added to the vbox later, but the unit selector is needed
        earlier than that */
 
-    us = sp_unit_selector_new (SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE);
+    Gtk::Widget* us = Glib::wrap(sp_unit_selector_new (SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE));
     SPDesktop *desktop = SP_ACTIVE_DESKTOP;
     if (desktop)
-        sp_unit_selector_set_unit (SP_UNIT_SELECTOR(us), SP_DT_NAMEDVIEW(desktop)->doc_units);
-    gtk_box_pack_end (GTK_BOX (unitbox), us, FALSE, FALSE, 0);
-    l = gtk_label_new (_("Units:"));
-    gtk_box_pack_end (GTK_BOX (unitbox), l, FALSE, FALSE, 3);
-    gtk_object_set_data (GTK_OBJECT (dlg), "units", us);
+        sp_unit_selector_set_unit (SP_UNIT_SELECTOR(us->gobj()), sp_desktop_namedview(desktop)->doc_units);
+    unitbox->pack_end(*us, false, false, 0);
+    Gtk::Label* l = new Gtk::Label(_("Units:"));
+    unitbox->pack_end(*l, false, false, 3);
+    gtk_object_set_data (GTK_OBJECT (dlg), "units", us->gobj());
 
-    hb = gtk_hbox_new (TRUE, 0);
-    gtk_container_set_border_width (GTK_CONTAINER (hb), 4);
-    gtk_box_pack_start(GTK_BOX(vb), hb, FALSE, FALSE, 3);
+    Gtk::HBox* togglebox = new Gtk::HBox(true, 0);
 
+    Gtk::ToggleButton* b;
     for (int i = 0; i < SELECTION_NUMBER_OF; i++) {
-        b = gtk_toggle_button_new_with_mnemonic (_(selection_labels[i]));
-        gtk_object_set_data (GTK_OBJECT (b), "key", GINT_TO_POINTER(i));
-        gtk_object_set_data (GTK_OBJECT (dlg), selection_names[i], b);
-        gtk_box_pack_start (GTK_BOX (hb), b, FALSE, TRUE, 0);
-        gtk_signal_connect ( GTK_OBJECT (b), "clicked", 
+        b = new Gtk::ToggleButton(_(selection_labels[i]), true);
+        b->set_data("key", GINT_TO_POINTER(i));
+        gtk_object_set_data (GTK_OBJECT (dlg), selection_names[i], b->gobj());
+        togglebox->pack_start(*b, false, true, 0);
+        gtk_signal_connect ( GTK_OBJECT (b->gobj()), "clicked",
                              GTK_SIGNAL_FUNC (sp_export_area_toggled), dlg );
     }
 
-    g_signal_connect ( G_OBJECT (INKSCAPE), "change_selection", 
+    g_signal_connect ( G_OBJECT (INKSCAPE), "change_selection",
                        G_CALLBACK (sp_export_selection_changed), dlg );
-    g_signal_connect ( G_OBJECT (INKSCAPE), "modify_selection", 
+    g_signal_connect ( G_OBJECT (INKSCAPE), "modify_selection",
                        G_CALLBACK (sp_export_selection_modified), dlg );
-    g_signal_connect ( G_OBJECT (INKSCAPE), "activate_desktop", 
+    g_signal_connect ( G_OBJECT (INKSCAPE), "activate_desktop",
                        G_CALLBACK (sp_export_selection_changed), dlg );
-    
-    t = gtk_table_new (2, 6, FALSE);
-    gtk_box_pack_start(GTK_BOX(vb), t, FALSE, FALSE, 0);
-    gtk_table_set_row_spacings (GTK_TABLE (t), 4);
-    gtk_table_set_col_spacings (GTK_TABLE (t), 4);
-    gtk_container_set_border_width (GTK_CONTAINER (t), 4);
-
-    sp_export_spinbutton_new ( "x0", 0.0, -1000000.0, 1000000.0, 0.1, 1.0, us, 
-                               t, 0, 0, _("_x0:"), NULL, EXPORT_COORD_PRECISION, 1,
-                               G_CALLBACK ( sp_export_area_x_value_changed), 
+
+    Gtk::Table* t = new Gtk::Table(2, 6, FALSE);
+    t->set_row_spacings (4);
+    t->set_col_spacings (4);
+
+    sp_export_spinbutton_new ( "x0", 0.0, -1000000.0, 1000000.0, 0.1, 1.0, us->gobj(),
+                               GTK_WIDGET(t->gobj()), 0, 0, _("_x0:"), NULL, EXPORT_COORD_PRECISION, 1,
+                               G_CALLBACK ( sp_export_area_x_value_changed),
                                dlg );
 
-    sp_export_spinbutton_new ( "x1", 0.0, -1000000.0, 1000000.0, 0.1, 1.0, us
-                               t, 2, 0, _("x_1:"), NULL, EXPORT_COORD_PRECISION, 1,
-                               G_CALLBACK (sp_export_area_x_value_changed), 
+    sp_export_spinbutton_new ( "x1", 0.0, -1000000.0, 1000000.0, 0.1, 1.0, us->gobj(),
+                               GTK_WIDGET(t->gobj()), 2, 0, _("x_1:"), NULL, EXPORT_COORD_PRECISION, 1,
+                               G_CALLBACK (sp_export_area_x_value_changed),
                                dlg );
 
-    sp_export_spinbutton_new ( "width", 0.0, -1000000.0, 1000000.0, 0.1, 1.0, 
-                               us, t, 4, 0, _("Width:"), NULL, EXPORT_COORD_PRECISION, 1,
-                               G_CALLBACK 
-                                   (sp_export_area_width_value_changed), 
+    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, _("Wid_th:"), NULL, EXPORT_COORD_PRECISION, 1,
+                               G_CALLBACK
+                                   (sp_export_area_width_value_changed),
                                dlg );
 
-    sp_export_spinbutton_new ( "y0", 0.0, -1000000.0, 1000000.0, 0.1, 1.0, us
-                               t, 0, 1, _("_y0:"), NULL, EXPORT_COORD_PRECISION, 1,
-                               G_CALLBACK (sp_export_area_y_value_changed), 
+    sp_export_spinbutton_new ( "y0", 0.0, -1000000.0, 1000000.0, 0.1, 1.0, us->gobj(),
+                               GTK_WIDGET(t->gobj()), 0, 1, _("_y0:"), NULL, EXPORT_COORD_PRECISION, 1,
+                               G_CALLBACK (sp_export_area_y_value_changed),
                                dlg );
 
-    sp_export_spinbutton_new ( "y1", 0.0, -1000000.0, 1000000.0, 0.1, 1.0, us
-                               t, 2, 1, _("y_1:"), NULL, EXPORT_COORD_PRECISION, 1,
-                               G_CALLBACK (sp_export_area_y_value_changed), 
+    sp_export_spinbutton_new ( "y1", 0.0, -1000000.0, 1000000.0, 0.1, 1.0, us->gobj(),
+                               GTK_WIDGET(t->gobj()), 2, 1, _("y_1:"), NULL, EXPORT_COORD_PRECISION, 1,
+                               G_CALLBACK (sp_export_area_y_value_changed),
                                dlg );
 
-    sp_export_spinbutton_new ( "height", 0.0, -1000000.0, 1000000.0, 0.1, 1.0, 
-                               us, t, 4, 1, _("Height:"), NULL, EXPORT_COORD_PRECISION, 1,
-                               G_CALLBACK (sp_export_area_height_value_changed), 
+    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, _("Hei_ght:"), NULL, EXPORT_COORD_PRECISION, 1,
+                               G_CALLBACK (sp_export_area_height_value_changed),
                                dlg );
 
-    /* Adding in the unit box */
-    gtk_box_pack_start(GTK_BOX(vb), unitbox, FALSE, FALSE, 0);
+    vb->pack_start(*togglebox, false, false, 3);
+    vb->pack_start(*t, false, false, 0);
+    vb->pack_start(*unitbox, false, false, 0);
+
+    return vb;
+} // end of sp_export_dialog_area_box
+
 
-    return f;
-} // end of sp_export_dialog_area_frame
+gchar* create_filepath_from_id (const gchar *id, const gchar *file_entry_text) {
 
+    if (id == NULL) /* This should never happen */
+        id = "bitmap";
+
+    gchar * directory = NULL;
+
+    if (directory == NULL && file_entry_text != NULL && file_entry_text[0] != '\0') {
+        // std::cout << "Directory from dialog" << std::endl;
+        directory = g_dirname(file_entry_text);
+    }
+
+    if (directory == NULL) {
+        /* Grab document directory */
+        if ( SP_ACTIVE_DOCUMENT->getURI() ) {
+            // std::cout << "Directory from document" << std::endl;
+            directory = g_dirname( SP_ACTIVE_DOCUMENT->getURI() );
+        }
+    }
+
+    if (directory == NULL) {
+        // std::cout << "Home Directory" << std::endl;
+        directory = homedir_path(NULL);
+    }
+
+    gchar * id_ext = g_strconcat(id, ".png", NULL);
+    gchar *filename = g_build_filename(directory, id_ext, NULL);
+    g_free(directory);
+    g_free(id_ext);
+    return filename;
+}
+
+static void
+batch_export_clicked (GtkWidget *widget, GtkObject *base)
+{
+    Gtk::Widget *vb_singleexport = (Gtk::Widget *)gtk_object_get_data(base, "vb_singleexport");
+    if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(widget))) {
+        vb_singleexport->set_sensitive(false);
+    } else {
+        vb_singleexport->set_sensitive(true);
+    }
+}
 
 void
 sp_export_dialog (void)
 {
+    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
     if (!dlg) {
-        GtkWidget *vb, *hb;
 
         gchar title[500];
         sp_ui_dialog_title_string (Inkscape::Verb::get(SP_VERB_FILE_EXPORT), title);
@@ -342,27 +407,23 @@ sp_export_dialog (void)
         dlg = sp_window_new (title, TRUE);
 
         if (x == -1000 || y == -1000) {
-            x = prefs_get_int_attribute (prefs_path, "x", 0);
-            y = prefs_get_int_attribute (prefs_path, "y", 0);
+            x = prefs->getInt(prefs_path + "x", 0);
+            y = prefs->getInt(prefs_path + "y", 0);
         }
 
         if (w ==0 || h == 0) {
-            w = prefs_get_int_attribute (prefs_path, "w", 0);
-            h = prefs_get_int_attribute (prefs_path, "h", 0);
+            w = prefs->getInt(prefs_path + "w", 0);
+            h = prefs->getInt(prefs_path + "h", 0);
         }
 
-        if (x<0) x=0;
-        if (y<0) y=0;
+//        if (x<0) x=0;
+//        if (y<0) y=0;
 
-        if (x != 0 || y != 0) {
+        if (w && h) gtk_window_resize ((GtkWindow *) dlg, w, h);
+        if (x >= 0 && y >= 0 && (x < (gdk_screen_width()-MIN_ONSCREEN_DISTANCE)) && (y < (gdk_screen_height()-MIN_ONSCREEN_DISTANCE)))
             gtk_window_move ((GtkWindow *) dlg, x, y);
-        } else {
+        else
             gtk_window_set_position(GTK_WINDOW(dlg), GTK_WIN_POS_CENTER);
-        }
-
-        if (w && h)
-            gtk_window_resize ((GtkWindow *) dlg, w, h);
-
         sp_transientize (dlg);
         wd.win = dlg;
         wd.stop = 0;
@@ -390,68 +451,81 @@ sp_export_dialog (void)
 
         GtkTooltips *tt = gtk_tooltips_new();
 
-        vb = gtk_vbox_new (FALSE, 4);
-        gtk_container_set_border_width (GTK_CONTAINER (vb), 0);
-        gtk_container_add (GTK_CONTAINER (dlg), vb);
+        Gtk::VBox *vb = new Gtk::VBox(false, 3);
+        vb->set_border_width(3);
+        gtk_container_add (GTK_CONTAINER (dlg), GTK_WIDGET(vb->gobj()));
+
+        Gtk::VBox *vb_singleexport = new Gtk::VBox(false, 0);
+        vb_singleexport->set_border_width(0);
+        vb->pack_start(*vb_singleexport);
+        gtk_object_set_data(GTK_OBJECT(dlg), "vb_singleexport", vb_singleexport);
 
         /* Export area frame */
         {
-            GtkWidget *f = sp_export_dialog_area_frame(dlg);
-            gtk_box_pack_start (GTK_BOX (vb), f, FALSE, FALSE, 0);
+            Gtk::VBox *area_box = sp_export_dialog_area_box(dlg);
+            area_box->set_border_width(3);
+            vb_singleexport->pack_start(*area_box, false, false, 0);
         }
 
         /* Bitmap size frame */
         {
-            GtkWidget *f = gtk_frame_new (_("Bitmap size"));
-            gtk_box_pack_start (GTK_BOX (vb), f, FALSE, FALSE, 0);
-            GtkWidget *t = gtk_table_new (2, 5, FALSE);
-            gtk_table_set_row_spacings (GTK_TABLE (t), 4);
-            gtk_table_set_col_spacings (GTK_TABLE (t), 4);
-            gtk_container_set_border_width (GTK_CONTAINER (t), 4);
-            gtk_container_add (GTK_CONTAINER (f), t);
-
-            sp_export_spinbutton_new ( "bmwidth", 16.0, 1.0, 1000000.0, 1.0, 10.0, 
-                                       NULL, t, 0, 0,
+            Gtk::VBox *size_box = new Gtk::VBox(false, 3);
+            size_box->set_border_width(3);
+
+            Gtk::Label* lbl = new Gtk::Label(_("<big><b>Bitmap size</b></big>"), Gtk::ALIGN_LEFT);
+            lbl->set_use_markup(true);
+            size_box->pack_start(*lbl, false, false, 0);
+            const int rows = 2;
+            const int cols = 5;
+            const bool homogeneous = false;
+            Gtk::Table *t = new Gtk::Table(rows, cols, homogeneous);
+            t->set_row_spacings (4);
+            t->set_col_spacings (4);
+            size_box->pack_start(*t);
+
+            sp_export_spinbutton_new ( "bmwidth", 16.0, 1.0, 1000000.0, 1.0, 10.0,
+                                       NULL, GTK_WIDGET(t->gobj()), 0, 0,
                                        _("_Width:"), _("pixels at"), 0, 1,
-                                       G_CALLBACK 
-                                       (sp_export_bitmap_width_value_changed), 
+                                       G_CALLBACK
+                                       (sp_export_bitmap_width_value_changed),
                                        dlg );
 
-            sp_export_spinbutton_new ( "xdpi", 
-                                       prefs_get_double_attribute 
-                                       ( "dialogs.export.defaultxdpi", 
-                                         "value", DPI_BASE), 
-                                       1.0, 9600.0, 0.1, 1.0, NULL, t, 3, 0,
+            sp_export_spinbutton_new ( "xdpi",
+                                       prefs->getDouble("/dialogs/export/defaultxdpi/value", DPI_BASE),
+                                       0.01, 100000.0, 0.1, 1.0, NULL, GTK_WIDGET(t->gobj()), 3, 0,
                                        NULL, _("dp_i"), 2, 1,
-                                       G_CALLBACK (sp_export_xdpi_value_changed), 
+                                       G_CALLBACK (sp_export_xdpi_value_changed),
                                        dlg );
 
-            sp_export_spinbutton_new ( "bmheight", 16.0, 1.0, 1000000.0, 1.0, 10.0, 
-                                       NULL, t, 0, 1, 
-                                       _("Height:"), _("pixels at"), 0, 1, 
+            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,
                                        G_CALLBACK
-                                       (sp_export_bitmap_height_value_changed), 
+                                       (sp_export_bitmap_height_value_changed),
                                        dlg );
 
             /** \todo
-             * Needs fixing: there's no way to set ydpi currently, so we use  
+             * Needs fixing: there's no way to set ydpi currently, so we use
              *       the defaultxdpi value here, too...
              */
-            sp_export_spinbutton_new ( "ydpi", prefs_get_double_attribute 
-                                       ( "dialogs.export.defaultxdpi", 
-                                         "value", DPI_BASE), 
-                                       1.0, 9600.0, 0.1, 1.0, NULL, t, 3, 1,
+            sp_export_spinbutton_new ( "ydpi", prefs->getDouble("/dialogs/export/defaultxdpi/value", DPI_BASE),
+                                       0.01, 100000.0, 0.1, 1.0, NULL, GTK_WIDGET(t->gobj()), 3, 1,
                                        NULL, _("dpi"), 2, 0, NULL, dlg );
+
+            vb_singleexport->pack_start(*size_box);
         }
 
         /* File entry */
         {
-            GtkWidget *frame = gtk_frame_new ("");
-            GtkWidget *flabel = gtk_label_new_with_mnemonic (_("_Filename"));
-            gtk_frame_set_label_widget (GTK_FRAME(frame), flabel);
-            gtk_box_pack_start (GTK_BOX (vb), frame, FALSE, FALSE, 0);
+            Gtk::VBox* file_box = new Gtk::VBox(false, 3);
+            file_box->set_border_width(3);
 
-            GtkWidget *fe = gtk_entry_new ();
+            // true = has mnemonic
+            Gtk::Label *flabel = new Gtk::Label(_("<big><b>_Filename</b></big>"), Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, true);
+            flabel->set_use_markup(true);
+            file_box->pack_start(*flabel, false, false, 0);
+
+            Gtk::Entry *fe = new Gtk::Entry();
 
             /*
              * set the default filename to be that of the current path + document
@@ -465,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) {
@@ -490,63 +563,108 @@ sp_export_dialog (void)
                         extension_point[0] = '\0';
 
                         final_name = g_strconcat(uri_copy, ".png", NULL);
-                        gtk_entry_set_text (GTK_ENTRY (fe), final_name);
+                        fe->set_text(final_name);
 
                         g_free(final_name);
                         g_free(uri_copy);
                     }
                 } else {
                     name = g_strconcat(uri, ".png", NULL);
-                    gtk_entry_set_text (GTK_ENTRY (fe), name);
+                    fe->set_text(name);
                     g_free(name);
                 }
 
-                doc_export_name = g_strdup(gtk_entry_get_text(GTK_ENTRY(fe)));
+                doc_export_name = g_strdup(fe->get_text().c_str());
             }
-            g_signal_connect ( G_OBJECT (fe), "changed",
+            g_signal_connect ( G_OBJECT (fe->gobj()), "changed",
                                G_CALLBACK (sp_export_filename_modified), dlg);
 
-            hb = gtk_hbox_new (FALSE, 5);
-            gtk_container_add (GTK_CONTAINER (frame), hb);
-            gtk_container_set_border_width (GTK_CONTAINER (hb), 4);
+            Gtk::HBox *hb = new Gtk::HBox(FALSE, 5);
 
             {
-                GtkWidget *b = gtk_button_new_with_mnemonic (_("_Browse..."));
-                gtk_box_pack_end (GTK_BOX (hb), b, FALSE, FALSE, 4);
-                g_signal_connect ( G_OBJECT (b), "clicked",
+                // true = has mnemonic
+                Gtk::Button *b = new Gtk::Button();
+
+                Gtk::HBox* pixlabel = new Gtk::HBox(false, 3);
+                Gtk::Image *im = new Gtk::Image(Gtk::StockID(Gtk::Stock::INDEX),
+                        Gtk::ICON_SIZE_BUTTON);
+                pixlabel->pack_start(*im);
+
+                Gtk::Label *l = new Gtk::Label();
+                l->set_markup_with_mnemonic(_("_Browse..."));
+                pixlabel->pack_start(*l);
+
+                b->add(*pixlabel);
+
+                hb->pack_end (*b, false, false, 4);
+                g_signal_connect ( G_OBJECT (b->gobj()), "clicked",
                                    G_CALLBACK (sp_export_browse_clicked), NULL );
             }
 
-            gtk_box_pack_start (GTK_BOX (hb), fe, TRUE, TRUE, 0);
-            gtk_object_set_data (GTK_OBJECT (dlg), "filename", fe);
+            hb->pack_start (*fe, true, true, 0);
+            file_box->add(*hb);
+            gtk_object_set_data (GTK_OBJECT (dlg), "filename", fe->gobj());
             gtk_object_set_data (GTK_OBJECT (dlg), "filename-modified", (gpointer)FALSE);
-            original_name = g_strdup(gtk_entry_get_text (GTK_ENTRY (fe)));
+            original_name = g_strdup(fe->get_text().c_str());
             // pressing enter in the filename field is the same as clicking export:
-            g_signal_connect ( G_OBJECT (fe), "activate",
+            g_signal_connect ( G_OBJECT (fe->gobj()), "activate",
                                G_CALLBACK (sp_export_export_clicked), dlg );
             // focus is in the filename initially:
-            gtk_widget_grab_focus (GTK_WIDGET (fe));
+            fe->grab_focus();
 
             // mnemonic in frame label moves focus to filename:
-            gtk_label_set_mnemonic_widget (GTK_LABEL(flabel), fe);
+            flabel->set_mnemonic_widget(*fe);
+
+            vb_singleexport->pack_start(*file_box);
+        }
+
+        {
+            Gtk::HBox* batch_box = new Gtk::HBox(FALSE, 5);
+            GtkWidget *be = gtk_check_button_new_with_label(_("Batch export all selected objects"));
+            gtk_widget_set_sensitive(GTK_WIDGET(be), TRUE);
+            gtk_object_set_data(GTK_OBJECT(dlg), "batch_checkbox", be);
+            batch_box->pack_start(*Glib::wrap(be), false, false);
+            gtk_tooltips_set_tip(tt, be, _("Export each selected object into its own PNG file, using export hints if any (caution, overwrites without asking!)"), NULL);
+            batch_box->show_all();
+            g_signal_connect(G_OBJECT(be), "toggled", GTK_SIGNAL_FUNC(batch_export_clicked), dlg);
+            vb->pack_start(*batch_box);
+        }
+
+        {
+            Gtk::HBox* hide_box = new Gtk::HBox(FALSE, 5);
+            GtkWidget *he = gtk_check_button_new_with_label(_("Hide all except selected"));
+            gtk_widget_set_sensitive(GTK_WIDGET(he), TRUE);
+            gtk_object_set_data(GTK_OBJECT(dlg), "hide_checkbox", he);
+            hide_box->pack_start(*Glib::wrap(he), false, false);
+            gtk_tooltips_set_tip(tt, he, _("In the exported image, hide all objects except those that are selected"), NULL);
+            hide_box->show_all();
+            vb->pack_start(*hide_box);
         }
 
         /* Buttons */
-        hb = gtk_hbox_new (FALSE, 0);
-        gtk_box_pack_end (GTK_BOX (vb), hb, FALSE, FALSE, 0);
+        Gtk::HButtonBox* bb = new Gtk::HButtonBox(Gtk::BUTTONBOX_END);
+        bb->set_border_width(3);
 
         {
-            GtkWidget *b = gtk_button_new ();
-            GtkWidget *l = gtk_label_new ("");
-            gtk_label_set_markup_with_mnemonic (GTK_LABEL(l), _(" <b>_Export</b> "));
-            gtk_container_add (GTK_CONTAINER(b), l);
-            gtk_tooltips_set_tip (tt, b, _("Export the bitmap file with these settings"), NULL);
-            gtk_signal_connect ( GTK_OBJECT (b), "clicked",
+            Gtk::Button *b = new Gtk::Button();
+            Gtk::HBox* image_label = new Gtk::HBox(false, 3);
+            Gtk::Image *im = new Gtk::Image(Gtk::StockID(Gtk::Stock::APPLY),
+                    Gtk::ICON_SIZE_BUTTON);
+            image_label->pack_start(*im);
+
+            Gtk::Label *l = new Gtk::Label();
+            l->set_markup_with_mnemonic(_("_Export"));
+            image_label->pack_start(*l);
+
+            b->add(*image_label);
+            gtk_tooltips_set_tip (tt, GTK_WIDGET(b->gobj()), _("Export the bitmap file with these settings"), NULL);
+            gtk_signal_connect ( GTK_OBJECT (b->gobj()), "clicked",
                                  GTK_SIGNAL_FUNC (sp_export_export_clicked), dlg );
-            gtk_box_pack_end (GTK_BOX (hb), b, FALSE, FALSE, 0);
+            bb->pack_end(*b, false, false, 0);
         }
 
-        gtk_widget_show_all (vb);
+        vb->pack_end(*bb, false, false, 0);
+        vb->show_all();
 
     } // end of if (!dlg)
 
@@ -557,25 +675,45 @@ sp_export_dialog (void)
     return;
 } // end of sp_export_dialog()
 
+static void
+sp_export_update_checkbuttons (GtkObject *base)
+{
+    gint num = g_slist_length((GSList *) sp_desktop_selection(SP_ACTIVE_DESKTOP)->itemList());
+    GtkWidget *be = (GtkWidget *)gtk_object_get_data(base, "batch_checkbox");
+    GtkWidget *he = (GtkWidget *)gtk_object_get_data(base, "hide_checkbox");
+    if (num >= 2) {
+        gtk_widget_set_sensitive (be, true);
+        gtk_button_set_label (GTK_BUTTON(be), g_strdup_printf (ngettext("Batch export %d selected object","Batch export %d selected objects",num), num));
+    } else {
+        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(be), FALSE);
+        gtk_widget_set_sensitive (be, FALSE);
+    }
+    if (num > 0) {
+        gtk_widget_set_sensitive (he, true);
+    } else {
+        gtk_widget_set_sensitive (he, false);
+    }
+}
+
 static inline void
 sp_export_find_default_selection(GtkWidget * dlg)
 {
     selection_type key = SELECTION_NUMBER_OF;
 
-    if ((SP_DT_SELECTION(SP_ACTIVE_DESKTOP))->isEmpty() == false) {
+    if ((sp_desktop_selection(SP_ACTIVE_DESKTOP))->isEmpty() == false) {
         key = SELECTION_SELECTION;
     }
 
     /* Try using the preferences */
     if (key == SELECTION_NUMBER_OF) {
-        const gchar *what = NULL;
+        Inkscape::Preferences *prefs = Inkscape::Preferences::get();
         int i = SELECTION_NUMBER_OF;
 
-        what = prefs_get_string_attribute ("dialogs.export.exportarea", "value");
+        Glib::ustring what = prefs->getString("/dialogs/export/exportarea/value");
 
-        if (what != NULL) {
+        if (!what.empty()) {
             for (i = 0; i < SELECTION_NUMBER_OF; i++) {
-                if (!strcmp (what, selection_names[i])) {
+                if (what == selection_names[i]) {
                     break;
                 }
             }
@@ -592,31 +730,31 @@ sp_export_find_default_selection(GtkWidget * dlg)
                                                        selection_names[key]);
     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
 
-    return;
+    sp_export_update_checkbuttons (GTK_OBJECT(dlg));
 }
 
 
 /**
- * \brief  If selection changed or a different document activated, we must 
+ * \brief  If selection changed or a different document activated, we must
  * recalculate any chosen areas
  *
  */
 static void
-sp_export_selection_changed ( Inkscape::Application *inkscape, 
-                              Inkscape::Selection *selection, 
+sp_export_selection_changed ( Inkscape::Application *inkscape,
+                              Inkscape::Selection *selection,
                               GtkObject *base )
 {
     selection_type current_key;
     current_key = (selection_type)(GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(base), "selection-type")));
 
     if ((current_key == SELECTION_DRAWING || current_key == SELECTION_PAGE) &&
-            (SP_DT_SELECTION(SP_ACTIVE_DESKTOP))->isEmpty() == false &&
+            (sp_desktop_selection(SP_ACTIVE_DESKTOP))->isEmpty() == false &&
             was_empty) {
         gtk_toggle_button_set_active
             ( GTK_TOGGLE_BUTTON ( gtk_object_get_data (base, selection_names[SELECTION_SELECTION])),
               TRUE );
     }
-    was_empty = (SP_DT_SELECTION(SP_ACTIVE_DESKTOP))->isEmpty();
+    was_empty = (sp_desktop_selection(SP_ACTIVE_DESKTOP))->isEmpty();
 
     current_key = (selection_type)(GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(base), "selection-type")));
 
@@ -627,15 +765,15 @@ sp_export_selection_changed ( Inkscape::Application *inkscape,
         GtkToggleButton * button;
         button = (GtkToggleButton *)gtk_object_get_data(base, selection_names[current_key]);
         sp_export_area_toggled(button, base);
-    } // end of if()
+    }
 
-    return;
-} // end of sp_export_selection_changed()
+    sp_export_update_checkbuttons (base);
+}
 
 static void
-sp_export_selection_modified ( Inkscape::Application *inkscape, 
-                               Inkscape::Selection *selection, 
-                               guint flags,
+sp_export_selection_modified ( Inkscape::Application */*inkscape*/,
+                               Inkscape::Selection */*selection*/,
+                               guint /*flags*/,
                                GtkObject *base )
 {
     selection_type current_key;
@@ -645,19 +783,20 @@ sp_export_selection_modified ( Inkscape::Application *inkscape,
         case SELECTION_DRAWING:
             if ( SP_ACTIVE_DESKTOP ) {
                 SPDocument *doc;
-                NRRect bbox;
-                doc = SP_DT_DOCUMENT (SP_ACTIVE_DESKTOP);
-                sp_item_bbox_desktop (SP_ITEM (SP_DOCUMENT_ROOT (doc)), &bbox);
-
-                if (!(bbox.x0 > bbox.x1 && bbox.y0 > bbox.y1)) {
-                    sp_export_set_area (base, bbox.x0, bbox.y0, bbox.x1, bbox.y1);
+                doc = sp_desktop_document (SP_ACTIVE_DESKTOP);
+                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],
+                                              bbox->max()[Geom::X],
+                                              bbox->max()[Geom::Y]);
                 }
             }
             break;
         case SELECTION_SELECTION:
-            if ((SP_DT_SELECTION(SP_ACTIVE_DESKTOP))->isEmpty() == false) {
+            if ((sp_desktop_selection(SP_ACTIVE_DESKTOP))->isEmpty() == false) {
                 NRRect bbox;
-                (SP_DT_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;
@@ -704,17 +843,17 @@ sp_export_area_toggled (GtkToggleButton *tb, GtkObject *base)
     if ( SP_ACTIVE_DESKTOP )
     {
         SPDocument *doc;
-        NRRect bbox;
-        doc = SP_DT_DOCUMENT (SP_ACTIVE_DESKTOP);
+        Geom::OptRect bbox;
+        doc = sp_desktop_document (SP_ACTIVE_DESKTOP);
 
         /* Notice how the switch is used to 'fall through' here to get
            various backups.  If you modify this without noticing you'll
            probabaly screw something up. */
         switch (key) {
             case SELECTION_SELECTION:
-                if ((SP_DT_SELECTION(SP_ACTIVE_DESKTOP))->isEmpty() == false)
+                if ((sp_desktop_selection(SP_ACTIVE_DESKTOP))->isEmpty() == false)
                 {
-                    (SP_DT_SELECTION (SP_ACTIVE_DESKTOP))->bounds(&bbox);
+                    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 */
@@ -723,23 +862,21 @@ sp_export_area_toggled (GtkToggleButton *tb, GtkObject *base)
                     break;
                 }
             case SELECTION_DRAWING:
-                /** \todo 
+                /** \todo
                  * This returns wrong values if the document has a viewBox.
                  */
-                sp_item_bbox_desktop (SP_ITEM (SP_DOCUMENT_ROOT (doc)), &bbox);
-                
+                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.x0 > bbox.x1 && bbox.y0 > bbox.y1)) { 
+                if (bbox) {
                     // std::cout << "Using selection: DRAWING" << std::endl;
                     key = SELECTION_DRAWING;
                     break;
                 }
             case SELECTION_PAGE:
-                bbox.x0 = 0.0;
-                bbox.y0 = 0.0;
-                bbox.x1 = sp_document_width (doc);
-                bbox.y1 = sp_document_height (doc);
+                bbox = Geom::Rect(Geom::Point(0.0, 0.0),
+                                  Geom::Point(doc->getWidth(), doc->getHeight()));
+
                 // std::cout << "Using selection: PAGE" << std::endl;
                 key = SELECTION_PAGE;
                 break;
@@ -747,15 +884,18 @@ sp_export_area_toggled (GtkToggleButton *tb, GtkObject *base)
             default:
                 break;
         } // switch
-        
-        // remember area setting
-        prefs_set_string_attribute ( "dialogs.export.exportarea", 
-                                     "value", selection_names[key]);
 
-        if (key != SELECTION_CUSTOM) {
-            sp_export_set_area (base, bbox.x0, bbox.y0, bbox.x1, bbox.y1);
+        // remember area setting
+        Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+        prefs->setString("/dialogs/export/exportarea/value", selection_names[key]);
+
+        if ( key != SELECTION_CUSTOM && bbox ) {
+            sp_export_set_area (base, bbox->min()[Geom::X],
+                                      bbox->min()[Geom::Y],
+                                      bbox->max()[Geom::X],
+                                      bbox->max()[Geom::Y]);
         }
-    
+
     } // end of if ( SP_ACTIVE_DESKTOP )
 
 
@@ -770,22 +910,7 @@ sp_export_area_toggled (GtkToggleButton *tb, GtkObject *base)
             case SELECTION_PAGE:
             case SELECTION_DRAWING: {
                 SPDocument * doc = SP_ACTIVE_DOCUMENT;
-                Inkscape::XML::Node * repr = sp_document_repr_root(doc);
-                const gchar * dpi_string;
-
-                filename = repr->attribute("inkscape:export-filename");
-
-                dpi_string = NULL;
-                dpi_string = repr->attribute("inkscape:export-xdpi");
-                if (dpi_string != NULL) {
-                    xdpi = atof(dpi_string);
-                }
-
-                dpi_string = NULL;
-                dpi_string = repr->attribute("inkscape:export-ydpi");
-                if (dpi_string != NULL) {
-                    ydpi = atof(dpi_string);
-                }
+                sp_document_get_export_hints (doc, &filename, &xdpi, &ydpi);
 
                 if (filename == NULL) {
                     if (doc_export_name != NULL) {
@@ -794,55 +919,18 @@ sp_export_area_toggled (GtkToggleButton *tb, GtkObject *base)
                         filename = g_strdup("");
                     }
                 }
-
                 break;
             }
             case SELECTION_SELECTION:
-                if ((SP_DT_SELECTION(SP_ACTIVE_DESKTOP))->isEmpty() == false) {
-                    const GSList * reprlst;
-                    bool filename_search = TRUE;
-                    bool xdpi_search = TRUE;
-                    bool ydpi_search = TRUE;
-
-                    reprlst = SP_DT_SELECTION(SP_ACTIVE_DESKTOP)->reprList();
-                    for(; reprlst != NULL &&
-                            filename_search &&
-                            xdpi_search &&
-                            ydpi_search;
-                            reprlst = reprlst->next) {
-                        const gchar * dpi_string;
-                        Inkscape::XML::Node * repr = (Inkscape::XML::Node *)reprlst->data;
-
-                        if (filename_search) {
-                            filename = repr->attribute("inkscape:export-filename");
-                            if (filename != NULL)
-                                filename_search = FALSE;
-                        }
+                if ((sp_desktop_selection(SP_ACTIVE_DESKTOP))->isEmpty() == false) {
 
-                        if (xdpi_search) {
-                            dpi_string = NULL;
-                            dpi_string = repr->attribute("inkscape:export-xdpi");
-                            if (dpi_string != NULL) {
-                                xdpi = atof(dpi_string);
-                                xdpi_search = FALSE;
-                            }
-                        }
-
-                        if (ydpi_search) {
-                            dpi_string = NULL;
-                            dpi_string = repr->attribute("inkscape:export-ydpi");
-                            if (dpi_string != NULL) {
-                                ydpi = atof(dpi_string);
-                                ydpi_search = FALSE;
-                            }
-                        }
-                    }
+                    sp_selection_get_export_hints (sp_desktop_selection(SP_ACTIVE_DESKTOP), &filename, &xdpi, &ydpi);
 
                     /* If we still don't have a filename -- let's build
                        one that's nice */
                     if (filename == NULL) {
                         const gchar * id = NULL;
-                        reprlst = SP_DT_SELECTION(SP_ACTIVE_DESKTOP)->reprList();
+                        const GSList * reprlst = sp_desktop_selection(SP_ACTIVE_DESKTOP)->reprList();
                         for(; reprlst != NULL; reprlst = reprlst->next) {
                             Inkscape::XML::Node * repr = (Inkscape::XML::Node *)reprlst->data;
                             if (repr->attribute("id")) {
@@ -850,35 +938,8 @@ sp_export_area_toggled (GtkToggleButton *tb, GtkObject *base)
                                 break;
                             }
                         }
-                        if (id == NULL) /* This should never happen */
-                            id = "bitmap";
-
-                        gchar * directory = NULL;
-                        const gchar * file_entry_text;
-
-                        file_entry_text = gtk_entry_get_text(GTK_ENTRY(file_entry));
-                        if (directory == NULL && file_entry_text != NULL && file_entry_text[0] != '\0') {
-                            // std::cout << "Directory from dialog" << std::endl;
-                            directory = g_dirname(file_entry_text);
-                        }
-
-                        if (directory == NULL) {
-                            /* Grab document directory */
-                            if (SP_DOCUMENT_URI(SP_ACTIVE_DOCUMENT)) {
-                                // std::cout << "Directory from document" << std::endl;
-                                directory = g_dirname(SP_DOCUMENT_URI(SP_ACTIVE_DOCUMENT));
-                            }
-                        }
-
-                        if (directory == NULL) {
-                            // std::cout << "Home Directory" << std::endl;
-                            directory = homedir_path(NULL);
-                        }
 
-                        gchar * id_ext = g_strconcat(id, ".png", NULL);
-                        filename = g_build_filename(directory, id_ext, NULL);
-                        g_free(directory);
-                        g_free(id_ext);
+                        filename = create_filepath_from_id (id, gtk_entry_get_text(GTK_ENTRY(file_entry)));
                     }
                 }
                 break;
@@ -897,7 +958,7 @@ sp_export_area_toggled (GtkToggleButton *tb, GtkObject *base)
             sp_export_value_set(base, "xdpi", xdpi);
         }
 
-        /* These can't be seperate, and setting x sets y, so for
+        /* These can't be separate, and setting x sets y, so for
            now setting this is disabled.  Hopefully it won't be in
            the future */
         if (FALSE && ydpi != 0.0) {
@@ -910,7 +971,7 @@ sp_export_area_toggled (GtkToggleButton *tb, GtkObject *base)
 
 /// Called when dialog is deleted
 static gint
-sp_export_progress_delete ( GtkWidget *widget, GdkEvent *event, GObject *base )
+sp_export_progress_delete ( GtkWidget */*widget*/, GdkEvent */*event*/, GObject *base )
 {
     g_object_set_data (base, "cancel", (gpointer) 1);
     return TRUE;
@@ -918,7 +979,7 @@ sp_export_progress_delete ( GtkWidget *widget, GdkEvent *event, GObject *base )
 
 /// Called when progress is cancelled
 static void
-sp_export_progress_cancel ( GtkWidget *widget, GObject *base )
+sp_export_progress_cancel ( GtkWidget */*widget*/, GObject *base )
 {
     g_object_set_data (base, "cancel", (gpointer) 1);
 } // end of sp_export_progress_cancel()
@@ -948,12 +1009,160 @@ sp_export_progress_callback (float value, void *data)
 
 } // end of sp_export_progress_callback()
 
+GtkWidget *
+create_progress_dialog (GtkObject *base, gchar *progress_text) {
+    GtkWidget *dlg, *prg, *btn; /* progressbar-stuff */
+
+    dlg = gtk_dialog_new ();
+    gtk_window_set_title (GTK_WINDOW (dlg), _("Export in progress"));
+    prg = gtk_progress_bar_new ();
+    sp_transientize (dlg);
+    gtk_window_set_resizable (GTK_WINDOW (dlg), FALSE);
+    g_object_set_data ((GObject *) base, "progress", prg);
+
+    gtk_progress_bar_set_text ((GtkProgressBar *) prg, progress_text);
+
+    gtk_progress_bar_set_orientation ( (GtkProgressBar *) prg,
+                                       GTK_PROGRESS_LEFT_TO_RIGHT);
+    gtk_box_pack_start ((GtkBox *) ((GtkDialog *) dlg)->vbox,
+                        prg, FALSE, FALSE, 4 );
+    btn = gtk_dialog_add_button ( GTK_DIALOG (dlg),
+                                  GTK_STOCK_CANCEL,
+                                  GTK_RESPONSE_CANCEL );
+
+    g_signal_connect ( (GObject *) dlg, "delete_event",
+                       (GCallback) sp_export_progress_delete, base);
+    g_signal_connect ( (GObject *) btn, "clicked",
+                       (GCallback) sp_export_progress_cancel, base);
+    gtk_window_set_modal ((GtkWindow *) dlg, TRUE);
+    gtk_widget_show_all (dlg);
+
+    return dlg;
+}
+
+// FIXME: Some lib function should be available to do this ...
+static gchar *
+filename_add_extension (const gchar *filename, const gchar *extension)
+{
+  const gchar *dot;
+
+  dot = strrchr (filename, '.');
+  if ( !dot )
+    return g_strconcat (filename, ".", extension, NULL);
+  {
+    if (dot[1] == '\0')
+      return g_strconcat (filename, extension, NULL);
+    else
+    {
+      if (g_strcasecmp (dot + 1, extension) == 0)
+        return g_strdup (filename);
+      else
+      {
+        return g_strconcat (filename, ".", extension, NULL);
+      }
+    }
+  }
+}
+
+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)
+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");
+    bool hide = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (he));
+    if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (be))) {
+        // Batch export of selected objects
+
+        gint num = g_slist_length((GSList *) sp_desktop_selection(SP_ACTIVE_DESKTOP)->itemList());
+        gint n = 0;
+
+        if (num < 1)
+            return;
+
+        gchar *progress_text = g_strdup_printf (_("Exporting %d files"), num);
+        GtkWidget *prog_dlg = create_progress_dialog (base, progress_text);
+        g_free (progress_text);
+
+        for (GSList *i = (GSList *) sp_desktop_selection(SP_ACTIVE_DESKTOP)->itemList();
+             i != NULL;
+             i = i->next) {
+            SPItem *item = reinterpret_cast<SPItem *>(i->data);
+
+            // retrieve export filename hint
+            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 = 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);
+            }
+            if (dpi == 0.0) {
+                dpi = DPI_BASE;
+            }
+
+            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);
+        }
+
+        gtk_widget_destroy (prog_dlg);
+        g_object_set_data (G_OBJECT (base), "cancel", (gpointer) 0);
+
+    } else {
+
     GtkWidget *fe = (GtkWidget *)gtk_object_get_data(base, "filename");
     gchar const *filename = gtk_entry_get_text(GTK_ENTRY(fe));
 
@@ -963,8 +1172,8 @@ sp_export_export_clicked (GtkButton *button, GtkObject *base)
     float const y1 = sp_export_value_get_px(base, "y1");
     float const xdpi = sp_export_value_get(base, "xdpi");
     float const ydpi = sp_export_value_get(base, "ydpi");
-    int const width = int(sp_export_value_get(base, "bmwidth") + 0.5);
-    int const height = int(sp_export_value_get(base, "bmheight") + 0.5);
+    unsigned long int const width = int(sp_export_value_get(base, "bmwidth") + 0.5);
+    unsigned long int const height = int(sp_export_value_get(base, "bmheight") + 0.5);
 
     if (filename == NULL || *filename == '\0') {
         sp_ui_error_dialog(_("You have to enter a filename"));
@@ -976,7 +1185,13 @@ sp_export_export_clicked (GtkButton *button, GtkObject *base)
         return;
     }
 
-    gchar *dirname = g_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)) )
     {
@@ -987,49 +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);
 
-    SPNamedView *nv = SP_DT_NAMEDVIEW(SP_ACTIVE_DESKTOP);
-    GtkWidget *dlg, *prg, *btn; /* progressbar-stuff */
-    char *fn;
-    gchar *text;
-
-    dlg = gtk_dialog_new ();
-    gtk_window_set_title (GTK_WINDOW (dlg), _("Export in progress"));
-    prg = gtk_progress_bar_new ();
-    sp_transientize (dlg);
-    gtk_window_set_resizable (GTK_WINDOW (dlg), FALSE);
-    g_object_set_data ((GObject *) base, "progress", prg);
-    fn = g_path_get_basename (filename);
-    text = g_strdup_printf ( _("Exporting %s (%d x %d)"), 
-                             fn, width, height);
+    gchar *fn = g_path_get_basename (path);
+    gchar *progress_text = g_strdup_printf (_("Exporting %s (%lu x %lu)"), fn, width, height);
     g_free (fn);
-    gtk_progress_bar_set_text ((GtkProgressBar *) prg, text);
-    g_free (text);
-    gtk_progress_bar_set_orientation ( (GtkProgressBar *) prg, 
-                                       GTK_PROGRESS_LEFT_TO_RIGHT);
-    gtk_box_pack_start ((GtkBox *) ((GtkDialog *) dlg)->vbox, 
-                        prg, FALSE, FALSE, 4 );
-    btn = gtk_dialog_add_button ( GTK_DIALOG (dlg), 
-                                  GTK_STOCK_CANCEL, 
-                                  GTK_RESPONSE_CANCEL );
-                                  
-    g_signal_connect ( (GObject *) dlg, "delete_event", 
-                       (GCallback) sp_export_progress_delete, base);
-    g_signal_connect ( (GObject *) btn, "clicked", 
-                       (GCallback) sp_export_progress_cancel, base);
-    gtk_window_set_modal ((GtkWindow *) dlg, TRUE);
-    gtk_widget_show_all (dlg);
-    
+
+    GtkWidget *prog_dlg = create_progress_dialog (base, progress_text);
+    g_free (progress_text);
+
     /* Do export */
-    if (!sp_export_png_file (SP_DT_DOCUMENT (SP_ACTIVE_DESKTOP), filename, 
-                             x0, y0, x1, y1, width, height, 
-                             nv->pagecolor, 
-                             sp_export_progress_callback, base)) {
+    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);
@@ -1039,10 +1232,10 @@ sp_export_export_clicked (GtkButton *button, GtkObject *base)
     /* Reset the filename so that it can be changed again by changing
        selections and all that */
     g_free(original_name);
-    original_name = g_strdup(filename);
+    original_name = g_strdup(filename_ext);
     gtk_object_set_data (GTK_OBJECT (base), "filename-modified", (gpointer)FALSE);
 
-    gtk_widget_destroy (dlg);
+    gtk_widget_destroy (prog_dlg);
     g_object_set_data (G_OBJECT (base), "cancel", (gpointer) 0);
 
     /* Setup the values in the document */
@@ -1050,93 +1243,107 @@ 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);
-            bool modified = FALSE;
-            const gchar * temp_string;
+            Inkscape::XML::Node * repr = doc->getReprRoot();
+            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);
 
-            temp_string = repr->attribute("inkscape:export-filename");
-            if (temp_string == NULL || strcmp(temp_string, filename)) {
-                repr->setAttribute("inkscape:export-filename", filename);
-                modified = TRUE;
+            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;
             }
             temp_string = repr->attribute("inkscape:export-xdpi");
             if (temp_string == NULL || xdpi != atof(temp_string)) {
                 sp_repr_set_svg_double(repr, "inkscape:export-xdpi", xdpi);
-                modified = TRUE;
+                modified = true;
             }
             temp_string = repr->attribute("inkscape:export-ydpi");
             if (temp_string == NULL || xdpi != atof(temp_string)) {
                 sp_repr_set_svg_double(repr, "inkscape:export-ydpi", ydpi);
-                modified = TRUE;
+                modified = true;
             }
+            DocumentUndo::setUndoSensitive(doc, saved);
 
-            if (modified)
-                repr->setAttribute("sodipodi:modified", "TRUE");
-            sp_document_set_undo_sensitive(doc, saved);
+            if (modified) {
+                doc->setModifiedSinceSave();
+            }
             break;
         }
         case SELECTION_SELECTION: {
             const GSList * reprlst;
             SPDocument * doc = SP_ACTIVE_DOCUMENT;
-            bool modified = FALSE;
+            bool modified = false;
 
-            bool saved = sp_document_get_undo_sensitive(doc);
-            sp_document_set_undo_sensitive(doc, FALSE);
-            reprlst = SP_DT_SELECTION(SP_ACTIVE_DESKTOP)->reprList();
+            bool saved = DocumentUndo::getUndoSensitive(doc);
+            DocumentUndo::setUndoSensitive(doc, false);
+            reprlst = sp_desktop_selection(SP_ACTIVE_DESKTOP)->reprList();
 
             for(; reprlst != NULL; reprlst = reprlst->next) {
                 Inkscape::XML::Node * repr = (Inkscape::XML::Node *)reprlst->data;
                 const gchar * temp_string;
 
                 if (repr->attribute("id") == NULL ||
-                        !(g_strrstr(filename, repr->attribute("id")) != NULL &&
-                          (!SP_DOCUMENT_URI(SP_ACTIVE_DOCUMENT) ||
-                            strcmp(g_dirname(filename), g_dirname(SP_DOCUMENT_URI(SP_ACTIVE_DOCUMENT))) == 0))) {
+                        !(g_strrstr(filename_ext, repr->attribute("id")) != NULL &&
+                          ( !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)) {
-                        repr->setAttribute("inkscape:export-filename", filename);
-                        modified = TRUE;
+                    if (temp_string == NULL || strcmp(temp_string, filename_ext)) {
+                        repr->setAttribute("inkscape:export-filename", filename_ext);
+                        modified = true;
                     }
                 }
                 temp_string = repr->attribute("inkscape:export-xdpi");
                 if (temp_string == NULL || xdpi != atof(temp_string)) {
                     sp_repr_set_svg_double(repr, "inkscape:export-xdpi", xdpi);
-                    modified = TRUE;
+                    modified = true;
                 }
                 temp_string = repr->attribute("inkscape:export-ydpi");
                 if (temp_string == NULL || xdpi != atof(temp_string)) {
                     sp_repr_set_svg_double(repr, "inkscape:export-ydpi", ydpi);
-                    modified = TRUE;
+                    modified = true;
                 }
             }
+            DocumentUndo::setUndoSensitive(doc, saved);
 
             if (modified) {
-                Inkscape::XML::Node * repr = sp_document_repr_root(doc);
-                repr->setAttribute("sodipodi:modified", "TRUE");
+                doc->setModifiedSinceSave();
             }
-
-            sp_document_set_undo_sensitive(doc, saved);
             break;
         }
         default:
             break;
     }
 
+    g_free (filename_ext);
+    g_free (path);
+
+    }
 
-    return;
 } // 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)
+sp_export_browse_clicked (GtkButton */*button*/, gpointer /*userdata*/)
 {
     GtkWidget *fs, *fe;
     const gchar *filename;
 
-    fs = gtk_file_selection_new (_("Select a filename for exporting"));
+    fs = gtk_file_chooser_dialog_new (_("Select a filename for exporting"),
+                                      (GtkWindow*)dlg,
+                                      GTK_FILE_CHOOSER_ACTION_SAVE,
+                                      GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+                                      GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
+                                      NULL );
+
+#ifdef WITH_GNOME_VFS
+    if (gnome_vfs_initialized()) {
+        gtk_file_chooser_set_local_only(GTK_FILE_CHOOSER(fs), false);
+    }
+#endif
+
     fe = (GtkWidget *)g_object_get_data (G_OBJECT (dlg), "filename");
 
     sp_transientize (fs);
@@ -1146,61 +1353,90 @@ 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_selection_set_filename (GTK_FILE_SELECTION (fs), filename);
+    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_signal_connect ( GTK_OBJECT (GTK_FILE_SELECTION (fs)->ok_button),
-                       "clicked",
-                       G_CALLBACK (sp_export_browse_store),
-                       (gpointer) fs );
+    }
+    g_free(extension_string);
+    g_free(title_string);
 
-    g_signal_connect_swapped ( GTK_OBJECT (GTK_FILE_SELECTION (fs)->ok_button),
-                               "clicked",
-                               G_CALLBACK (gtk_widget_destroy),
-                               (gpointer) fs );
+#else
+    if (gtk_dialog_run (GTK_DIALOG (fs)) == GTK_RESPONSE_ACCEPT)
+    {
+        gchar *file;
 
-    g_signal_connect_swapped ( GTK_OBJECT
-                                   (GTK_FILE_SELECTION (fs)->cancel_button),
-                               "clicked",
-                               G_CALLBACK (gtk_widget_destroy),
-                               (gpointer) fs );
+        file = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (fs));
 
-    gtk_widget_show (fs);
+        gchar * utf8file = g_filename_to_utf8( file, -1, NULL, NULL, NULL );
+        gtk_entry_set_text (GTK_ENTRY (fe), utf8file);
 
-    return;
-} // end of sp_export_browse_clicked()
+        g_object_set_data (G_OBJECT (dlg), "filename", fe);
 
-/// Called when OK clicked in file dialog
-static void
-sp_export_browse_store (GtkButton *button, gpointer userdata)
-{
-    GtkWidget *fs = (GtkWidget *)userdata, *fe;
-    const gchar *file;
-
-    fe = (GtkWidget *)g_object_get_data (G_OBJECT (dlg), "filename");
-
-    file = gtk_file_selection_get_filename (GTK_FILE_SELECTION (fs));
-    gchar * utf8file = g_filename_to_utf8( file, -1, NULL, NULL, NULL );
-    gtk_entry_set_text (GTK_ENTRY (fe), utf8file);
-    g_free(utf8file);
+        g_free(utf8file);
+        g_free(file);
+    }
+#endif
 
-    g_object_set_data (G_OBJECT (dlg), "filename", fe);
+    gtk_widget_destroy (fs);
 
     return;
-} // end of sp_export_browse_store()
+} // end of sp_export_browse_clicked()
 
 // TODO: Move this to nr-rect-fns.h.
 static bool
-sp_export_bbox_equal(NR::Rect const &one, NR::Rect const &two)
-{ 
+sp_export_bbox_equal(Geom::Rect const &one, Geom::Rect const &two)
+{
     double const epsilon = pow(10.0, -EXPORT_COORD_PRECISION);
     return (
-        (fabs(one.min()[NR::X] - two.min()[NR::X]) < epsilon) &&
-        (fabs(one.min()[NR::Y] - two.min()[NR::Y]) < epsilon) &&
-        (fabs(one.max()[NR::X] - two.max()[NR::X]) < epsilon) &&
-        (fabs(one.max()[NR::Y] - two.max()[NR::Y]) < epsilon)
+        (fabs(one.min()[Geom::X] - two.min()[Geom::X]) < epsilon) &&
+        (fabs(one.min()[Geom::Y] - two.min()[Geom::Y]) < epsilon) &&
+        (fabs(one.max()[Geom::X] - two.max()[Geom::X]) < epsilon) &&
+        (fabs(one.max()[Geom::Y] - two.max()[Geom::Y]) < epsilon)
         );
 }
 
@@ -1233,11 +1469,11 @@ sp_export_detect_size(GtkObject * base) {
     selection_type this_test[SELECTION_NUMBER_OF + 1];
     selection_type key = SELECTION_NUMBER_OF;
 
-    NR::Point x(sp_export_value_get_px (base, "x0"),
-                sp_export_value_get_px (base, "y0"));
-    NR::Point y(sp_export_value_get_px (base, "x1"),
-                sp_export_value_get_px (base, "y1"));
-    NR::Rect current_bbox(x, y);
+    Geom::Point x(sp_export_value_get_px (base, "x0"),
+                  sp_export_value_get_px (base, "y0"));
+    Geom::Point y(sp_export_value_get_px (base, "x1"),
+                  sp_export_value_get_px (base, "y1"));
+    Geom::Rect current_bbox(x, y);
     //std::cout << "Current " << current_bbox;
 
     this_test[0] = (selection_type)(GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(base), "selection-type")));
@@ -1253,22 +1489,22 @@ sp_export_detect_size(GtkObject * base) {
         // std::cout << "Looking at: " << selection_names[this_test[i]] << std::endl;
         switch (this_test[i]) {
             case SELECTION_SELECTION:
-                if ((SP_DT_SELECTION(SP_ACTIVE_DESKTOP))->isEmpty() == false) {
-                    NR::Rect bbox = (SP_DT_SELECTION (SP_ACTIVE_DESKTOP))->bounds();
+                if ((sp_desktop_selection(SP_ACTIVE_DESKTOP))->isEmpty() == false) {
+                    Geom::OptRect bbox = (sp_desktop_selection (SP_ACTIVE_DESKTOP))->bounds(SPItem::RENDERING_BBOX);
 
                     //std::cout << "Selection " << bbox;
-                    if (sp_export_bbox_equal(bbox,current_bbox)) {
+                    if ( bbox && sp_export_bbox_equal(*bbox,current_bbox)) {
                         key = SELECTION_SELECTION;
                     }
                 }
                 break;
             case SELECTION_DRAWING: {
-                SPDocument *doc = SP_DT_DOCUMENT (SP_ACTIVE_DESKTOP);
+                SPDocument *doc = sp_desktop_document (SP_ACTIVE_DESKTOP);
 
-                NR::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 (sp_export_bbox_equal(bbox,current_bbox)) {
+                if ( bbox && sp_export_bbox_equal(*bbox,current_bbox) ) {
                     key = SELECTION_DRAWING;
                 }
                 break;
@@ -1277,12 +1513,12 @@ sp_export_detect_size(GtkObject * base) {
             case SELECTION_PAGE: {
                 SPDocument *doc;
 
-                doc = SP_DT_DOCUMENT (SP_ACTIVE_DESKTOP);
+                doc = sp_desktop_document (SP_ACTIVE_DESKTOP);
 
-                NR::Point x(0.0, 0.0);
-                NR::Point y(sp_document_width(doc),
-                            sp_document_height(doc));
-                NR::Rect bbox(x, y);
+                Geom::Point x(0.0, 0.0);
+                Geom::Point y(doc->getWidth(),
+                              doc->getHeight());
+                Geom::Rect bbox(x, y);
 
                 // std::cout << "Page " << bbox;
                 if (sp_export_bbox_equal(bbox,current_bbox)) {
@@ -1406,7 +1642,7 @@ sp_export_area_y_value_changed (GtkAdjustment *adj, GtkObject *base)
 
 /// Called when x1-x0 or area width is changed
 static void
-sp_export_area_width_value_changed (GtkAdjustment *adj, GtkObject *base)
+sp_export_area_width_value_changed (GtkAdjustment */*adj*/, GtkObject *base)
 {
     float x0, x1, xdpi, width, bmwidth;
 
@@ -1443,7 +1679,7 @@ sp_export_area_width_value_changed (GtkAdjustment *adj, GtkObject *base)
 
 /// Called when y1-y0 or area height is changed.
 static void
-sp_export_area_height_value_changed (GtkAdjustment *adj, GtkObject *base)
+sp_export_area_height_value_changed (GtkAdjustment */*adj*/, GtkObject *base)
 {
 
     float y0, y1, ydpi, height, bmheight;
@@ -1526,7 +1762,7 @@ sp_export_set_image_x (GtkObject *base)
 
 /// Called when pixel width is changed
 static void
-sp_export_bitmap_width_value_changed (GtkAdjustment *adj, GtkObject *base)
+sp_export_bitmap_width_value_changed (GtkAdjustment */*adj*/, GtkObject *base)
 {
     float x0, x1, bmwidth, xdpi;
 
@@ -1561,7 +1797,7 @@ sp_export_bitmap_width_value_changed (GtkAdjustment *adj, GtkObject *base)
 
 /// Called when pixel height is changed
 static void
-sp_export_bitmap_height_value_changed (GtkAdjustment *adj, GtkObject *base)
+sp_export_bitmap_height_value_changed (GtkAdjustment */*adj*/, GtkObject *base)
 {
     float y0, y1, bmheight, xdpi;
 
@@ -1623,7 +1859,7 @@ sp_export_bitmap_height_value_changed (GtkAdjustment *adj, GtkObject *base)
     currently be independent.  This is likely to change in the future.
 */
 void
-sp_export_xdpi_value_changed (GtkAdjustment *adj, GtkObject *base)
+sp_export_xdpi_value_changed (GtkAdjustment */*adj*/, GtkObject *base)
 {
     float x0, x1, xdpi, bmwidth;
 
@@ -1642,7 +1878,8 @@ sp_export_xdpi_value_changed (GtkAdjustment *adj, GtkObject *base)
     xdpi = sp_export_value_get (base, "xdpi");
 
     // remember xdpi setting
-    prefs_set_double_attribute ("dialogs.export.defaultxdpi", "value", xdpi);
+    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+    prefs->setDouble("/dialogs/export/defaultxdpi/value", xdpi);
 
     bmwidth = (x1 - x0) * xdpi / DPI_BASE;
 
@@ -1758,7 +1995,7 @@ sp_export_value_get ( GtkObject *base, const gchar *key )
     adj = (GtkAdjustment *)gtk_object_get_data (base, key);
 
     return adj->value;
-} // end of sp_export_value_get()
+}
 
 /**
     \brief  Grabs a value in the export dialog and converts the unit
@@ -1815,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 :