Code

Merge and cleanup of GSoC C++-ification project.
[inkscape.git] / src / dialogs / export.cpp
index 835003e5e621737df23b2c948820b879216611b9..7e99c2496efb96fb12b2de617fe2ca73db65cc7f 100644 (file)
@@ -5,6 +5,8 @@
  *   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.
 
 #ifdef WIN32
 #include <windows.h>
-#include <COMMDLG.h>
+#include <commdlg.h>
 #include <gdk/gdkwin32.h>
 #endif
 
+using Inkscape::DocumentUndo;
+
 #define SP_EXPORT_MIN_SIZE 1.0
 
 #define DPI_BASE PX_PER_IN
@@ -362,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() );
         }
     }
 
@@ -535,12 +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);
-                const gchar *text_extension = Inkscape::Preferences::get()->getString("/dialogs/save_as/default").c_str();
+                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) {
@@ -780,7 +784,7 @@ sp_export_selection_modified ( Inkscape::Application */*inkscape*/,
             if ( SP_ACTIVE_DESKTOP ) {
                 SPDocument *doc;
                 doc = sp_desktop_document (SP_ACTIVE_DESKTOP);
-                Geom::OptRect 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],
@@ -792,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;
@@ -849,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 */
@@ -861,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) {
@@ -871,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;
@@ -1060,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)
@@ -1067,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");
@@ -1087,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);
@@ -1105,21 +1131,21 @@ sp_export_export_clicked (GtkButton */*button*/, GtkObject *base)
             }
 
             Geom::OptRect area;
-            sp_item_invoke_bbox(item, area, sp_item_i2d_affine((SPItem *) item), TRUE);
+            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 (sp_desktop_document (SP_ACTIVE_DESKTOP), fn,
+                    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(fn);
+                        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);
@@ -1128,6 +1154,7 @@ sp_export_export_clicked (GtkButton */*button*/, GtkObject *base)
                 }
             }
             n++;
+            g_free(path);
             sp_export_progress_callback((float)n/num, base);
         }
 
@@ -1158,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)) )
     {
@@ -1169,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,
+    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);
@@ -1213,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;
@@ -1235,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();
@@ -1247,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) {
@@ -1257,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);
@@ -1276,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();
@@ -1288,6 +1317,7 @@ sp_export_export_clicked (GtkButton */*button*/, GtkObject *base)
     }
 
     g_free (filename_ext);
+    g_free (path);
 
     }
 
@@ -1329,48 +1359,52 @@ sp_export_browse_clicked (GtkButton */*button*/, gpointer /*userdata*/)
     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 = (WCHAR*)g_utf8_to_utf16("PNG\0*.png\0\0", 12, NULL, NULL, NULL);
-       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];
+    // 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);
+    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(utf8string);
+
+    }
+    g_free(extension_string);
+    g_free(title_string);
 
-       }
-       g_free(extension_string);
-       g_free(title_string);
-       g_free(filter_string);
 #else
     if (gtk_dialog_run (GTK_DIALOG (fs)) == GTK_RESPONSE_ACCEPT)
     {
@@ -1456,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) {
-                    Geom::OptRect 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)) {
@@ -1467,7 +1501,7 @@ sp_export_detect_size(GtkObject * base) {
             case SELECTION_DRAWING: {
                 SPDocument *doc = sp_desktop_document (SP_ACTIVE_DESKTOP);
 
-                Geom::OptRect 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) ) {
@@ -1482,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;
@@ -2023,4 +2057,4 @@ sp_export_filename_modified (GtkObject * object, gpointer data)
   fill-column:99
   End:
 */
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :