X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fdialogs%2Fexport.cpp;h=0e2a08eb4c4442f3ae08ab55c1fedc54489d1e0d;hb=690d37ddd3470e494dde1e3ee20b942736e734d2;hp=6cd1084124f08f25e885acb2492301cf4b982852;hpb=2c2433148c078bfb2f60622e263bbb817e78abdd;p=inkscape.git diff --git a/src/dialogs/export.cpp b/src/dialogs/export.cpp index 6cd108412..0e2a08eb4 100644 --- a/src/dialogs/export.cpp +++ b/src/dialogs/export.cpp @@ -8,8 +8,9 @@ * Authors: * Lauris Kaplinski * bulia byak + * Johan Engelen * - * 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 @@ -20,6 +21,18 @@ #endif #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef WITH_GNOME_VFS +# include // gnome_vfs_initialized +#endif #include #include "helper/unit-menu.h" @@ -34,6 +47,7 @@ #include "file.h" #include "macros.h" #include "sp-namedview.h" +#include "selection-chemistry.h" #include "dialog-events.h" #include "../prefs-utils.h" @@ -45,6 +59,9 @@ #include "io/sys.h" +#include "helper/png-write.h" +#include + #define SP_EXPORT_MIN_SIZE 1.0 @@ -52,35 +69,38 @@ #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, + GtkObject *base); -static void sp_export_area_x_value_changed ( GtkAdjustment *adj, +static void sp_export_area_y_value_changed ( GtkAdjustment *adj, GtkObject *base); - -static void sp_export_area_y_value_changed ( GtkAdjustment *adj, + +static void sp_export_area_width_value_changed ( GtkAdjustment *adj, GtkObject *base); - -static void sp_export_area_width_value_changed ( GtkAdjustment *adj, + +static void sp_export_area_height_value_changed ( GtkAdjustment *adj, GtkObject *base); - -static void sp_export_area_height_value_changed ( GtkAdjustment *adj, + +static void sp_export_bitmap_width_value_changed ( GtkAdjustment *adj, GtkObject *base); - -static void sp_export_bitmap_width_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 ); @@ -123,7 +143,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); @@ -141,7 +161,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); @@ -180,7 +200,7 @@ 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, @@ -188,7 +208,7 @@ sp_export_spinbutton_new ( gchar *key, float val, float min, float max, 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 (a, "key", const_cast(key)); gtk_object_set_data (GTK_OBJECT (dlg), (const gchar *)key, a); if (us) { @@ -239,99 +259,138 @@ sp_export_spinbutton_new ( gchar *key, float val, float min, float max, } // 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(_("Export area"), 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, _("Width:"), 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, _("Height:"), 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_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); + 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) { if (!dlg) { - GtkWidget *vb, *hb; gchar title[500]; sp_ui_dialog_title_string (Inkscape::Verb::get(SP_VERB_FILE_EXPORT), title); @@ -348,15 +407,14 @@ sp_export_dialog (void) h = prefs_get_int_attribute (prefs_path, "h", 0); } - if (x != 0 || y != 0) { +// if (x<0) x=0; +// if (y<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; @@ -384,65 +442,85 @@ 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(_("Bitmap size"), 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_get_double_attribute + ( "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, 10.0, - NULL, t, 0, 1, _("Height:"), _("pixels at"), - 0, 0, NULL, dlg ); + 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), + 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_get_double_attribute + ( "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(_("_Filename"), 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 @@ -481,63 +559,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), _(" _Export ")); - 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) @@ -548,12 +671,32 @@ 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; } @@ -583,31 +726,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"))); @@ -618,15 +761,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; @@ -636,19 +779,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); + NR::Maybe bbox = sp_item_bbox_desktop (SP_ITEM (SP_DOCUMENT_ROOT (doc))); + if (bbox) { + sp_export_set_area (base, bbox->min()[NR::X], + bbox->min()[NR::Y], + bbox->max()[NR::X], + bbox->max()[NR::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); sp_export_set_area (base, bbox.x0, bbox.y0, bbox.x1, bbox.y1); } break; @@ -695,17 +839,17 @@ sp_export_area_toggled (GtkToggleButton *tb, GtkObject *base) if ( SP_ACTIVE_DESKTOP ) { SPDocument *doc; - NRRect bbox; - doc = SP_DT_DOCUMENT (SP_ACTIVE_DESKTOP); + NR::Maybe 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(); /* Only if there is a selection that we can set do we break, otherwise we fall through to the drawing */ @@ -714,23 +858,22 @@ 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_bbox_desktop (SP_ITEM (SP_DOCUMENT_ROOT (doc))); /* 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 = NR::Rect(NR::Point(0.0, 0.0), + NR::Point(sp_document_width(doc), sp_document_height(doc)) + ); + // std::cout << "Using selection: PAGE" << std::endl; key = SELECTION_PAGE; break; @@ -738,15 +881,18 @@ sp_export_area_toggled (GtkToggleButton *tb, GtkObject *base) default: break; } // switch - + // remember area setting - prefs_set_string_attribute ( "dialogs.export.exportarea", + 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); + if ( key != SELECTION_CUSTOM && bbox ) { + sp_export_set_area (base, bbox->min()[NR::X], + bbox->min()[NR::Y], + bbox->max()[NR::X], + bbox->max()[NR::Y]); } - + } // end of if ( SP_ACTIVE_DESKTOP ) @@ -761,22 +907,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) { @@ -785,55 +916,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 (xdpi_search) { - dpi_string = NULL; - dpi_string = repr->attribute("inkscape:export-xdpi"); - if (dpi_string != NULL) { - xdpi = atof(dpi_string); - xdpi_search = FALSE; - } - } + if ((sp_desktop_selection(SP_ACTIVE_DESKTOP))->isEmpty() == 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")) { @@ -841,35 +935,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; @@ -888,7 +955,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) { @@ -901,7 +968,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; @@ -909,7 +976,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() @@ -939,12 +1006,136 @@ 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) +{ + 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); + } + } + } +} + /// 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); + + 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 = (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); + } + + // retrieve export dpi hints + const gchar *dpi_hint = SP_OBJECT_REPR(item)->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; + } + + NRRect area; + sp_item_invoke_bbox(item, &area, from_2geom(sp_item_i2r_affine((SPItem *) item)), TRUE); + + gint width = (gint) ((area.x1 - area.x0) * dpi / PX_PER_IN + 0.5); + gint height = (gint) ((area.y1 - area.y0) * dpi / PX_PER_IN + 0.5); + + if (width > 1 && height > 1) { + /* Do export */ + if (!sp_export_png_file (sp_desktop_document (SP_ACTIVE_DESKTOP), fn, + area.x0, area.y0, area.x1, area.y1, width, height, dpi, dpi, + nv->pagecolor, + NULL, NULL, TRUE, // overwrite without asking + hide ? (GSList *) sp_desktop_selection(SP_ACTIVE_DESKTOP)->itemList() : NULL + )) { + gchar * error; + gchar * safeFile = Inkscape::IO::sanitizeString(fn); + error = g_strdup_printf(_("Could not export to filename %s.\n"), safeFile); + sp_ui_error_dialog(error); + g_free(safeFile); + g_free(error); + } + } + n++; + 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)); @@ -954,8 +1145,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")); @@ -967,7 +1158,7 @@ sp_export_export_clicked (GtkButton *button, GtkObject *base) return; } - gchar *dirname = g_dirname(filename); + gchar *dirname = g_path_get_dirname(filename); if ( dirname == NULL || !Inkscape::IO::file_test(dirname, (GFileTest)(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) ) { @@ -982,43 +1173,24 @@ sp_export_export_clicked (GtkButton *button, GtkObject *base) } g_free(dirname); - SPNamedView *nv = SP_DT_NAMEDVIEW(SP_ACTIVE_DESKTOP); - GtkWidget *dlg, *prg, *btn; /* progressbar-stuff */ - char *fn; - gchar *text; + // 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); - 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 (filename_ext); + + 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), filename_ext, + x0, y0, 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); error = g_strdup_printf(_("Could not export to filename %s.\n"), safeFile); @@ -1030,10 +1202,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 */ @@ -1042,92 +1214,105 @@ sp_export_export_clicked (GtkButton *button, GtkObject *base) case SELECTION_DRAWING: { SPDocument * doc = SP_ACTIVE_DOCUMENT; Inkscape::XML::Node * repr = sp_document_repr_root(doc); - bool modified = FALSE; + bool modified = false; const gchar * temp_string; bool saved = sp_document_get_undo_sensitive(doc); - sp_document_set_undo_sensitive(doc, FALSE); + sp_document_set_undo_sensitive(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; + 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; } - - 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(); + sp_document_set_undo_sensitive(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 && + !(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))) { 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; } } + sp_document_set_undo_sensitive(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); + + } - return; } // end of sp_export_export_clicked() /// Called when Browse button is clicked 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); @@ -1140,52 +1325,32 @@ sp_export_browse_clicked (GtkButton *button, gpointer userdata) filename = homedir_path(NULL); } - gtk_file_selection_set_filename (GTK_FILE_SELECTION (fs), filename); - - g_signal_connect ( GTK_OBJECT (GTK_FILE_SELECTION (fs)->ok_button), - "clicked", - G_CALLBACK (sp_export_browse_store), - (gpointer) fs ); + gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (fs), filename); - g_signal_connect_swapped ( GTK_OBJECT (GTK_FILE_SELECTION (fs)->ok_button), - "clicked", - G_CALLBACK (gtk_widget_destroy), - (gpointer) fs ); + 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); + } - 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) -{ +{ double const epsilon = pow(10.0, -EXPORT_COORD_PRECISION); return ( (fabs(one.min()[NR::X] - two.min()[NR::X]) < epsilon) && @@ -1244,22 +1409,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) { + NR::Maybe bbox = (sp_desktop_selection (SP_ACTIVE_DESKTOP))->bounds(); //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))); + NR::Maybe bbox = sp_item_bbox_desktop (SP_ITEM (SP_DOCUMENT_ROOT (doc))); // 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; @@ -1268,7 +1433,7 @@ 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), @@ -1397,7 +1562,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; @@ -1434,7 +1599,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; @@ -1492,9 +1657,32 @@ sp_export_set_image_y (GtkObject *base) return; } // end of sp_export_set_image_y() +/** + \brief A function to set the xdpi + \param base The export dialog + + This function grabs all of the x values and then figures out the + new bitmap size based on the changing dpi value. The dpi value is + gotten from the xdpi setting as these can not currently be independent. +*/ +static void +sp_export_set_image_x (GtkObject *base) +{ + float x0, x1, xdpi; + + x0 = sp_export_value_get_px (base, "x0"); + x1 = sp_export_value_get_px (base, "x1"); + xdpi = sp_export_value_get (base, "xdpi"); + + sp_export_value_set (base, "ydpi", xdpi); + sp_export_value_set (base, "bmwidth", (x1 - x0) * xdpi / DPI_BASE); + + return; +} // end of sp_export_set_image_x() + /// 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; @@ -1527,6 +1715,41 @@ sp_export_bitmap_width_value_changed (GtkAdjustment *adj, GtkObject *base) return; } // end of sp_export_bitmap_width_value_changed() +/// Called when pixel height is changed +static void +sp_export_bitmap_height_value_changed (GtkAdjustment */*adj*/, GtkObject *base) +{ + float y0, y1, bmheight, xdpi; + + if (gtk_object_get_data (base, "update")) + return; + + if (sp_unit_selector_update_test ((SPUnitSelector *)gtk_object_get_data + (base, "units"))) { + return; + } + + gtk_object_set_data (base, "update", GUINT_TO_POINTER (TRUE)); + + y0 = sp_export_value_get_px (base, "y0"); + y1 = sp_export_value_get_px (base, "y1"); + bmheight = sp_export_value_get (base, "bmheight"); + + if (bmheight < SP_EXPORT_MIN_SIZE) { + bmheight = SP_EXPORT_MIN_SIZE; + sp_export_value_set (base, "bmheight", bmheight); + } + + xdpi = bmheight * DPI_BASE / (y1 - y0); + sp_export_value_set (base, "xdpi", xdpi); + + sp_export_set_image_x (base); + + gtk_object_set_data (base, "update", GUINT_TO_POINTER (FALSE)); + + return; +} // end of sp_export_bitmap_width_value_changed() + /** \brief A function to adjust the bitmap width when the xdpi value changes \param adj The adjustment that was changed @@ -1556,7 +1779,7 @@ sp_export_bitmap_width_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; @@ -1691,7 +1914,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