diff options
| author | Jabier Arraiza Cenoz <jabier.arraiza@marker.es> | 2014-04-01 17:00:00 +0000 |
|---|---|---|
| committer | Jabiertxof <jtx@jtx.marker.es> | 2014-04-01 17:00:00 +0000 |
| commit | 208ccdf9782984702f79b8ba416e67dd1e2c2dfa (patch) | |
| tree | 79d15123aa526c49c6386db6245fbfc6b7a63eaf /src/ui/dialog | |
| parent | update to trunk (diff) | |
| parent | partial 2geom update: (diff) | |
| download | inkscape-208ccdf9782984702f79b8ba416e67dd1e2c2dfa.tar.gz inkscape-208ccdf9782984702f79b8ba416e67dd1e2c2dfa.zip | |
update to trunk
(bzr r12588.1.32)
Diffstat (limited to 'src/ui/dialog')
44 files changed, 3630 insertions, 2698 deletions
diff --git a/src/ui/dialog/Makefile_insert b/src/ui/dialog/Makefile_insert index c37767a08..daa8aea22 100644 --- a/src/ui/dialog/Makefile_insert +++ b/src/ui/dialog/Makefile_insert @@ -5,6 +5,7 @@ ink_common_sources += \ ui/dialog/aboutbox.h \ ui/dialog/align-and-distribute.cpp \ ui/dialog/align-and-distribute.h \ + ui/dialog/arrange-tab.h \ ui/dialog/behavior.h \ ui/dialog/calligraphic-profile-rename.h \ ui/dialog/calligraphic-profile-rename.cpp \ @@ -50,6 +51,8 @@ ink_common_sources += \ ui/dialog/floating-behavior.h \ ui/dialog/glyphs.cpp \ ui/dialog/glyphs.h \ + ui/dialog/grid-arrange-tab.h \ + ui/dialog/grid-arrange-tab.cpp \ ui/dialog/guides.cpp \ ui/dialog/guides.h \ ui/dialog/icon-preview.cpp \ @@ -79,6 +82,8 @@ ink_common_sources += \ ui/dialog/object-properties.cpp \ ui/dialog/object-properties.h \ ui/dialog/panel-dialog.h \ + ui/dialog/polar-arrange-tab.cpp \ + ui/dialog/polar-arrange-tab.h \ ui/dialog/print.cpp \ ui/dialog/print.h \ ui/dialog/print-colors-preview-dialog.cpp \ diff --git a/src/ui/dialog/arrange-tab.h b/src/ui/dialog/arrange-tab.h new file mode 100644 index 000000000..3ffe1ef4c --- /dev/null +++ b/src/ui/dialog/arrange-tab.h @@ -0,0 +1,54 @@ +/** + * @brief Arrange tools base class + */ +/* Authors: + * * Declara Denis + * Copyright (C) 2012 Authors + * + * Released under GNU GPL. Read the file 'COPYING' for more information. + */ + +#ifndef INKSCAPE_UI_DIALOG_ARRANGE_TAB_H +#define INKSCAPE_UI_DIALOG_ARRANGE_TAB_H + +#include <gtkmm/box.h> + +namespace Inkscape { +namespace UI { +namespace Dialog { + +/** + * This interface should be implemented by each arrange mode. + * The class is a Gtk::VBox and will be displayed as a tab in + * the dialog + */ +class ArrangeTab : public Gtk::VBox +{ +public: + ArrangeTab() {}; + virtual ~ArrangeTab() {}; + + /** + * Do the actual work! This method is invoked to actually arrange the + * selection + */ + virtual void arrange() = 0; +}; + +} //namespace Dialog +} //namespace UI +} //namespace Inkscape + + +#endif /* INKSCAPE_UI_DIALOG_ARRANGE_TAB_H */ + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + 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:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/dialog/clonetiler.cpp b/src/ui/dialog/clonetiler.cpp index 87c399339..fb131d8da 100644 --- a/src/ui/dialog/clonetiler.cpp +++ b/src/ui/dialog/clonetiler.cpp @@ -2063,9 +2063,9 @@ guint32 CloneTiler::clonetiler_trace_pick(Geom::Rect box) /* Find visible area */ cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, ibox.width(), ibox.height()); - Inkscape::DrawingContext ct(s, ibox.min()); + Inkscape::DrawingContext dc(s, ibox.min()); /* Render */ - trace_drawing->render(ct, ibox); + trace_drawing->render(dc, ibox); double R = 0, G = 0, B = 0, A = 0; ink_cairo_surface_average_color(s, R, G, B, A); cairo_surface_destroy(s); diff --git a/src/ui/dialog/dialog-manager.cpp b/src/ui/dialog/dialog-manager.cpp index 6d32e3aa8..47e1fdd30 100644 --- a/src/ui/dialog/dialog-manager.cpp +++ b/src/ui/dialog/dialog-manager.cpp @@ -116,8 +116,8 @@ DialogManager::DialogManager() { // registerFactory("PrintColorsPreviewDialog", &create<PrintColorsPreviewDialog, FloatingBehavior>); registerFactory("SvgFontsDialog", &create<SvgFontsDialog, FloatingBehavior>); registerFactory("Swatches", &create<SwatchesPanel, FloatingBehavior>); + registerFactory("TileDialog", &create<ArrangeDialog, FloatingBehavior>); registerFactory("Symbols", &create<SymbolsDialog, FloatingBehavior>); - registerFactory("TileDialog", &create<TileDialog, FloatingBehavior>); registerFactory("Trace", &create<TraceDialog, FloatingBehavior>); registerFactory("PixelArt", &create<PixelArtDialog, FloatingBehavior>); registerFactory("Transformation", &create<Transformation, FloatingBehavior>); @@ -150,8 +150,8 @@ DialogManager::DialogManager() { // registerFactory("PrintColorsPreviewDialog", &create<PrintColorsPreviewDialog, DockBehavior>); registerFactory("SvgFontsDialog", &create<SvgFontsDialog, DockBehavior>); registerFactory("Swatches", &create<SwatchesPanel, DockBehavior>); + registerFactory("TileDialog", &create<ArrangeDialog, DockBehavior>); registerFactory("Symbols", &create<SymbolsDialog, DockBehavior>); - registerFactory("TileDialog", &create<TileDialog, DockBehavior>); registerFactory("Trace", &create<TraceDialog, DockBehavior>); registerFactory("PixelArt", &create<PixelArtDialog, DockBehavior>); registerFactory("Transformation", &create<Transformation, DockBehavior>); diff --git a/src/ui/dialog/dialog.cpp b/src/ui/dialog/dialog.cpp index 3cc3f3d88..645294bb5 100644 --- a/src/ui/dialog/dialog.cpp +++ b/src/ui/dialog/dialog.cpp @@ -26,11 +26,11 @@ #include "ui/tools/tool-base.h" #include "desktop.h" #include "desktop-handles.h" -#include "modifier-fns.h" #include "shortcuts.h" #include "preferences.h" #include "interface.h" #include "verbs.h" +#include "ui/tool/event-utils.h" #include <gtk/gtk.h> @@ -279,7 +279,7 @@ bool Dialog::_onEvent(GdkEvent *event) case GDK_KEY_F4: case GDK_KEY_w: case GDK_KEY_W: { - if (mod_ctrl_only(event->key.state)) { + if (Inkscape::UI::held_only_control(event->key)) { _close(); ret = true; } diff --git a/src/ui/dialog/document-metadata.cpp b/src/ui/dialog/document-metadata.cpp index efe25d843..09c505860 100644 --- a/src/ui/dialog/document-metadata.cpp +++ b/src/ui/dialog/document-metadata.cpp @@ -122,7 +122,7 @@ DocumentMetadata::build_metadata() _page_metadata1.show(); - Gtk::Label *label = manage (new Gtk::Label); + Gtk::Label *label = Gtk::manage (new Gtk::Label); label->set_markup (_("<b>Dublin Core Entities</b>")); label->set_alignment (0.0); @@ -140,7 +140,7 @@ DocumentMetadata::build_metadata() if ( entity->editable == RDF_EDIT_GENERIC ) { EntityEntry *w = EntityEntry::create (entity, _wr); _rdflist.push_back (w); - Gtk::HBox *space = manage (new Gtk::HBox); + Gtk::HBox *space = Gtk::manage (new Gtk::HBox); space->set_size_request (SPACE_SIZE_X, SPACE_SIZE_Y); #if WITH_GTKMM_3_0 @@ -164,7 +164,7 @@ DocumentMetadata::build_metadata() _page_metadata2.show(); row = 0; - Gtk::Label *llabel = manage (new Gtk::Label); + Gtk::Label *llabel = Gtk::manage (new Gtk::Label); llabel->set_markup (_("<b>License</b>")); llabel->set_alignment (0.0); @@ -178,7 +178,7 @@ DocumentMetadata::build_metadata() /* add license selector pull-down and URI */ ++row; _licensor.init (_wr); - Gtk::HBox *space = manage (new Gtk::HBox); + Gtk::HBox *space = Gtk::manage (new Gtk::HBox); space->set_size_request (SPACE_SIZE_X, SPACE_SIZE_Y); #if WITH_GTKMM_3_0 diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp index d324d2d1b..67e788e21 100644 --- a/src/ui/dialog/document-properties.cpp +++ b/src/ui/dialog/document-properties.cpp @@ -35,6 +35,7 @@ #include "sp-namedview.h" #include "sp-root.h" #include "sp-script.h" +#include "style.h" #include "svg/stringstream.h" #include "tools-switch.h" #include "ui/widget/color-picker.h" @@ -106,6 +107,7 @@ DocumentProperties::DocumentProperties() _page_metadata1(Gtk::manage(new UI::Widget::NotebookPage(1, 1))), _page_metadata2(Gtk::manage(new UI::Widget::NotebookPage(1, 1))), //--------------------------------------------------------------- + _rcb_antialias(_("Use antialiasing"), _("If unset, no antialiasing will be done on the drawing"), "shape-rendering", _wr, false, NULL, NULL, NULL, "crispEdges"), _rcb_canb(_("Show page _border"), _("If set, rectangular page border is shown"), "showborder", _wr, false), _rcb_bord(_("Border on _top of drawing"), _("If set, border is always on top of the drawing"), "borderlayer", _wr, false), _rcb_shad(_("_Show border shadow"), _("If set, page border shows a shadow on its right and lower side"), "inkscape:showpageshadow", _wr, false), @@ -239,7 +241,8 @@ inline void attach_all(Gtk::Table &table, Gtk::Widget *const arr[], unsigned con yoptions = Gtk::FILL|Gtk::EXPAND; } if (docum_prop_flag) { - if( i==(n-4) || i==(n-6) ) { + // this sets the padding for subordinate widgets on the "Page" page + if( i==(n-8) || i==(n-10) ) { #if WITH_GTKMM_3_0 arr[i+1]->set_hexpand(); arr[i+1]->set_margin_left(20); @@ -294,7 +297,7 @@ inline void attach_all(Gtk::Table &table, Gtk::Widget *const arr[], unsigned con table.attach (label, 0, 3, r, r+1, Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0,0,0); #endif } else { - Gtk::HBox *space = manage (new Gtk::HBox); + Gtk::HBox *space = Gtk::manage (new Gtk::HBox); space->set_size_request (SPACE_SIZE_X, SPACE_SIZE_Y); #if WITH_GTKMM_3_0 @@ -314,30 +317,30 @@ void DocumentProperties::build_page() { _page_page->show(); - Gtk::Label* label_gen = manage (new Gtk::Label); + Gtk::Label* label_gen = Gtk::manage (new Gtk::Label); label_gen->set_markup (_("<b>General</b>")); - Gtk::Label* label_col = manage (new Gtk::Label); - label_col->set_markup (_("<b>Color</b>")); - Gtk::Label* label_bor = manage (new Gtk::Label); - label_bor->set_markup (_("<b>Border</b>")); - Gtk::Label *label_for = manage (new Gtk::Label); + Gtk::Label *label_for = Gtk::manage (new Gtk::Label); label_for->set_markup (_("<b>Page Size</b>")); + Gtk::Label* label_dsp = Gtk::manage (new Gtk::Label); + label_dsp->set_markup (_("<b>Display</b>")); _page_sizer.init(); Gtk::Widget *const widget_array[] = { label_gen, 0, 0, &_rum_deflt, - label_col, 0, - _rcp_bg._label, &_rcp_bg, + //label_col, 0, + //_rcp_bg._label, &_rcp_bg, 0, 0, label_for, 0, 0, &_page_sizer, 0, 0, - label_bor, 0, + label_dsp, 0, 0, &_rcb_canb, 0, &_rcb_bord, 0, &_rcb_shad, + 0, &_rcb_antialias, + _rcp_bg._label, &_rcp_bg, _rcp_bord._label, &_rcp_bord, }; @@ -353,7 +356,7 @@ void DocumentProperties::build_guides() { _page_guides->show(); - Gtk::Label *label_gui = manage (new Gtk::Label); + Gtk::Label *label_gui = Gtk::manage (new Gtk::Label); label_gui->set_markup (_("<b>Guides</b>")); Gtk::Widget *const widget_array[] = @@ -371,13 +374,13 @@ void DocumentProperties::build_snap() { _page_snap->show(); - Gtk::Label *label_o = manage (new Gtk::Label); + Gtk::Label *label_o = Gtk::manage (new Gtk::Label); label_o->set_markup (_("<b>Snap to objects</b>")); - Gtk::Label *label_gr = manage (new Gtk::Label); + Gtk::Label *label_gr = Gtk::manage (new Gtk::Label); label_gr->set_markup (_("<b>Snap to grids</b>")); - Gtk::Label *label_gu = manage (new Gtk::Label); + Gtk::Label *label_gu = Gtk::manage (new Gtk::Label); label_gu->set_markup (_("<b>Snap to guides</b>")); - Gtk::Label *label_m = manage (new Gtk::Label); + Gtk::Label *label_m = Gtk::manage (new Gtk::Label); label_m->set_markup (_("<b>Miscellaneous</b>")); Gtk::Widget *const array[] = @@ -604,13 +607,13 @@ void DocumentProperties::removeSelectedProfile(){ void DocumentProperties::build_cms() { _page_cms->show(); - Gtk::Label *label_link= manage (new Gtk::Label("", Gtk::ALIGN_START)); + Gtk::Label *label_link= Gtk::manage (new Gtk::Label("", Gtk::ALIGN_START)); label_link->set_markup (_("<b>Linked Color Profiles:</b>")); - Gtk::Label *label_avail = manage (new Gtk::Label("", Gtk::ALIGN_START)); + Gtk::Label *label_avail = Gtk::manage (new Gtk::Label("", Gtk::ALIGN_START)); label_avail->set_markup (_("<b>Available Color Profiles:</b>")); _link_btn.set_tooltip_text(_("Link Profile")); -#if GTK_CHECK_VERSION(3,10,0) +#if WITH_GTKMM_3_10 _link_btn.set_image_from_icon_name(INKSCAPE_ICON("list-add"), Gtk::ICON_SIZE_SMALL_TOOLBAR); #else Gtk::Image *image_link = Gtk::manage(new Gtk::Image()); @@ -619,7 +622,7 @@ void DocumentProperties::build_cms() #endif _unlink_btn.set_tooltip_text(_("Unlink Profile")); -#if GTK_CHECK_VERSION(3,10,0) +#if WITH_GTKMM_3_10 _unlink_btn.set_image_from_icon_name(INKSCAPE_ICON("list-remove"), Gtk::ICON_SIZE_SMALL_TOOLBAR); #else Gtk::Image *image_unlink = Gtk::manage(new Gtk::Image()); @@ -743,11 +746,11 @@ void DocumentProperties::build_scripting() //# External scripts tab _page_external_scripts->show(); - Gtk::Label *label_external= manage (new Gtk::Label("", Gtk::ALIGN_START)); + Gtk::Label *label_external= Gtk::manage (new Gtk::Label("", Gtk::ALIGN_START)); label_external->set_markup (_("<b>External script files:</b>")); _external_add_btn.set_tooltip_text(_("Add the current file name or browse for a file")); -#if GTK_CHECK_VERSION(3,10,0) +#if WITH_GTKMM_3_10 _external_add_btn.set_image_from_icon_name(INKSCAPE_ICON("list-add"), Gtk::ICON_SIZE_SMALL_TOOLBAR); #else Gtk::Image *image_ext_add = Gtk::manage(new Gtk::Image()); @@ -756,7 +759,7 @@ void DocumentProperties::build_scripting() #endif _external_remove_btn.set_tooltip_text(_("Remove")); -#if GTK_CHECK_VERSION(3,10,0) +#if WITH_GTKMM_3_10 _external_remove_btn.set_image_from_icon_name(INKSCAPE_ICON("list-remove"), Gtk::ICON_SIZE_SMALL_TOOLBAR); #else Gtk::Image *image_ext_rm = Gtk::manage(new Gtk::Image()); @@ -832,11 +835,11 @@ void DocumentProperties::build_scripting() //# Embedded scripts tab _page_embedded_scripts->show(); - Gtk::Label *label_embedded= manage (new Gtk::Label("", Gtk::ALIGN_START)); + Gtk::Label *label_embedded= Gtk::manage (new Gtk::Label("", Gtk::ALIGN_START)); label_embedded->set_markup (_("<b>Embedded script files:</b>")); _embed_new_btn.set_tooltip_text(_("New")); -#if GTK_CHECK_VERSION(3,10,0) +#if WITH_GTKMM_3_10 _embed_new_btn.set_image_from_icon_name(INKSCAPE_ICON("list-add"), Gtk::ICON_SIZE_SMALL_TOOLBAR); #else Gtk::Image *image_embed_new = Gtk::manage(new Gtk::Image()); @@ -845,7 +848,7 @@ void DocumentProperties::build_scripting() #endif _embed_remove_btn.set_tooltip_text(_("Remove")); -#if GTK_CHECK_VERSION(3,10,0) +#if WITH_GTKMM_3_10 _embed_remove_btn.set_image_from_icon_name(INKSCAPE_ICON("list-remove"), Gtk::ICON_SIZE_SMALL_TOOLBAR); #else Gtk::Image *image_embed_rm = Gtk::manage(new Gtk::Image()); @@ -919,7 +922,7 @@ void DocumentProperties::build_scripting() // TODO restore? _EmbeddedScriptsList.set_fixed_height_mode(true); //# Set up the Embedded Scripts content box - Gtk::Label *label_embedded_content= manage (new Gtk::Label("", Gtk::ALIGN_START)); + Gtk::Label *label_embedded_content= Gtk::manage (new Gtk::Label("", Gtk::ALIGN_START)); label_embedded_content->set_markup (_("<b>Content:</b>")); label_embedded_content->set_alignment(0.0); @@ -998,7 +1001,7 @@ void DocumentProperties::build_metadata() _page_metadata1->show(); - Gtk::Label *label = manage (new Gtk::Label); + Gtk::Label *label = Gtk::manage (new Gtk::Label); label->set_markup (_("<b>Dublin Core Entities</b>")); label->set_alignment (0.0); @@ -1016,7 +1019,7 @@ void DocumentProperties::build_metadata() if ( entity->editable == RDF_EDIT_GENERIC ) { EntityEntry *w = EntityEntry::create (entity, _wr); _rdflist.push_back (w); - Gtk::HBox *space = manage (new Gtk::HBox); + Gtk::HBox *space = Gtk::manage (new Gtk::HBox); space->set_size_request (SPACE_SIZE_X, SPACE_SIZE_Y); #if WITH_GTKMM_3_0 @@ -1037,15 +1040,15 @@ void DocumentProperties::build_metadata() } } - Gtk::Button *button_save = manage (new Gtk::Button(_("_Save as default"),1)); + Gtk::Button *button_save = Gtk::manage (new Gtk::Button(_("_Save as default"),1)); button_save->set_tooltip_text(_("Save this metadata as the default metadata")); - Gtk::Button *button_load = manage (new Gtk::Button(_("Use _default"),1)); + Gtk::Button *button_load = Gtk::manage (new Gtk::Button(_("Use _default"),1)); button_load->set_tooltip_text(_("Use the previously saved default metadata here")); #if WITH_GTKMM_3_0 - Gtk::ButtonBox *box_buttons = manage (new Gtk::ButtonBox); + Gtk::ButtonBox *box_buttons = Gtk::manage (new Gtk::ButtonBox); #else - Gtk::HButtonBox *box_buttons = manage (new Gtk::HButtonBox); + Gtk::HButtonBox *box_buttons = Gtk::manage (new Gtk::HButtonBox); #endif box_buttons->set_layout(Gtk::BUTTONBOX_END); @@ -1060,7 +1063,7 @@ void DocumentProperties::build_metadata() _page_metadata2->show(); row = 0; - Gtk::Label *llabel = manage (new Gtk::Label); + Gtk::Label *llabel = Gtk::manage (new Gtk::Label); llabel->set_markup (_("<b>License</b>")); llabel->set_alignment (0.0); @@ -1074,7 +1077,7 @@ void DocumentProperties::build_metadata() /* add license selector pull-down and URI */ ++row; _licensor.init (_wr); - Gtk::HBox *space = manage (new Gtk::HBox); + Gtk::HBox *space = Gtk::manage (new Gtk::HBox); space->set_size_request (SPACE_SIZE_X, SPACE_SIZE_Y); #if WITH_GTKMM_3_0 @@ -1473,6 +1476,10 @@ void DocumentProperties::update() _rcp_bord.setRgba32 (nv->bordercolor); _rcb_shad.setActive (nv->showpageshadow); + SPRoot *root = dt->getDocument()->getRoot(); + _rcb_antialias.set_xml_target(root->getRepr(), dt->getDocument()); + _rcb_antialias.setActive(root->style->shape_rendering.computed != SP_CSS_SHAPE_RENDERING_CRISPEDGES); + if (nv->doc_units) { _rum_deflt.setUnit (nv->doc_units->abbr); } @@ -1538,12 +1545,12 @@ void DocumentProperties::update() Gtk::HBox& DocumentProperties::_createPageTabLabel(const Glib::ustring& label, const char *label_image) { - Gtk::HBox *_tab_label_box = manage(new Gtk::HBox(false, 0)); + Gtk::HBox *_tab_label_box = Gtk::manage(new Gtk::HBox(false, 0)); _tab_label_box->set_spacing(4); _tab_label_box->pack_start(*Glib::wrap(sp_icon_new(Inkscape::ICON_SIZE_DECORATION, label_image))); - Gtk::Label *_tab_label = manage(new Gtk::Label(label, true)); + Gtk::Label *_tab_label = Gtk::manage(new Gtk::Label(label, true)); _tab_label_box->pack_start(*_tab_label); _tab_label_box->show_all(); @@ -1703,9 +1710,14 @@ void DocumentProperties::onDocUnitChange() repr->setAttribute("inkscape:document-units", os.str().c_str()); // Set viewBox - Inkscape::Util::Quantity width = doc->getWidth(); - Inkscape::Util::Quantity height = doc->getHeight(); - doc->setViewBox(Geom::Rect::from_xywh(0, 0, width.value(doc_unit), height.value(doc_unit))); + if (doc->getRoot()->viewBox_set) { + gdouble scale = Inkscape::Util::Quantity::convert(1, old_doc_unit, doc_unit); + doc->setViewBox(doc->getRoot()->viewBox*Geom::Scale(scale)); + } else { + Inkscape::Util::Quantity width = doc->getWidth(); + Inkscape::Util::Quantity height = doc->getHeight(); + doc->setViewBox(Geom::Rect::from_xywh(0, 0, width.value(doc_unit), height.value(doc_unit))); + } // TODO: Fix bug in nodes tool instead of switching away from it if (tools_active(getDesktop()) == TOOLS_NODES) { @@ -1729,8 +1741,14 @@ void DocumentProperties::onDocUnitChange() prefs->setBool("/options/transform/gradient", true); { ShapeEditor::blockSetItem(true); + gdouble viewscale = doc->getWidth().value("px")/doc->getRoot()->viewBox.width(); + if (doc->getHeight().value("px")/doc->getRoot()->viewBox.height() < viewscale) + viewscale = doc->getHeight().value("px")/doc->getRoot()->viewBox.height(); gdouble scale = Inkscape::Util::Quantity::convert(1, old_doc_unit, doc_unit); - doc->getRoot()->scaleChildItemsRec(Geom::Scale(scale), Geom::Point(0, doc->getHeight().value("px"))); + doc->getRoot()->scaleChildItemsRec(Geom::Scale(scale), Geom::Point(-viewscale*doc->getRoot()->viewBox.min()[Geom::X] + + (doc->getWidth().value("px") - viewscale*doc->getRoot()->viewBox.width())/2, + viewscale*doc->getRoot()->viewBox.min()[Geom::Y] + + (doc->getHeight().value("px") + viewscale*doc->getRoot()->viewBox.height())/2)); ShapeEditor::blockSetItem(false); } prefs->setBool("/options/transform/stroke", transform_stroke); diff --git a/src/ui/dialog/document-properties.h b/src/ui/dialog/document-properties.h index e3ca91731..495f3177d 100644 --- a/src/ui/dialog/document-properties.h +++ b/src/ui/dialog/document-properties.h @@ -117,6 +117,7 @@ protected: UI::Widget::Registry _wr; //--------------------------------------------------------------- + UI::Widget::RegisteredCheckButton _rcb_antialias; UI::Widget::RegisteredCheckButton _rcb_canb; UI::Widget::RegisteredCheckButton _rcb_bord; UI::Widget::RegisteredCheckButton _rcb_shad; diff --git a/src/ui/dialog/export.cpp b/src/ui/dialog/export.cpp index 340a3dad0..913713e5c 100644 --- a/src/ui/dialog/export.cpp +++ b/src/ui/dialog/export.cpp @@ -144,11 +144,13 @@ namespace Dialog { /** A list of strings that is used both in the preferences, and in the data fields to describe the various values of \c selection_type. */ static const char * selection_names[SELECTION_NUMBER_OF] = { - "page", "drawing", "selection", "custom"}; + "page", "drawing", "selection", "custom" +}; /** The names on the buttons for the various selection types. */ static const char * selection_labels[SELECTION_NUMBER_OF] = { - N_("_Page"), N_("_Drawing"), N_("_Selection"), N_("_Custom")}; + N_("_Page"), N_("_Drawing"), N_("_Selection"), N_("_Custom") +}; Export::Export (void) : UI::Widget::Panel ("", "/dialogs/export/", SP_VERB_DIALOG_EXPORT), @@ -201,7 +203,7 @@ Export::Export (void) : /* gets added to the vbox later, but the unit selector is needed earlier than that */ unit_selector.setUnitType(Inkscape::Util::UNIT_TYPE_LINEAR); - + SPDesktop *desktop = SP_ACTIVE_DESKTOP; if (desktop) { unit_selector.setUnit(sp_desktop_namedview(desktop)->doc_units->abbr); @@ -232,28 +234,28 @@ Export::Export (void) : #endif x0_adj = createSpinbutton ( "x0", 0.0, -1000000.0, 1000000.0, 0.1, 1.0, - t, 0, 0, _("_x0:"), "", EXPORT_COORD_PRECISION, 1, - &Export::onAreaX0Change); + t, 0, 0, _("_x0:"), "", EXPORT_COORD_PRECISION, 1, + &Export::onAreaX0Change); x1_adj = createSpinbutton ( "x1", 0.0, -1000000.0, 1000000.0, 0.1, 1.0, - t, 0, 1, _("x_1:"), "", EXPORT_COORD_PRECISION, 1, - &Export::onAreaX1Change); + t, 0, 1, _("x_1:"), "", EXPORT_COORD_PRECISION, 1, + &Export::onAreaX1Change); width_adj = createSpinbutton ( "width", 0.0, 0.0, PNG_UINT_31_MAX, 0.1, 1.0, - t, 0, 2, _("Wid_th:"), "", EXPORT_COORD_PRECISION, 1, - &Export::onAreaWidthChange); + t, 0, 2, _("Wid_th:"), "", EXPORT_COORD_PRECISION, 1, + &Export::onAreaWidthChange); y0_adj = createSpinbutton ( "y0", 0.0, -1000000.0, 1000000.0, 0.1, 1.0, - t, 2, 0, _("_y0:"), "", EXPORT_COORD_PRECISION, 1, - &Export::onAreaY0Change); + t, 2, 0, _("_y0:"), "", EXPORT_COORD_PRECISION, 1, + &Export::onAreaY0Change); y1_adj = createSpinbutton ( "y1", 0.0, -1000000.0, 1000000.0, 0.1, 1.0, - t, 2, 1, _("y_1:"), "", EXPORT_COORD_PRECISION, 1, - &Export::onAreaY1Change); + t, 2, 1, _("y_1:"), "", EXPORT_COORD_PRECISION, 1, + &Export::onAreaY1Change); height_adj = createSpinbutton ( "height", 0.0, 0.0, PNG_UINT_31_MAX, 0.1, 1.0, - t, 2, 2, _("Hei_ght:"), "", EXPORT_COORD_PRECISION, 1, - &Export::onAreaHeightChange); + t, 2, 2, _("Hei_ght:"), "", EXPORT_COORD_PRECISION, 1, + &Export::onAreaHeightChange); area_box.pack_start(togglebox, false, false, 3); area_box.pack_start(*t, false, false, 0); @@ -284,27 +286,27 @@ Export::Export (void) : size_box.pack_start(*t); bmwidth_adj = createSpinbutton ( "bmwidth", 16.0, 1.0, 1000000.0, 1.0, 10.0, - t, 0, 0, - _("_Width:"), _("pixels at"), 0, 1, - &Export::onBitmapWidthChange); + t, 0, 0, + _("_Width:"), _("pixels at"), 0, 1, + &Export::onBitmapWidthChange); xdpi_adj = createSpinbutton ( "xdpi", - prefs->getDouble("/dialogs/export/defaultxdpi/value", DPI_BASE), - 0.01, 100000.0, 0.1, 1.0, t, 3, 0, - "", _("dp_i"), 2, 1, - &Export::onExportXdpiChange); + prefs->getDouble("/dialogs/export/defaultxdpi/value", DPI_BASE), + 0.01, 100000.0, 0.1, 1.0, t, 3, 0, + "", _("dp_i"), 2, 1, + &Export::onExportXdpiChange); bmheight_adj = createSpinbutton ( "bmheight", 16.0, 1.0, 1000000.0, 1.0, 10.0, - t, 0, 1, - _("_Height:"), _("pixels at"), 0, 1, - &Export::onBitmapHeightChange); + t, 0, 1, + _("_Height:"), _("pixels at"), 0, 1, + &Export::onBitmapHeightChange); /** TODO * There's no way to set ydpi currently, so we use the defaultxdpi value here, too... */ ydpi_adj = createSpinbutton ( "ydpi", prefs->getDouble("/dialogs/export/defaultxdpi/value", DPI_BASE), - 0.01, 100000.0, 0.1, 1.0, t, 3, 1, - "", _("dpi"), 2, 0, NULL ); + 0.01, 100000.0, 0.1, 1.0, t, 3, 1, + "", _("dpi"), 2, 0, NULL ); singleexport_box.pack_start(size_box); } @@ -482,18 +484,18 @@ void Export::set_default_filename () { #if WITH_GTKMM_3_0 Glib::RefPtr<Gtk::Adjustment> Export::createSpinbutton( gchar const * /*key*/, float val, float min, float max, - float step, float page, - Gtk::Grid *t, int x, int y, - const Glib::ustring ll, const Glib::ustring lr, - int digits, unsigned int sensitive, - void (Export::*cb)() ) + float step, float page, + Gtk::Grid *t, int x, int y, + const Glib::ustring& ll, const Glib::ustring& lr, + int digits, unsigned int sensitive, + void (Export::*cb)() ) #else Gtk::Adjustment * Export::createSpinbutton( gchar const * /*key*/, float val, float min, float max, - float step, float page, - Gtk::Table *t, int x, int y, - const Glib::ustring ll, const Glib::ustring lr, - int digits, unsigned int sensitive, - void (Export::*cb)() ) + float step, float page, + Gtk::Table *t, int x, int y, + const Glib::ustring& ll, const Glib::ustring& lr, + int digits, unsigned int sensitive, + void (Export::*cb)() ) #endif { #if WITH_GTKMM_3_0 @@ -535,7 +537,9 @@ Gtk::Adjustment * Export::createSpinbutton( gchar const * /*key*/, float val, fl sb->set_sensitive (sensitive); pos++; - if (!ll.empty()) { l->set_mnemonic_widget(*sb);} + if (!ll.empty()) { + l->set_mnemonic_widget(*sb); + } if (!lr.empty()) { l = new Gtk::Label(lr,true); @@ -565,7 +569,7 @@ Gtk::Adjustment * Export::createSpinbutton( gchar const * /*key*/, float val, fl Glib::ustring Export::create_filepath_from_id (Glib::ustring id, const Glib::ustring &file_entry_text) { if (id.empty()) - { /* This should never happen */ + { /* This should never happen */ id = "bitmap"; } @@ -678,35 +682,35 @@ void Export::onSelectionModified ( guint /*flags*/ ) { Inkscape::Selection * Sel; switch (current_key) { - case SELECTION_DRAWING: - if ( SP_ACTIVE_DESKTOP ) { - SPDocument *doc; - doc = sp_desktop_document (SP_ACTIVE_DESKTOP); - Geom::OptRect bbox = doc->getRoot()->desktopVisualBounds(); - if (bbox) { - setArea ( bbox->left(), - bbox->top(), - bbox->right(), - bbox->bottom()); - } + case SELECTION_DRAWING: + if ( SP_ACTIVE_DESKTOP ) { + SPDocument *doc; + doc = sp_desktop_document (SP_ACTIVE_DESKTOP); + Geom::OptRect bbox = doc->getRoot()->desktopVisualBounds(); + if (bbox) { + setArea ( bbox->left(), + bbox->top(), + bbox->right(), + bbox->bottom()); } - break; - case SELECTION_SELECTION: - Sel = sp_desktop_selection(SP_ACTIVE_DESKTOP); - if (Sel->isEmpty() == false) { - Geom::OptRect bbox = Sel->visualBounds(); - if (bbox) - { - setArea ( bbox->left(), - bbox->top(), - bbox->right(), - bbox->bottom()); - } + } + break; + case SELECTION_SELECTION: + Sel = sp_desktop_selection(SP_ACTIVE_DESKTOP); + if (Sel->isEmpty() == false) { + Geom::OptRect bbox = Sel->visualBounds(); + if (bbox) + { + setArea ( bbox->left(), + bbox->top(), + bbox->right(), + bbox->bottom()); } - break; - default: - /* Do nothing for page or for custom */ - break; + } + break; + default: + /* Do nothing for page or for custom */ + break; } return; @@ -738,39 +742,39 @@ void Export::onAreaToggled () various backups. If you modify this without noticing you'll probabaly screw something up. */ switch (key) { - case SELECTION_SELECTION: - if ((sp_desktop_selection(SP_ACTIVE_DESKTOP))->isEmpty() == false) - { - bbox = sp_desktop_selection (SP_ACTIVE_DESKTOP)->visualBounds(); - /* Only if there is a selection that we can set - do we break, otherwise we fall through to the - drawing */ - // std::cout << "Using selection: SELECTION" << std::endl; - key = SELECTION_SELECTION; - break; - } - case SELECTION_DRAWING: - /** \todo - * This returns wrong values if the document has a viewBox. - */ - bbox = doc->getRoot()->desktopVisualBounds(); - /* If the drawing is valid, then we'll use it and break - otherwise we drop through to the page settings */ - if (bbox) { - // std::cout << "Using selection: DRAWING" << std::endl; - key = SELECTION_DRAWING; - break; - } - case SELECTION_PAGE: - bbox = Geom::Rect(Geom::Point(0.0, 0.0), - Geom::Point(doc->getWidth().value("px"), doc->getHeight().value("px"))); - - // std::cout << "Using selection: PAGE" << std::endl; - key = SELECTION_PAGE; + case SELECTION_SELECTION: + if ((sp_desktop_selection(SP_ACTIVE_DESKTOP))->isEmpty() == false) + { + bbox = sp_desktop_selection (SP_ACTIVE_DESKTOP)->visualBounds(); + /* Only if there is a selection that we can set + do we break, otherwise we fall through to the + drawing */ + // std::cout << "Using selection: SELECTION" << std::endl; + key = SELECTION_SELECTION; break; - case SELECTION_CUSTOM: - default: + } + case SELECTION_DRAWING: + /** \todo + * This returns wrong values if the document has a viewBox. + */ + bbox = doc->getRoot()->desktopVisualBounds(); + /* If the drawing is valid, then we'll use it and break + otherwise we drop through to the page settings */ + if (bbox) { + // std::cout << "Using selection: DRAWING" << std::endl; + key = SELECTION_DRAWING; break; + } + case SELECTION_PAGE: + bbox = Geom::Rect(Geom::Point(0.0, 0.0), + Geom::Point(doc->getWidth().value("px"), doc->getHeight().value("px"))); + + // std::cout << "Using selection: PAGE" << std::endl; + key = SELECTION_PAGE; + break; + case SELECTION_CUSTOM: + default: + break; } // switch current_key = key; @@ -780,9 +784,9 @@ void Export::onAreaToggled () if ( key != SELECTION_CUSTOM && bbox ) { setArea ( bbox->min()[Geom::X], - bbox->min()[Geom::Y], - bbox->max()[Geom::X], - bbox->max()[Geom::Y]); + bbox->min()[Geom::Y], + bbox->max()[Geom::X], + bbox->max()[Geom::Y]); } } // end of if ( SP_ACTIVE_DESKTOP ) @@ -793,43 +797,43 @@ void Export::onAreaToggled () float xdpi = 0.0, ydpi = 0.0; switch (key) { - case SELECTION_PAGE: - case SELECTION_DRAWING: { - SPDocument * doc = SP_ACTIVE_DOCUMENT; - sp_document_get_export_hints (doc, filename, &xdpi, &ydpi); - - if (filename.empty()) { - if (!doc_export_name.empty()) { - filename = doc_export_name; - } + case SELECTION_PAGE: + case SELECTION_DRAWING: { + SPDocument * doc = SP_ACTIVE_DOCUMENT; + sp_document_get_export_hints (doc, filename, &xdpi, &ydpi); + + if (filename.empty()) { + if (!doc_export_name.empty()) { + filename = doc_export_name; } - break; } - case SELECTION_SELECTION: - if ((sp_desktop_selection(SP_ACTIVE_DESKTOP))->isEmpty() == 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.empty()) { - const gchar * id = "object"; - 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")) { - id = repr->attribute("id"); - break; - } - } + break; + } + case SELECTION_SELECTION: + if ((sp_desktop_selection(SP_ACTIVE_DESKTOP))->isEmpty() == false) { - filename = create_filepath_from_id (id, filename_entry.get_text()); + 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.empty()) { + const gchar * id = "object"; + 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")) { + id = repr->attribute("id"); + break; + } } + + filename = create_filepath_from_id (id, filename_entry.get_text()); } - break; - case SELECTION_CUSTOM: - default: - break; + } + break; + case SELECTION_CUSTOM: + default: + break; } if (!filename.empty()) { @@ -895,8 +899,8 @@ unsigned int Export::onProgressCallback(float value, void *dlg) int evtcount = 0; while ((evtcount < 16) && gdk_events_pending()) { - gtk_main_iteration_do(FALSE); - evtcount += 1; + gtk_main_iteration_do(FALSE); + evtcount += 1; } gtk_main_iteration_do(FALSE); @@ -960,7 +964,7 @@ Glib::ustring Export::filename_add_extension (Glib::ustring filename, Glib::ustr } else { - return filename = filename + "." + extension; + return filename = filename + "." + extension; } } } @@ -1045,7 +1049,7 @@ void Export::onExport () dpi = atof(dpi_hint); } if (dpi == 0.0) { - dpi = DPI_BASE; + dpi = getValue(xdpi_adj); } Geom::OptRect area = item->desktopVisualBounds(); @@ -1057,9 +1061,9 @@ void Export::onExport () // Do export gchar * safeFile = Inkscape::IO::sanitizeString(path.c_str()); MessageCleaner msgCleanup(desktop->messageStack()->pushF(Inkscape::IMMEDIATE_MESSAGE, - _("Exporting file <b>%s</b>..."), safeFile), desktop); + _("Exporting file <b>%s</b>..."), safeFile), desktop); MessageCleaner msgFlashCleanup(desktop->messageStack()->flashF(Inkscape::IMMEDIATE_MESSAGE, - _("Exporting file <b>%s</b>..."), safeFile), desktop); + _("Exporting file <b>%s</b>..."), safeFile), desktop); if (!sp_export_png_file (doc, path.c_str(), *area, width, height, dpi, dpi, @@ -1067,7 +1071,7 @@ void Export::onExport () onProgressCallback, (void*)prog_dlg, TRUE, // overwrite without asking hide ? const_cast<GSList *>(sp_desktop_selection(desktop)->itemList()) : NULL - )) { + )) { gchar * error = g_strdup_printf(_("Could not export to filename %s.\n"), safeFile); desktop->messageStack()->flashF(Inkscape::ERROR_MESSAGE, @@ -1096,7 +1100,7 @@ void Export::onExport () } else { Glib::ustring filename = filename_entry.get_text(); - if (filename.empty()){ + if (filename.empty()) { desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("You have to enter a filename.")); sp_ui_error_dialog(_("You have to enter a filename")); return; @@ -1125,7 +1129,7 @@ void Export::onExport () Glib::ustring dirname = Glib::path_get_dirname(path); if ( dirname.empty() - || !Inkscape::IO::file_test(dirname.c_str(), (GFileTest)(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) ) + || !Inkscape::IO::file_test(dirname.c_str(), (GFileTest)(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) ) { gchar *safeDir = Inkscape::IO::sanitizeString(dirname.c_str()); gchar *error = g_strdup_printf(_("Directory %s does not exist or is not a directory.\n"), @@ -1151,12 +1155,12 @@ void Export::onExport () /* Do export */ ExportResult status = sp_export_png_file(sp_desktop_document(desktop), path.c_str(), - Geom::Rect(Geom::Point(x0, y0), Geom::Point(x1, y1)), width, height, xdpi, ydpi, - nv->pagecolor, - onProgressCallback, (void*)prog_dlg, - FALSE, - hide ? const_cast<GSList *>(sp_desktop_selection(desktop)->itemList()) : NULL - ); + Geom::Rect(Geom::Point(x0, y0), Geom::Point(x1, y1)), width, height, xdpi, ydpi, + nv->pagecolor, + onProgressCallback, (void*)prog_dlg, + FALSE, + hide ? const_cast<GSList *>(sp_desktop_selection(desktop)->itemList()) : NULL + ); if (status == EXPORT_ERROR) { gchar * safeFile = Inkscape::IO::sanitizeString(path.c_str()); gchar * error = g_strdup_printf(_("Could not export to filename %s.\n"), safeFile); @@ -1189,19 +1193,65 @@ void Export::onExport () /* Setup the values in the document */ switch (current_key) { - case SELECTION_PAGE: - case SELECTION_DRAWING: { - SPDocument * doc = SP_ACTIVE_DOCUMENT; - Inkscape::XML::Node * repr = doc->getReprRoot(); - bool modified = false; - - bool saved = DocumentUndo::getUndoSensitive(doc); - DocumentUndo::setUndoSensitive(doc, false); - - gchar const *temp_string = repr->attribute("inkscape:export-filename"); - if (temp_string == NULL || (filename_ext != temp_string)) { - repr->setAttribute("inkscape:export-filename", filename_ext.c_str()); - modified = true; + case SELECTION_PAGE: + case SELECTION_DRAWING: { + SPDocument * doc = SP_ACTIVE_DOCUMENT; + Inkscape::XML::Node * repr = doc->getReprRoot(); + bool modified = false; + + bool saved = DocumentUndo::getUndoSensitive(doc); + DocumentUndo::setUndoSensitive(doc, false); + + gchar const *temp_string = repr->attribute("inkscape:export-filename"); + if (temp_string == NULL || (filename_ext != temp_string)) { + repr->setAttribute("inkscape:export-filename", filename_ext.c_str()); + 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; + } + temp_string = repr->attribute("inkscape:export-ydpi"); + if (temp_string == NULL || ydpi != atof(temp_string)) { + sp_repr_set_svg_double(repr, "inkscape:export-ydpi", ydpi); + modified = true; + } + DocumentUndo::setUndoSensitive(doc, saved); + + if (modified) { + doc->setModifiedSinceSave(); + } + break; + } + case SELECTION_SELECTION: { + const GSList * reprlst; + SPDocument * doc = SP_ACTIVE_DOCUMENT; + bool modified = false; + + bool saved = DocumentUndo::getUndoSensitive(doc); + DocumentUndo::setUndoSensitive(doc, false); + reprlst = sp_desktop_selection(desktop)->reprList(); + + for(; reprlst != NULL; reprlst = reprlst->next) { + Inkscape::XML::Node * repr = static_cast<Inkscape::XML::Node *>(reprlst->data); + const gchar * temp_string; + Glib::ustring dir = Glib::path_get_dirname(filename.c_str()); + const gchar* docURI=SP_ACTIVE_DOCUMENT->getURI(); + Glib::ustring docdir; + if (docURI) + { + docdir = Glib::path_get_dirname(docURI); + } + if (repr->attribute("id") == NULL || + !(filename_ext.find_last_of(repr->attribute("id")) && + ( !docURI || + (dir == docdir)))) { + temp_string = repr->attribute("inkscape:export-filename"); + if (temp_string == NULL || (filename_ext != temp_string)) { + repr->setAttribute("inkscape:export-filename", filename_ext.c_str()); + modified = true; + } } temp_string = repr->attribute("inkscape:export-xdpi"); if (temp_string == NULL || xdpi != atof(temp_string)) { @@ -1213,62 +1263,16 @@ void Export::onExport () sp_repr_set_svg_double(repr, "inkscape:export-ydpi", ydpi); modified = true; } - DocumentUndo::setUndoSensitive(doc, saved); - - if (modified) { - doc->setModifiedSinceSave(); - } - break; } - case SELECTION_SELECTION: { - const GSList * reprlst; - SPDocument * doc = SP_ACTIVE_DOCUMENT; - bool modified = false; - - bool saved = DocumentUndo::getUndoSensitive(doc); - DocumentUndo::setUndoSensitive(doc, false); - reprlst = sp_desktop_selection(desktop)->reprList(); - - for(; reprlst != NULL; reprlst = reprlst->next) { - Inkscape::XML::Node * repr = static_cast<Inkscape::XML::Node *>(reprlst->data); - const gchar * temp_string; - Glib::ustring dir = Glib::path_get_dirname(filename.c_str()); - const gchar* docURI=SP_ACTIVE_DOCUMENT->getURI(); - Glib::ustring docdir; - if (docURI) - { - docdir = Glib::path_get_dirname(docURI); - } - if (repr->attribute("id") == NULL || - !(filename_ext.find_last_of(repr->attribute("id")) && - ( !docURI || - (dir == docdir)))) { - temp_string = repr->attribute("inkscape:export-filename"); - if (temp_string == NULL || (filename_ext != temp_string)) { - repr->setAttribute("inkscape:export-filename", filename_ext.c_str()); - 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; - } - temp_string = repr->attribute("inkscape:export-ydpi"); - if (temp_string == NULL || ydpi != atof(temp_string)) { - sp_repr_set_svg_double(repr, "inkscape:export-ydpi", ydpi); - modified = true; - } - } - DocumentUndo::setUndoSensitive(doc, saved); + DocumentUndo::setUndoSensitive(doc, saved); - if (modified) { - doc->setModifiedSinceSave(); - } - break; + if (modified) { + doc->setModifiedSinceSave(); } - default: - break; + break; + } + default: + break; } } @@ -1331,8 +1335,8 @@ void Export::onBrowse () // Copy the selected file name, converting from UTF-8 to UTF-16 std::string dirname = Glib::path_get_dirname(filename.raw()); if ( !Glib::file_test(dirname, Glib::FILE_TEST_EXISTS) || - Glib::file_test(filename, Glib::FILE_TEST_IS_DIR) || - dirname.empty() ) + Glib::file_test(filename, Glib::FILE_TEST_IS_DIR) || + dirname.empty() ) { Glib::ustring tmp; filename = create_filepath_from_id(tmp, tmp); @@ -1407,11 +1411,11 @@ bool Export::bbox_equal(Geom::Rect const &one, Geom::Rect const &two) { double const epsilon = pow(10.0, -EXPORT_COORD_PRECISION); return ( - (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) - ); + (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) + ); } /** @@ -1454,48 +1458,48 @@ void Export::detectSize() { for (int i = 0; i < SELECTION_NUMBER_OF + 1 && - key == SELECTION_NUMBER_OF && - SP_ACTIVE_DESKTOP != NULL; + key == SELECTION_NUMBER_OF && + SP_ACTIVE_DESKTOP != NULL; i++) { 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(SPItem::VISUAL_BBOX); + case SELECTION_SELECTION: + if ((sp_desktop_selection(SP_ACTIVE_DESKTOP))->isEmpty() == false) { + Geom::OptRect bbox = (sp_desktop_selection (SP_ACTIVE_DESKTOP))->bounds(SPItem::VISUAL_BBOX); - if ( bbox && bbox_equal(*bbox,current_bbox)) { - key = SELECTION_SELECTION; - } + if ( bbox && bbox_equal(*bbox,current_bbox)) { + key = SELECTION_SELECTION; } - break; - case SELECTION_DRAWING: { - SPDocument *doc = sp_desktop_document (SP_ACTIVE_DESKTOP); + } + break; + case SELECTION_DRAWING: { + SPDocument *doc = sp_desktop_document (SP_ACTIVE_DESKTOP); - Geom::OptRect bbox = doc->getRoot()->desktopVisualBounds(); + Geom::OptRect bbox = doc->getRoot()->desktopVisualBounds(); - if ( bbox && bbox_equal(*bbox,current_bbox) ) { - key = SELECTION_DRAWING; - } - break; + if ( bbox && bbox_equal(*bbox,current_bbox) ) { + key = SELECTION_DRAWING; } + break; + } - case SELECTION_PAGE: { - SPDocument *doc; + case SELECTION_PAGE: { + SPDocument *doc; - doc = sp_desktop_document (SP_ACTIVE_DESKTOP); + doc = sp_desktop_document (SP_ACTIVE_DESKTOP); - Geom::Point x(0.0, 0.0); - Geom::Point y(doc->getWidth().value("px"), - doc->getHeight().value("px")); - Geom::Rect bbox(x, y); + Geom::Point x(0.0, 0.0); + Geom::Point y(doc->getWidth().value("px"), + doc->getHeight().value("px")); + Geom::Rect bbox(x, y); - if (bbox_equal(bbox,current_bbox)) { - key = SELECTION_PAGE; - } + if (bbox_equal(bbox,current_bbox)) { + key = SELECTION_PAGE; + } - break; - } + break; + } default: - break; + break; } } // std::cout << std::endl; @@ -1579,7 +1583,7 @@ void Export::areaYChange (Gtk::Adjustment *adj) height = SP_EXPORT_MIN_SIZE; //key = (const gchar *)g_object_get_data(G_OBJECT (adj), "key"); if (adj == y1_adj) { - //if (!strcmp (key, "y0")) { + //if (!strcmp (key, "y0")) { y1 = y0 + height * DPI_BASE / ydpi; setValuePx(y1_adj, y1); } else { diff --git a/src/ui/dialog/export.h b/src/ui/dialog/export.h index 79e597414..6f3c0dfac 100644 --- a/src/ui/dialog/export.h +++ b/src/ui/dialog/export.h @@ -56,7 +56,9 @@ public: Export (); ~Export (); - static Export &getInstance() { return *new Export(); } + static Export &getInstance() { + return *new Export(); + } private: @@ -97,7 +99,7 @@ private: float getValue (Gtk::Adjustment *adj); float getValuePx (Gtk::Adjustment *adj); #endif - + /** * Helper function to create, style and pack spinbuttons for the export dialog. * @@ -121,20 +123,20 @@ private: */ #if WITH_GTKMM_3_0 Glib::RefPtr<Gtk::Adjustment> createSpinbutton( gchar const *key, float val, float min, float max, - float step, float page, - Gtk::Grid *t, int x, int y, - const Glib::ustring ll, const Glib::ustring lr, - int digits, unsigned int sensitive, - void (Export::*cb)() ); + float step, float page, + Gtk::Grid *t, int x, int y, + const Glib::ustring& ll, const Glib::ustring& lr, + int digits, unsigned int sensitive, + void (Export::*cb)() ); #else Gtk::Adjustment * createSpinbutton( gchar const *key, float val, float min, float max, - float step, float page, - Gtk::Table *t, int x, int y, - const Glib::ustring ll, const Glib::ustring lr, - int digits, unsigned int sensitive, - void (Export::*cb)() ); + float step, float page, + Gtk::Table *t, int x, int y, + const Glib::ustring& ll, const Glib::ustring& lr, + int digits, unsigned int sensitive, + void (Export::*cb)() ); #endif - + /** * One of the area select radio buttons was pressed */ @@ -153,8 +155,12 @@ private: /** * Area X value changed callback */ - void onAreaX0Change() {areaXChange(x0_adj);} ; - void onAreaX1Change() {areaXChange(x1_adj);} ; + void onAreaX0Change() { + areaXChange(x0_adj); + } ; + void onAreaX1Change() { + areaXChange(x1_adj); + } ; #if WITH_GTKMM_3_0 void areaXChange(Glib::RefPtr<Gtk::Adjustment>& adj); #else @@ -164,8 +170,12 @@ private: /** * Area Y value changed callback */ - void onAreaY0Change() {areaYChange(y0_adj);} ; - void onAreaY1Change() {areaYChange(y1_adj);} ; + void onAreaY0Change() { + areaYChange(y0_adj); + } ; + void onAreaY1Change() { + areaYChange(y1_adj); + } ; #if WITH_GTKMM_3_0 void areaYChange(Glib::RefPtr<Gtk::Adjustment>& adj); #else @@ -235,14 +245,14 @@ private: /** * Creates progress dialog for batch exporting. - * + * * @param progress_text Text to be shown in the progress bar */ Gtk::Dialog * create_progress_dialog (Glib::ustring progress_text); /** * Callback to be used in for loop to update the progress bar. - * + * * @param value number between 0 and 1 indicating the fraction of progress (0.17 = 17 % progress) * @param dlg void pointer to the Gtk::Dialog progress dialog */ diff --git a/src/ui/dialog/filedialogimpl-gtkmm.cpp b/src/ui/dialog/filedialogimpl-gtkmm.cpp index fdc9cecc3..8ba3ad684 100644 --- a/src/ui/dialog/filedialogimpl-gtkmm.cpp +++ b/src/ui/dialog/filedialogimpl-gtkmm.cpp @@ -18,7 +18,7 @@ */ #ifdef HAVE_CONFIG_H -# include <config.h> +#include <config.h> #endif #include "filedialogimpl-gtkmm.h" @@ -29,7 +29,7 @@ #include "preferences.h" #ifdef WITH_GNOME_VFS -# include <libgnomevfs/gnome-vfs.h> +#include <libgnomevfs/gnome-vfs.h> #endif #include <gtkmm/expander.h> @@ -46,24 +46,19 @@ #include "svg-view-widget.h" #include "inkscape.h" -//Routines from file.cpp +// Routines from file.cpp #undef INK_DUMP_FILENAME_CONV #ifdef INK_DUMP_FILENAME_CONV -void dump_str( const gchar* str, const gchar* prefix ); -void dump_ustr( const Glib::ustring& ustr ); +void dump_str(const gchar *str, const gchar *prefix); +void dump_ustr(const Glib::ustring &ustr); #endif -namespace Inkscape -{ -namespace UI -{ -namespace Dialog -{ - - +namespace Inkscape { +namespace UI { +namespace Dialog { @@ -71,64 +66,51 @@ namespace Dialog //### U T I L I T Y //######################################################################## -void -fileDialogExtensionToPattern(Glib::ustring &pattern, - Glib::ustring &extension) +void fileDialogExtensionToPattern(Glib::ustring &pattern, Glib::ustring &extension) { - for (unsigned int i = 0; i < extension.length(); i++ ) - { + for (unsigned int i = 0; i < extension.length(); ++i) { Glib::ustring::value_type ch = extension[i]; - if ( Glib::Unicode::isalpha(ch) ) - { + if (Glib::Unicode::isalpha(ch)) { pattern += '['; pattern += Glib::Unicode::toupper(ch); pattern += Glib::Unicode::tolower(ch); pattern += ']'; - } - else - { + } else { pattern += ch; - } } + } } -void -findEntryWidgets(Gtk::Container *parent, - std::vector<Gtk::Entry *> &result) +void findEntryWidgets(Gtk::Container *parent, std::vector<Gtk::Entry *> &result) { - if (!parent) + if (!parent) { return; + } std::vector<Gtk::Widget *> children = parent->get_children(); - for (unsigned int i=0; i<children.size() ; i++) - { + for (unsigned int i = 0; i < children.size(); ++i) { Gtk::Widget *child = children[i]; GtkWidget *wid = child->gobj(); if (GTK_IS_ENTRY(wid)) - result.push_back(dynamic_cast<Gtk::Entry *>(child)); + result.push_back(dynamic_cast<Gtk::Entry *>(child)); else if (GTK_IS_CONTAINER(wid)) findEntryWidgets(dynamic_cast<Gtk::Container *>(child), result); - } - + } } -void -findExpanderWidgets(Gtk::Container *parent, - std::vector<Gtk::Expander *> &result) +void findExpanderWidgets(Gtk::Container *parent, std::vector<Gtk::Expander *> &result) { if (!parent) return; std::vector<Gtk::Widget *> children = parent->get_children(); - for (unsigned int i=0; i<children.size() ; i++) - { + for (unsigned int i = 0; i < children.size(); ++i) { Gtk::Widget *child = children[i]; GtkWidget *wid = child->gobj(); if (GTK_IS_EXPANDER(wid)) - result.push_back(dynamic_cast<Gtk::Expander *>(child)); + result.push_back(dynamic_cast<Gtk::Expander *>(child)); else if (GTK_IS_CONTAINER(wid)) findExpanderWidgets(dynamic_cast<Gtk::Container *>(child), result); - } - + } } @@ -144,13 +126,13 @@ bool SVGPreview::setDocument(SPDocument *doc) doc->doRef(); document = doc; - //This should remove it from the box, and free resources + // This should remove it from the box, and free resources if (viewerGtk) Gtk::Container::remove(*viewerGtk); - viewerGtk = Glib::wrap(sp_svg_view_widget_new(doc)); + viewerGtk = Glib::wrap(sp_svg_view_widget_new(doc)); Gtk::VBox *vbox = Glib::wrap(gobj()); - vbox->pack_start(*viewerGtk, TRUE, TRUE, 0); + vbox->pack_start(*viewerGtk, TRUE, TRUE, 0); viewerGtk->show(); return true; } @@ -166,7 +148,7 @@ bool SVGPreview::setFileName(Glib::ustring &theFileName) * I don't know why passing false to keepalive is bad. But it * prevents the display of an svg with a non-ascii filename */ - SPDocument *doc = SPDocument::createNewDoc (fileName.c_str(), true); + SPDocument *doc = SPDocument::createNewDoc(fileName.c_str(), true); if (!doc) { g_warning("SVGView: error loading document '%s'\n", fileName.c_str()); return false; @@ -189,7 +171,7 @@ bool SVGPreview::setFromMem(char const *xmlBuffer) gint len = (gint)strlen(xmlBuffer); SPDocument *doc = SPDocument::createNewDocFromMem(xmlBuffer, len, 0); if (!doc) { - g_warning("SVGView: error loading buffer '%s'\n",xmlBuffer); + g_warning("SVGView: error loading buffer '%s'\n", xmlBuffer); return false; } @@ -216,21 +198,22 @@ void SVGPreview::showImage(Glib::ustring &theFileName) # display it nicely? #####################################*/ - //Arbitrary size of svg doc -- rather 'portrait' shaped - gint previewWidth = 400; + // Arbitrary size of svg doc -- rather 'portrait' shaped + gint previewWidth = 400; gint previewHeight = 600; - //Get some image info. Smart pointer does not need to be deleted + // Get some image info. Smart pointer does not need to be deleted Glib::RefPtr<Gdk::Pixbuf> img(NULL); - try { + try + { img = Gdk::Pixbuf::create_from_file(fileName); } - catch (const Glib::FileError & e) + catch (const Glib::FileError &e) { g_message("caught Glib::FileError in SVGPreview::showImage"); return; } - catch (const Gdk::PixbufError & e) + catch (const Gdk::PixbufError &e) { g_message("Gdk::PixbufError in SVGPreview::showImage"); return; @@ -241,70 +224,66 @@ void SVGPreview::showImage(Glib::ustring &theFileName) return; } - gint imgWidth = img->get_width(); + gint imgWidth = img->get_width(); gint imgHeight = img->get_height(); - //Find the minimum scale to fit the image inside the preview area - double scaleFactorX = (0.9 *(double)previewWidth) / ((double)imgWidth); - double scaleFactorY = (0.9 *(double)previewHeight) / ((double)imgHeight); + // Find the minimum scale to fit the image inside the preview area + double scaleFactorX = (0.9 * (double)previewWidth) / ((double)imgWidth); + double scaleFactorY = (0.9 * (double)previewHeight) / ((double)imgHeight); double scaleFactor = scaleFactorX; if (scaleFactorX > scaleFactorY) scaleFactor = scaleFactorY; - //Now get the resized values - gint scaledImgWidth = (int) (scaleFactor * (double)imgWidth); - gint scaledImgHeight = (int) (scaleFactor * (double)imgHeight); + // Now get the resized values + gint scaledImgWidth = (int)(scaleFactor * (double)imgWidth); + gint scaledImgHeight = (int)(scaleFactor * (double)imgHeight); - //center the image on the area - gint imgX = (previewWidth - scaledImgWidth) / 2; + // center the image on the area + gint imgX = (previewWidth - scaledImgWidth) / 2; gint imgY = (previewHeight - scaledImgHeight) / 2; - //wrap a rectangle around the image - gint rectX = imgX-1; - gint rectY = imgY-1; - gint rectWidth = scaledImgWidth +2; - gint rectHeight = scaledImgHeight+2; - - //Our template. Modify to taste - gchar const *xformat = - "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" - "<svg\n" - "xmlns=\"http://www.w3.org/2000/svg\"\n" - "xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n" - "width=\"%d\" height=\"%d\">\n" //# VALUES HERE - "<rect\n" - " style=\"fill:#eeeeee;stroke:none\"\n" - " x=\"-100\" y=\"-100\" width=\"4000\" height=\"4000\"/>\n" - "<image x=\"%d\" y=\"%d\" width=\"%d\" height=\"%d\"\n" - "xlink:href=\"%s\"/>\n" - "<rect\n" - " style=\"fill:none;" - " stroke:#000000;stroke-width:1.0;" - " stroke-linejoin:miter;stroke-opacity:1.0000000;" - " stroke-miterlimit:4.0000000;stroke-dasharray:none\"\n" - " x=\"%d\" y=\"%d\" width=\"%d\" height=\"%d\"/>\n" - "<text\n" - " style=\"font-size:24.000000;font-style:normal;font-weight:normal;" - " fill:#000000;fill-opacity:1.0000000;stroke:none;" - " font-family:Sans\"\n" - " x=\"10\" y=\"26\">%d x %d</text>\n" //# VALUES HERE - "</svg>\n\n"; - - //if (!Glib::get_charset()) //If we are not utf8 + // wrap a rectangle around the image + gint rectX = imgX - 1; + gint rectY = imgY - 1; + gint rectWidth = scaledImgWidth + 2; + gint rectHeight = scaledImgHeight + 2; + + // Our template. Modify to taste + gchar const *xformat = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<svg\n" + "xmlns=\"http://www.w3.org/2000/svg\"\n" + "xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n" + "width=\"%d\" height=\"%d\">\n" //# VALUES HERE + "<rect\n" + " style=\"fill:#eeeeee;stroke:none\"\n" + " x=\"-100\" y=\"-100\" width=\"4000\" height=\"4000\"/>\n" + "<image x=\"%d\" y=\"%d\" width=\"%d\" height=\"%d\"\n" + "xlink:href=\"%s\"/>\n" + "<rect\n" + " style=\"fill:none;" + " stroke:#000000;stroke-width:1.0;" + " stroke-linejoin:miter;stroke-opacity:1.0000000;" + " stroke-miterlimit:4.0000000;stroke-dasharray:none\"\n" + " x=\"%d\" y=\"%d\" width=\"%d\" height=\"%d\"/>\n" + "<text\n" + " style=\"font-size:24.000000;font-style:normal;font-weight:normal;" + " fill:#000000;fill-opacity:1.0000000;stroke:none;" + " font-family:Sans\"\n" + " x=\"10\" y=\"26\">%d x %d</text>\n" //# VALUES HERE + "</svg>\n\n"; + + // if (!Glib::get_charset()) //If we are not utf8 fileName = Glib::filename_to_utf8(fileName); - //Fill in the template + // Fill in the template /* FIXME: Do proper XML quoting for fileName. */ - gchar *xmlBuffer = g_strdup_printf(xformat, - previewWidth, previewHeight, - imgX, imgY, scaledImgWidth, scaledImgHeight, - fileName.c_str(), - rectX, rectY, rectWidth, rectHeight, - imgWidth, imgHeight); + gchar *xmlBuffer = + g_strdup_printf(xformat, previewWidth, previewHeight, imgX, imgY, scaledImgWidth, scaledImgHeight, + fileName.c_str(), rectX, rectY, rectWidth, rectHeight, imgWidth, imgHeight); - //g_message("%s\n", xmlBuffer); + // g_message("%s\n", xmlBuffer); - //now show it! + // now show it! setFromMem(xmlBuffer); g_free(xmlBuffer); } @@ -313,97 +292,95 @@ void SVGPreview::showImage(Glib::ustring &theFileName) void SVGPreview::showNoPreview() { - //Are we already showing it? + // Are we already showing it? if (showingNoPreview) return; - //Arbitrary size of svg doc -- rather 'portrait' shaped - gint previewWidth = 300; + // Arbitrary size of svg doc -- rather 'portrait' shaped + gint previewWidth = 300; gint previewHeight = 600; - //Our template. Modify to taste + // Our template. Modify to taste gchar const *xformat = - "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" - "<svg\n" - "xmlns=\"http://www.w3.org/2000/svg\"\n" - "xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n" - "width=\"%d\" height=\"%d\">\n" //# VALUES HERE - "<g transform=\"translate(-190,24.27184)\" style=\"opacity:0.12\">\n" - "<path\n" - "style=\"font-size:12;fill:#ffffff;fill-rule:evenodd;stroke:#000000;stroke-width:0.936193pt\"\n" - "d=\"M 397.64309 320.25301 L 280.39197 282.517 L 250.74227 124.83447 L 345.08225 " - "29.146783 L 393.59996 46.667064 L 483.89679 135.61619 L 397.64309 320.25301 z \"\n" - "id=\"whiteSpace\" />\n" - "<path\n" - "style=\"font-size:12;fill-rule:evenodd;stroke-width:1pt;fill:#000000;fill-opacity:1\"\n" - "d=\"M 476.95792 339.17168 C 495.78197 342.93607 499.54842 356.11361 495.78197 359.87802 " - "C 492.01856 363.6434 482.6065 367.40781 475.07663 361.76014 C 467.54478 " - "356.11361 467.54478 342.93607 476.95792 339.17168 z \"\n" - "id=\"droplet01\" />\n" - "<path\n" - "style=\"font-size:12;fill-rule:evenodd;stroke-width:1pt;fill:#000000;fill-opacity:1\"\n" - "d=\"M 286.46194 340.42914 C 284.6277 340.91835 269.30405 327.71337 257.16909 333.8338 " - "C 245.03722 339.95336 236.89276 353.65666 248.22676 359.27982 C 259.56184 364.90298 " - "267.66433 358.41867 277.60113 351.44119 C 287.53903 344.46477 " - "287.18046 343.1206 286.46194 340.42914 z \"\n" - "id=\"droplet02\" />\n" - "<path\n" - "style=\"font-size:12;fill-rule:evenodd;stroke-width:1pt;fill:#000000;fill-opacity:1\"\n" - "d=\"M 510.35756 306.92856 C 520.59494 304.36879 544.24333 306.92856 540.47688 321.98634 " - "C 536.71354 337.04806 504.71297 331.39827 484.00371 323.87156 C 482.12141 " - "308.81083 505.53237 308.13423 510.35756 306.92856 z \"\n" - "id=\"droplet03\" />\n" - "<path\n" - "style=\"font-size:12;fill-rule:evenodd;stroke-width:1pt;fill:#000000;fill-opacity:1\"\n" - "d=\"M 359.2403 21.362537 C 347.92693 21.362537 336.6347 25.683095 327.96556 34.35223 " - "L 173.87387 188.41466 C 165.37697 196.9114 161.1116 207.95813 160.94269 219.04577 " - "L 160.88418 219.04577 C 160.88418 219.08524 160.94076 219.12322 160.94269 219.16279 " - "C 160.94033 219.34888 160.88418 219.53256 160.88418 219.71865 L 161.14748 219.71865 " - "C 164.0966 230.93917 240.29699 245.24198 248.79866 253.74346 C 261.63771 266.58263 " - "199.5652 276.01151 212.4041 288.85074 C 225.24316 301.68979 289.99433 313.6933 302.8346 " - "326.53254 C 315.67368 339.37161 276.5961 353.04289 289.43532 365.88196 C 302.27439 " - "378.72118 345.40201 362.67257 337.5908 396.16198 C 354.92909 413.50026 391.10302 " - "405.2208 415.32417 387.88252 C 428.16323 375.04345 390.6948 376.17577 403.53397 " - "363.33668 C 416.37304 350.49745 448.78128 350.4282 476.08902 319.71589 C 465.09739 " - "302.62116 429.10801 295.34136 441.94719 282.50217 C 454.78625 269.66311 479.74708 " - "276.18423 533.60644 251.72479 C 559.89837 239.78398 557.72636 230.71459 557.62567 " - "219.71865 C 557.62356 219.48727 557.62567 219.27892 557.62567 219.04577 L 557.56716 " - "219.04577 C 557.3983 207.95812 553.10345 196.9114 544.60673 188.41466 L 390.54428 " - "34.35223 C 381.87515 25.683095 370.55366 21.362537 359.2403 21.362537 z M 357.92378 " - "41.402939 C 362.95327 41.533963 367.01541 45.368018 374.98006 50.530832 L 447.76915 " - "104.50827 C 448.56596 105.02498 449.32484 105.564 450.02187 106.11735 C 450.7189 106.67062 " - "451.3556 107.25745 451.95277 107.84347 C 452.54997 108.42842 453.09281 109.01553 453.59111 " - "109.62808 C 454.08837 110.24052 454.53956 110.86661 454.93688 111.50048 C 455.33532 112.13538 " - "455.69164 112.78029 455.9901 113.43137 C 456.28877 114.08363 456.52291 114.75639 456.7215 " - "115.42078 C 456.92126 116.08419 457.08982 116.73973 457.18961 117.41019 C 457.28949 " - "118.08184 457.33588 118.75535 457.33588 119.42886 L 414.21245 98.598549 L 409.9118 " - "131.16055 L 386.18512 120.04324 L 349.55654 144.50131 L 335.54288 96.1703 L 317.4919 " - "138.4453 L 267.08369 143.47735 L 267.63956 121.03795 C 267.63956 115.64823 296.69685 " - "77.915899 314.39075 68.932902 L 346.77721 45.674327 C 351.55594 42.576634 354.90608 " - "41.324327 357.92378 41.402939 z M 290.92738 261.61333 C 313.87149 267.56365 339.40299 " - "275.37038 359.88393 275.50997 L 360.76161 284.72563 C 343.2235 282.91785 306.11346 " - "274.45012 297.36372 269.98057 L 290.92738 261.61333 z \"\n" - "id=\"mountainDroplet\" />\n" - "</g> <g transform=\"translate(-20,0)\">\n" - "<text xml:space=\"preserve\"\n" - "style=\"font-size:32.000000;font-style:normal;font-variant:normal;font-weight:bold;" - "font-stretch:normal;fill:#000000;fill-opacity:1.0000000;stroke:none;stroke-width:1.0000000pt;" - "stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000;" - "font-family:Sans;text-anchor:middle;writing-mode:lr\"\n" - "x=\"190\" y=\"240\">%s</text></g>\n" //# VALUE HERE - "</svg>\n\n"; - - //Fill in the template - gchar *xmlBuffer = g_strdup_printf(xformat, - previewWidth, previewHeight, _("No preview")); - - //g_message("%s\n", xmlBuffer); - - //now show it! + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<svg\n" + "xmlns=\"http://www.w3.org/2000/svg\"\n" + "xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n" + "width=\"%d\" height=\"%d\">\n" //# VALUES HERE + "<g transform=\"translate(-190,24.27184)\" style=\"opacity:0.12\">\n" + "<path\n" + "style=\"font-size:12;fill:#ffffff;fill-rule:evenodd;stroke:#000000;stroke-width:0.936193pt\"\n" + "d=\"M 397.64309 320.25301 L 280.39197 282.517 L 250.74227 124.83447 L 345.08225 " + "29.146783 L 393.59996 46.667064 L 483.89679 135.61619 L 397.64309 320.25301 z \"\n" + "id=\"whiteSpace\" />\n" + "<path\n" + "style=\"font-size:12;fill-rule:evenodd;stroke-width:1pt;fill:#000000;fill-opacity:1\"\n" + "d=\"M 476.95792 339.17168 C 495.78197 342.93607 499.54842 356.11361 495.78197 359.87802 " + "C 492.01856 363.6434 482.6065 367.40781 475.07663 361.76014 C 467.54478 " + "356.11361 467.54478 342.93607 476.95792 339.17168 z \"\n" + "id=\"droplet01\" />\n" + "<path\n" + "style=\"font-size:12;fill-rule:evenodd;stroke-width:1pt;fill:#000000;fill-opacity:1\"\n" + "d=\"M 286.46194 340.42914 C 284.6277 340.91835 269.30405 327.71337 257.16909 333.8338 " + "C 245.03722 339.95336 236.89276 353.65666 248.22676 359.27982 C 259.56184 364.90298 " + "267.66433 358.41867 277.60113 351.44119 C 287.53903 344.46477 " + "287.18046 343.1206 286.46194 340.42914 z \"\n" + "id=\"droplet02\" />\n" + "<path\n" + "style=\"font-size:12;fill-rule:evenodd;stroke-width:1pt;fill:#000000;fill-opacity:1\"\n" + "d=\"M 510.35756 306.92856 C 520.59494 304.36879 544.24333 306.92856 540.47688 321.98634 " + "C 536.71354 337.04806 504.71297 331.39827 484.00371 323.87156 C 482.12141 " + "308.81083 505.53237 308.13423 510.35756 306.92856 z \"\n" + "id=\"droplet03\" />\n" + "<path\n" + "style=\"font-size:12;fill-rule:evenodd;stroke-width:1pt;fill:#000000;fill-opacity:1\"\n" + "d=\"M 359.2403 21.362537 C 347.92693 21.362537 336.6347 25.683095 327.96556 34.35223 " + "L 173.87387 188.41466 C 165.37697 196.9114 161.1116 207.95813 160.94269 219.04577 " + "L 160.88418 219.04577 C 160.88418 219.08524 160.94076 219.12322 160.94269 219.16279 " + "C 160.94033 219.34888 160.88418 219.53256 160.88418 219.71865 L 161.14748 219.71865 " + "C 164.0966 230.93917 240.29699 245.24198 248.79866 253.74346 C 261.63771 266.58263 " + "199.5652 276.01151 212.4041 288.85074 C 225.24316 301.68979 289.99433 313.6933 302.8346 " + "326.53254 C 315.67368 339.37161 276.5961 353.04289 289.43532 365.88196 C 302.27439 " + "378.72118 345.40201 362.67257 337.5908 396.16198 C 354.92909 413.50026 391.10302 " + "405.2208 415.32417 387.88252 C 428.16323 375.04345 390.6948 376.17577 403.53397 " + "363.33668 C 416.37304 350.49745 448.78128 350.4282 476.08902 319.71589 C 465.09739 " + "302.62116 429.10801 295.34136 441.94719 282.50217 C 454.78625 269.66311 479.74708 " + "276.18423 533.60644 251.72479 C 559.89837 239.78398 557.72636 230.71459 557.62567 " + "219.71865 C 557.62356 219.48727 557.62567 219.27892 557.62567 219.04577 L 557.56716 " + "219.04577 C 557.3983 207.95812 553.10345 196.9114 544.60673 188.41466 L 390.54428 " + "34.35223 C 381.87515 25.683095 370.55366 21.362537 359.2403 21.362537 z M 357.92378 " + "41.402939 C 362.95327 41.533963 367.01541 45.368018 374.98006 50.530832 L 447.76915 " + "104.50827 C 448.56596 105.02498 449.32484 105.564 450.02187 106.11735 C 450.7189 106.67062 " + "451.3556 107.25745 451.95277 107.84347 C 452.54997 108.42842 453.09281 109.01553 453.59111 " + "109.62808 C 454.08837 110.24052 454.53956 110.86661 454.93688 111.50048 C 455.33532 112.13538 " + "455.69164 112.78029 455.9901 113.43137 C 456.28877 114.08363 456.52291 114.75639 456.7215 " + "115.42078 C 456.92126 116.08419 457.08982 116.73973 457.18961 117.41019 C 457.28949 " + "118.08184 457.33588 118.75535 457.33588 119.42886 L 414.21245 98.598549 L 409.9118 " + "131.16055 L 386.18512 120.04324 L 349.55654 144.50131 L 335.54288 96.1703 L 317.4919 " + "138.4453 L 267.08369 143.47735 L 267.63956 121.03795 C 267.63956 115.64823 296.69685 " + "77.915899 314.39075 68.932902 L 346.77721 45.674327 C 351.55594 42.576634 354.90608 " + "41.324327 357.92378 41.402939 z M 290.92738 261.61333 C 313.87149 267.56365 339.40299 " + "275.37038 359.88393 275.50997 L 360.76161 284.72563 C 343.2235 282.91785 306.11346 " + "274.45012 297.36372 269.98057 L 290.92738 261.61333 z \"\n" + "id=\"mountainDroplet\" />\n" + "</g> <g transform=\"translate(-20,0)\">\n" + "<text xml:space=\"preserve\"\n" + "style=\"font-size:32.000000;font-style:normal;font-variant:normal;font-weight:bold;" + "font-stretch:normal;fill:#000000;fill-opacity:1.0000000;stroke:none;stroke-width:1.0000000pt;" + "stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000;" + "font-family:Sans;text-anchor:middle;writing-mode:lr\"\n" + "x=\"190\" y=\"240\">%s</text></g>\n" //# VALUE HERE + "</svg>\n\n"; + + // Fill in the template + gchar *xmlBuffer = g_strdup_printf(xformat, previewWidth, previewHeight, _("No preview")); + + // g_message("%s\n", xmlBuffer); + + // now show it! setFromMem(xmlBuffer); g_free(xmlBuffer); showingNoPreview = true; - } @@ -414,142 +391,137 @@ void SVGPreview::showNoPreview() void SVGPreview::showTooLarge(long fileLength) { - //Arbitrary size of svg doc -- rather 'portrait' shaped - gint previewWidth = 300; + // Arbitrary size of svg doc -- rather 'portrait' shaped + gint previewWidth = 300; gint previewHeight = 600; - //Our template. Modify to taste + // Our template. Modify to taste gchar const *xformat = - "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" - "<svg\n" - "xmlns=\"http://www.w3.org/2000/svg\"\n" - "xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n" - "width=\"%d\" height=\"%d\">\n" //# VALUES HERE - "<g transform=\"translate(-170,24.27184)\" style=\"opacity:0.12\">\n" - "<path\n" - "style=\"font-size:12;fill:#ffffff;fill-rule:evenodd;stroke:#000000;stroke-width:0.936193pt\"\n" - "d=\"M 397.64309 320.25301 L 280.39197 282.517 L 250.74227 124.83447 L 345.08225 " - "29.146783 L 393.59996 46.667064 L 483.89679 135.61619 L 397.64309 320.25301 z \"\n" - "id=\"whiteSpace\" />\n" - "<path\n" - "style=\"font-size:12;fill-rule:evenodd;stroke-width:1pt;fill:#000000;fill-opacity:1\"\n" - "d=\"M 476.95792 339.17168 C 495.78197 342.93607 499.54842 356.11361 495.78197 359.87802 " - "C 492.01856 363.6434 482.6065 367.40781 475.07663 361.76014 C 467.54478 " - "356.11361 467.54478 342.93607 476.95792 339.17168 z \"\n" - "id=\"droplet01\" />\n" - "<path\n" - "style=\"font-size:12;fill-rule:evenodd;stroke-width:1pt;fill:#000000;fill-opacity:1\"\n" - "d=\"M 286.46194 340.42914 C 284.6277 340.91835 269.30405 327.71337 257.16909 333.8338 " - "C 245.03722 339.95336 236.89276 353.65666 248.22676 359.27982 C 259.56184 364.90298 " - "267.66433 358.41867 277.60113 351.44119 C 287.53903 344.46477 " - "287.18046 343.1206 286.46194 340.42914 z \"\n" - "id=\"droplet02\" />\n" - "<path\n" - "style=\"font-size:12;fill-rule:evenodd;stroke-width:1pt;fill:#000000;fill-opacity:1\"\n" - "d=\"M 510.35756 306.92856 C 520.59494 304.36879 544.24333 306.92856 540.47688 321.98634 " - "C 536.71354 337.04806 504.71297 331.39827 484.00371 323.87156 C 482.12141 " - "308.81083 505.53237 308.13423 510.35756 306.92856 z \"\n" - "id=\"droplet03\" />\n" - "<path\n" - "style=\"font-size:12;fill-rule:evenodd;stroke-width:1pt;fill:#000000;fill-opacity:1\"\n" - "d=\"M 359.2403 21.362537 C 347.92693 21.362537 336.6347 25.683095 327.96556 34.35223 " - "L 173.87387 188.41466 C 165.37697 196.9114 161.1116 207.95813 160.94269 219.04577 " - "L 160.88418 219.04577 C 160.88418 219.08524 160.94076 219.12322 160.94269 219.16279 " - "C 160.94033 219.34888 160.88418 219.53256 160.88418 219.71865 L 161.14748 219.71865 " - "C 164.0966 230.93917 240.29699 245.24198 248.79866 253.74346 C 261.63771 266.58263 " - "199.5652 276.01151 212.4041 288.85074 C 225.24316 301.68979 289.99433 313.6933 302.8346 " - "326.53254 C 315.67368 339.37161 276.5961 353.04289 289.43532 365.88196 C 302.27439 " - "378.72118 345.40201 362.67257 337.5908 396.16198 C 354.92909 413.50026 391.10302 " - "405.2208 415.32417 387.88252 C 428.16323 375.04345 390.6948 376.17577 403.53397 " - "363.33668 C 416.37304 350.49745 448.78128 350.4282 476.08902 319.71589 C 465.09739 " - "302.62116 429.10801 295.34136 441.94719 282.50217 C 454.78625 269.66311 479.74708 " - "276.18423 533.60644 251.72479 C 559.89837 239.78398 557.72636 230.71459 557.62567 " - "219.71865 C 557.62356 219.48727 557.62567 219.27892 557.62567 219.04577 L 557.56716 " - "219.04577 C 557.3983 207.95812 553.10345 196.9114 544.60673 188.41466 L 390.54428 " - "34.35223 C 381.87515 25.683095 370.55366 21.362537 359.2403 21.362537 z M 357.92378 " - "41.402939 C 362.95327 41.533963 367.01541 45.368018 374.98006 50.530832 L 447.76915 " - "104.50827 C 448.56596 105.02498 449.32484 105.564 450.02187 106.11735 C 450.7189 106.67062 " - "451.3556 107.25745 451.95277 107.84347 C 452.54997 108.42842 453.09281 109.01553 453.59111 " - "109.62808 C 454.08837 110.24052 454.53956 110.86661 454.93688 111.50048 C 455.33532 112.13538 " - "455.69164 112.78029 455.9901 113.43137 C 456.28877 114.08363 456.52291 114.75639 456.7215 " - "115.42078 C 456.92126 116.08419 457.08982 116.73973 457.18961 117.41019 C 457.28949 " - "118.08184 457.33588 118.75535 457.33588 119.42886 L 414.21245 98.598549 L 409.9118 " - "131.16055 L 386.18512 120.04324 L 349.55654 144.50131 L 335.54288 96.1703 L 317.4919 " - "138.4453 L 267.08369 143.47735 L 267.63956 121.03795 C 267.63956 115.64823 296.69685 " - "77.915899 314.39075 68.932902 L 346.77721 45.674327 C 351.55594 42.576634 354.90608 " - "41.324327 357.92378 41.402939 z M 290.92738 261.61333 C 313.87149 267.56365 339.40299 " - "275.37038 359.88393 275.50997 L 360.76161 284.72563 C 343.2235 282.91785 306.11346 " - "274.45012 297.36372 269.98057 L 290.92738 261.61333 z \"\n" - "id=\"mountainDroplet\" />\n" - "</g>\n" - "<text xml:space=\"preserve\"\n" - "style=\"font-size:32.000000;font-style:normal;font-variant:normal;font-weight:bold;" - "font-stretch:normal;fill:#000000;fill-opacity:1.0000000;stroke:none;stroke-width:1.0000000pt;" - "stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000;" - "font-family:Sans;text-anchor:middle;writing-mode:lr\"\n" - "x=\"170\" y=\"215\">%5.1f MB</text>\n" //# VALUE HERE - "<text xml:space=\"preserve\"\n" - "style=\"font-size:24.000000;font-style:normal;font-variant:normal;font-weight:bold;" - "font-stretch:normal;fill:#000000;fill-opacity:1.0000000;stroke:none;stroke-width:1.0000000pt;" - "stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000;" - "font-family:Sans;text-anchor:middle;writing-mode:lr\"\n" - "x=\"180\" y=\"245\">%s</text>\n" //# VALUE HERE - "</svg>\n\n"; - - //Fill in the template + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<svg\n" + "xmlns=\"http://www.w3.org/2000/svg\"\n" + "xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n" + "width=\"%d\" height=\"%d\">\n" //# VALUES HERE + "<g transform=\"translate(-170,24.27184)\" style=\"opacity:0.12\">\n" + "<path\n" + "style=\"font-size:12;fill:#ffffff;fill-rule:evenodd;stroke:#000000;stroke-width:0.936193pt\"\n" + "d=\"M 397.64309 320.25301 L 280.39197 282.517 L 250.74227 124.83447 L 345.08225 " + "29.146783 L 393.59996 46.667064 L 483.89679 135.61619 L 397.64309 320.25301 z \"\n" + "id=\"whiteSpace\" />\n" + "<path\n" + "style=\"font-size:12;fill-rule:evenodd;stroke-width:1pt;fill:#000000;fill-opacity:1\"\n" + "d=\"M 476.95792 339.17168 C 495.78197 342.93607 499.54842 356.11361 495.78197 359.87802 " + "C 492.01856 363.6434 482.6065 367.40781 475.07663 361.76014 C 467.54478 " + "356.11361 467.54478 342.93607 476.95792 339.17168 z \"\n" + "id=\"droplet01\" />\n" + "<path\n" + "style=\"font-size:12;fill-rule:evenodd;stroke-width:1pt;fill:#000000;fill-opacity:1\"\n" + "d=\"M 286.46194 340.42914 C 284.6277 340.91835 269.30405 327.71337 257.16909 333.8338 " + "C 245.03722 339.95336 236.89276 353.65666 248.22676 359.27982 C 259.56184 364.90298 " + "267.66433 358.41867 277.60113 351.44119 C 287.53903 344.46477 " + "287.18046 343.1206 286.46194 340.42914 z \"\n" + "id=\"droplet02\" />\n" + "<path\n" + "style=\"font-size:12;fill-rule:evenodd;stroke-width:1pt;fill:#000000;fill-opacity:1\"\n" + "d=\"M 510.35756 306.92856 C 520.59494 304.36879 544.24333 306.92856 540.47688 321.98634 " + "C 536.71354 337.04806 504.71297 331.39827 484.00371 323.87156 C 482.12141 " + "308.81083 505.53237 308.13423 510.35756 306.92856 z \"\n" + "id=\"droplet03\" />\n" + "<path\n" + "style=\"font-size:12;fill-rule:evenodd;stroke-width:1pt;fill:#000000;fill-opacity:1\"\n" + "d=\"M 359.2403 21.362537 C 347.92693 21.362537 336.6347 25.683095 327.96556 34.35223 " + "L 173.87387 188.41466 C 165.37697 196.9114 161.1116 207.95813 160.94269 219.04577 " + "L 160.88418 219.04577 C 160.88418 219.08524 160.94076 219.12322 160.94269 219.16279 " + "C 160.94033 219.34888 160.88418 219.53256 160.88418 219.71865 L 161.14748 219.71865 " + "C 164.0966 230.93917 240.29699 245.24198 248.79866 253.74346 C 261.63771 266.58263 " + "199.5652 276.01151 212.4041 288.85074 C 225.24316 301.68979 289.99433 313.6933 302.8346 " + "326.53254 C 315.67368 339.37161 276.5961 353.04289 289.43532 365.88196 C 302.27439 " + "378.72118 345.40201 362.67257 337.5908 396.16198 C 354.92909 413.50026 391.10302 " + "405.2208 415.32417 387.88252 C 428.16323 375.04345 390.6948 376.17577 403.53397 " + "363.33668 C 416.37304 350.49745 448.78128 350.4282 476.08902 319.71589 C 465.09739 " + "302.62116 429.10801 295.34136 441.94719 282.50217 C 454.78625 269.66311 479.74708 " + "276.18423 533.60644 251.72479 C 559.89837 239.78398 557.72636 230.71459 557.62567 " + "219.71865 C 557.62356 219.48727 557.62567 219.27892 557.62567 219.04577 L 557.56716 " + "219.04577 C 557.3983 207.95812 553.10345 196.9114 544.60673 188.41466 L 390.54428 " + "34.35223 C 381.87515 25.683095 370.55366 21.362537 359.2403 21.362537 z M 357.92378 " + "41.402939 C 362.95327 41.533963 367.01541 45.368018 374.98006 50.530832 L 447.76915 " + "104.50827 C 448.56596 105.02498 449.32484 105.564 450.02187 106.11735 C 450.7189 106.67062 " + "451.3556 107.25745 451.95277 107.84347 C 452.54997 108.42842 453.09281 109.01553 453.59111 " + "109.62808 C 454.08837 110.24052 454.53956 110.86661 454.93688 111.50048 C 455.33532 112.13538 " + "455.69164 112.78029 455.9901 113.43137 C 456.28877 114.08363 456.52291 114.75639 456.7215 " + "115.42078 C 456.92126 116.08419 457.08982 116.73973 457.18961 117.41019 C 457.28949 " + "118.08184 457.33588 118.75535 457.33588 119.42886 L 414.21245 98.598549 L 409.9118 " + "131.16055 L 386.18512 120.04324 L 349.55654 144.50131 L 335.54288 96.1703 L 317.4919 " + "138.4453 L 267.08369 143.47735 L 267.63956 121.03795 C 267.63956 115.64823 296.69685 " + "77.915899 314.39075 68.932902 L 346.77721 45.674327 C 351.55594 42.576634 354.90608 " + "41.324327 357.92378 41.402939 z M 290.92738 261.61333 C 313.87149 267.56365 339.40299 " + "275.37038 359.88393 275.50997 L 360.76161 284.72563 C 343.2235 282.91785 306.11346 " + "274.45012 297.36372 269.98057 L 290.92738 261.61333 z \"\n" + "id=\"mountainDroplet\" />\n" + "</g>\n" + "<text xml:space=\"preserve\"\n" + "style=\"font-size:32.000000;font-style:normal;font-variant:normal;font-weight:bold;" + "font-stretch:normal;fill:#000000;fill-opacity:1.0000000;stroke:none;stroke-width:1.0000000pt;" + "stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000;" + "font-family:Sans;text-anchor:middle;writing-mode:lr\"\n" + "x=\"170\" y=\"215\">%5.1f MB</text>\n" //# VALUE HERE + "<text xml:space=\"preserve\"\n" + "style=\"font-size:24.000000;font-style:normal;font-variant:normal;font-weight:bold;" + "font-stretch:normal;fill:#000000;fill-opacity:1.0000000;stroke:none;stroke-width:1.0000000pt;" + "stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000;" + "font-family:Sans;text-anchor:middle;writing-mode:lr\"\n" + "x=\"180\" y=\"245\">%s</text>\n" //# VALUE HERE + "</svg>\n\n"; + + // Fill in the template double floatFileLength = ((double)fileLength) / 1048576.0; - //printf("%ld %f\n", fileLength, floatFileLength); - gchar *xmlBuffer = g_strdup_printf(xformat, - previewWidth, previewHeight, floatFileLength, - _("too large for preview")); + // printf("%ld %f\n", fileLength, floatFileLength); + gchar *xmlBuffer = + g_strdup_printf(xformat, previewWidth, previewHeight, floatFileLength, _("too large for preview")); - //g_message("%s\n", xmlBuffer); + // g_message("%s\n", xmlBuffer); - //now show it! + // now show it! setFromMem(xmlBuffer); g_free(xmlBuffer); - } bool SVGPreview::set(Glib::ustring &fileName, int dialogType) { - if (!Glib::file_test(fileName, Glib::FILE_TEST_EXISTS)) + if (!Glib::file_test(fileName, Glib::FILE_TEST_EXISTS)) { + showNoPreview(); return false; + } - //g_message("fname:%s", fileName.c_str()); if (Glib::file_test(fileName, Glib::FILE_TEST_IS_DIR)) { showNoPreview(); return false; } - if (Glib::file_test(fileName, Glib::FILE_TEST_IS_REGULAR)) - { + if (Glib::file_test(fileName, Glib::FILE_TEST_IS_REGULAR)) { Glib::ustring fileNameUtf8 = Glib::filename_to_utf8(fileName); - gchar *fName = const_cast<gchar *>(fileNameUtf8.c_str()); + gchar *fName = const_cast<gchar *>( + fileNameUtf8.c_str()); // const-cast probably not necessary? (not necessary on Windows version of stat()) struct stat info; - if (g_file_test (fName, G_FILE_TEST_EXISTS) && g_stat(fName, &info)) - { - g_warning("SVGPreview::set() : %s : %s", - fName, strerror(errno)); - return FALSE; - } - long fileLen = info.st_size; - if (fileLen > 0xA00000L) - { + if (g_stat(fName, &info)) // stat returns 0 upon success + { + g_warning("SVGPreview::set() : %s : %s", fName, strerror(errno)); + return false; + } + if (info.st_size > 0xA00000L) { showingNoPreview = false; - showTooLarge(fileLen); - return FALSE; - } + showTooLarge(info.st_size); + return false; } + } Glib::ustring svg = ".svg"; Glib::ustring svgz = ".svgz"; if ((dialogType == SVG_TYPES || dialogType == IMPORT_TYPES) && - (hasSuffix(fileName, svg) || hasSuffix(fileName, svgz) ) - ) { + (hasSuffix(fileName, svg) || hasSuffix(fileName, svgz))) { bool retval = setFileName(fileName); showingNoPreview = false; return retval; @@ -567,16 +539,15 @@ bool SVGPreview::set(Glib::ustring &fileName, int dialogType) SVGPreview::SVGPreview() { if (!INKSCAPE) - inkscape_application_init("",false); + inkscape_application_init("", false); document = NULL; viewerGtk = NULL; - set_size_request(150,150); + set_size_request(150, 150); showingNoPreview = false; } SVGPreview::~SVGPreview() { - } @@ -589,32 +560,30 @@ void FileDialogBaseGtk::internalSetup() // Open executable file dialogs don't need the preview panel if (_dialogType != EXE_TYPES) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - bool enablePreview = prefs->getBool( preferenceBase + "/enable_preview", true); + bool enablePreview = prefs->getBool(preferenceBase + "/enable_preview", true); - previewCheckbox.set_label( Glib::ustring(_("Enable preview")) ); - previewCheckbox.set_active( enablePreview ); + previewCheckbox.set_label(Glib::ustring(_("Enable preview"))); + previewCheckbox.set_active(enablePreview); - previewCheckbox.signal_toggled().connect( - sigc::mem_fun(*this, &FileDialogBaseGtk::_previewEnabledCB) ); + previewCheckbox.signal_toggled().connect(sigc::mem_fun(*this, &FileDialogBaseGtk::_previewEnabledCB)); - //Catch selection-changed events, so we can adjust the text widget - signal_update_preview().connect( - sigc::mem_fun(*this, &FileDialogBaseGtk::_updatePreviewCallback) ); + // Catch selection-changed events, so we can adjust the text widget + signal_update_preview().connect(sigc::mem_fun(*this, &FileDialogBaseGtk::_updatePreviewCallback)); //###### Add a preview widget set_preview_widget(svgPreview); - set_preview_widget_active( enablePreview ); - set_use_preview_label (false); + set_preview_widget_active(enablePreview); + set_use_preview_label(false); } } -void FileDialogBaseGtk::cleanup( bool showConfirmed ) +void FileDialogBaseGtk::cleanup(bool showConfirmed) { if (_dialogType != EXE_TYPES) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - if ( showConfirmed ) { - prefs->setBool( preferenceBase + "/enable_preview", previewCheckbox.get_active() ); + if (showConfirmed) { + prefs->setBool(preferenceBase + "/enable_preview", previewCheckbox.get_active()); } } } @@ -624,7 +593,7 @@ void FileDialogBaseGtk::_previewEnabledCB() { bool enabled = previewCheckbox.get_active(); set_preview_widget_active(enabled); - if ( enabled ) { + if (enabled) { _updatePreviewCallback(); } else { // Clears out any current preview image. @@ -643,12 +612,12 @@ void FileDialogBaseGtk::_updatePreviewCallback() bool enabled = previewCheckbox.get_active(); #ifdef WITH_GNOME_VFS - if ( fileName.empty() && gnome_vfs_initialized() ) { + if (fileName.empty() && gnome_vfs_initialized()) { fileName = get_preview_uri(); } #endif - if ( enabled && !fileName.empty() ) { + if (enabled && !fileName.empty()) { svgPreview.set(fileName, _dialogType); } else { svgPreview.showNoPreview(); @@ -663,11 +632,9 @@ void FileDialogBaseGtk::_updatePreviewCallback() /** * Constructor. Not called directly. Use the factory. */ -FileOpenDialogImplGtk::FileOpenDialogImplGtk(Gtk::Window& parentWindow, - const Glib::ustring &dir, - FileDialogType fileTypes, - const Glib::ustring &title) : - FileDialogBaseGtk(parentWindow, title, Gtk::FILE_CHOOSER_ACTION_OPEN, fileTypes, "/dialogs/open") +FileOpenDialogImplGtk::FileOpenDialogImplGtk(Gtk::Window &parentWindow, const Glib::ustring &dir, + FileDialogType fileTypes, const Glib::ustring &title) + : FileDialogBaseGtk(parentWindow, title, Gtk::FILE_CHOOSER_ACTION_OPEN, fileTypes, "/dialogs/open") { @@ -700,7 +667,8 @@ FileOpenDialogImplGtk::FileOpenDialogImplGtk(Gtk::Window& parentWindow, Glib::ustring::size_type len = udir.length(); // leaving a trailing backslash on the directory name leads to the infamous // double-directory bug on win32 - if (len != 0 && udir[len - 1] == '\\') udir.erase(len - 1); + if (len != 0 && udir[len - 1] == '\\') + udir.erase(len - 1); if (_dialogType == EXE_TYPES) { set_filename(udir.c_str()); } else { @@ -709,21 +677,18 @@ FileOpenDialogImplGtk::FileOpenDialogImplGtk(Gtk::Window& parentWindow, } if (_dialogType != EXE_TYPES) { - set_extra_widget( previewCheckbox ); + set_extra_widget(previewCheckbox); } //###### Add the file types menu createFilterMenu(); add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); - set_default(*add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK)); + set_default(*add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK)); //###### Allow easy access to our examples folder - if ( Inkscape::IO::file_test(INKSCAPE_EXAMPLESDIR, G_FILE_TEST_EXISTS) - && Inkscape::IO::file_test(INKSCAPE_EXAMPLESDIR, G_FILE_TEST_IS_DIR) - && g_path_is_absolute(INKSCAPE_EXAMPLESDIR) - ) - { + if (Inkscape::IO::file_test(INKSCAPE_EXAMPLESDIR, G_FILE_TEST_EXISTS) && + Inkscape::IO::file_test(INKSCAPE_EXAMPLESDIR, G_FILE_TEST_IS_DIR) && g_path_is_absolute(INKSCAPE_EXAMPLESDIR)) { add_shortcut_folder(INKSCAPE_EXAMPLESDIR); } } @@ -733,23 +698,22 @@ FileOpenDialogImplGtk::FileOpenDialogImplGtk(Gtk::Window& parentWindow, */ FileOpenDialogImplGtk::~FileOpenDialogImplGtk() { - } void FileOpenDialogImplGtk::addFilterMenu(Glib::ustring name, Glib::ustring pattern) { #if WITH_GTKMM_3_0 - Glib::RefPtr<Gtk::FileFilter> allFilter = Gtk::FileFilter::create(); - allFilter->set_name(_(name.c_str())); - allFilter->add_pattern(pattern); + Glib::RefPtr<Gtk::FileFilter> allFilter = Gtk::FileFilter::create(); + allFilter->set_name(_(name.c_str())); + allFilter->add_pattern(pattern); #else - Gtk::FileFilter allFilter; - allFilter.set_name(_(name.c_str())); - allFilter.add_pattern(pattern); + Gtk::FileFilter allFilter; + allFilter.set_name(_(name.c_str())); + allFilter.add_pattern(pattern); #endif - extensionMap[Glib::ustring(_("All Files"))]=NULL; - add_filter(allFilter); + extensionMap[Glib::ustring(_("All Files"))] = NULL; + add_filter(allFilter); } void FileOpenDialogImplGtk::createFilterMenu() @@ -768,68 +732,69 @@ void FileOpenDialogImplGtk::createFilterMenu() allFilter.set_name(_("All Files")); allFilter.add_pattern("*"); #endif - extensionMap[Glib::ustring(_("All Files"))]=NULL; + extensionMap[Glib::ustring(_("All Files"))] = NULL; add_filter(allFilter); } else { #if WITH_GTKMM_3_0 Glib::RefPtr<Gtk::FileFilter> allInkscapeFilter = Gtk::FileFilter::create(); allInkscapeFilter->set_name(_("All Inkscape Files")); - - Glib::RefPtr<Gtk::FileFilter> allFilter = Gtk::FileFilter::create(); + + Glib::RefPtr<Gtk::FileFilter> allFilter = Gtk::FileFilter::create(); allFilter->set_name(_("All Files")); allFilter->add_pattern("*"); - - Glib::RefPtr<Gtk::FileFilter> allImageFilter = Gtk::FileFilter::create(); + + Glib::RefPtr<Gtk::FileFilter> allImageFilter = Gtk::FileFilter::create(); allImageFilter->set_name(_("All Images")); - - Glib::RefPtr<Gtk::FileFilter> allVectorFilter = Gtk::FileFilter::create(); + + Glib::RefPtr<Gtk::FileFilter> allVectorFilter = Gtk::FileFilter::create(); allVectorFilter->set_name(_("All Vectors")); - - Glib::RefPtr<Gtk::FileFilter> allBitmapFilter = Gtk::FileFilter::create(); + + Glib::RefPtr<Gtk::FileFilter> allBitmapFilter = Gtk::FileFilter::create(); allBitmapFilter->set_name(_("All Bitmaps")); #else Gtk::FileFilter allInkscapeFilter; allInkscapeFilter.set_name(_("All Inkscape Files")); - - Gtk::FileFilter allFilter; + + Gtk::FileFilter allFilter; allFilter.set_name(_("All Files")); allFilter.add_pattern("*"); - - Gtk::FileFilter allImageFilter; + + Gtk::FileFilter allImageFilter; allImageFilter.set_name(_("All Images")); - - Gtk::FileFilter allVectorFilter; + + Gtk::FileFilter allVectorFilter; allVectorFilter.set_name(_("All Vectors")); - - Gtk::FileFilter allBitmapFilter; + + Gtk::FileFilter allBitmapFilter; allBitmapFilter.set_name(_("All Bitmaps")); #endif - extensionMap[Glib::ustring(_("All Inkscape Files"))]=NULL; + extensionMap[Glib::ustring(_("All Inkscape Files"))] = NULL; add_filter(allInkscapeFilter); - extensionMap[Glib::ustring(_("All Files"))]=NULL; + extensionMap[Glib::ustring(_("All Files"))] = NULL; add_filter(allFilter); - - extensionMap[Glib::ustring(_("All Images"))]=NULL; + + extensionMap[Glib::ustring(_("All Images"))] = NULL; add_filter(allImageFilter); - extensionMap[Glib::ustring(_("All Vectors"))]=NULL; + extensionMap[Glib::ustring(_("All Vectors"))] = NULL; add_filter(allVectorFilter); - extensionMap[Glib::ustring(_("All Bitmaps"))]=NULL; + extensionMap[Glib::ustring(_("All Bitmaps"))] = NULL; add_filter(allBitmapFilter); - //patterns added dynamically below + // patterns added dynamically below Inkscape::Extension::DB::InputList extension_list; Inkscape::Extension::db.get_input_list(extension_list); for (Inkscape::Extension::DB::InputList::iterator current_item = extension_list.begin(); current_item != extension_list.end(); ++current_item) { - Inkscape::Extension::Input * imod = *current_item; + Inkscape::Extension::Input *imod = *current_item; // FIXME: would be nice to grey them out instead of not listing them - if (imod->deactivated()) continue; + if (imod->deactivated()) + continue; Glib::ustring upattern("*"); Glib::ustring extension = imod->get_extension(); @@ -838,7 +803,7 @@ void FileOpenDialogImplGtk::createFilterMenu() Glib::ustring uname(_(imod->get_filetypename())); #if WITH_GTKMM_3_0 - Glib::RefPtr<Gtk::FileFilter> filter = Gtk::FileFilter::create(); + Glib::RefPtr<Gtk::FileFilter> filter = Gtk::FileFilter::create(); filter->set_name(uname); filter->add_pattern(upattern); #else @@ -850,14 +815,14 @@ void FileOpenDialogImplGtk::createFilterMenu() add_filter(filter); extensionMap[uname] = imod; - //g_message("ext %s:%s '%s'\n", ioext->name, ioext->mimetype, upattern.c_str()); +// g_message("ext %s:%s '%s'\n", ioext->name, ioext->mimetype, upattern.c_str()); #if WITH_GTKMM_3_0 allInkscapeFilter->add_pattern(upattern); - if ( strncmp("image", imod->get_mimetype(), 5)==0 ) + if (strncmp("image", imod->get_mimetype(), 5) == 0) allImageFilter->add_pattern(upattern); #else allInkscapeFilter.add_pattern(upattern); - if ( strncmp("image", imod->get_mimetype(), 5)==0 ) + if (strncmp("image", imod->get_mimetype(), 5) == 0) allImageFilter.add_pattern(upattern); #endif @@ -865,32 +830,32 @@ void FileOpenDialogImplGtk::createFilterMenu() // g_print ("%s\n", imod->get_mimetype()); // I don't know of any other way to define "bitmap" formats other than by listing them - if ( - strncmp("image/png", imod->get_mimetype(), 9)==0 || - strncmp("image/jpeg", imod->get_mimetype(), 10)==0 || - strncmp("image/gif", imod->get_mimetype(), 9)==0 || - strncmp("image/x-icon", imod->get_mimetype(), 12)==0 || - strncmp("image/x-navi-animation", imod->get_mimetype(), 22)==0 || - strncmp("image/x-cmu-raster", imod->get_mimetype(), 18)==0 || - strncmp("image/x-xpixmap", imod->get_mimetype(), 15)==0 || - strncmp("image/bmp", imod->get_mimetype(), 9)==0 || - strncmp("image/vnd.wap.wbmp", imod->get_mimetype(), 18)==0 || - strncmp("image/tiff", imod->get_mimetype(), 10)==0 || - strncmp("image/x-xbitmap", imod->get_mimetype(), 15)==0 || - strncmp("image/x-tga", imod->get_mimetype(), 11)==0 || - strncmp("image/x-pcx", imod->get_mimetype(), 11)==0 - ) + if (strncmp("image/png", imod->get_mimetype(), 9) == 0 || + strncmp("image/jpeg", imod->get_mimetype(), 10) == 0 || + strncmp("image/gif", imod->get_mimetype(), 9) == 0 || + strncmp("image/x-icon", imod->get_mimetype(), 12) == 0 || + strncmp("image/x-navi-animation", imod->get_mimetype(), 22) == 0 || + strncmp("image/x-cmu-raster", imod->get_mimetype(), 18) == 0 || + strncmp("image/x-xpixmap", imod->get_mimetype(), 15) == 0 || + strncmp("image/bmp", imod->get_mimetype(), 9) == 0 || + strncmp("image/vnd.wap.wbmp", imod->get_mimetype(), 18) == 0 || + strncmp("image/tiff", imod->get_mimetype(), 10) == 0 || + strncmp("image/x-xbitmap", imod->get_mimetype(), 15) == 0 || + strncmp("image/x-tga", imod->get_mimetype(), 11) == 0 || + strncmp("image/x-pcx", imod->get_mimetype(), 11) == 0) + { #if WITH_GTKMM_3_0 allBitmapFilter->add_pattern(upattern); #else allBitmapFilter.add_pattern(upattern); #endif - else + } else { #if WITH_GTKMM_3_0 allVectorFilter->add_pattern(upattern); #else allVectorFilter.add_pattern(upattern); #endif + } } } return; @@ -899,50 +864,43 @@ void FileOpenDialogImplGtk::createFilterMenu() /** * Show this dialog modally. Return true if user hits [OK] */ -bool -FileOpenDialogImplGtk::show() +bool FileOpenDialogImplGtk::show() { - set_modal (TRUE); //Window - sp_transientize(GTK_WIDGET(gobj())); //Make transient - gint b = run(); //Dialog + set_modal(TRUE); // Window + sp_transientize(GTK_WIDGET(gobj())); // Make transient + gint b = run(); // Dialog svgPreview.showNoPreview(); hide(); - if (b == Gtk::RESPONSE_OK) - { - //This is a hack, to avoid the warning messages that - //Gtk::FileChooser::get_filter() returns - //should be: Gtk::FileFilter *filter = get_filter(); + if (b == Gtk::RESPONSE_OK) { + // This is a hack, to avoid the warning messages that + // Gtk::FileChooser::get_filter() returns + // should be: Gtk::FileFilter *filter = get_filter(); GtkFileChooser *gtkFileChooser = Gtk::FileChooser::gobj(); GtkFileFilter *filter = gtk_file_chooser_get_filter(gtkFileChooser); - if (filter) - { - //Get which extension was chosen, if any + if (filter) { + // Get which extension was chosen, if any extension = extensionMap[gtk_file_filter_get_name(filter)]; - } + } myFilename = get_filename(); #ifdef WITH_GNOME_VFS if (myFilename.empty() && gnome_vfs_initialized()) myFilename = get_uri(); #endif - cleanup( true ); - return TRUE; - } - else - { - cleanup( false ); - return FALSE; - } + cleanup(true); + return true; + } else { + cleanup(false); + return false; + } } - /** * Get the file extension type that was selected by the user. Valid after an [OK] */ -Inkscape::Extension::Extension * -FileOpenDialogImplGtk::getSelectionType() +Inkscape::Extension::Extension *FileOpenDialogImplGtk::getSelectionType() { return extension; } @@ -951,8 +909,7 @@ FileOpenDialogImplGtk::getSelectionType() /** * Get the file name chosen by the user. Valid after an [OK] */ -Glib::ustring -FileOpenDialogImplGtk::getFilename (void) +Glib::ustring FileOpenDialogImplGtk::getFilename(void) { return myFilename; } @@ -961,7 +918,7 @@ FileOpenDialogImplGtk::getFilename (void) /** * To Get Multiple filenames selected at-once. */ -std::vector<Glib::ustring>FileOpenDialogImplGtk::getFilenames() +std::vector<Glib::ustring> FileOpenDialogImplGtk::getFilenames() { #if WITH_GTKMM_3_0 std::vector<std::string> result_tmp = get_filenames(); @@ -969,9 +926,8 @@ std::vector<Glib::ustring>FileOpenDialogImplGtk::getFilenames() // Copy filenames to a vector of type Glib::ustring std::vector<Glib::ustring> result; - for (std::vector<std::string>::iterator it = result_tmp.begin(); - it != result_tmp.end(); ++it) - result.push_back(*it); + for (std::vector<std::string>::iterator it = result_tmp.begin(); it != result_tmp.end(); ++it) + result.push_back(*it); #else std::vector<Glib::ustring> result = get_filenames(); @@ -991,7 +947,6 @@ Glib::ustring FileOpenDialogImplGtk::getCurrentDirectory() - //######################################################################## //# F I L E S A V E //######################################################################## @@ -999,16 +954,14 @@ Glib::ustring FileOpenDialogImplGtk::getCurrentDirectory() /** * Constructor */ -FileSaveDialogImplGtk::FileSaveDialogImplGtk( Gtk::Window &parentWindow, - const Glib::ustring &dir, - FileDialogType fileTypes, - const Glib::ustring &title, - const Glib::ustring &/*default_key*/, - const gchar* docTitle, - const Inkscape::Extension::FileSaveMethod save_method) : - FileDialogBaseGtk(parentWindow, title, Gtk::FILE_CHOOSER_ACTION_SAVE, fileTypes, - (save_method == Inkscape::Extension::FILE_SAVE_METHOD_SAVE_COPY) ? "/dialogs/save_copy" : "/dialogs/save_as"), - save_method(save_method) +FileSaveDialogImplGtk::FileSaveDialogImplGtk(Gtk::Window &parentWindow, const Glib::ustring &dir, + FileDialogType fileTypes, const Glib::ustring &title, + const Glib::ustring & /*default_key*/, const gchar *docTitle, + const Inkscape::Extension::FileSaveMethod save_method) + : FileDialogBaseGtk(parentWindow, title, Gtk::FILE_CHOOSER_ACTION_SAVE, fileTypes, + (save_method == Inkscape::Extension::FILE_SAVE_METHOD_SAVE_COPY) ? "/dialogs/save_copy" + : "/dialogs/save_as") + , save_method(save_method) { FileSaveDialog::myDocTitle = docTitle; @@ -1030,18 +983,19 @@ FileSaveDialogImplGtk::FileSaveDialogImplGtk( Gtk::Window &parentWindow, _dialogType = fileTypes; /* Set the pwd and/or the filename */ - if (dir.size() > 0) - { + if (dir.size() > 0) { Glib::ustring udir(dir); Glib::ustring::size_type len = udir.length(); // leaving a trailing backslash on the directory name leads to the infamous // double-directory bug on win32 - if (len != 0 && udir[len - 1] == '\\') udir.erase(len - 1); - myFilename = udir; + if ((len != 0) && (udir[len - 1] == '\\')) { + udir.erase(len - 1); } + myFilename = udir; + } //###### Add the file types menu - //createFilterMenu(); + // createFilterMenu(); //###### Do we want the .xxx extension automatically added? Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -1055,60 +1009,54 @@ FileSaveDialogImplGtk::FileSaveDialogImplGtk( Gtk::Window &parentWindow, if (_dialogType != CUSTOM_TYPE) createFileTypeMenu(); - fileTypeComboBox.set_size_request(200,40); - fileTypeComboBox.signal_changed().connect( - sigc::mem_fun(*this, &FileSaveDialogImplGtk::fileTypeChangedCallback) ); + fileTypeComboBox.set_size_request(200, 40); + fileTypeComboBox.signal_changed().connect(sigc::mem_fun(*this, &FileSaveDialogImplGtk::fileTypeChangedCallback)); - childBox.pack_start( checksBox ); - childBox.pack_end( fileTypeComboBox ); - checksBox.pack_start( fileTypeCheckbox ); - checksBox.pack_start( previewCheckbox ); + childBox.pack_start(checksBox); + childBox.pack_end(fileTypeComboBox); + checksBox.pack_start(fileTypeCheckbox); + checksBox.pack_start(previewCheckbox); - set_extra_widget( childBox ); + set_extra_widget(childBox); - //Let's do some customization + // Let's do some customization fileNameEntry = NULL; Gtk::Container *cont = get_toplevel(); std::vector<Gtk::Entry *> entries; findEntryWidgets(cont, entries); - //g_message("Found %d entry widgets\n", entries.size()); - if (!entries.empty()) - { - //Catch when user hits [return] on the text field + // g_message("Found %d entry widgets\n", entries.size()); + if (!entries.empty()) { + // Catch when user hits [return] on the text field fileNameEntry = entries[0]; fileNameEntry->signal_activate().connect( - sigc::mem_fun(*this, &FileSaveDialogImplGtk::fileNameEntryChangedCallback) ); - } + sigc::mem_fun(*this, &FileSaveDialogImplGtk::fileNameEntryChangedCallback)); + } - //Let's do more customization + // Let's do more customization std::vector<Gtk::Expander *> expanders; findExpanderWidgets(cont, expanders); - //g_message("Found %d expander widgets\n", expanders.size()); - if (!expanders.empty()) - { - //Always show the file list + // g_message("Found %d expander widgets\n", expanders.size()); + if (!expanders.empty()) { + // Always show the file list Gtk::Expander *expander = expanders[0]; expander->set_expanded(true); - } + } // allow easy access to the user's own templates folder - gchar *templates = profile_path ("templates"); - if ( Inkscape::IO::file_test(templates, G_FILE_TEST_EXISTS) - && Inkscape::IO::file_test(templates, G_FILE_TEST_IS_DIR) - && g_path_is_absolute(templates) - ) - { + gchar *templates = profile_path("templates"); + if (Inkscape::IO::file_test(templates, G_FILE_TEST_EXISTS) && + Inkscape::IO::file_test(templates, G_FILE_TEST_IS_DIR) && g_path_is_absolute(templates)) { add_shortcut_folder(templates); } - g_free (templates); + g_free(templates); - //if (extension == NULL) + // if (extension == NULL) // checkbox.set_sensitive(FALSE); add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); - set_default(*add_button(Gtk::Stock::SAVE, Gtk::RESPONSE_OK)); + set_default(*add_button(Gtk::Stock::SAVE, Gtk::RESPONSE_OK)); show_all_children(); } @@ -1129,27 +1077,27 @@ void FileSaveDialogImplGtk::fileNameEntryChangedCallback() return; Glib::ustring fileName = fileNameEntry->get_text(); - if (!Glib::get_charset()) //If we are not utf8 + if (!Glib::get_charset()) // If we are not utf8 fileName = Glib::filename_to_utf8(fileName); - //g_message("User hit return. Text is '%s'\n", fileName.c_str()); + // g_message("User hit return. Text is '%s'\n", fileName.c_str()); if (!Glib::path_is_absolute(fileName)) { - //try appending to the current path + // try appending to the current path // not this way: fileName = get_current_folder() + "/" + fileName; std::vector<Glib::ustring> pathSegments; - pathSegments.push_back( get_current_folder() ); - pathSegments.push_back( fileName ); + pathSegments.push_back(get_current_folder()); + pathSegments.push_back(fileName); fileName = Glib::build_filename(pathSegments); } - //g_message("path:'%s'\n", fileName.c_str()); + // g_message("path:'%s'\n", fileName.c_str()); if (Glib::file_test(fileName, Glib::FILE_TEST_IS_DIR)) { set_current_folder(fileName); - } else if (/*Glib::file_test(fileName, Glib::FILE_TEST_IS_REGULAR)*/1) { - //dialog with either (1) select a regular file or (2) cd to dir - //simulate an 'OK' + } else if (/*Glib::file_test(fileName, Glib::FILE_TEST_IS_REGULAR)*/ 1) { + // dialog with either (1) select a regular file or (2) cd to dir + // simulate an 'OK' set_filename(fileName); response(Gtk::RESPONSE_OK); } @@ -1163,10 +1111,11 @@ void FileSaveDialogImplGtk::fileNameEntryChangedCallback() void FileSaveDialogImplGtk::fileTypeChangedCallback() { int sel = fileTypeComboBox.get_active_row_number(); - if (sel<0 || sel >= (int)fileTypes.size()) + if ((sel < 0) || (sel >= (int)fileTypes.size())) return; + FileType type = fileTypes[sel]; - //g_message("selected: %s\n", type.name.c_str()); + // g_message("selected: %s\n", type.name.c_str()); extension = type.extension; #if WITH_GTKMM_3_0 @@ -1193,7 +1142,7 @@ void FileSaveDialogImplGtk::addFileType(Glib::ustring name, Glib::ustring patter fileTypeComboBox.set_active(0); - fileTypeChangedCallback(); //call at least once to set the filter + fileTypeChangedCallback(); // call at least once to set the filter } void FileSaveDialogImplGtk::createFileTypeMenu() @@ -1203,20 +1152,20 @@ void FileSaveDialogImplGtk::createFileTypeMenu() knownExtensions.clear(); for (Inkscape::Extension::DB::OutputList::iterator current_item = extension_list.begin(); - current_item != extension_list.end(); ++current_item) - { - Inkscape::Extension::Output * omod = *current_item; + current_item != extension_list.end(); ++current_item) { + Inkscape::Extension::Output *omod = *current_item; // FIXME: would be nice to grey them out instead of not listing them - if (omod->deactivated()) continue; + if (omod->deactivated()) + continue; FileType type; - type.name = (_(omod->get_filetypename())); - type.pattern = "*"; + type.name = (_(omod->get_filetypename())); + type.pattern = "*"; Glib::ustring extension = omod->get_extension(); - knownExtensions.insert( extension.casefold() ); - fileDialogExtensionToPattern (type.pattern, extension); - type.extension= omod; + knownExtensions.insert(extension.casefold()); + fileDialogExtensionToPattern(type.pattern, extension); + type.extension = omod; fileTypeComboBox.append(type.name); fileTypes.push_back(type); } @@ -1231,23 +1180,20 @@ void FileSaveDialogImplGtk::createFileTypeMenu() fileTypeComboBox.set_active(0); - fileTypeChangedCallback(); //call at least once to set the filter + fileTypeChangedCallback(); // call at least once to set the filter } - - /** * Show this dialog modally. Return true if user hits [OK] */ -bool -FileSaveDialogImplGtk::show() +bool FileSaveDialogImplGtk::show() { change_path(myFilename); - set_modal (TRUE); //Window - sp_transientize(GTK_WIDGET(gobj())); //Make transient - gint b = run(); //Dialog + set_modal(TRUE); // Window + sp_transientize(GTK_WIDGET(gobj())); // Make transient + gint b = run(); // Dialog svgPreview.showNoPreview(); set_preview_widget_active(false); hide(); @@ -1255,7 +1201,7 @@ FileSaveDialogImplGtk::show() if (b == Gtk::RESPONSE_OK) { updateNameAndExtension(); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - + // Store changes of the "Append filename automatically" checkbox back to preferences. if (save_method == Inkscape::Extension::FILE_SAVE_METHOD_SAVE_COPY) { prefs->setBool("/dialogs/save_copy/append_extension", fileTypeCheckbox.get_active()); @@ -1263,14 +1209,14 @@ FileSaveDialogImplGtk::show() prefs->setBool("/dialogs/save_as/append_extension", fileTypeCheckbox.get_active()); } - Inkscape::Extension::store_file_extension_in_prefs ((extension != NULL ? extension->get_id() : "" ), save_method); + Inkscape::Extension::store_file_extension_in_prefs((extension != NULL ? extension->get_id() : ""), save_method); - cleanup( true ); + cleanup(true); - return TRUE; + return true; } else { - cleanup( false ); - return FALSE; + cleanup(false); + return false; } } @@ -1278,23 +1224,22 @@ FileSaveDialogImplGtk::show() /** * Get the file extension type that was selected by the user. Valid after an [OK] */ -Inkscape::Extension::Extension * -FileSaveDialogImplGtk::getSelectionType() +Inkscape::Extension::Extension *FileSaveDialogImplGtk::getSelectionType() { return extension; } -void FileSaveDialogImplGtk::setSelectionType( Inkscape::Extension::Extension * key ) +void FileSaveDialogImplGtk::setSelectionType(Inkscape::Extension::Extension *key) { // If no pointer to extension is passed in, look up based on filename extension. - if ( !key ) { + if (!key) { // Not quite UTF-8 here. gchar *filenameLower = g_ascii_strdown(myFilename.c_str(), -1); - for ( int i = 0; !key && (i < (int)fileTypes.size()); i++ ) { - Inkscape::Extension::Output *ext = dynamic_cast<Inkscape::Extension::Output*>(fileTypes[i].extension); - if ( ext && ext->get_extension() ) { - gchar *extensionLower = g_ascii_strdown( ext->get_extension(), -1 ); - if ( g_str_has_suffix(filenameLower, extensionLower) ) { + for (int i = 0; !key && (i < (int)fileTypes.size()); i++) { + Inkscape::Extension::Output *ext = dynamic_cast<Inkscape::Extension::Output *>(fileTypes[i].extension); + if (ext && ext->get_extension()) { + gchar *extensionLower = g_ascii_strdown(ext->get_extension(), -1); + if (g_str_has_suffix(filenameLower, extensionLower)) { key = fileTypes[i].extension; } g_free(extensionLower); @@ -1304,17 +1249,17 @@ void FileSaveDialogImplGtk::setSelectionType( Inkscape::Extension::Extension * k } // Ensure the proper entry in the combo box is selected. - if ( key ) { + if (key) { extension = key; - gchar const * extensionID = extension->get_id(); - if ( extensionID ) { - for ( int i = 0; i < (int)fileTypes.size(); i++ ) { + gchar const *extensionID = extension->get_id(); + if (extensionID) { + for (int i = 0; i < (int)fileTypes.size(); i++) { Inkscape::Extension::Extension *ext = fileTypes[i].extension; - if ( ext ) { - gchar const * id = ext->get_id(); - if ( id && ( strcmp(extensionID, id) == 0) ) { + if (ext) { + gchar const *id = ext->get_id(); + if (id && (strcmp(extensionID, id) == 0)) { int oldSel = fileTypeComboBox.get_active_row_number(); - if ( i != oldSel ) { + if (i != oldSel) { fileTypeComboBox.set_active(i); } break; @@ -1340,32 +1285,34 @@ FileSaveDialogImplGtk::change_title(const Glib::ustring& title) /** * Change the default save path location. */ -void -FileSaveDialogImplGtk::change_path(const Glib::ustring& path) +void FileSaveDialogImplGtk::change_path(const Glib::ustring &path) { myFilename = path; if (Glib::file_test(myFilename, Glib::FILE_TEST_IS_DIR)) { - //fprintf(stderr,"set_current_folder(%s)\n",myFilename.c_str()); + // fprintf(stderr,"set_current_folder(%s)\n",myFilename.c_str()); set_current_folder(myFilename); } else { - //fprintf(stderr,"set_filename(%s)\n",myFilename.c_str()); - if ( Glib::file_test( myFilename, Glib::FILE_TEST_EXISTS ) ) { + // fprintf(stderr,"set_filename(%s)\n",myFilename.c_str()); + if (Glib::file_test(myFilename, Glib::FILE_TEST_EXISTS)) { set_filename(myFilename); } else { - std::string dirName = Glib::path_get_dirname( myFilename ); - if ( dirName != get_current_folder() ) { + std::string dirName = Glib::path_get_dirname(myFilename); + if (dirName != get_current_folder()) { set_current_folder(dirName); } } Glib::ustring basename = Glib::path_get_basename(myFilename); - //fprintf(stderr,"set_current_name(%s)\n",basename.c_str()); - try { - set_current_name( Glib::filename_to_utf8(basename) ); - } catch ( Glib::ConvertError& e ) { - g_warning( "Error converting save filename to UTF-8." ); + // fprintf(stderr,"set_current_name(%s)\n",basename.c_str()); + try + { + set_current_name(Glib::filename_to_utf8(basename)); + } + catch (Glib::ConvertError &e) + { + g_warning("Error converting save filename to UTF-8."); // try a fallback. - set_current_name( basename ); + set_current_name(basename); } } } @@ -1375,16 +1322,16 @@ void FileSaveDialogImplGtk::updateNameAndExtension() // Pick up any changes the user has typed in. Glib::ustring tmp = get_filename(); #ifdef WITH_GNOME_VFS - if ( tmp.empty() && gnome_vfs_initialized() ) { + if (tmp.empty() && gnome_vfs_initialized()) { tmp = get_uri(); } #endif - if ( !tmp.empty() ) { + if (!tmp.empty()) { myFilename = tmp; } - Inkscape::Extension::Output* newOut = extension ? dynamic_cast<Inkscape::Extension::Output*>(extension) : 0; - if ( fileTypeCheckbox.get_active() && newOut ) { + Inkscape::Extension::Output *newOut = extension ? dynamic_cast<Inkscape::Extension::Output *>(extension) : 0; + if (fileTypeCheckbox.get_active() && newOut) { // Append the file extension if it's not already present and display it in the file name entry field appendExtension(myFilename, newOut); change_path(myFilename); @@ -1407,27 +1354,27 @@ void FileExportDialogImpl::fileNameEntryChangedCallback() return; Glib::ustring fileName = fileNameEntry->get_text(); - if (!Glib::get_charset()) //If we are not utf8 + if (!Glib::get_charset()) // If we are not utf8 fileName = Glib::filename_to_utf8(fileName); - //g_message("User hit return. Text is '%s'\n", fileName.c_str()); + // g_message("User hit return. Text is '%s'\n", fileName.c_str()); if (!Glib::path_is_absolute(fileName)) { - //try appending to the current path + // try appending to the current path // not this way: fileName = get_current_folder() + "/" + fileName; std::vector<Glib::ustring> pathSegments; - pathSegments.push_back( get_current_folder() ); - pathSegments.push_back( fileName ); + pathSegments.push_back(get_current_folder()); + pathSegments.push_back(fileName); fileName = Glib::build_filename(pathSegments); } - //g_message("path:'%s'\n", fileName.c_str()); + // g_message("path:'%s'\n", fileName.c_str()); if (Glib::file_test(fileName, Glib::FILE_TEST_IS_DIR)) { set_current_folder(fileName); - } else if (/*Glib::file_test(fileName, Glib::FILE_TEST_IS_REGULAR)*/1) { - //dialog with either (1) select a regular file or (2) cd to dir - //simulate an 'OK' + } else if (/*Glib::file_test(fileName, Glib::FILE_TEST_IS_REGULAR)*/ 1) { + // dialog with either (1) select a regular file or (2) cd to dir + // simulate an 'OK' set_filename(fileName); response(Gtk::RESPONSE_OK); } @@ -1441,10 +1388,11 @@ void FileExportDialogImpl::fileNameEntryChangedCallback() void FileExportDialogImpl::fileTypeChangedCallback() { int sel = fileTypeComboBox.get_active_row_number(); - if (sel<0 || sel >= (int)fileTypes.size()) + if ((sel < 0) || (sel >= (int)fileTypes.size())) return; + FileType type = fileTypes[sel]; - //g_message("selected: %s\n", type.name.c_str()); + // g_message("selected: %s\n", type.name.c_str()); Gtk::FileFilter filter; filter.add_pattern(type.pattern); set_filter(filter); @@ -1458,19 +1406,19 @@ void FileExportDialogImpl::createFileTypeMenu() Inkscape::Extension::db.get_output_list(extension_list); for (Inkscape::Extension::DB::OutputList::iterator current_item = extension_list.begin(); - current_item != extension_list.end(); ++current_item) - { - Inkscape::Extension::Output * omod = *current_item; + current_item != extension_list.end(); ++current_item) { + Inkscape::Extension::Output *omod = *current_item; // FIXME: would be nice to grey them out instead of not listing them - if (omod->deactivated()) continue; + if (omod->deactivated()) + continue; FileType type; - type.name = (_(omod->get_filetypename())); - type.pattern = "*"; + type.name = (_(omod->get_filetypename())); + type.pattern = "*"; Glib::ustring extension = omod->get_extension(); - fileDialogExtensionToPattern (type.pattern, extension); - type.extension= omod; + fileDialogExtensionToPattern(type.pattern, extension); + type.extension = omod; fileTypeComboBox.append_text(type.name); fileTypes.push_back(type); } @@ -1485,28 +1433,26 @@ void FileExportDialogImpl::createFileTypeMenu() fileTypeComboBox.set_active(0); - fileTypeChangedCallback(); //call at least once to set the filter + fileTypeChangedCallback(); // call at least once to set the filter } /** * Constructor */ -FileExportDialogImpl::FileExportDialogImpl( Gtk::Window& parentWindow, - const Glib::ustring &dir, - FileDialogType fileTypes, - const Glib::ustring &title, - const Glib::ustring &/*default_key*/ ) : - FileDialogBaseGtk(parentWindow, title, Gtk::FILE_CHOOSER_ACTION_SAVE, fileTypes, "/dialogs/export"), - sourceX0Spinner("X0", _("Left edge of source")), - sourceY0Spinner("Y0", _("Top edge of source")), - sourceX1Spinner("X1", _("Right edge of source")), - sourceY1Spinner("Y1", _("Bottom edge of source")), - sourceWidthSpinner("Width", _("Source width")), - sourceHeightSpinner("Height", _("Source height")), - destWidthSpinner("Width", _("Destination width")), - destHeightSpinner("Height", _("Destination height")), - destDPISpinner("DPI", _("Resolution (dots per inch)")) +FileExportDialogImpl::FileExportDialogImpl(Gtk::Window &parentWindow, const Glib::ustring &dir, + FileDialogType fileTypes, const Glib::ustring &title, + const Glib::ustring & /*default_key*/) + : FileDialogBaseGtk(parentWindow, title, Gtk::FILE_CHOOSER_ACTION_SAVE, fileTypes, "/dialogs/export") + , sourceX0Spinner("X0", _("Left edge of source")) + , sourceY0Spinner("Y0", _("Top edge of source")) + , sourceX1Spinner("X1", _("Right edge of source")) + , sourceY1Spinner("Y1", _("Bottom edge of source")) + , sourceWidthSpinner("Width", _("Source width")) + , sourceHeightSpinner("Height", _("Source height")) + , destWidthSpinner("Width", _("Destination width")) + , destHeightSpinner("Height", _("Destination height")) + , destDPISpinner("DPI", _("Resolution (dots per inch)")) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); append_extension = prefs->getBool("/dialogs/save_export/append_extension", true); @@ -1529,15 +1475,15 @@ FileExportDialogImpl::FileExportDialogImpl( Gtk::Window& parentWindow, _dialogType = fileTypes; /* Set the pwd and/or the filename */ - if (dir.size()>0) - { + if (dir.size() > 0) { Glib::ustring udir(dir); Glib::ustring::size_type len = udir.length(); // leaving a trailing backslash on the directory name leads to the infamous // double-directory bug on win32 - if (len != 0 && udir[len - 1] == '\\') udir.erase(len - 1); + if ((len != 0) && (udir[len - 1] == '\\')) + udir.erase(len - 1); set_current_folder(udir.c_str()); - } + } //######################################### //## EXTRA WIDGET -- SOURCE SIDE @@ -1564,16 +1510,16 @@ FileExportDialogImpl::FileExportDialogImpl( Gtk::Window& parentWindow, - //dimension buttons - sourceTable.resize(3,3); - sourceTable.attach(sourceX0Spinner, 0,1,0,1); - sourceTable.attach(sourceY0Spinner, 1,2,0,1); + // dimension buttons + sourceTable.resize(3, 3); + sourceTable.attach(sourceX0Spinner, 0, 1, 0, 1); + sourceTable.attach(sourceY0Spinner, 1, 2, 0, 1); sourceUnitsSpinner.setUnitType(UNIT_TYPE_LINEAR); - sourceTable.attach(sourceUnitsSpinner, 2,3,0,1); - sourceTable.attach(sourceX1Spinner, 0,1,1,2); - sourceTable.attach(sourceY1Spinner, 1,2,1,2); - sourceTable.attach(sourceWidthSpinner, 0,1,2,3); - sourceTable.attach(sourceHeightSpinner, 1,2,2,3); + sourceTable.attach(sourceUnitsSpinner, 2, 3, 0, 1); + sourceTable.attach(sourceX1Spinner, 0, 1, 1, 2); + sourceTable.attach(sourceY1Spinner, 1, 2, 1, 2); + sourceTable.attach(sourceWidthSpinner, 0, 1, 2, 3); + sourceTable.attach(sourceHeightSpinner, 1, 2, 2, 3); sourceBox.pack_start(sourceTable); sourceFrame.set_label(_("Source")); @@ -1586,12 +1532,12 @@ FileExportDialogImpl::FileExportDialogImpl( Gtk::Window& parentWindow, //######################################### - destTable.resize(3,3); - destTable.attach(destWidthSpinner, 0,1,0,1); - destTable.attach(destHeightSpinner, 1,2,0,1); + destTable.resize(3, 3); + destTable.attach(destWidthSpinner, 0, 1, 0, 1); + destTable.attach(destHeightSpinner, 1, 2, 0, 1); destUnitsSpinner.setUnitType(UNIT_TYPE_LINEAR); - destTable.attach(destUnitsSpinner, 2,3,0,1); - destTable.attach(destDPISpinner, 0,1,1,2); + destTable.attach(destUnitsSpinner, 2, 3, 0, 1); + destTable.attach(destDPISpinner, 0, 1, 1, 2); destBox.pack_start(destTable); @@ -1609,8 +1555,6 @@ FileExportDialogImpl::FileExportDialogImpl( Gtk::Window& parentWindow, - - //###### File options //###### Do we want the .xxx extension automatically added? fileTypeCheckbox.set_label(Glib::ustring(_("Append filename extension automatically"))); @@ -1619,9 +1563,8 @@ FileExportDialogImpl::FileExportDialogImpl( Gtk::Window& parentWindow, //###### File type menu createFileTypeMenu(); - fileTypeComboBox.set_size_request(200,40); - fileTypeComboBox.signal_changed().connect( - sigc::mem_fun(*this, &FileExportDialogImpl::fileTypeChangedCallback) ); + fileTypeComboBox.set_size_request(200, 40); + fileTypeComboBox.signal_changed().connect(sigc::mem_fun(*this, &FileExportDialogImpl::fileTypeChangedCallback)); destBox.pack_start(fileTypeComboBox); @@ -1637,38 +1580,35 @@ FileExportDialogImpl::FileExportDialogImpl( Gtk::Window& parentWindow, - - //Let's do some customization + // Let's do some customization fileNameEntry = NULL; Gtk::Container *cont = get_toplevel(); std::vector<Gtk::Entry *> entries; findEntryWidgets(cont, entries); - //g_message("Found %d entry widgets\n", entries.size()); - if (!entries.empty()) - { - //Catch when user hits [return] on the text field + // g_message("Found %d entry widgets\n", entries.size()); + if (!entries.empty()) { + // Catch when user hits [return] on the text field fileNameEntry = entries[0]; fileNameEntry->signal_activate().connect( - sigc::mem_fun(*this, &FileExportDialogImpl::fileNameEntryChangedCallback) ); - } + sigc::mem_fun(*this, &FileExportDialogImpl::fileNameEntryChangedCallback)); + } - //Let's do more customization + // Let's do more customization std::vector<Gtk::Expander *> expanders; findExpanderWidgets(cont, expanders); - //g_message("Found %d expander widgets\n", expanders.size()); - if (!expanders.empty()) - { - //Always show the file list + // g_message("Found %d expander widgets\n", expanders.size()); + if (!expanders.empty()) { + // Always show the file list Gtk::Expander *expander = expanders[0]; expander->set_expanded(true); - } + } - //if (extension == NULL) + // if (extension == NULL) // checkbox.set_sensitive(FALSE); add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); - set_default(*add_button(Gtk::Stock::SAVE, Gtk::RESPONSE_OK)); + set_default(*add_button(Gtk::Stock::SAVE, Gtk::RESPONSE_OK)); show_all_children(); } @@ -1685,30 +1625,28 @@ FileExportDialogImpl::~FileExportDialogImpl() /** * Show this dialog modally. Return true if user hits [OK] */ -bool -FileExportDialogImpl::show() +bool FileExportDialogImpl::show() { - Glib::ustring s = Glib::filename_to_utf8 (get_current_folder()); - if (s.length() == 0) - s = getcwd (NULL, 0); - set_current_folder(Glib::filename_from_utf8(s)); //hack to force initial dir listing - set_modal (TRUE); //Window - sp_transientize(GTK_WIDGET(gobj())); //Make transient - gint b = run(); //Dialog + Glib::ustring s = Glib::filename_to_utf8(get_current_folder()); + if (s.length() == 0) { + s = getcwd(NULL, 0); + } + set_current_folder(Glib::filename_from_utf8(s)); // hack to force initial dir listing + set_modal(TRUE); // Window + sp_transientize(GTK_WIDGET(gobj())); // Make transient + gint b = run(); // Dialog svgPreview.showNoPreview(); hide(); - if (b == Gtk::RESPONSE_OK) - { - int sel = fileTypeComboBox.get_active_row_number (); - if (sel>=0 && sel< (int)fileTypes.size()) - { + if (b == Gtk::RESPONSE_OK) { + int sel = fileTypeComboBox.get_active_row_number(); + if (sel >= 0 && sel < (int)fileTypes.size()) { FileType &type = fileTypes[sel]; extension = type.extension; - } + } myFilename = get_filename(); #ifdef WITH_GNOME_VFS - if ( myFilename.empty() && gnome_vfs_initialized() ) { + if (myFilename.empty() && gnome_vfs_initialized()) { myFilename = get_uri(); } #endif @@ -1722,20 +1660,17 @@ FileExportDialogImpl::show() prefs->setBool("/dialogs/save_export/append_extension", append_extension); prefs->setBool("/dialogs/save_export/default", ( extension != NULL ? extension->get_id() : "" )); */ - return TRUE; - } - else - { - return FALSE; - } + return true; + } else { + return false; + } } /** * Get the file extension type that was selected by the user. Valid after an [OK] */ -Inkscape::Extension::Extension * -FileExportDialogImpl::getSelectionType() +Inkscape::Extension::Extension *FileExportDialogImpl::getSelectionType() { return extension; } @@ -1744,8 +1679,7 @@ FileExportDialogImpl::getSelectionType() /** * Get the file name chosen by the user. Valid after an [OK] */ -Glib::ustring -FileExportDialogImpl::getFilename() +Glib::ustring FileExportDialogImpl::getFilename() { return myFilename; } @@ -1753,9 +1687,9 @@ FileExportDialogImpl::getFilename() #endif // NEW_EXPORT_DIALOG -} //namespace Dialog -} //namespace UI -} //namespace Inkscape +} // namespace Dialog +} // namespace UI +} // namespace Inkscape /* Local Variables: diff --git a/src/ui/dialog/fill-and-stroke.cpp b/src/ui/dialog/fill-and-stroke.cpp index 19b873d54..c55d55cda 100644 --- a/src/ui/dialog/fill-and-stroke.cpp +++ b/src/ui/dialog/fill-and-stroke.cpp @@ -131,7 +131,7 @@ FillAndStroke::_savePagePref(guint page_num) void FillAndStroke::_layoutPageFill() { - fillWdgt = manage(sp_fill_style_widget_new()); + fillWdgt = Gtk::manage(sp_fill_style_widget_new()); #if WITH_GTKMM_3_0 _page_fill->table().attach(*fillWdgt, 0, 0, 1, 1); @@ -143,7 +143,7 @@ FillAndStroke::_layoutPageFill() void FillAndStroke::_layoutPageStrokePaint() { - strokeWdgt = manage(sp_stroke_style_paint_widget_new()); + strokeWdgt = Gtk::manage(sp_stroke_style_paint_widget_new()); #if WITH_GTKMM_3_0 _page_stroke_paint->table().attach(*strokeWdgt, 0, 0, 1, 1); @@ -195,11 +195,11 @@ FillAndStroke::showPageStrokeStyle() Gtk::HBox& FillAndStroke::_createPageTabLabel(const Glib::ustring& label, const char *label_image) { - Gtk::HBox *_tab_label_box = manage(new Gtk::HBox(false, 4)); + Gtk::HBox *_tab_label_box = Gtk::manage(new Gtk::HBox(false, 4)); _tab_label_box->pack_start(*Glib::wrap(sp_icon_new(Inkscape::ICON_SIZE_DECORATION, label_image))); - Gtk::Label *_tab_label = manage(new Gtk::Label(label, true)); + Gtk::Label *_tab_label = Gtk::manage(new Gtk::Label(label, true)); _tab_label_box->pack_start(*_tab_label); _tab_label_box->show_all(); diff --git a/src/ui/dialog/filter-effects-dialog.cpp b/src/ui/dialog/filter-effects-dialog.cpp index 38e05a1c7..c2367c2a2 100644 --- a/src/ui/dialog/filter-effects-dialog.cpp +++ b/src/ui/dialog/filter-effects-dialog.cpp @@ -47,6 +47,7 @@ #include "filters/blend.h" #include "filters/colormatrix.h" #include "filters/componenttransfer.h" +#include "filters/componenttransfer-funcnode.h" #include "filters/composite.h" #include "filters/convolvematrix.h" #include "filters/displacementmap.h" @@ -369,6 +370,36 @@ public: } }; +// Used for tableValue in feComponentTransfer +class EntryAttr : public Gtk::Entry, public AttrWidget +{ +public: + EntryAttr(const SPAttributeEnum a, char* tip_text) + : AttrWidget(a) + { + signal_changed().connect(signal_attr_changed().make_slot()); + if (tip_text) { + set_tooltip_text(tip_text); + } + } + + // No validity checking is done + Glib::ustring get_as_attribute() const + { + return get_text(); + } + + void set_from_attribute(SPObject* o) + { + const gchar* val = attribute_value(o); + if(val) { + set_text( val ); + } else { + set_text( "" ); + } + } +}; + /* Displays/Edits the matrix for feConvolveMatrix or feColorMatrix */ class FilterEffectsDialog::MatrixAttr : public Gtk::Frame, public AttrWidget { @@ -746,7 +777,7 @@ public: _groups[i] = new Gtk::VBox; b.pack_start(*_groups[i], false, false); } - _current_type = 0; + //_current_type = 0; If set to 0 then update_and_show() fails to update properly. } ~Settings() @@ -766,9 +797,9 @@ public: for(unsigned i = 0; i < _groups.size(); ++i) _groups[i]->hide(); } - if(t >= 0) - _groups[t]->show_all(); - + if(t >= 0) { + _groups[t]->show(); // Do not use show_all(), it shows children than should be hidden + } _dialog.set_attrs_locked(true); for(unsigned i = 0; i < _attrwidgets[_current_type].size(); ++i) _attrwidgets[_current_type][i]->set_from_attribute(ob); @@ -800,7 +831,10 @@ public: // LightSource LightSourceControl* add_lightsource(); - // CheckBox + // Component Transfer Values + ComponentTransferValues* add_componenttransfervalues(const Glib::ustring& label, SPFeFuncNode::Channel channel); + + // CheckButton CheckButtonAttr* add_checkbutton(bool def, const SPAttributeEnum attr, const Glib::ustring& label, const Glib::ustring& tv, const Glib::ustring& fv, char* tip_text = NULL) { @@ -938,6 +972,18 @@ public: add_attr_widget(combo->get_attrwidget()); return combo->get_attrwidget(); } + + // Entry + EntryAttr* add_entry(const SPAttributeEnum attr, + const Glib::ustring& label, + char* tip_text = NULL) + { + EntryAttr* entry = new EntryAttr(attr, tip_text); + add_widget(entry, label); + add_attr_widget(entry); + return entry; + } + private: void add_attr_widget(AttrWidget* a) { @@ -973,6 +1019,154 @@ private: int _current_type, _max_types; }; +// Displays sliders and/or tables for feComponentTransfer +class FilterEffectsDialog::ComponentTransferValues : public Gtk::Frame, public AttrWidget +{ +public: + ComponentTransferValues(FilterEffectsDialog& d, SPFeFuncNode::Channel channel) + : AttrWidget(SP_ATTR_INVALID), + _dialog(d), + _settings(d, _box, sigc::mem_fun(*this, &ComponentTransferValues::set_func_attr), COMPONENTTRANSFER_TYPE_ERROR), + _type(ComponentTransferTypeConverter, SP_ATTR_TYPE, false), + _channel(channel), + _funcNode(NULL) + { + set_shadow_type(Gtk::SHADOW_IN); + add(_box); + _box.add(_type); + _box.reorder_child(_type, 0); + _type.signal_changed().connect(sigc::mem_fun(*this, &ComponentTransferValues::on_type_changed)); + + _settings.type(COMPONENTTRANSFER_TYPE_LINEAR); + _settings.add_spinscale(1, SP_ATTR_SLOPE, _("Slope"), -10, 10, 0.1, 0.01, 2); + _settings.add_spinscale(0, SP_ATTR_INTERCEPT, _("Intercept"), -10, 10, 0.1, 0.01, 2); + + _settings.type(COMPONENTTRANSFER_TYPE_GAMMA); + _settings.add_spinscale(1, SP_ATTR_AMPLITUDE, _("Amplitude"), 0, 10, 0.1, 0.01, 2); + _settings.add_spinscale(1, SP_ATTR_EXPONENT, _("Exponent"), 0, 10, 0.1, 0.01, 2); + _settings.add_spinscale(0, SP_ATTR_OFFSET, _("Offset"), -10, 10, 0.1, 0.01, 2); + + _settings.type(COMPONENTTRANSFER_TYPE_TABLE); + _settings.add_entry(SP_ATTR_TABLEVALUES, _("Table")); + + _settings.type(COMPONENTTRANSFER_TYPE_DISCRETE); + _settings.add_entry(SP_ATTR_TABLEVALUES, _("Discrete")); + + //_settings.type(COMPONENTTRANSFER_TYPE_IDENTITY); + _settings.type(-1); // Force update_and_show() to show/hide windows correctly + } + + // FuncNode can be in any order so we must search to find correct one. + SPFeFuncNode* find_node(SPFeComponentTransfer* ct) + { + SPObject* node = ct->children; + SPFeFuncNode* funcNode = NULL; + bool found = false; + for(;node;node=node->next){ + funcNode = SP_FEFUNCNODE(node); + if( funcNode->channel == _channel ) { + found = true; + break; + } + } + if( !found ) + funcNode = NULL; + + return funcNode; + } + + void set_func_attr(const AttrWidget* input) + { + _dialog.set_attr( _funcNode, input->get_attribute(), input->get_as_attribute().c_str()); + } + + // Set new type and update widget visibility + virtual void set_from_attribute(SPObject* o) + { + // See componenttransfer.cpp + if(SP_IS_FECOMPONENTTRANSFER(o)) { + SPFeComponentTransfer* ct = SP_FECOMPONENTTRANSFER(o); + + _funcNode = find_node(ct); + if( _funcNode ) { + _type.set_from_attribute( _funcNode ); + } else { + // Create <funcNode> + SPFilterPrimitive* prim = _dialog._primitive_list.get_selected(); + if(prim) { + Inkscape::XML::Document *xml_doc = prim->document->getReprDoc(); + Inkscape::XML::Node *repr = NULL; + switch(_channel) { + case SPFeFuncNode::R: + repr = xml_doc->createElement("svg:feFuncR"); + break; + case SPFeFuncNode::G: + repr = xml_doc->createElement("svg:feFuncG"); + break; + case SPFeFuncNode::B: + repr = xml_doc->createElement("svg:feFuncB"); + break; + case SPFeFuncNode::A: + repr = xml_doc->createElement("svg:feFuncA"); + break; + } + + //XML Tree being used directly here while it shouldn't be. + prim->getRepr()->appendChild(repr); + Inkscape::GC::release(repr); + + // Now we should find it! + _funcNode = find_node(ct); + if( _funcNode ) { + _funcNode->setAttribute( "type", "identity" ); + } else { + //std::cout << "ERROR ERROR: feFuncX not found!" << std::endl; + } + } + } + + update(); + } + } + +private: + void on_type_changed() + { + SPFilterPrimitive* prim = _dialog._primitive_list.get_selected(); + if(prim) { + + _funcNode->getRepr()->setAttribute( "type", _type.get_as_attribute().c_str() ); + + SPFilter* filter = _dialog._filter_modifier.get_selected_filter(); + filter->requestModified(SP_OBJECT_MODIFIED_FLAG); + + DocumentUndo::done(prim->document, SP_VERB_DIALOG_FILTER_EFFECTS, _("New transfer function type")); + update(); + } + } + + void update() + { + SPFilterPrimitive* prim = _dialog._primitive_list.get_selected(); + if(prim && _funcNode) { + _settings.show_and_update(_type.get_active_data()->id, _funcNode); + } + } + +public: + virtual Glib::ustring get_as_attribute() const + { + return ""; + } + + FilterEffectsDialog& _dialog; + Gtk::VBox _box; + Settings _settings; + ComboBoxEnum<FilterComponentTransferType> _type; + SPFeFuncNode::Channel _channel; // RGBA + SPFeFuncNode* _funcNode; +}; + // Settings for the three light source objects class FilterEffectsDialog::LightSourceControl : public AttrWidget { @@ -1012,6 +1206,9 @@ public: _settings.add_spinscale(1, SP_ATTR_SPECULAREXPONENT, _("Specular Exponent"), 1, 100, 1, 1, 0, _("Exponent value controlling the focus for the light source")); //TODO: here I have used 100 degrees as default value. But spec says that if not specified, no limiting cone is applied. So, there should be a way for the user to set a "no limiting cone" option. _settings.add_spinscale(100, SP_ATTR_LIMITINGCONEANGLE, _("Cone Angle"), 1, 100, 1, 1, 0, _("This is the angle between the spot light axis (i.e. the axis between the light source and the point to which it is pointing at) and the spot light cone. No light is projected outside this cone.")); + + _settings.type(-1); // Force update_and_show() to show/hide windows correctly + } Gtk::VBox& get_box() @@ -1102,6 +1299,16 @@ private: bool _locked; }; + // ComponentTransferValues +FilterEffectsDialog::ComponentTransferValues* FilterEffectsDialog::Settings::add_componenttransfervalues(const Glib::ustring& label, SPFeFuncNode::Channel channel) + { + ComponentTransferValues* ct = new ComponentTransferValues(_dialog, channel); + add_widget(ct, label); + add_attr_widget(ct); + return ct; + } + + FilterEffectsDialog::LightSourceControl* FilterEffectsDialog::Settings::add_lightsource() { LightSourceControl* ls = new LightSourceControl(_dialog); @@ -1156,11 +1363,9 @@ FilterEffectsDialog::FilterModifier::FilterModifier(FilterEffectsDialog& d) sw->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); _list.get_column(1)->set_resizable(true); _list.set_reorderable(true); + _list.enable_model_drag_dest (Gdk::ACTION_MOVE); - // We can track the drag/drop reordering from the row_delete (occurs after - // row_inserted and may occur many times when adding a new item) - _model->signal_row_deleted().connect( - sigc::mem_fun(*this, &FilterModifier::on_filter_reorder)); + _list.signal_drag_drop().connect( sigc::mem_fun(*this, &FilterModifier::on_filter_move), false ); sw->set_shadow_type(Gtk::SHADOW_IN); show_all_children(); @@ -1225,7 +1430,10 @@ void FilterEffectsDialog::FilterModifier::on_document_replaced(SPDesktop * /*des if (_resource_changed) { _resource_changed.disconnect(); } - _resource_changed = document->connectResourcesChanged("filter",sigc::mem_fun(*this, &FilterModifier::update_filters)); + if (document) + { + _resource_changed = document->connectResourcesChanged("filter",sigc::mem_fun(*this, &FilterModifier::update_filters)); + } update_filters(); } @@ -1307,12 +1515,20 @@ void FilterEffectsDialog::FilterModifier::on_name_edited(const Glib::ustring& pa } } -void FilterEffectsDialog::FilterModifier::on_filter_reorder(const Gtk::TreeModel::Path& /*path*/) { +bool FilterEffectsDialog::FilterModifier::on_filter_move(const Glib::RefPtr<Gdk::DragContext>& /*context*/, int /*x*/, int /*y*/, guint /*time*/) { + +//const Gtk::TreeModel::Path& /*path*/) { +/* The code below is bugged. Use of "object->getRepr()->setPosition(0)" is dangerous! + Writing back the reordered list to XML (reordering XML nodes) should be implemented differently. + Note that the dialog does also not update its list of filters when the order is manually changed + using the XML dialog for(Gtk::TreeModel::iterator i = _model->children().begin(); i != _model->children().end(); ++i) { SPObject* object = (*i)[_columns.filter]; - if(object && object->getRepr()) + if(object && object->getRepr()) ; object->getRepr()->setPosition(0); } +*/ + return false; } void FilterEffectsDialog::FilterModifier::on_selection_toggled(const Glib::ustring& path) @@ -2527,7 +2743,6 @@ FilterEffectsDialog::FilterEffectsDialog() _sizegroup->set_ignore_hidden(); _add_primitive_type.remove_row(NR_FILTER_TILE); - _add_primitive_type.remove_row(NR_FILTER_COMPONENTTRANSFER); // Initialize widget hierarchy #if WITH_GTKMM_3_0 @@ -2629,15 +2844,10 @@ void FilterEffectsDialog::init_settings_widgets() colmat->signal_attr_changed().connect(sigc::mem_fun(*this, &FilterEffectsDialog::update_color_matrix)); _settings->type(NR_FILTER_COMPONENTTRANSFER); - _settings->add_notimplemented(); - /* - //TRANSLATORS: for info on "Slope" and "Intercept", see http://id.mind.net/~zona/mmts/functionInstitute/linearFunctions/lsif.html - _settings->add_combo(COMPONENTTRANSFER_TYPE_IDENTITY, SP_ATTR_TYPE, _("Type"), ComponentTransferTypeConverter); - _ct_slope = _settings->add_spinscale(1, SP_ATTR_SLOPE, _("Slope"), -10, 10, 0.1, 0.01, 2); - _ct_intercept = _settings->add_spinscale(0, SP_ATTR_INTERCEPT, _("Intercept"), -10, 10, 0.1, 0.01, 2); - _ct_amplitude = _settings->add_spinscale(1, SP_ATTR_AMPLITUDE, _("Amplitude"), 0, 10, 0.1, 0.01, 2); - _ct_exponent = _settings->add_spinscale(1, SP_ATTR_EXPONENT, _("Exponent"), 0, 10, 0.1, 0.01, 2); - _ct_offset = _settings->add_spinscale(0, SP_ATTR_OFFSET, _("Offset"), -10, 10, 0.1, 0.01, 2);*/ + _settings->add_componenttransfervalues(_("R:"), SPFeFuncNode::R); + _settings->add_componenttransfervalues(_("G:"), SPFeFuncNode::G); + _settings->add_componenttransfervalues(_("B:"), SPFeFuncNode::B); + _settings->add_componenttransfervalues(_("A:"), SPFeFuncNode::A); _settings->type(NR_FILTER_COMPOSITE); _settings->add_combo(COMPOSITE_OVER, SP_ATTR_OPERATOR, _("Operator:"), CompositeOperatorConverter); @@ -2953,21 +3163,6 @@ void FilterEffectsDialog::update_settings_sensitivity() _k3->set_sensitive(use_k); _k4->set_sensitive(use_k); -// Component transfer not yet implemented -/* - if(SP_IS_FECOMPONENTTRANSFER(prim)) { - SPFeComponentTransfer* ct = SP_FECOMPONENTTRANSFER(prim); - const bool linear = ct->type == COMPONENTTRANSFER_TYPE_LINEAR; - const bool gamma = ct->type == COMPONENTTRANSFER_TYPE_GAMMA; - - _ct_table->set_sensitive(ct->type == COMPONENTTRANSFER_TYPE_TABLE || ct->type == COMPONENTTRANSFER_TYPE_DISCRETE); - _ct_slope->set_sensitive(linear); - _ct_intercept->set_sensitive(linear); - _ct_amplitude->set_sensitive(gamma); - _ct_exponent->set_sensitive(gamma); - _ct_offset->set_sensitive(gamma); - } -*/ } void FilterEffectsDialog::update_color_matrix() diff --git a/src/ui/dialog/filter-effects-dialog.h b/src/ui/dialog/filter-effects-dialog.h index a2a2a3c6e..3fc19e7de 100644 --- a/src/ui/dialog/filter-effects-dialog.h +++ b/src/ui/dialog/filter-effects-dialog.h @@ -86,7 +86,7 @@ private: void on_filter_selection_changed(); void on_name_edited(const Glib::ustring&, const Glib::ustring&); - void on_filter_reorder(const Gtk::TreeModel::Path& path); + bool on_filter_move(const Glib::RefPtr<Gdk::DragContext>& /*context*/, int x, int y, guint /*time*/); void on_selection_toggled(const Glib::ustring&); void update_filters(); @@ -282,6 +282,7 @@ private: class Settings; class MatrixAttr; class ColorMatrixValues; + class ComponentTransferValues; class LightSourceControl; Settings* _settings; Settings* _filter_general_settings; @@ -290,6 +291,9 @@ private: // Color Matrix ColorMatrixValues* _color_matrix_values; + // Component Transfer + ComponentTransferValues* _component_transfer_values; + // Convolve Matrix MatrixAttr* _convolve_matrix; DualSpinButton* _convolve_order; @@ -297,7 +301,6 @@ private: // For controlling setting sensitivity Gtk::Widget* _k1, *_k2, *_k3, *_k4; - Gtk::Widget* _ct_table, *_ct_slope, *_ct_intercept, *_ct_amplitude, *_ct_exponent, *_ct_offset; // To prevent unwanted signals bool _locked; diff --git a/src/ui/dialog/grid-arrange-tab.cpp b/src/ui/dialog/grid-arrange-tab.cpp new file mode 100644 index 000000000..8c0a4dc66 --- /dev/null +++ b/src/ui/dialog/grid-arrange-tab.cpp @@ -0,0 +1,809 @@ +/* + * A simple dialog for creating grid type arrangements of selected objects + * + * Authors: + * Bob Jamison ( based off trace dialog) + * John Cliff + * Other dudes from The Inkscape Organization + * Abhishek Sharma + * Declara Denis + * + * Copyright (C) 2004 Bob Jamison + * Copyright (C) 2004 John Cliff + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ +//#define DEBUG_GRID_ARRANGE 1 + +#include "ui/dialog/grid-arrange-tab.h" +#include <gtk/gtk.h> //for GTK_RESPONSE* types +#include <glibmm/i18n.h> +#include <gtkmm/stock.h> + +#if WITH_GTKMM_3_0 +# include <gtkmm/grid.h> +#else +# include <gtkmm/table.h> +#endif + +#include <2geom/transforms.h> + +#include "verbs.h" +#include "preferences.h" +#include "inkscape.h" +#include "desktop-handles.h" +#include "selection.h" +#include "document.h" +#include "document-undo.h" +#include "sp-item.h" +#include "widgets/icon.h" +#include "desktop.h" +//#include "sp-item-transform.h" FIXME +#include "ui/dialog/tile.h" // for Inkscape::UI::Dialog::ArrangeDialog + +/* + * Sort items by their x co-ordinates, taking account of y (keeps rows intact) + * + * <0 *elem1 goes before *elem2 + * 0 *elem1 == *elem2 + * >0 *elem1 goes after *elem2 + */ +static int sp_compare_x_position(SPItem *first, SPItem *second) +{ + using Geom::X; + using Geom::Y; + + Geom::OptRect a = first->documentVisualBounds(); + Geom::OptRect b = second->documentVisualBounds(); + + if ( !a || !b ) { + // FIXME? + return 0; + } + + double const a_height = a->dimensions()[Y]; + double const b_height = b->dimensions()[Y]; + + bool a_in_b_vert = false; + if ((a->min()[Y] < b->min()[Y] + 0.1) && (a->min()[Y] > b->min()[Y] - b_height)) { + a_in_b_vert = true; + } else if ((b->min()[Y] < a->min()[Y] + 0.1) && (b->min()[Y] > a->min()[Y] - a_height)) { + a_in_b_vert = true; + } else if (b->min()[Y] == a->min()[Y]) { + a_in_b_vert = true; + } else { + a_in_b_vert = false; + } + + if (!a_in_b_vert) { + return -1; + } + if (a_in_b_vert && a->min()[X] > b->min()[X]) { + return 1; + } + if (a_in_b_vert && a->min()[X] < b->min()[X]) { + return -1; + } + return 0; +} + +/* + * Sort items by their y co-ordinates. + */ +static int sp_compare_y_position(SPItem *first, SPItem *second) +{ + Geom::OptRect a = first->documentVisualBounds(); + Geom::OptRect b = second->documentVisualBounds(); + + if ( !a || !b ) { + // FIXME? + return 0; + } + + if (a->min()[Geom::Y] > b->min()[Geom::Y]) { + return 1; + } + if (a->min()[Geom::Y] < b->min()[Geom::Y]) { + return -1; + } + + return 0; +} + +namespace Inkscape { +namespace UI { +namespace Dialog { + + +//######################################################################### +//## E V E N T S +//######################################################################### + +/* + * + * This arranges the selection in a grid pattern. + * + */ + +void GridArrangeTab::arrange() +{ + + int cnt,row_cnt,col_cnt,a,row,col; + double grid_left,grid_top,col_width,row_height,paddingx,paddingy,width, height, new_x, new_y; + double total_col_width,total_row_height; + col_width = 0; + row_height = 0; + total_col_width=0; + total_row_height=0; + + // check for correct numbers in the row- and col-spinners + on_col_spinbutton_changed(); + on_row_spinbutton_changed(); + + // set padding to manual values + paddingx = XPadding.getValue("px"); + paddingy = YPadding.getValue("px"); + + std::vector<double> row_heights; + std::vector<double> col_widths; + std::vector<double> row_ys; + std::vector<double> col_xs; + + int NoOfCols = NoOfColsSpinner.get_value_as_int(); + int NoOfRows = NoOfRowsSpinner.get_value_as_int(); + + width = 0; + for (a=0;a<NoOfCols; a++){ + col_widths.push_back(width); + } + + height = 0; + for (a=0;a<NoOfRows; a++){ + row_heights.push_back(height); + } + grid_left = 99999; + grid_top = 99999; + + SPDesktop *desktop = Parent->getDesktop(); + sp_desktop_document(desktop)->ensureUpToDate(); + + Inkscape::Selection *selection = sp_desktop_selection (desktop); + const GSList *items = selection ? selection->itemList() : 0; + cnt=0; + for (; items != NULL; items = items->next) { + SPItem *item = SP_ITEM(items->data); + Geom::OptRect b = item->documentVisualBounds(); + if (!b) { + continue; + } + + width = b->dimensions()[Geom::X]; + height = b->dimensions()[Geom::Y]; + + if (b->min()[Geom::X] < grid_left) { + grid_left = b->min()[Geom::X]; + } + if (b->min()[Geom::Y] < grid_top) { + grid_top = b->min()[Geom::Y]; + } + if (width > col_width) { + col_width = width; + } + if (height > row_height) { + row_height = height; + } + } + + + // require the sorting done before we can calculate row heights etc. + + g_return_if_fail(selection); + const GSList *items2 = selection->itemList(); + GSList *rev = g_slist_copy(const_cast<GSList *>(items2)); + GSList *sorted = NULL; + rev = g_slist_sort(rev, (GCompareFunc) sp_compare_y_position); + sorted = g_slist_sort(rev, (GCompareFunc) sp_compare_x_position); + + + // Calculate individual Row and Column sizes if necessary + + + cnt=0; + const GSList *sizes = sorted; + for (; sizes != NULL; sizes = sizes->next) { + SPItem *item = SP_ITEM(sizes->data); + Geom::OptRect b = item->documentVisualBounds(); + if (b) { + width = b->dimensions()[Geom::X]; + height = b->dimensions()[Geom::Y]; + if (width > col_widths[(cnt % NoOfCols)]) { + col_widths[(cnt % NoOfCols)] = width; + } + if (height > row_heights[(cnt / NoOfCols)]) { + row_heights[(cnt / NoOfCols)] = height; + } + } + + cnt++; + } + + + /// Make sure the top and left of the grid dont move by compensating for align values. + if (RowHeightButton.get_active()){ + grid_top = grid_top - (((row_height - row_heights[0]) / 2)*(VertAlign)); + } + if (ColumnWidthButton.get_active()){ + grid_left = grid_left - (((col_width - col_widths[0]) /2)*(HorizAlign)); + } + + #ifdef DEBUG_GRID_ARRANGE + g_print("\n cx = %f cy= %f gridleft=%f",cx,cy,grid_left); + #endif + + // Calculate total widths and heights, allowing for columns and rows non uniformly sized. + + if (ColumnWidthButton.get_active()){ + total_col_width = col_width * NoOfCols; + col_widths.clear(); + for (a=0;a<NoOfCols; a++){ + col_widths.push_back(col_width); + } + } else { + for (a = 0; a < (int)col_widths.size(); a++) + { + total_col_width += col_widths[a] ; + } + } + + if (RowHeightButton.get_active()){ + total_row_height = row_height * NoOfRows; + row_heights.clear(); + for (a=0;a<NoOfRows; a++){ + row_heights.push_back(row_height); + } + } else { + for (a = 0; a < (int)row_heights.size(); a++) + { + total_row_height += row_heights[a] ; + } + } + + + Geom::OptRect sel_bbox = selection->visualBounds(); + // Fit to bbox, calculate padding between rows accordingly. + if ( sel_bbox && !SpaceManualRadioButton.get_active() ){ +#ifdef DEBUG_GRID_ARRANGE +g_print("\n row = %f col = %f selection x= %f selection y = %f", total_row_height,total_col_width, b.extent(Geom::X), b.extent(Geom::Y)); +#endif + paddingx = (sel_bbox->width() - total_col_width) / (NoOfCols -1); + paddingy = (sel_bbox->height() - total_row_height) / (NoOfRows -1); + } + +/* + Horizontal align - Left = 0 + Centre = 1 + Right = 2 + + Vertical align - Top = 0 + Middle = 1 + Bottom = 2 + + X position is calculated by taking the grids left co-ord, adding the distance to the column, + then adding 1/2 the spacing multiplied by the align variable above, + Y position likewise, takes the top of the grid, adds the y to the current row then adds the padding in to align it. + +*/ + + // Calculate row and column x and y coords required to allow for columns and rows which are non uniformly sized. + + for (a=0;a<NoOfCols; a++){ + if (a<1) col_xs.push_back(0); + else col_xs.push_back(col_widths[a-1]+paddingx+col_xs[a-1]); + } + + + for (a=0;a<NoOfRows; a++){ + if (a<1) row_ys.push_back(0); + else row_ys.push_back(row_heights[a-1]+paddingy+row_ys[a-1]); + } + + cnt=0; + for (row_cnt=0; ((sorted != NULL) && (row_cnt<NoOfRows)); row_cnt++) { + + GSList *current_row = NULL; + for (col_cnt = 0; ((sorted != NULL) && (col_cnt<NoOfCols)); col_cnt++) { + current_row = g_slist_append (current_row, sorted->data); + sorted = sorted->next; + } + + for (; current_row != NULL; current_row = current_row->next) { + SPItem *item=SP_ITEM(current_row->data); + Inkscape::XML::Node *repr = item->getRepr(); + Geom::OptRect b = item->documentVisualBounds(); + Geom::Point min; + if (b) { + width = b->dimensions()[Geom::X]; + height = b->dimensions()[Geom::Y]; + min = b->min(); + } else { + width = height = 0; + min = Geom::Point(0, 0); + } + + row = cnt / NoOfCols; + col = cnt % NoOfCols; + + new_x = grid_left + (((col_widths[col] - width)/2)*HorizAlign) + col_xs[col]; + new_y = grid_top + (((row_heights[row] - height)/2)*VertAlign) + row_ys[row]; + + // signs are inverted between x and y due to y inversion + Geom::Point move = Geom::Point(new_x - min[Geom::X], min[Geom::Y] - new_y); + Geom::Affine const affine = Geom::Affine(Geom::Translate(move)); + item->set_i2d_affine(item->i2dt_affine() * affine); + item->doWriteTransform(repr, item->transform, NULL); + SP_OBJECT (current_row->data)->updateRepr(); + cnt +=1; + } + g_slist_free (current_row); + } + + DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_SELECTION_ARRANGE, + _("Arrange in a grid")); + +} + + +//######################################################################### +//## E V E N T S +//######################################################################### + +/** + * changed value in # of columns spinbox. + */ +void GridArrangeTab::on_row_spinbutton_changed() +{ + // quit if run by the attr_changed listener + if (updating) { + return; + } + + // in turn, prevent listener from responding + updating = true; + SPDesktop *desktop = Parent->getDesktop(); + + Inkscape::Selection *selection = desktop ? desktop->selection : 0; + g_return_if_fail( selection ); + + GSList const *items = selection->itemList(); + int selcount = g_slist_length((GSList *)items); + + double PerCol = ceil(selcount / NoOfColsSpinner.get_value()); + NoOfRowsSpinner.set_value(PerCol); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble("/dialogs/gridtiler/NoOfCols", NoOfColsSpinner.get_value()); + updating=false; +} + +/** + * changed value in # of rows spinbox. + */ +void GridArrangeTab::on_col_spinbutton_changed() +{ + // quit if run by the attr_changed listener + if (updating) { + return; + } + + // in turn, prevent listener from responding + updating = true; + SPDesktop *desktop = Parent->getDesktop(); + Inkscape::Selection *selection = desktop ? desktop->selection : 0; + g_return_if_fail(selection); + + GSList const *items = selection->itemList(); + int selcount = g_slist_length((GSList *)items); + + double PerRow = ceil(selcount / NoOfRowsSpinner.get_value()); + NoOfColsSpinner.set_value(PerRow); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble("/dialogs/gridtiler/NoOfCols", PerRow); + + updating=false; +} + +/** + * changed value in x padding spinbox. + */ +void GridArrangeTab::on_xpad_spinbutton_changed() +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble("/dialogs/gridtiler/XPad", XPadding.getValue("px")); + +} + +/** + * changed value in y padding spinbox. + */ +void GridArrangeTab::on_ypad_spinbutton_changed() +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble("/dialogs/gridtiler/YPad", YPadding.getValue("px")); +} + + +/** + * checked/unchecked autosize Rows button. + */ +void GridArrangeTab::on_RowSize_checkbutton_changed() +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + if (RowHeightButton.get_active()) { + prefs->setDouble("/dialogs/gridtiler/AutoRowSize", 20); + } else { + prefs->setDouble("/dialogs/gridtiler/AutoRowSize", -20); + } + RowHeightBox.set_sensitive ( !RowHeightButton.get_active()); +} + +/** + * checked/unchecked autosize Rows button. + */ +void GridArrangeTab::on_ColSize_checkbutton_changed() +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + if (ColumnWidthButton.get_active()) { + prefs->setDouble("/dialogs/gridtiler/AutoColSize", 20); + } else { + prefs->setDouble("/dialogs/gridtiler/AutoColSize", -20); + } + ColumnWidthBox.set_sensitive ( !ColumnWidthButton.get_active()); +} + +/** + * changed value in columns spinbox. + */ +void GridArrangeTab::on_rowSize_spinbutton_changed() +{ + // quit if run by the attr_changed listener + if (updating) { + return; + } + + // in turn, prevent listener from responding + updating = true; + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble("/dialogs/gridtiler/RowHeight", RowHeightSpinner.get_value()); + updating=false; + +} + +/** + * changed value in rows spinbox. + */ +void GridArrangeTab::on_colSize_spinbutton_changed() +{ + // quit if run by the attr_changed listener + if (updating) { + return; + } + + // in turn, prevent listener from responding + updating = true; + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble("/dialogs/gridtiler/ColWidth", ColumnWidthSpinner.get_value()); + updating=false; + +} + +/** + * changed Radio button in Spacing group. + */ +void GridArrangeTab::Spacing_button_changed() +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + if (SpaceManualRadioButton.get_active()) { + prefs->setDouble("/dialogs/gridtiler/SpacingType", 20); + } else { + prefs->setDouble("/dialogs/gridtiler/SpacingType", -20); + } + + XPadding.set_sensitive ( SpaceManualRadioButton.get_active()); + YPadding.set_sensitive ( SpaceManualRadioButton.get_active()); +} + +/** + * changed Anchor selection widget. + */ +void GridArrangeTab::Align_changed() +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + VertAlign = AlignmentSelector.getVerticalAlignment(); + prefs->setInt("/dialogs/gridtiler/VertAlign", VertAlign); + HorizAlign = AlignmentSelector.getHorizontalAlignment(); + prefs->setInt("/dialogs/gridtiler/HorizAlign", HorizAlign); +} + +/** + * Desktop selection changed + */ +void GridArrangeTab::updateSelection() +{ + // quit if run by the attr_changed listener + if (updating) { + return; + } + + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + // in turn, prevent listener from responding + updating = true; + SPDesktop *desktop = Parent->getDesktop(); + Inkscape::Selection *selection = desktop ? desktop->selection : 0; + GSList const *items = selection ? selection->itemList() : 0; + + if (items) { + int selcount = g_slist_length((GSList *)items); + + if (NoOfColsSpinner.get_value() > 1 && NoOfRowsSpinner.get_value() > 1){ + // Update the number of rows assuming number of columns wanted remains same. + double NoOfRows = ceil(selcount / NoOfColsSpinner.get_value()); + NoOfRowsSpinner.set_value(NoOfRows); + + // if the selection has less than the number set for one row, reduce it appropriately + if (selcount < NoOfColsSpinner.get_value()) { + double NoOfCols = ceil(selcount / NoOfRowsSpinner.get_value()); + NoOfColsSpinner.set_value(NoOfCols); + prefs->setInt("/dialogs/gridtiler/NoOfCols", NoOfCols); + } + } else { + double PerRow = ceil(sqrt(selcount)); + double PerCol = ceil(sqrt(selcount)); + NoOfRowsSpinner.set_value(PerRow); + NoOfColsSpinner.set_value(PerCol); + prefs->setInt("/dialogs/gridtiler/NoOfCols", static_cast<int>(PerCol)); + } + } + + updating = false; +} + + + +/*########################## +## Experimental +##########################*/ + +static void updateSelectionCallback(Inkscape::Application */*inkscape*/, Inkscape::Selection */*selection*/, GridArrangeTab *dlg) +{ + dlg->updateSelection(); +} + + +//######################################################################### +//## C O N S T R U C T O R / D E S T R U C T O R +//######################################################################### +/** + * Constructor + */ +GridArrangeTab::GridArrangeTab(ArrangeDialog *parent) + : Parent(parent), + XPadding(_("X:"), _("Horizontal spacing between columns."), UNIT_TYPE_LINEAR, "", "object-columns", &PaddingUnitMenu), + YPadding(_("Y:"), _("Vertical spacing between rows."), XPadding, "", "object-rows", &PaddingUnitMenu), +#if WITH_GTKMM_3_0 + PaddingTable(Gtk::manage(new Gtk::Grid())) +#else + PaddingTable(Gtk::manage(new Gtk::Table(2, 2, false))) +#endif +{ + // bool used by spin button callbacks to stop loops where they change each other. + updating = false; + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + + // could not do this in gtkmm - there's no Gtk::SizeGroup public constructor (!) + GtkSizeGroup *_col1 = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); + GtkSizeGroup *_col2 = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); + GtkSizeGroup *_col3 = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); + + { + // Selection Change signal + g_signal_connect ( G_OBJECT (INKSCAPE), "change_selection", G_CALLBACK (updateSelectionCallback), this); + } + + Gtk::Box *contents = this; + +#define MARGIN 2 + + //##Set up the panel + + SPDesktop *desktop = Parent->getDesktop(); + + Inkscape::Selection *selection = desktop ? desktop->selection : 0; + g_return_if_fail( selection ); + int selcount = 1; + if (!selection->isEmpty()) { + GSList const *items = selection->itemList(); + selcount = g_slist_length((GSList *)items); + } + + + /*#### Number of Rows ####*/ + + double PerRow = ceil(sqrt(selcount)); + double PerCol = ceil(sqrt(selcount)); + + #ifdef DEBUG_GRID_ARRANGE + g_print("/n PerRox = %f PerCol = %f selcount = %d",PerRow,PerCol,selcount); + #endif + + NoOfRowsLabel.set_text_with_mnemonic(_("_Rows:")); + NoOfRowsLabel.set_mnemonic_widget(NoOfRowsSpinner); + NoOfRowsBox.pack_start(NoOfRowsLabel, false, false, MARGIN); + + NoOfRowsSpinner.set_digits(0); + NoOfRowsSpinner.set_increments(1, 0); + NoOfRowsSpinner.set_range(1.0, 10000.0); + NoOfRowsSpinner.set_value(PerCol); + NoOfRowsSpinner.signal_changed().connect(sigc::mem_fun(*this, &GridArrangeTab::on_col_spinbutton_changed)); + NoOfRowsSpinner.set_tooltip_text(_("Number of rows")); + NoOfRowsBox.pack_start(NoOfRowsSpinner, false, false, MARGIN); + gtk_size_group_add_widget(_col1, (GtkWidget *) NoOfRowsBox.gobj()); + + RowHeightButton.set_label(_("Equal _height")); + RowHeightButton.set_use_underline(true); + double AutoRow = prefs->getDouble("/dialogs/gridtiler/AutoRowSize", 15); + if (AutoRow>0) + AutoRowSize=true; + else + AutoRowSize=false; + RowHeightButton.set_active(AutoRowSize); + + NoOfRowsBox.pack_start(RowHeightButton, false, false, MARGIN); + + RowHeightButton.set_tooltip_text(_("If not set, each row has the height of the tallest object in it")); + RowHeightButton.signal_toggled().connect(sigc::mem_fun(*this, &GridArrangeTab::on_RowSize_checkbutton_changed)); + + SpinsHBox.pack_start(NoOfRowsBox, false, false, MARGIN); + + + /*#### Label for X ####*/ + padXByYLabel.set_label(" "); + XByYLabelVBox.pack_start(padXByYLabel, false, false, MARGIN); + XByYLabel.set_markup(" × "); + XByYLabelVBox.pack_start(XByYLabel, false, false, MARGIN); + SpinsHBox.pack_start(XByYLabelVBox, false, false, MARGIN); + gtk_size_group_add_widget(_col2, GTK_WIDGET(XByYLabelVBox.gobj())); + + /*#### Number of columns ####*/ + + NoOfColsLabel.set_text_with_mnemonic(_("_Columns:")); + NoOfColsLabel.set_mnemonic_widget(NoOfColsSpinner); + NoOfColsBox.pack_start(NoOfColsLabel, false, false, MARGIN); + + NoOfColsSpinner.set_digits(0); + NoOfColsSpinner.set_increments(1, 0); + NoOfColsSpinner.set_range(1.0, 10000.0); + NoOfColsSpinner.set_value(PerRow); + NoOfColsSpinner.signal_changed().connect(sigc::mem_fun(*this, &GridArrangeTab::on_row_spinbutton_changed)); + NoOfColsSpinner.set_tooltip_text(_("Number of columns")); + NoOfColsBox.pack_start(NoOfColsSpinner, false, false, MARGIN); + gtk_size_group_add_widget(_col3, GTK_WIDGET(NoOfColsBox.gobj())); + + ColumnWidthButton.set_label(_("Equal _width")); + ColumnWidthButton.set_use_underline(true); + double AutoCol = prefs->getDouble("/dialogs/gridtiler/AutoColSize", 15); + if (AutoCol>0) + AutoColSize=true; + else + AutoColSize=false; + ColumnWidthButton.set_active(AutoColSize); + NoOfColsBox.pack_start(ColumnWidthButton, false, false, MARGIN); + + ColumnWidthButton.set_tooltip_text(_("If not set, each column has the width of the widest object in it")); + ColumnWidthButton.signal_toggled().connect(sigc::mem_fun(*this, &GridArrangeTab::on_ColSize_checkbutton_changed)); + + SpinsHBox.pack_start(NoOfColsBox, false, false, MARGIN); + + TileBox.pack_start(SpinsHBox, false, false, MARGIN); + + VertAlign = prefs->getInt("/dialogs/gridtiler/VertAlign", 1); + HorizAlign = prefs->getInt("/dialogs/gridtiler/HorizAlign", 1); + + // Anchor selection widget + AlignLabel.set_label("Alignment:"); + AlignLabel.set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_CENTER); + AlignmentSelector.setAlignment(HorizAlign, VertAlign); + AlignmentSelector.on_selectionChanged().connect(sigc::mem_fun(*this, &GridArrangeTab::Align_changed)); + TileBox.pack_start(AlignLabel, false, false, MARGIN); + TileBox.pack_start(AlignmentSelector, true, false, MARGIN); + + { + /*#### Radio buttons to control spacing manually or to fit selection bbox ####*/ + SpaceByBBoxRadioButton.set_label(_("_Fit into selection box")); + SpaceByBBoxRadioButton.set_use_underline (true); + SpaceByBBoxRadioButton.signal_toggled().connect(sigc::mem_fun(*this, &GridArrangeTab::Spacing_button_changed)); + SpacingGroup = SpaceByBBoxRadioButton.get_group(); + + SpacingVBox.pack_start(SpaceByBBoxRadioButton, false, false, MARGIN); + + SpaceManualRadioButton.set_label(_("_Set spacing:")); + SpaceManualRadioButton.set_use_underline (true); + SpaceManualRadioButton.set_group(SpacingGroup); + SpaceManualRadioButton.signal_toggled().connect(sigc::mem_fun(*this, &GridArrangeTab::Spacing_button_changed)); + SpacingVBox.pack_start(SpaceManualRadioButton, false, false, MARGIN); + + TileBox.pack_start(SpacingVBox, false, false, MARGIN); + } + + { + /*#### Padding ####*/ + PaddingUnitMenu.setUnitType(UNIT_TYPE_LINEAR); + PaddingUnitMenu.setUnit("px"); + + YPadding.setDigits(5); + YPadding.setIncrements(0.2, 0); + YPadding.setRange(-10000, 10000); + double yPad = prefs->getDouble("/dialogs/gridtiler/YPad", 15); + YPadding.setValue(yPad, "px"); + YPadding.signal_value_changed().connect(sigc::mem_fun(*this, &GridArrangeTab::on_ypad_spinbutton_changed)); + + XPadding.setDigits(5); + XPadding.setIncrements(0.2, 0); + XPadding.setRange(-10000, 10000); + double xPad = prefs->getDouble("/dialogs/gridtiler/XPad", 15); + XPadding.setValue(xPad, "px"); + + XPadding.signal_value_changed().connect(sigc::mem_fun(*this, &GridArrangeTab::on_xpad_spinbutton_changed)); + } + + PaddingTable->set_border_width(MARGIN); + +#if WITH_GTKMM_3_0 + PaddingTable->set_row_spacing(MARGIN); + PaddingTable->set_column_spacing(MARGIN); + PaddingTable->attach(XPadding, 0, 0, 1, 1); + PaddingTable->attach(PaddingUnitMenu, 1, 0, 1, 1); + PaddingTable->attach(YPadding, 0, 1, 1, 1); +#else + PaddingTable->set_row_spacings(MARGIN); + PaddingTable->set_col_spacings(MARGIN); + PaddingTable->attach(XPadding, 0, 1, 0, 1, Gtk::SHRINK, Gtk::SHRINK); + PaddingTable->attach(PaddingUnitMenu, 1, 2, 0, 1, Gtk::SHRINK, Gtk::SHRINK); + PaddingTable->attach(YPadding, 0, 1, 1, 2, Gtk::SHRINK, Gtk::SHRINK); +#endif + + TileBox.pack_start(*PaddingTable, false, false, MARGIN); + + contents->pack_start(TileBox); + + double SpacingType = prefs->getDouble("/dialogs/gridtiler/SpacingType", 15); + if (SpacingType>0) { + ManualSpacing=true; + } else { + ManualSpacing=false; + } + SpaceManualRadioButton.set_active(ManualSpacing); + SpaceByBBoxRadioButton.set_active(!ManualSpacing); + XPadding.set_sensitive (ManualSpacing); + YPadding.set_sensitive (ManualSpacing); + + //## The OK button FIXME + /*TileOkButton = addResponseButton(C_("Rows and columns dialog","_Arrange"), GTK_RESPONSE_APPLY); + TileOkButton->set_use_underline(true); + TileOkButton->set_tooltip_text(_("Arrange selected objects"));*/ + + show_all_children(); +} + +} //namespace Dialog +} //namespace UI +} //namespace Inkscape + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + 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:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/dialog/grid-arrange-tab.h b/src/ui/dialog/grid-arrange-tab.h new file mode 100644 index 000000000..9d6700b39 --- /dev/null +++ b/src/ui/dialog/grid-arrange-tab.h @@ -0,0 +1,154 @@ +/** + * @brief Arranges Objects into a Grid + */ +/* Authors: + * Bob Jamison ( based off trace dialog) + * John Cliff + * Other dudes from The Inkscape Organization + * Abhishek Sharma + * Declara Denis + * + * Copyright (C) 2004 Bob Jamison + * Copyright (C) 2004 John Cliff + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef INKSCAPE_UI_DIALOG_GRID_ARRANGE_TAB_H +#define INKSCAPE_UI_DIALOG_GRID_ARRANGE_TAB_H + +#include <gtkmm.h> + +#include "ui/dialog/arrange-tab.h" + +#include "ui/widget/anchor-selector.h" +#include "ui/widget/scalar-unit.h" +#include "ui/widget/spinbutton.h" + +namespace Inkscape { +namespace UI { +namespace Dialog { + +class ArrangeDialog; + +/** + * Dialog for tiling an object + */ +class GridArrangeTab : public ArrangeTab { +public: + GridArrangeTab(ArrangeDialog *parent); + virtual ~GridArrangeTab() {}; + + /** + * Do the actual work + */ + virtual void arrange(); + + /** + * Respond to selection change + */ + void updateSelection(); + + // Callbacks from spinbuttons + void on_row_spinbutton_changed(); + void on_col_spinbutton_changed(); + void on_xpad_spinbutton_changed(); + void on_ypad_spinbutton_changed(); + void on_RowSize_checkbutton_changed(); + void on_ColSize_checkbutton_changed(); + void on_rowSize_spinbutton_changed(); + void on_colSize_spinbutton_changed(); + void Spacing_button_changed(); + void Align_changed(); + + +private: + GridArrangeTab(GridArrangeTab const &d); // no copy + void operator=(GridArrangeTab const &d); // no assign + + ArrangeDialog *Parent; + + bool userHidden; + bool updating; + + Gtk::VBox TileBox; + Gtk::Button *TileOkButton; + Gtk::Button *TileCancelButton; + + // Number selected label + Gtk::Label SelectionContentsLabel; + + + Gtk::HBox AlignHBox; + Gtk::HBox SpinsHBox; + + // Number per Row + Gtk::VBox NoOfColsBox; + Gtk::Label NoOfColsLabel; + Inkscape::UI::Widget::SpinButton NoOfColsSpinner; + bool AutoRowSize; + Gtk::CheckButton RowHeightButton; + + Gtk::VBox XByYLabelVBox; + Gtk::Label padXByYLabel; + Gtk::Label XByYLabel; + + // Number per Column + Gtk::VBox NoOfRowsBox; + Gtk::Label NoOfRowsLabel; + Inkscape::UI::Widget::SpinButton NoOfRowsSpinner; + bool AutoColSize; + Gtk::CheckButton ColumnWidthButton; + + // Alignment + Gtk::Label AlignLabel; + Inkscape::UI::Widget::AnchorSelector AlignmentSelector; + double VertAlign; + double HorizAlign; + + Inkscape::UI::Widget::UnitMenu PaddingUnitMenu; + Inkscape::UI::Widget::ScalarUnit XPadding; + Inkscape::UI::Widget::ScalarUnit YPadding; + +#if WITH_GTKMM_3_0 + Gtk::Grid *PaddingTable; +#else + Gtk::Table *PaddingTable; +#endif + + // BBox or manual spacing + Gtk::VBox SpacingVBox; + Gtk::RadioButtonGroup SpacingGroup; + Gtk::RadioButton SpaceByBBoxRadioButton; + Gtk::RadioButton SpaceManualRadioButton; + bool ManualSpacing; + + // Row height + Gtk::VBox RowHeightVBox; + Gtk::HBox RowHeightBox; + Gtk::Label RowHeightLabel; + Inkscape::UI::Widget::SpinButton RowHeightSpinner; + + // Column width + Gtk::VBox ColumnWidthVBox; + Gtk::HBox ColumnWidthBox; + Gtk::Label ColumnWidthLabel; + Inkscape::UI::Widget::SpinButton ColumnWidthSpinner; +}; + +} //namespace Dialog +} //namespace UI +} //namespace Inkscape + +#endif /* INKSCAPE_UI_DIALOG_GRID_ARRANGE_TAB_H */ + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + 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:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/dialog/guides.cpp b/src/ui/dialog/guides.cpp index e84f25733..80740113c 100644 --- a/src/ui/dialog/guides.cpp +++ b/src/ui/dialog/guides.cpp @@ -68,20 +68,6 @@ void GuidelinePropertiesDialog::showDialog(SPGuide *guide, SPDesktop *desktop) { dialog.run(); } -void GuidelinePropertiesDialog::_colorChanged() -{ -#if WITH_GTKMM_3_0 - const Gdk::RGBA c = _color.get_rgba(); - unsigned r = c.get_red_u()/257, g = c.get_green_u()/257, b = c.get_blue_u()/257; -#else - const Gdk::Color c = _color.get_color(); - unsigned r = c.get_red()/257, g = c.get_green()/257, b = c.get_blue()/257; -#endif - //TODO: why 257? verify this! - - sp_guide_set_color(*_guide, r, g, b, true); -} - void GuidelinePropertiesDialog::_modeChanged() { _mode = !_relative_toggle.get_active(); @@ -100,7 +86,7 @@ void GuidelinePropertiesDialog::_modeChanged() } } -void GuidelinePropertiesDialog::_onApply() +void GuidelinePropertiesDialog::_onOK() { double deg_angle = _spin_angle.getValue(DEG); if (!_mode) @@ -124,18 +110,26 @@ void GuidelinePropertiesDialog::_onApply() sp_guide_moveto(*_guide, newpos, true); - const gchar* name = _label_entry.getEntry()->get_text().c_str(); + const gchar* name = g_strdup( _label_entry.getEntry()->get_text().c_str() ); + sp_guide_set_label(*_guide, name, true); + g_free((gpointer) name); + +#if WITH_GTKMM_3_0 + const Gdk::RGBA c = _color.get_rgba(); + unsigned r = c.get_red_u()/257, g = c.get_green_u()/257, b = c.get_blue_u()/257; +#else + const Gdk::Color c = _color.get_color(); + unsigned r = c.get_red()/257, g = c.get_green()/257, b = c.get_blue()/257; +#endif + //TODO: why 257? verify this! + + sp_guide_set_color(*_guide, r, g, b, true); DocumentUndo::done(_guide->document, SP_VERB_NONE, _("Set guide properties")); } -void GuidelinePropertiesDialog::_onOK() -{ - _onApply(); -} - void GuidelinePropertiesDialog::_onDelete() { SPDocument *doc = _guide->document; @@ -157,10 +151,6 @@ void GuidelinePropertiesDialog::_response(gint response) break; case Gtk::RESPONSE_DELETE_EVENT: break; -/* case GTK_RESPONSE_APPLY: - _onApply(); - break; -*/ default: g_assert_not_reached(); } @@ -222,9 +212,6 @@ void GuidelinePropertiesDialog::_setup() { 1, 3, 3, 4, Gtk::EXPAND | Gtk::FILL, Gtk::FILL); #endif - _color.signal_color_set().connect(sigc::mem_fun(*this, &GuidelinePropertiesDialog::_colorChanged)); - - // unitmenus /* fixme: We should allow percents here too, as percents of the canvas size */ _unit_menu.setUnitType(UNIT_TYPE_LINEAR); diff --git a/src/ui/dialog/guides.h b/src/ui/dialog/guides.h index 422fed7fe..22bf5097a 100644 --- a/src/ui/dialog/guides.h +++ b/src/ui/dialog/guides.h @@ -62,13 +62,11 @@ public: protected: void _setup(); - void _onApply(); void _onOK(); void _onDelete(); void _response(gint response); void _modeChanged(); - void _colorChanged(); private: GuidelinePropertiesDialog(GuidelinePropertiesDialog const &); // no copy diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp index 03108b403..d826ece09 100644 --- a/src/ui/dialog/inkscape-preferences.cpp +++ b/src/ui/dialog/inkscape-preferences.cpp @@ -1534,9 +1534,9 @@ void InkscapePreferences::initKeyboardShortcuts(Gtk::TreeModel::iterator iter_ui row++; #if WITH_GTKMM_3_0 - Gtk::ButtonBox *box_buttons = manage(new Gtk::ButtonBox); + Gtk::ButtonBox *box_buttons = Gtk::manage(new Gtk::ButtonBox); #else - Gtk::HButtonBox *box_buttons = manage (new Gtk::HButtonBox); + Gtk::HButtonBox *box_buttons = Gtk::manage (new Gtk::HButtonBox); #endif box_buttons->set_layout(Gtk::BUTTONBOX_END); @@ -1549,14 +1549,14 @@ void InkscapePreferences::initKeyboardShortcuts(Gtk::TreeModel::iterator iter_ui _page_keyshortcuts.attach(*box_buttons, 0, 3, row, row+1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK); #endif - UI::Widget::Button *kb_reset = manage(new UI::Widget::Button(_("Reset"), _("Remove all your customized keyboard shortcuts, and revert to the shortcuts in the shortcut file listed above"))); + UI::Widget::Button *kb_reset = Gtk::manage(new UI::Widget::Button(_("Reset"), _("Remove all your customized keyboard shortcuts, and revert to the shortcuts in the shortcut file listed above"))); box_buttons->pack_start(*kb_reset, true, true, 6); box_buttons->set_child_secondary(*kb_reset); - UI::Widget::Button *kb_import = manage(new UI::Widget::Button(_("Import ..."), _("Import custom keyboard shortcuts from a file"))); + UI::Widget::Button *kb_import = Gtk::manage(new UI::Widget::Button(_("Import ..."), _("Import custom keyboard shortcuts from a file"))); box_buttons->pack_end(*kb_import, true, true, 6); - UI::Widget::Button *kb_export = manage(new UI::Widget::Button(_("Export ..."), _("Export custom keyboard shortcuts to a file"))); + UI::Widget::Button *kb_export = Gtk::manage(new UI::Widget::Button(_("Export ..."), _("Export custom keyboard shortcuts to a file"))); box_buttons->pack_end(*kb_export, true, true, 6); kb_reset->signal_clicked().connect( sigc::mem_fun(*this, &InkscapePreferences::onKBReset) ); diff --git a/src/ui/dialog/input.cpp b/src/ui/dialog/input.cpp index 82e65435d..4be6716a5 100644 --- a/src/ui/dialog/input.cpp +++ b/src/ui/dialog/input.cpp @@ -53,10 +53,10 @@ /* XPM */ static char const * core_xpm[] = { "16 16 4 1", -" c None", -". c #808080", -"+ c #000000", -"@ c #FFFFFF", +" c None", +". c #808080", +"+ c #000000", +"@ c #FFFFFF", " ", " ", " ", @@ -291,9 +291,9 @@ static char const *button_on[] = { /* XPM */ static char const * axis_none_xpm[] = { "24 8 3 1", -" c None", -". c #000000", -"+ c #808080", +" c None", +". c #000000", +"+ c #808080", " ", " .++++++++++++++++++. ", " .+ . .+. ", @@ -305,10 +305,10 @@ static char const * axis_none_xpm[] = { /* XPM */ static char const * axis_off_xpm[] = { "24 8 4 1", -" c None", -". c #808080", -"+ c #000000", -"@ c #FFFFFF", +" c None", +". c #808080", +"+ c #000000", +"@ c #FFFFFF", " ", " .++++++++++++++++++. ", " .+@@@@@@@@@@@@@@@@@@+. ", @@ -320,9 +320,9 @@ static char const * axis_off_xpm[] = { /* XPM */ static char const * axis_on_xpm[] = { "24 8 3 1", -" c None", -". c #000000", -"+ c #00FF00", +" c None", +". c #000000", +"+ c #00FF00", " ", " .................... ", " ..++++++++++++++++++.. ", @@ -1151,9 +1151,9 @@ InputDialogImpl::ConfPanel::ConfPanel() : useExt.signal_toggled().connect(sigc::mem_fun(*this, &InputDialogImpl::ConfPanel::useExtToggled)); #if WITH_GTKMM_3_0 - Gtk::ButtonBox *buttonBox = manage(new Gtk::ButtonBox); + Gtk::ButtonBox *buttonBox = Gtk::manage(new Gtk::ButtonBox); #else - Gtk::HButtonBox *buttonBox = manage (new Gtk::HButtonBox); + Gtk::HButtonBox *buttonBox = Gtk::manage (new Gtk::HButtonBox); #endif buttonBox->set_layout (Gtk::BUTTONBOX_END); @@ -1707,9 +1707,9 @@ void InputDialogImpl::updateTestAxes( Glib::ustring const& key, GdkDevice* dev ) axesValues[i].set_sensitive(true); if ( dev && (i < static_cast<gint>(G_N_ELEMENTS(axesValues)) ) ) { // FIXME: Device axis ranges are inaccessible in GTK+ 3 and - // are deprecated in GTK+ 2. Progress-bar ranges are disabled - // until we find an alternative solution - + // are deprecated in GTK+ 2. Progress-bar ranges are disabled + // until we find an alternative solution + // if ( (dev->axes[i].max - dev->axes[i].min) > epsilon ) { axesValues[i].set_sensitive(true); // axesValues[i].set_fraction( (axesMap[key][i].second- dev->axes[i].min) / (dev->axes[i].max - dev->axes[i].min) ); @@ -1726,10 +1726,10 @@ void InputDialogImpl::updateTestAxes( Glib::ustring const& key, GdkDevice* dev ) if ( dev && (i < static_cast<gint>(G_N_ELEMENTS(axesValues)) ) ) { // FIXME: Device axis ranges are inaccessible in GTK+ 3 and - // are deprecated in GTK+ 2. Progress-bar ranges are disabled - // until we find an alternative solution + // are deprecated in GTK+ 2. Progress-bar ranges are disabled + // until we find an alternative solution - // if ( (dev->axes[i].max - dev->axes[i].min) > epsilon ) { + // if ( (dev->axes[i].max - dev->axes[i].min) > epsilon ) { axesValues[i].set_sensitive(true); // axesValues[i].set_fraction( (axesMap[key][i].second- dev->axes[i].min) / (dev->axes[i].max - dev->axes[i].min) ); // } @@ -1860,8 +1860,8 @@ bool InputDialogImpl::eventSnoop(GdkEvent* event) GdkEventButton* btnEvt = reinterpret_cast<GdkEventButton*>(event); if ( btnEvt->device ) { key = getKeyFor(btnEvt->device); - source = gdk_device_get_source(btnEvt->device); - devName = gdk_device_get_name(btnEvt->device); + source = gdk_device_get_source(btnEvt->device); + devName = gdk_device_get_name(btnEvt->device); mapAxesValues(key, btnEvt->axes, btnEvt->device); if ( buttonMap[key].find(btnEvt->button) == buttonMap[key].end() ) { @@ -1889,8 +1889,8 @@ bool InputDialogImpl::eventSnoop(GdkEvent* event) GdkEventMotion* btnMtn = reinterpret_cast<GdkEventMotion*>(event); if ( btnMtn->device ) { key = getKeyFor(btnMtn->device); - source = gdk_device_get_source(btnMtn->device); - devName = gdk_device_get_name(btnMtn->device); + source = gdk_device_get_source(btnMtn->device); + devName = gdk_device_get_name(btnMtn->device); mapAxesValues(key, btnMtn->axes, btnMtn->device); } gchar* name = gtk_accelerator_name(0, static_cast<GdkModifierType>(btnMtn->state)); @@ -1915,19 +1915,16 @@ bool InputDialogImpl::eventSnoop(GdkEvent* event) if ( (lastSourceSeen != source) || (lastDevnameSeen != devName) ) { switch (source) { - case GDK_SOURCE_MOUSE: - { + case GDK_SOURCE_MOUSE: { testThumb.set(getPix(PIX_CORE)); + break; } - break; - case GDK_SOURCE_CURSOR: - { -// g_message("flip to cursor"); + case GDK_SOURCE_CURSOR: { +// g_message("flip to cursor"); testThumb.set(getPix(PIX_MOUSE)); + break; } - break; - case GDK_SOURCE_PEN: - { + case GDK_SOURCE_PEN: { if (devName == _("pad")) { // g_message("flip to pad"); testThumb.set(getPix(PIX_SIDEBUTTONS)); @@ -1935,17 +1932,24 @@ bool InputDialogImpl::eventSnoop(GdkEvent* event) // g_message("flip to pen"); testThumb.set(getPix(PIX_TIP)); } + break; } - break; - case GDK_SOURCE_ERASER: - { + case GDK_SOURCE_ERASER: { // g_message("flip to eraser"); testThumb.set(getPix(PIX_ERASER)); + break; } - break; -// default: -// g_message("gurgle"); +#if WITH_GTKMM_3_0 + /// \fixme GTK3 added new GDK_SOURCEs that should be handled here! + case GDK_SOURCE_KEYBOARD: + case GDK_SOURCE_TOUCHSCREEN: + case GDK_SOURCE_TOUCHPAD: { + g_warning("InputDialogImpl::eventSnoop : unhandled GDK_SOURCE type!"); + break; + } +#endif } + updateTestButtons(key, hotButton); lastSourceSeen = source; lastDevnameSeen = devName; diff --git a/src/ui/dialog/layer-properties.cpp b/src/ui/dialog/layer-properties.cpp index f19828b1f..d5540b88a 100644 --- a/src/ui/dialog/layer-properties.cpp +++ b/src/ui/dialog/layer-properties.cpp @@ -213,7 +213,7 @@ LayerPropertiesDialog::_setup_layers_controls() { _tree.set_model( _store ); _tree.set_headers_visible(false); - Inkscape::UI::Widget::ImageToggler *eyeRenderer = manage( new Inkscape::UI::Widget::ImageToggler( + Inkscape::UI::Widget::ImageToggler *eyeRenderer = Gtk::manage( new Inkscape::UI::Widget::ImageToggler( INKSCAPE_ICON("object-visible"), INKSCAPE_ICON("object-hidden")) ); int visibleColNum = _tree.append_column("vis", *eyeRenderer) - 1; Gtk::TreeViewColumn* col = _tree.get_column(visibleColNum); @@ -221,7 +221,7 @@ LayerPropertiesDialog::_setup_layers_controls() { col->add_attribute( eyeRenderer->property_active(), _model->_colVisible ); } - Inkscape::UI::Widget::ImageToggler * renderer = manage( new Inkscape::UI::Widget::ImageToggler( + Inkscape::UI::Widget::ImageToggler * renderer = Gtk::manage( new Inkscape::UI::Widget::ImageToggler( INKSCAPE_ICON("object-locked"), INKSCAPE_ICON("object-unlocked")) ); int lockedColNum = _tree.append_column("lock", *renderer) - 1; col = _tree.get_column(lockedColNum); @@ -229,7 +229,7 @@ LayerPropertiesDialog::_setup_layers_controls() { col->add_attribute( renderer->property_active(), _model->_colLocked ); } - Gtk::CellRendererText *_text_renderer = manage(new Gtk::CellRendererText()); + Gtk::CellRendererText *_text_renderer = Gtk::manage(new Gtk::CellRendererText()); int nameColNum = _tree.append_column("Name", *_text_renderer) - 1; Gtk::TreeView::Column *_name_column = _tree.get_column(nameColNum); _name_column->add_attribute(_text_renderer->property_text(), _model->_colLabel); diff --git a/src/ui/dialog/layers.cpp b/src/ui/dialog/layers.cpp index 381810f1e..b5dac0595 100644 --- a/src/ui/dialog/layers.cpp +++ b/src/ui/dialog/layers.cpp @@ -92,7 +92,7 @@ void LayersPanel::_styleButton( Gtk::Button& btn, SPDesktop *desktop, unsigned i if ( iconName ) { GtkWidget *child = sp_icon_new( Inkscape::ICON_SIZE_SMALL_TOOLBAR, iconName ); gtk_widget_show( child ); - btn.add( *manage(Glib::wrap(child)) ); + btn.add( *Gtk::manage(Glib::wrap(child)) ); btn.set_relief(Gtk::RELIEF_NONE); set = true; } @@ -104,7 +104,7 @@ void LayersPanel::_styleButton( Gtk::Button& btn, SPDesktop *desktop, unsigned i if ( !set && action && action->image ) { GtkWidget *child = sp_icon_new( Inkscape::ICON_SIZE_SMALL_TOOLBAR, action->image ); gtk_widget_show( child ); - btn.add( *manage(Glib::wrap(child)) ); + btn.add( *Gtk::manage(Glib::wrap(child)) ); set = true; } @@ -149,7 +149,7 @@ Gtk::MenuItem& LayersPanel::_addPopupItem( SPDesktop *desktop, unsigned int code Gtk::Widget* wrapped = 0; if ( iconWidget ) { - wrapped = manage(Glib::wrap(iconWidget)); + wrapped = Gtk::manage(Glib::wrap(iconWidget)); wrapped->show(); } @@ -809,7 +809,7 @@ LayersPanel::LayersPanel() : _tree.set_reorderable(true); _tree.enable_model_drag_dest (Gdk::ACTION_MOVE); - Inkscape::UI::Widget::ImageToggler *eyeRenderer = manage( new Inkscape::UI::Widget::ImageToggler( + Inkscape::UI::Widget::ImageToggler *eyeRenderer = Gtk::manage( new Inkscape::UI::Widget::ImageToggler( INKSCAPE_ICON("object-visible"), INKSCAPE_ICON("object-hidden")) ); int visibleColNum = _tree.append_column("vis", *eyeRenderer) - 1; eyeRenderer->signal_pre_toggle().connect( sigc::mem_fun(*this, &LayersPanel::_preToggle) ); @@ -821,7 +821,7 @@ LayersPanel::LayersPanel() : } - Inkscape::UI::Widget::ImageToggler * renderer = manage( new Inkscape::UI::Widget::ImageToggler( + Inkscape::UI::Widget::ImageToggler * renderer = Gtk::manage( new Inkscape::UI::Widget::ImageToggler( INKSCAPE_ICON("object-locked"), INKSCAPE_ICON("object-unlocked")) ); int lockedColNum = _tree.append_column("lock", *renderer) - 1; renderer->signal_pre_toggle().connect( sigc::mem_fun(*this, &LayersPanel::_preToggle) ); @@ -832,7 +832,7 @@ LayersPanel::LayersPanel() : col->add_attribute( renderer->property_active(), _model->_colLocked ); } - _text_renderer = manage(new Gtk::CellRendererText()); + _text_renderer = Gtk::manage(new Gtk::CellRendererText()); int nameColNum = _tree.append_column("Name", *_text_renderer) - 1; _name_column = _tree.get_column(nameColNum); _name_column->add_attribute(_text_renderer->property_text(), _model->_colLabel); @@ -880,40 +880,40 @@ LayersPanel::LayersPanel() : SPDesktop* targetDesktop = getDesktop(); - Gtk::Button* btn = manage( new Gtk::Button() ); + Gtk::Button* btn = Gtk::manage( new Gtk::Button() ); _styleButton( *btn, targetDesktop, SP_VERB_LAYER_NEW, INKSCAPE_ICON("list-add"), C_("Layers", "New") ); btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &LayersPanel::_takeAction), (int)BUTTON_NEW) ); _buttonsSecondary.pack_start(*btn, Gtk::PACK_SHRINK); - btn = manage( new Gtk::Button() ); + btn = Gtk::manage( new Gtk::Button() ); _styleButton( *btn, targetDesktop, SP_VERB_LAYER_TO_BOTTOM, INKSCAPE_ICON("go-bottom"), C_("Layers", "Bot") ); btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &LayersPanel::_takeAction), (int)BUTTON_BOTTOM) ); _watchingNonBottom.push_back( btn ); _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK); - btn = manage( new Gtk::Button() ); + btn = Gtk::manage( new Gtk::Button() ); _styleButton( *btn, targetDesktop, SP_VERB_LAYER_LOWER, INKSCAPE_ICON("go-down"), C_("Layers", "Dn") ); btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &LayersPanel::_takeAction), (int)BUTTON_DOWN) ); _watchingNonBottom.push_back( btn ); _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK); - btn = manage( new Gtk::Button() ); + btn = Gtk::manage( new Gtk::Button() ); _styleButton( *btn, targetDesktop, SP_VERB_LAYER_RAISE, INKSCAPE_ICON("go-up"), C_("Layers", "Up") ); btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &LayersPanel::_takeAction), (int)BUTTON_UP) ); _watchingNonTop.push_back( btn ); _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK); - btn = manage( new Gtk::Button() ); + btn = Gtk::manage( new Gtk::Button() ); _styleButton( *btn, targetDesktop, SP_VERB_LAYER_TO_TOP, INKSCAPE_ICON("go-top"), C_("Layers", "Top") ); btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &LayersPanel::_takeAction), (int)BUTTON_TOP) ); _watchingNonTop.push_back( btn ); _buttonsPrimary.pack_end(*btn, Gtk::PACK_SHRINK); -// btn = manage( new Gtk::Button("Dup") ); +// btn = Gtk::manage( new Gtk::Button("Dup") ); // btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &LayersPanel::_takeAction), (int)BUTTON_DUPLICATE) ); // _buttonsRow.add( *btn ); - btn = manage( new Gtk::Button() ); + btn = Gtk::manage( new Gtk::Button() ); _styleButton( *btn, targetDesktop, SP_VERB_LAYER_DELETE, INKSCAPE_ICON("list-remove"), _("X") ); btn->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &LayersPanel::_takeAction), (int)BUTTON_DELETE) ); _watching.push_back( btn ); @@ -930,19 +930,19 @@ LayersPanel::LayersPanel() : _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_DUPLICATE, 0, "Duplicate", (int)BUTTON_DUPLICATE ) ); _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_NEW, 0, "New", (int)BUTTON_NEW ) ); - _popupMenu.append(*manage(new Gtk::SeparatorMenuItem())); + _popupMenu.append(*Gtk::manage(new Gtk::SeparatorMenuItem())); _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_SOLO, 0, "Solo", (int)BUTTON_SOLO ) ); _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_SHOW_ALL, 0, "Show All", (int)BUTTON_SHOW_ALL ) ); _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_HIDE_ALL, 0, "Hide All", (int)BUTTON_HIDE_ALL ) ); - _popupMenu.append(*manage(new Gtk::SeparatorMenuItem())); + _popupMenu.append(*Gtk::manage(new Gtk::SeparatorMenuItem())); _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_LOCK_OTHERS, 0, "Lock Others", (int)BUTTON_LOCK_OTHERS ) ); _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_LOCK_ALL, 0, "Lock All", (int)BUTTON_LOCK_ALL ) ); _watching.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_UNLOCK_ALL, 0, "Unlock All", (int)BUTTON_UNLOCK_ALL ) ); - _popupMenu.append(*manage(new Gtk::SeparatorMenuItem())); + _popupMenu.append(*Gtk::manage(new Gtk::SeparatorMenuItem())); _watchingNonTop.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_RAISE, INKSCAPE_ICON("go-up"), "Up", (int)BUTTON_UP ) ); _watchingNonBottom.push_back( &_addPopupItem( targetDesktop, SP_VERB_LAYER_LOWER, INKSCAPE_ICON("go-down"), "Down", (int)BUTTON_DOWN ) ); diff --git a/src/ui/dialog/livepatheffect-editor.cpp b/src/ui/dialog/livepatheffect-editor.cpp index b81b300e2..9a569725c 100644 --- a/src/ui/dialog/livepatheffect-editor.cpp +++ b/src/ui/dialog/livepatheffect-editor.cpp @@ -107,7 +107,7 @@ LivePathEffectEditor::LivePathEffectEditor() effectcontrol_frame.add(effectcontrol_vbox); button_add.set_tooltip_text(_("Add path effect")); -#if GTK_CHECK_VERSION(3,10,0) +#if WITH_GTKMM_3_10 button_add.set_image_from_icon_name(INKSCAPE_ICON("list-add"), Gtk::ICON_SIZE_SMALL_TOOLBAR); #else Gtk::Image *image_add = Gtk::manage(new Gtk::Image()); @@ -117,7 +117,7 @@ LivePathEffectEditor::LivePathEffectEditor() button_add.set_relief(Gtk::RELIEF_NONE); button_remove.set_tooltip_text(_("Delete current path effect")); -#if GTK_CHECK_VERSION(3,10,0) +#if WITH_GTKMM_3_10 button_remove.set_image_from_icon_name(INKSCAPE_ICON("list-remove"), Gtk::ICON_SIZE_SMALL_TOOLBAR); #else Gtk::Image *image_remove = Gtk::manage(new Gtk::Image()); @@ -127,7 +127,7 @@ LivePathEffectEditor::LivePathEffectEditor() button_remove.set_relief(Gtk::RELIEF_NONE); button_up.set_tooltip_text(_("Raise the current path effect")); -#if GTK_CHECK_VERSION(3,10,0) +#if WITH_GTKMM_3_10 button_up.set_image_from_icon_name(INKSCAPE_ICON("go-up"), Gtk::ICON_SIZE_SMALL_TOOLBAR); #else Gtk::Image *image_up = Gtk::manage(new Gtk::Image()); @@ -137,7 +137,7 @@ LivePathEffectEditor::LivePathEffectEditor() button_up.set_relief(Gtk::RELIEF_NONE); button_down.set_tooltip_text(_("Lower the current path effect")); -#if GTK_CHECK_VERSION(3,10,0) +#if WITH_GTKMM_3_10 button_down.set_image_from_icon_name(INKSCAPE_ICON("go-down"), Gtk::ICON_SIZE_SMALL_TOOLBAR); #else Gtk::Image *image_down = Gtk::manage(new Gtk::Image()); @@ -172,7 +172,7 @@ LivePathEffectEditor::LivePathEffectEditor() effectlist_selection->signal_changed().connect( sigc::mem_fun(*this, &LivePathEffectEditor::on_effect_selection_changed) ); //Add the visibility icon column: - Inkscape::UI::Widget::ImageToggler *eyeRenderer = manage( new Inkscape::UI::Widget::ImageToggler( + Inkscape::UI::Widget::ImageToggler *eyeRenderer = Gtk::manage( new Inkscape::UI::Widget::ImageToggler( INKSCAPE_ICON("object-visible"), INKSCAPE_ICON("object-hidden")) ); int visibleColNum = effectlist_view.append_column("is_visible", *eyeRenderer) - 1; eyeRenderer->signal_toggled().connect( sigc::mem_fun(*this, &LivePathEffectEditor::on_visibility_toggled) ); diff --git a/src/ui/dialog/new-from-template.cpp b/src/ui/dialog/new-from-template.cpp index 177f15195..f326bb3ee 100644 --- a/src/ui/dialog/new-from-template.cpp +++ b/src/ui/dialog/new-from-template.cpp @@ -29,7 +29,7 @@ NewFromTemplate::NewFromTemplate() get_vbox()->pack_start(_main_widget); Gtk::Alignment *align; - align = manage(new Gtk::Alignment(Gtk::ALIGN_END, Gtk::ALIGN_CENTER, 0.0, 0.0)); + align = Gtk::manage(new Gtk::Alignment(Gtk::ALIGN_END, Gtk::ALIGN_CENTER, 0.0, 0.0)); get_vbox()->pack_end(*align, Gtk::PACK_SHRINK); align->set_padding(0, 0, 0, 15); align->add(_create_template_button); @@ -44,10 +44,13 @@ NewFromTemplate::NewFromTemplate() void NewFromTemplate::_createFromTemplate() { _main_widget.createTemplate(); - - response(0); + _onClose(); } +void NewFromTemplate::_onClose() +{ + response(0); +} void NewFromTemplate::load_new_from_template() { diff --git a/src/ui/dialog/new-from-template.h b/src/ui/dialog/new-from-template.h index 8ebcb2863..2b40af2a6 100644 --- a/src/ui/dialog/new-from-template.h +++ b/src/ui/dialog/new-from-template.h @@ -23,6 +23,8 @@ namespace UI { class NewFromTemplate : public Gtk::Dialog { + +friend class TemplateLoadTab; public: static void load_new_from_template(); @@ -32,6 +34,7 @@ private: TemplateLoadTab _main_widget; void _createFromTemplate(); + void _onClose(); }; } diff --git a/src/ui/dialog/object-properties.cpp b/src/ui/dialog/object-properties.cpp index 82b2cf6b1..28e9b360b 100644 --- a/src/ui/dialog/object-properties.cpp +++ b/src/ui/dialog/object-properties.cpp @@ -28,9 +28,9 @@ #include "object-properties.h" #include "widgets/sp-attribute-widget.h" -#include "../../desktop-handles.h" -#include "../../document.h" -#include "../../document-undo.h" +#include "desktop-handles.h" +#include "document.h" +#include "document-undo.h" #include "verbs.h" #include "inkscape.h" #include "selection.h" @@ -51,481 +51,479 @@ namespace Inkscape { namespace UI { namespace Dialog { -ObjectProperties::ObjectProperties (void) : - UI::Widget::Panel ("", "/dialogs/object/", SP_VERB_DIALOG_ITEM), - blocked (false), - CurrentItem(NULL), -#if WITH_GTKMM_3_0 - TopTable(Gtk::manage(new Gtk::Grid())), -#else - TopTable(Gtk::manage(new Gtk::Table(4, 4))), -#endif - LabelID(_("_ID:"), 1), - LabelLabel(_("_Label:"), 1), - LabelTitle(_("_Title:"),1), - LabelImageRendering(_("_Image Rendering:"),1), - LabelDescription(_("_Description:"),1), - FrameDescription("", FALSE), - HBoxCheck(FALSE, 0), -#if WITH_GTKMM_3_0 - CheckTable(Gtk::manage(new Gtk::Grid())), -#else - CheckTable(Gtk::manage(new Gtk::Table(1, 2, true))), -#endif - CBHide(_("_Hide"), 1), - CBLock(_("L_ock"), 1), - BSet (_("_Set"), 1), - LabelInteractivity(_("_Interactivity"), 1), - attrTable(Gtk::manage(new SPAttributeTable())), - desktop(NULL), - deskTrack(), - selectChangedConn(), - subselChangedConn() +ObjectProperties::ObjectProperties() + : UI::Widget::Panel ("", "/dialogs/object/", SP_VERB_DIALOG_ITEM) + , _blocked (false) + , _current_item(NULL) + , _label_id(_("_ID:"), 1) + , _label_label(_("_Label:"), 1) + , _label_title(_("_Title:"), 1) + , _label_image_rendering(_("_Image Rendering:"), 1) + , _cb_hide(_("_Hide"), 1) + , _cb_lock(_("L_ock"), 1) + , _attr_table(Gtk::manage(new SPAttributeTable())) + , _desktop(NULL) { //initialize labels for the table at the bottom of the dialog - int_attrs.push_back("onclick"); - int_attrs.push_back("onmouseover"); - int_attrs.push_back("onmouseout"); - int_attrs.push_back("onmousedown"); - int_attrs.push_back("onmouseup"); - int_attrs.push_back("onmousemove"); - int_attrs.push_back("onfocusin"); - int_attrs.push_back("onfocusout"); - int_attrs.push_back("onload"); - - int_labels.push_back("onclick:"); - int_labels.push_back("onmouseover:"); - int_labels.push_back("onmouseout:"); - int_labels.push_back("onmousedown:"); - int_labels.push_back("onmouseup:"); - int_labels.push_back("onmousemove:"); - int_labels.push_back("onfocusin:"); - int_labels.push_back("onfocusout:"); - int_labels.push_back("onload:"); - - desktopChangeConn = deskTrack.connectDesktopChanged( sigc::mem_fun(*this, &ObjectProperties::setTargetDesktop) ); - deskTrack.connect(GTK_WIDGET(gobj())); - -#if WITH_GTKMM_3_0 - CheckTable->set_row_homogeneous(); - CheckTable->set_column_homogeneous(true); -#endif - - MakeWidget(); + _int_attrs.push_back("onclick"); + _int_attrs.push_back("onmouseover"); + _int_attrs.push_back("onmouseout"); + _int_attrs.push_back("onmousedown"); + _int_attrs.push_back("onmouseup"); + _int_attrs.push_back("onmousemove"); + _int_attrs.push_back("onfocusin"); + _int_attrs.push_back("onfocusout"); + _int_attrs.push_back("onload"); + + _int_labels.push_back("onclick:"); + _int_labels.push_back("onmouseover:"); + _int_labels.push_back("onmouseout:"); + _int_labels.push_back("onmousedown:"); + _int_labels.push_back("onmouseup:"); + _int_labels.push_back("onmousemove:"); + _int_labels.push_back("onfocusin:"); + _int_labels.push_back("onfocusout:"); + _int_labels.push_back("onload:"); + + _desktop_changed_connection = _desktop_tracker.connectDesktopChanged( + sigc::mem_fun(*this, &ObjectProperties::_setTargetDesktop) + ); + _desktop_tracker.connect(GTK_WIDGET(gobj())); + + _init(); } -ObjectProperties::~ObjectProperties (void) +ObjectProperties::~ObjectProperties() { - subselChangedConn.disconnect(); - selectChangedConn.disconnect(); - desktopChangeConn.disconnect(); - deskTrack.disconnect(); + _subselection_changed_connection.disconnect(); + _selection_changed_connection.disconnect(); + _desktop_changed_connection.disconnect(); + _desktop_tracker.disconnect(); } -void ObjectProperties::MakeWidget(void) +void ObjectProperties::_init() { Gtk::Box *contents = _getContents(); contents->set_spacing(0); - - TopTable->set_border_width(4); #if WITH_GTKMM_3_0 - TopTable->set_row_spacing(4); - TopTable->set_column_spacing(0); + Gtk::Grid *grid_top = Gtk::manage(new Gtk::Grid()); + grid_top->set_row_spacing(4); + grid_top->set_column_spacing(0); #else - TopTable->set_row_spacings(4); - TopTable->set_col_spacings(0); + Gtk::Table *grid_top = Gtk::manage(new Gtk::Table(4, 4)); + grid_top->set_row_spacings(4); + grid_top->set_col_spacings(0); #endif - contents->pack_start (*TopTable, false, false, 0); + grid_top->set_border_width(4); + + contents->pack_start(*grid_top, false, false, 0); + /* Create the label for the object id */ - LabelID.set_label (LabelID.get_label() + " "); - LabelID.set_alignment (1, 0.5); + _label_id.set_label(_label_id.get_label() + " "); + _label_id.set_alignment(1, 0.5); #if WITH_GTKMM_3_0 - LabelID.set_valign(Gtk::ALIGN_CENTER); - TopTable->attach(LabelID, 0, 0, 1, 1); + _label_id.set_valign(Gtk::ALIGN_CENTER); + grid_top->attach(_label_id, 0, 0, 1, 1); #else - TopTable->attach(LabelID, 0, 1, 0, 1, - Gtk::SHRINK | Gtk::FILL, - Gtk::AttachOptions(), 0, 0 ); + grid_top->attach(_label_id, 0, 1, 0, 1, + Gtk::SHRINK | Gtk::FILL, + Gtk::AttachOptions(), 0, 0 ); #endif + /* Create the entry box for the object id */ - EntryID.set_tooltip_text (_("The id= attribute (only letters, digits, and the characters .-_: allowed)")); - EntryID.set_max_length (64); + _entry_id.set_tooltip_text(_("The id= attribute (only letters, digits, and the characters .-_: allowed)")); + _entry_id.set_max_length(64); #if WITH_GTKMM_3_0 - EntryID.set_valign(Gtk::ALIGN_CENTER); - TopTable->attach(EntryID, 1, 0, 1, 1); + _entry_id.set_valign(Gtk::ALIGN_CENTER); + grid_top->attach(_entry_id, 1, 0, 1, 1); #else - TopTable->attach(EntryID, 1, 2, 0, 1, + grid_top->attach(_entry_id, 1, 2, 0, 1, Gtk::EXPAND | Gtk::FILL, Gtk::AttachOptions(), 0, 0 ); #endif - LabelID.set_mnemonic_widget (EntryID); + _label_id.set_mnemonic_widget(_entry_id); // pressing enter in the id field is the same as clicking Set: - EntryID.signal_activate().connect(sigc::mem_fun(this, &ObjectProperties::label_changed)); + _entry_id.signal_activate().connect(sigc::mem_fun(this, &ObjectProperties::_labelChanged)); // focus is in the id field initially: - EntryID.grab_focus(); + _entry_id.grab_focus(); + /* Create the label for the object label */ - LabelLabel.set_label (LabelLabel.get_label() + " "); - LabelLabel.set_alignment (1, 0.5); + _label_label.set_label(_label_label.get_label() + " "); + _label_label.set_alignment(1, 0.5); #if WITH_GTKMM_3_0 - LabelLabel.set_valign(Gtk::ALIGN_CENTER); - TopTable->attach(LabelLabel, 0, 1, 1, 1); + _label_label.set_valign(Gtk::ALIGN_CENTER); + grid_top->attach(_label_label, 0, 1, 1, 1); #else - TopTable->attach(LabelLabel, 0, 1, 1, 2, + grid_top->attach(_label_label, 0, 1, 1, 2, Gtk::SHRINK | Gtk::FILL, Gtk::AttachOptions(), 0, 0 ); #endif + /* Create the entry box for the object label */ - EntryLabel.set_tooltip_text (_("A freeform label for the object")); - EntryLabel.set_max_length (256); + _entry_label.set_tooltip_text(_("A freeform label for the object")); + _entry_label.set_max_length(256); #if WITH_GTKMM_3_0 - EntryLabel.set_hexpand(); - EntryLabel.set_valign(Gtk::ALIGN_CENTER); - TopTable->attach(EntryLabel, 1, 1, 1, 1); + _entry_label.set_hexpand(); + _entry_label.set_valign(Gtk::ALIGN_CENTER); + grid_top->attach(_entry_label, 1, 1, 1, 1); #else - TopTable->attach(EntryLabel, 1, 2, 1, 2, + grid_top->attach(_entry_label, 1, 2, 1, 2, Gtk::EXPAND | Gtk::FILL, Gtk::AttachOptions(), 0, 0 ); #endif - LabelLabel.set_mnemonic_widget (EntryLabel); + _label_label.set_mnemonic_widget(_entry_label); // pressing enter in the label field is the same as clicking Set: - EntryLabel.signal_activate().connect(sigc::mem_fun(this, &ObjectProperties::label_changed)); + _entry_label.signal_activate().connect(sigc::mem_fun(this, &ObjectProperties::_labelChanged)); + /* Create the label for the object title */ - LabelTitle.set_label (LabelTitle.get_label() + " "); - LabelTitle.set_alignment (1, 0.5); + _label_title.set_label(_label_title.get_label() + " "); + _label_title.set_alignment (1, 0.5); #if WITH_GTKMM_3_0 - LabelTitle.set_valign(Gtk::ALIGN_CENTER); - TopTable->attach(LabelTitle, 0, 2, 1, 1); + _label_title.set_valign(Gtk::ALIGN_CENTER); + grid_top->attach(_label_title, 0, 2, 1, 1); #else - TopTable->attach(LabelTitle, 0, 1, 2, 3, + grid_top->attach(_label_title, 0, 1, 2, 3, Gtk::SHRINK | Gtk::FILL, Gtk::AttachOptions(), 0, 0 ); #endif /* Create the entry box for the object title */ - EntryTitle.set_sensitive (FALSE); - EntryTitle.set_max_length (256); + _entry_title.set_sensitive (FALSE); + _entry_title.set_max_length (256); #if WITH_GTKMM_3_0 - EntryTitle.set_hexpand(); - EntryTitle.set_valign(Gtk::ALIGN_CENTER); - TopTable->attach(EntryTitle, 1, 2, 1, 1); + _entry_title.set_hexpand(); + _entry_title.set_valign(Gtk::ALIGN_CENTER); + grid_top->attach(_entry_title, 1, 2, 1, 1); #else - TopTable->attach(EntryTitle, 1, 2, 2, 3, + grid_top->attach(_entry_title, 1, 2, 2, 3, Gtk::EXPAND | Gtk::FILL, Gtk::AttachOptions(), 0, 0 ); #endif - LabelTitle.set_mnemonic_widget (EntryTitle); + _label_title.set_mnemonic_widget(_entry_title); // pressing enter in the label field is the same as clicking Set: - EntryTitle.signal_activate().connect(sigc::mem_fun(this, &ObjectProperties::label_changed)); + _entry_title.signal_activate().connect(sigc::mem_fun(this, &ObjectProperties::_labelChanged)); /* Create the frame for the object description */ - FrameDescription.set_label_widget (LabelDescription); - FrameDescription.set_padding (0,0,0,0); - contents->pack_start (FrameDescription, true, true, 0); + Gtk::Label *label_desc = Gtk::manage(new Gtk::Label(_("_Description:"), 1)); + UI::Widget::Frame *frame_desc = Gtk::manage(new UI::Widget::Frame("", FALSE)); + frame_desc->set_label_widget(*label_desc); + frame_desc->set_padding (0,0,0,0); + contents->pack_start(*frame_desc, true, true, 0); /* Create the text view box for the object description */ - FrameTextDescription.set_border_width(4); - FrameTextDescription.set_sensitive (FALSE); - FrameDescription.add (FrameTextDescription); - FrameTextDescription.set_shadow_type (Gtk::SHADOW_IN); + _ft_description.set_border_width(4); + _ft_description.set_sensitive(FALSE); + frame_desc->add(_ft_description); + _ft_description.set_shadow_type(Gtk::SHADOW_IN); - TextViewDescription.set_wrap_mode(Gtk::WRAP_WORD); - TextViewDescription.get_buffer()->set_text(""); - FrameTextDescription.add (TextViewDescription); - TextViewDescription.add_mnemonic_label(LabelDescription); + _tv_description.set_wrap_mode(Gtk::WRAP_WORD); + _tv_description.get_buffer()->set_text(""); + _ft_description.add(_tv_description); + _tv_description.add_mnemonic_label(*label_desc); /* Image rendering */ /* Create the label for the object ImageRendering */ - LabelImageRendering.set_label (LabelImageRendering.get_label() + " "); - LabelImageRendering.set_alignment (1, 0.5); + _label_image_rendering.set_label(_label_image_rendering.get_label() + " "); + _label_image_rendering.set_alignment(1, 0.5); #if WITH_GTKMM_3_0 - LabelImageRendering.set_valign(Gtk::ALIGN_CENTER); - TopTable->attach(LabelImageRendering, 0, 3, 1, 1); + _label_image_rendering.set_valign(Gtk::ALIGN_CENTER); + grid_top->attach(_label_image_rendering, 0, 3, 1, 1); #else - TopTable->attach(LabelImageRendering, 0, 1, 3, 4, - Gtk::SHRINK | Gtk::FILL, - Gtk::AttachOptions(), 0, 0 ); + grid_top->attach(_label_image_rendering, 0, 1, 3, 4, + Gtk::SHRINK | Gtk::FILL, + Gtk::AttachOptions(), 0, 0 ); #endif /* Create the combo box text for the 'image-rendering' property */ - ComboBoxTextImageRendering.append( "auto" ); - ComboBoxTextImageRendering.append( "optimizeQuality" ); - ComboBoxTextImageRendering.append( "optimizeSpeed" ); - ComboBoxTextImageRendering.set_tooltip_text (_("The 'image-rendering' property can influence how a bitmap is up-scaled:\n\t'auto' no preference;\n\t'optimizeQuality' smooth;\n\t'optimizeSpeed' blocky.\nNote that this behaviour is not defined in the SVG 1.1 specification and not all browsers follow this interpretation.")); + _combo_image_rendering.append( "auto" ); + _combo_image_rendering.append( "optimizeQuality" ); + _combo_image_rendering.append( "optimizeSpeed" ); + _combo_image_rendering.set_tooltip_text(_("The 'image-rendering' property can influence how a bitmap is up-scaled:\n\t'auto' no preference;\n\t'optimizeQuality' smooth;\n\t'optimizeSpeed' blocky.\nNote that this behaviour is not defined in the SVG 1.1 specification and not all browsers follow this interpretation.")); #if WITH_GTKMM_3_0 - ComboBoxTextImageRendering.set_valign(Gtk::ALIGN_CENTER); - TopTable->attach(ComboBoxTextImageRendering, 1, 3, 1, 1); + _combo_image_rendering.set_valign(Gtk::ALIGN_CENTER); + grid_top->attach(_combo_image_rendering, 1, 3, 1, 1); #else - TopTable->attach(ComboBoxTextImageRendering, 1, 2, 3, 4, + grid_top->attach(_combo_image_rendering, 1, 2, 3, 4, Gtk::EXPAND | Gtk::FILL, Gtk::AttachOptions(), 0, 0 ); #endif - LabelImageRendering.set_mnemonic_widget (ComboBoxTextImageRendering); + _label_image_rendering.set_mnemonic_widget(_combo_image_rendering); - ComboBoxTextImageRendering.signal_changed().connect(sigc::mem_fun(this, &ObjectProperties::image_rendering_changed)); + _combo_image_rendering.signal_changed().connect( + sigc::mem_fun(this, &ObjectProperties::_imageRenderingChanged) + ); /* Check boxes */ - contents->pack_start (HBoxCheck, FALSE, FALSE, 0); - CheckTable->set_border_width(4); - HBoxCheck.pack_start(*CheckTable, true, true, 0); + Gtk::HBox *hb_checkboxes = Gtk::manage(new Gtk::HBox()); + contents->pack_start(*hb_checkboxes, FALSE, FALSE, 0); + +#if WITH_GTKMM_3_0 + Gtk::Grid *grid_cb = Gtk::manage(new Gtk::Grid()); + grid_cb->set_row_homogeneous(); + grid_cb->set_column_homogeneous(true); +#else + Gtk::Table *grid_cb = Gtk::manage(new Gtk::Table(1, 2, true)); +#endif + + grid_cb->set_border_width(4); + hb_checkboxes->pack_start(*grid_cb, true, true, 0); /* Hide */ - CBHide.set_tooltip_text (_("Check to make the object invisible")); + _cb_hide.set_tooltip_text (_("Check to make the object invisible")); #if WITH_GTKMM_3_0 - CBHide.set_hexpand(); - CBHide.set_valign(Gtk::ALIGN_CENTER); - CheckTable->attach(CBHide, 0, 0, 1, 1); + _cb_hide.set_hexpand(); + _cb_hide.set_valign(Gtk::ALIGN_CENTER); + grid_cb->attach(_cb_hide, 0, 0, 1, 1); #else - CheckTable->attach(CBHide, 0, 1, 0, 1, + grid_cb->attach(_cb_hide, 0, 1, 0, 1, Gtk::EXPAND | Gtk::FILL, Gtk::AttachOptions(), 0, 0 ); #endif - CBHide.signal_toggled().connect(sigc::mem_fun(this, &ObjectProperties::hidden_toggled)); + _cb_hide.signal_toggled().connect(sigc::mem_fun(this, &ObjectProperties::_hiddenToggled)); /* Lock */ // TRANSLATORS: "Lock" is a verb here - CBLock.set_tooltip_text (_("Check to make the object insensitive (not selectable by mouse)")); + _cb_lock.set_tooltip_text(_("Check to make the object insensitive (not selectable by mouse)")); #if WITH_GTKMM_3_0 - CBLock.set_hexpand(); - CBLock.set_valign(Gtk::ALIGN_CENTER); - CheckTable->attach(CBLock, 1, 0, 1, 1); + _cb_lock.set_hexpand(); + _cb_lock.set_valign(Gtk::ALIGN_CENTER); + grid_cb->attach(_cb_lock, 1, 0, 1, 1); #else - CheckTable->attach(CBLock, 1, 2, 0, 1, - Gtk::EXPAND | Gtk::FILL, - Gtk::AttachOptions(), 0, 0 ); + grid_cb->attach(_cb_lock, 1, 2, 0, 1, + Gtk::EXPAND | Gtk::FILL, + Gtk::AttachOptions(), 0, 0 ); #endif - CBLock.signal_toggled().connect(sigc::mem_fun(this, &ObjectProperties::sensitivity_toggled)); + _cb_lock.signal_toggled().connect(sigc::mem_fun(this, &ObjectProperties::_sensitivityToggled)); /* Button for setting the object's id, label, title and description. */ + Gtk::Button *btn_set = Gtk::manage(new Gtk::Button(_("_Set"), 1)); #if WITH_GTKMM_3_0 - BSet.set_hexpand(); - BSet.set_valign(Gtk::ALIGN_CENTER); - CheckTable->attach(BSet, 2, 0, 1, 1); + btn_set->set_hexpand(); + btn_set->set_valign(Gtk::ALIGN_CENTER); + grid_cb->attach(*btn_set, 2, 0, 1, 1); #else - CheckTable->attach(BSet, 2, 3, 0, 1, - Gtk::EXPAND | Gtk::FILL, - Gtk::AttachOptions(), 0, 0 ); + grid_cb->attach(*btn_set, 2, 3, 0, 1, + Gtk::EXPAND | Gtk::FILL, + Gtk::AttachOptions(), 0, 0 ); #endif - BSet.signal_clicked().connect(sigc::mem_fun(this, &ObjectProperties::label_changed)); + btn_set->signal_clicked().connect(sigc::mem_fun(this, &ObjectProperties::_labelChanged)); /* Create the frame for interactivity options */ - EInteractivity.set_label_widget (LabelInteractivity); - contents->pack_start (EInteractivity, FALSE, FALSE, 0); - show_all (); - widget_setup(); + Gtk::Label *label_interactivity = Gtk::manage(new Gtk::Label(_("_Interactivity"), 1)); + _exp_interactivity.set_label_widget(*label_interactivity); + contents->pack_start(_exp_interactivity, FALSE, FALSE, 0); + + show_all(); + update(); } -void ObjectProperties::widget_setup(void) +void ObjectProperties::update() { - if (blocked || !desktop) - { + if (_blocked || !_desktop) { return; } - if (SP_ACTIVE_DESKTOP != desktop) - { + if (SP_ACTIVE_DESKTOP != _desktop) { return; } - Inkscape::Selection *selection = sp_desktop_selection (SP_ACTIVE_DESKTOP); + Inkscape::Selection *selection = sp_desktop_selection(SP_ACTIVE_DESKTOP); Gtk::Box *contents = _getContents(); if (!selection->singleItem()) { contents->set_sensitive (false); - CurrentItem = NULL; + _current_item = NULL; //no selection anymore or multiple objects selected, means that we need //to close the connections to the previously selected object - attrTable->clear(); + _attr_table->clear(); return; } else { contents->set_sensitive (true); } SPItem *item = selection->singleItem(); - if (CurrentItem == item) + if (_current_item == item) { //otherwise we would end up wasting resources through the modify selection - //callback when moving an object (endlessly setting the labels and recreating attrTable) + //callback when moving an object (endlessly setting the labels and recreating _attr_table) return; } - blocked = true; + _blocked = true; - CBLock.set_active (item->isLocked()); /* Sensitive */ - CBHide.set_active (item->isExplicitlyHidden()); /* Hidden */ + _cb_lock.set_active(item->isLocked()); /* Sensitive */ + _cb_hide.set_active(item->isExplicitlyHidden()); /* Hidden */ if (item->cloned) { /* ID */ - EntryID.set_text (""); - EntryID.set_sensitive (FALSE); - LabelID.set_text (_("Ref")); + _entry_id.set_text(""); + _entry_id.set_sensitive(FALSE); + _label_id.set_text(_("Ref")); /* Label */ - EntryLabel.set_text (""); - EntryLabel.set_sensitive (FALSE); - LabelLabel.set_text (_("Ref")); + _entry_label.set_text(""); + _entry_label.set_sensitive(FALSE); + _label_label.set_text(_("Ref")); } else { SPObject *obj = static_cast<SPObject*>(item); /* ID */ - EntryID.set_text (obj->getId()); - EntryID.set_sensitive (TRUE); - LabelID.set_markup_with_mnemonic (_("_ID:")); + _entry_id.set_text(obj->getId()); + _entry_id.set_sensitive(TRUE); + _label_id.set_markup_with_mnemonic(_("_ID:") + Glib::ustring(" ")); /* Label */ - EntryLabel.set_text(obj->defaultLabel()); - EntryLabel.set_sensitive (TRUE); + _entry_label.set_text(obj->defaultLabel()); + _entry_label.set_sensitive(TRUE); /* Title */ gchar *title = obj->title(); if (title) { - EntryTitle.set_text(title); + _entry_title.set_text(title); g_free(title); } else { - EntryTitle.set_text(""); + _entry_title.set_text(""); } - EntryTitle.set_sensitive(TRUE); + _entry_title.set_sensitive(TRUE); /* Image Rendering */ - if( SP_IS_IMAGE( item ) ) { - ComboBoxTextImageRendering.show(); - LabelImageRendering.show(); + if (SP_IS_IMAGE(item)) { + _combo_image_rendering.show(); + _label_image_rendering.show(); char const *str = obj->getStyleProperty( "image-rendering", "auto" ); - if( strcmp( str, "auto" ) == 0 ) { - ComboBoxTextImageRendering.set_active(0); - } else if( strcmp( str, "optimizeQuality" ) == 0 ) { - ComboBoxTextImageRendering.set_active(1); - } else { - ComboBoxTextImageRendering.set_active(2); + if (strcmp( str, "auto" ) == 0) { + _combo_image_rendering.set_active(0); + } else if (strcmp(str, "optimizeQuality") == 0) { + _combo_image_rendering.set_active(1); + } else { + _combo_image_rendering.set_active(2); } } else { - ComboBoxTextImageRendering.hide(); - ComboBoxTextImageRendering.unset_active(); - LabelImageRendering.hide(); + _combo_image_rendering.hide(); + _combo_image_rendering.unset_active(); + _label_image_rendering.hide(); } /* Description */ gchar *desc = obj->desc(); if (desc) { - TextViewDescription.get_buffer()->set_text(desc); + _tv_description.get_buffer()->set_text(desc); g_free(desc); } else { - TextViewDescription.get_buffer()->set_text(""); + _tv_description.get_buffer()->set_text(""); } - FrameTextDescription.set_sensitive(TRUE); + _ft_description.set_sensitive(TRUE); - if (CurrentItem == NULL) - { - attrTable->set_object(obj, int_labels, int_attrs, (GtkWidget*)EInteractivity.gobj()); - } - else - { - attrTable->change_object(obj); + if (_current_item == NULL) { + _attr_table->set_object(obj, _int_labels, _int_attrs, (GtkWidget*) _exp_interactivity.gobj()); + } else { + _attr_table->change_object(obj); } - attrTable->show_all(); + _attr_table->show_all(); } - CurrentItem = item; - blocked = false; + _current_item = item; + _blocked = false; } -void ObjectProperties::label_changed(void) +void ObjectProperties::_labelChanged() { - if (blocked) - { + if (_blocked) { return; } SPItem *item = sp_desktop_selection(SP_ACTIVE_DESKTOP)->singleItem(); g_return_if_fail (item != NULL); - blocked = true; + _blocked = true; /* Retrieve the label widget for the object's id */ - gchar *id = g_strdup(EntryID.get_text().c_str()); - g_strcanon (id, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.:", '_'); - if (!strcmp (id, item->getId())) { - LabelID.set_markup_with_mnemonic(_("_ID:")); + gchar *id = g_strdup(_entry_id.get_text().c_str()); + g_strcanon(id, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.:", '_'); + if (strcmp(id, item->getId()) == 0) { + _label_id.set_markup_with_mnemonic(_("_ID:")); } else if (!*id || !isalnum (*id)) { - LabelID.set_text (_("Id invalid! ")); + _label_id.set_text(_("Id invalid! ")); } else if (SP_ACTIVE_DOCUMENT->getObjectById(id) != NULL) { - LabelID.set_text (_("Id exists! ")); + _label_id.set_text(_("Id exists! ")); } else { SPException ex; - LabelID.set_markup_with_mnemonic(_("_ID:")); - SP_EXCEPTION_INIT (&ex); + _label_id.set_markup_with_mnemonic(_("_ID:")); + SP_EXCEPTION_INIT(&ex); item->setAttribute("id", id, &ex); DocumentUndo::done(SP_ACTIVE_DOCUMENT, SP_VERB_DIALOG_ITEM, _("Set object ID")); } - g_free (id); + g_free(id); /* Retrieve the label widget for the object's label */ - Glib::ustring label = EntryLabel.get_text(); + Glib::ustring label = _entry_label.get_text(); /* Give feedback on success of setting the drawing object's label * using the widget's label text */ SPObject *obj = static_cast<SPObject*>(item); - if (label.compare (obj->defaultLabel())) { + if (label.compare(obj->defaultLabel())) { obj->setLabel(label.c_str()); DocumentUndo::done(SP_ACTIVE_DOCUMENT, SP_VERB_DIALOG_ITEM, _("Set object label")); } /* Retrieve the title */ - if (obj->setTitle(EntryTitle.get_text().c_str())) + if (obj->setTitle(_entry_title.get_text().c_str())) { DocumentUndo::done(SP_ACTIVE_DOCUMENT, SP_VERB_DIALOG_ITEM, _("Set object title")); + } /* Retrieve the description */ Gtk::TextBuffer::iterator start, end; - TextViewDescription.get_buffer()->get_bounds(start, end); - Glib::ustring desc = TextViewDescription.get_buffer()->get_text(start, end, TRUE); - if (obj->setDesc(desc.c_str())) + _tv_description.get_buffer()->get_bounds(start, end); + Glib::ustring desc = _tv_description.get_buffer()->get_text(start, end, TRUE); + if (obj->setDesc(desc.c_str())) { DocumentUndo::done(SP_ACTIVE_DOCUMENT, SP_VERB_DIALOG_ITEM, _("Set object description")); + } - blocked = false; + _blocked = false; } -void ObjectProperties::image_rendering_changed(void) +void ObjectProperties::_imageRenderingChanged() { - if (blocked) - { + if (_blocked) { return; } SPItem *item = sp_desktop_selection(SP_ACTIVE_DESKTOP)->singleItem(); g_return_if_fail (item != NULL); - blocked = true; + _blocked = true; - Glib::ustring scale = ComboBoxTextImageRendering.get_active_text(); + Glib::ustring scale = _combo_image_rendering.get_active_text(); // We should unset if the parent computed value is auto and the desired value is auto. SPCSSAttr *css = sp_repr_css_attr_new(); @@ -536,64 +534,67 @@ void ObjectProperties::image_rendering_changed(void) } sp_repr_css_attr_unref( css ); - blocked = false; + _blocked = false; } -void ObjectProperties::sensitivity_toggled (void) +void ObjectProperties::_sensitivityToggled() { - if (blocked) - { + if (_blocked) { return; } SPItem *item = sp_desktop_selection(SP_ACTIVE_DESKTOP)->singleItem(); - g_return_if_fail (item != NULL); + g_return_if_fail(item != NULL); - blocked = true; - item->setLocked(CBLock.get_active()); + _blocked = true; + item->setLocked(_cb_lock.get_active()); DocumentUndo::done(SP_ACTIVE_DOCUMENT, SP_VERB_DIALOG_ITEM, - CBLock.get_active()? _("Lock object") : _("Unlock object")); - blocked = false; + _cb_lock.get_active() ? _("Lock object") : _("Unlock object")); + _blocked = false; } -void ObjectProperties::hidden_toggled(void) +void ObjectProperties::_hiddenToggled() { - if (blocked) - { + if (_blocked) { return; } SPItem *item = sp_desktop_selection(SP_ACTIVE_DESKTOP)->singleItem(); - g_return_if_fail (item != NULL); + g_return_if_fail(item != NULL); - blocked = true; - item->setExplicitlyHidden(CBHide.get_active()); + _blocked = true; + item->setExplicitlyHidden(_cb_hide.get_active()); DocumentUndo::done(SP_ACTIVE_DOCUMENT, SP_VERB_DIALOG_ITEM, - CBHide.get_active()? _("Hide object") : _("Unhide object")); - blocked = false; + _cb_hide.get_active() ? _("Hide object") : _("Unhide object")); + _blocked = false; } -void ObjectProperties::setDesktop(SPDesktop *desktop) +void ObjectProperties::_setDesktop(SPDesktop *desktop) { Panel::setDesktop(desktop); - deskTrack.setBase(desktop); + _desktop_tracker.setBase(desktop); } -void ObjectProperties::setTargetDesktop(SPDesktop *desktop) +void ObjectProperties::_setTargetDesktop(SPDesktop *desktop) { - if (this->desktop != desktop) { - if (this->desktop) { - subselChangedConn.disconnect(); - selectChangedConn.disconnect(); + if (this->_desktop != desktop) { + if (this->_desktop) { + _subselection_changed_connection.disconnect(); + _selection_changed_connection.disconnect(); } - this->desktop = desktop; + this->_desktop = desktop; if (desktop && desktop->selection) { - selectChangedConn = desktop->selection->connectChanged(sigc::hide(sigc::mem_fun(*this, &ObjectProperties::widget_setup))); - subselChangedConn = desktop->connectToolSubselectionChanged(sigc::hide(sigc::mem_fun(*this, &ObjectProperties::widget_setup))); + _selection_changed_connection = desktop->selection->connectChanged( + sigc::hide(sigc::mem_fun(*this, &ObjectProperties::update)) + ); + _subselection_changed_connection = desktop->connectToolSubselectionChanged( + sigc::hide(sigc::mem_fun(*this, &ObjectProperties::update)) + ); } - widget_setup(); + update(); } } + } } } diff --git a/src/ui/dialog/object-properties.h b/src/ui/dialog/object-properties.h index 721c12c56..093f273f6 100644 --- a/src/ui/dialog/object-properties.h +++ b/src/ui/dialog/object-properties.h @@ -69,98 +69,64 @@ namespace Dialog { */ class ObjectProperties : public Widget::Panel { public: - ObjectProperties (); - ~ObjectProperties (); + ObjectProperties(); + ~ObjectProperties(); static ObjectProperties &getInstance() { return *new ObjectProperties(); } - /** - * Updates entries and other child widgets on selection change, object modification, etc. - */ - void widget_setup(void); + /// Updates entries and other child widgets on selection change, object modification, etc. + void update(); private: - bool blocked; - SPItem *CurrentItem; //to store the current item, for not wasting resources - std::vector<Glib::ustring> int_attrs; - std::vector<Glib::ustring> int_labels; + bool _blocked; + SPItem *_current_item; //to store the current item, for not wasting resources + std::vector<Glib::ustring> _int_attrs; + std::vector<Glib::ustring> _int_labels; + + Gtk::Label _label_id; //the label for the object ID + Gtk::Entry _entry_id; //the entry for the object ID + Gtk::Label _label_label; //the label for the object label + Gtk::Entry _entry_label; //the entry for the object label + Gtk::Label _label_title; //the label for the object title + Gtk::Entry _entry_title; //the entry for the object title + Gtk::Label _label_image_rendering; // the label for 'image-rendering' + Gtk::ComboBoxText _combo_image_rendering; // the combo box text for 'image-rendering' -#if WITH_GTKMM_3_0 - Gtk::Grid *TopTable; //the table with the object properties -#else - Gtk::Table *TopTable; //the table with the object properties -#endif + Gtk::Frame _ft_description; //the frame for the text of the object description + Gtk::TextView _tv_description; //the text view object showing the object description - Gtk::Label LabelID; //the label for the object ID - Gtk::Entry EntryID; //the entry for the object ID - Gtk::Label LabelLabel; //the label for the object label - Gtk::Entry EntryLabel; //the entry for the object label - Gtk::Label LabelTitle; //the label for the object title - Gtk::Entry EntryTitle; //the entry for the object title - Gtk::Label LabelImageRendering; // the label for 'image-rendering' - Gtk::ComboBoxText ComboBoxTextImageRendering; // the combo box text for 'image-rendering' + Gtk::CheckButton _cb_hide; //the check button hide + Gtk::CheckButton _cb_lock; //the check button lock + + Gtk::Expander _exp_interactivity; //the expander for interactivity + SPAttributeTable *_attr_table; //the widget for showing the on... names at the bottom - Gtk::Label LabelDescription; //the label for the object description - UI::Widget::Frame FrameDescription; //the frame for the object description - Gtk::Frame FrameTextDescription; //the frame for the text of the object description - Gtk::TextView TextViewDescription; //the text view object showing the object description + SPDesktop *_desktop; + DesktopTracker _desktop_tracker; + sigc::connection _desktop_changed_connection; + sigc::connection _selection_changed_connection; + sigc::connection _subselection_changed_connection; - Gtk::HBox HBoxCheck; // the HBox for the check boxes + /// Constructor auxiliary function creating the child widgets. + void _init(); -#if WITH_GTKMM_3_0 - Gtk::Grid *CheckTable; //the table for the check boxes -#else - Gtk::Table *CheckTable; //the table for the check boxes -#endif + /// Sets object properties (ID, label, title, description) on user input. + void _labelChanged(); - Gtk::CheckButton CBHide; //the check button hide - Gtk::CheckButton CBLock; //the check button lock - Gtk::Button BSet; //the button set - - Gtk::Label LabelInteractivity; //the label for interactivity - Gtk::Expander EInteractivity; //the label for interactivity - SPAttributeTable *attrTable; //the widget for showing the on... names at the bottom - - SPDesktop *desktop; - DesktopTracker deskTrack; - sigc::connection desktopChangeConn; - sigc::connection selectChangedConn; - sigc::connection subselChangedConn; - - /** - * Constructor auxiliary function creating the child widgets. - */ - void MakeWidget(void); - - /** - * Sets object properties (ID, label, title, description) on user input. - */ - void label_changed(void); - - /** - * Callback for 'image-rendering'. - */ - void image_rendering_changed(void); - - /** - * Callback for checkbox Lock. - */ - void sensitivity_toggled (void); - - /** - * Callback for checkbox Hide. - */ - void hidden_toggled(void); - - /** - * Can be invoked for setting the desktop. Currently not used. - */ - void setDesktop(SPDesktop *desktop); + /// Callback for 'image-rendering'. + void _imageRenderingChanged(); + + /// Callback for checkbox Lock. + void _sensitivityToggled(); + + /// Callback for checkbox Hide. + void _hiddenToggled(); + + /// Can be invoked for setting the desktop. Currently not used. + void _setDesktop(SPDesktop *desktop); - /** - * Is invoked by the desktop tracker when the desktop changes. - */ - void setTargetDesktop(SPDesktop *desktop); + /// Is invoked by the desktop tracker when the desktop changes. + void _setTargetDesktop(SPDesktop *desktop); }; } diff --git a/src/ui/dialog/ocaldialogs.cpp b/src/ui/dialog/ocaldialogs.cpp index 93fcab863..f676e75fd 100644 --- a/src/ui/dialog/ocaldialogs.cpp +++ b/src/ui/dialog/ocaldialogs.cpp @@ -1166,8 +1166,6 @@ void ImportDialog::on_xml_file_read(const Glib::RefPtr<Gio::AsyncResult>& result // free the document xmlFreeDoc(doc); - // free the global variables that may have been allocated by the parser - xmlCleanupParser(); } @@ -1336,7 +1334,8 @@ ImportDialog::ImportDialog(Gtk::Window& parent_window, FileDialogType file_types */ ImportDialog::~ImportDialog() { - + // free the global variables that may have been allocated by the parser + xmlCleanupParser(); } /** diff --git a/src/ui/dialog/pixelartdialog.cpp b/src/ui/dialog/pixelartdialog.cpp index ce5b6584d..2d25f54d7 100644 --- a/src/ui/dialog/pixelartdialog.cpp +++ b/src/ui/dialog/pixelartdialog.cpp @@ -16,6 +16,16 @@ # include <config.h> #endif +#ifdef GLIBMM_DISABLE_DEPRECATED +# undef GLIBMM_DISABLE_DEPRECATED +# include <glibmm/thread.h> +# include <glibmm/dispatcher.h> +# define GLIBMM_DISABLE_DEPRECATED 1 +#else // GLIBMM_DISABLE_DEPRECATED +# include <glibmm/thread.h> +# include <glibmm/dispatcher.h> +#endif // GLIBMM_DISABLE_DEPRECATED + #include "pixelartdialog.h" #include <gtkmm/radiobutton.h> #include <gtkmm/stock.h> @@ -54,18 +64,6 @@ namespace Inkscape { namespace UI { namespace Dialog { -template<class T> -T move(T &obj) -{ -#ifdef LIBDEPIXELIZE_ENABLE_CPP11 - return std::move(obj); -#else - T ret; - std::swap(obj, ret); - return ret; -#endif // LIBDEPIXELIZE_ENABLE_CPP11 -} - /** * A dialog for adjusting pixel art -> vector tracing parameters */ @@ -77,6 +75,23 @@ public: ~PixelArtDialogImpl(); private: + struct Input + { + Glib::RefPtr<Gdk::Pixbuf> pixbuf; + SVGLength x; + SVGLength y; + }; + struct Output + { + Output(Tracer::Splines splines, SVGLength x, SVGLength y) : + splines(splines), x(x), y(y) + {} + + Tracer::Splines splines; + SVGLength x; + SVGLength y; + }; + void setDesktop(SPDesktop *desktop); void setTargetDesktop(SPDesktop *desktop); @@ -89,7 +104,8 @@ private: Tracer::Kopf2011::Options options(); void vectorize(); - void processLibdepixelize(SPImage *img); + void processLibdepixelize(const Input &image); + void importOutput(const Output &out); void setDefaults(); void updatePreview(); @@ -133,9 +149,21 @@ private: Gtk::RadioButton optimizeRadioButton; #endif // LIBDEPIXELIZE_INKSCAPE_ENABLE_SMOOTH + //############ UI Logic data + SPDesktop *desktop; DesktopTracker deskTrack; sigc::connection desktopChangeConn; + + //############ Threads + void workerThread(); + void onWorkerThreadFinished(); + Glib::Thread *thread; + volatile gint abortThread; // C++11's atomic stuff is sooo much nicer + Glib::Dispatcher dispatcher; + std::vector<Input> queue; + std::vector<Output> output; + Tracer::Kopf2011::Options lastOptions; }; void PixelArtDialogImpl::setDesktop(SPDesktop *desktop) @@ -288,6 +316,9 @@ PixelArtDialogImpl::PixelArtDialogImpl() : deskTrack.connect(GTK_WIDGET(gobj())); signalResponse().connect(sigc::mem_fun(*this, &PixelArtDialogImpl::responseCallback)); + + dispatcher.connect( + sigc::mem_fun(*this, &PixelArtDialogImpl::onWorkerThreadFinished) ); } void PixelArtDialogImpl::responseCallback(int response_id) @@ -295,7 +326,8 @@ void PixelArtDialogImpl::responseCallback(int response_id) if (response_id == GTK_RESPONSE_OK) { vectorize(); } else if (response_id == GTK_RESPONSE_CANCEL) { - // TODO + // libdepixelize's interface need to be extended to allow aborts + g_atomic_int_set(&abortThread, true); } else if (response_id == GTK_RESPONSE_HELP) { setDefaults(); } else { @@ -340,39 +372,53 @@ void PixelArtDialogImpl::vectorize() return; } - bool found = false; - for ( GSList const *list = desktop->selection->itemList() ; list ; list = list->next ) { if ( !SP_IS_IMAGE(list->data) ) continue; - found = true; + SPImage *img = SP_IMAGE(list->data); + Input input; + input.pixbuf = Glib::wrap(img->pixbuf->getPixbufRaw(), true); + input.x = img->x; + input.y = img->y; + + if ( input.pixbuf->get_width() > 256 + || input.pixbuf->get_height() > 256 ) { + char *msg = _("Image looks too big. Process may take a while and is" + " wise to save your document before continue." + "\n\nContinue the procedure (without saving)?"); + Gtk::MessageDialog dialog(msg, false, Gtk::MESSAGE_WARNING, + Gtk::BUTTONS_OK_CANCEL, true); + + if ( dialog.run() != Gtk::RESPONSE_OK ) + continue; + } - processLibdepixelize(SP_IMAGE(list->data)); + queue.push_back(input); } - if ( !found ) { + if ( !queue.size() ) { char *msg = _("Select an <b>image</b> to trace"); msgStack->flash(Inkscape::ERROR_MESSAGE, msg); return; } - DocumentUndo::done(desktop->doc(), SP_VERB_SELECTION_PIXEL_ART, - _("Trace pixel art")); + mainCancelButton->set_sensitive(true); + mainOkButton->set_sensitive(false); - // Flush pending updates - desktop->doc()->ensureUpToDate(); + lastOptions = options(); + + g_atomic_int_set(&abortThread, false); + thread = Glib::Thread::create(sigc::mem_fun(*this, &PixelArtDialogImpl::workerThread), + /*joinable =*/true); } -void PixelArtDialogImpl::processLibdepixelize(SPImage *img) +void PixelArtDialogImpl::processLibdepixelize(const Input &input) { Tracer::Splines out; - Glib::RefPtr<Gdk::Pixbuf> pixbuf - = Glib::wrap(img->pixbuf->getPixbufRaw(), true); - - if ( pixbuf->get_width() > 256 || pixbuf->get_height() > 256 ) { + if ( input.pixbuf->get_width() > 256 || input.pixbuf->get_height() > 256 ) { char *msg = _("Image looks too big. Process may take a while and it is" " wise to save your document before continuing." "\n\nContinue the procedure (without saving)?"); @@ -384,16 +430,23 @@ void PixelArtDialogImpl::processLibdepixelize(SPImage *img) } if ( voronoiRadioButton.get_active() ) { - out = Tracer::Kopf2011::to_voronoi(pixbuf, options()); + output.push_back(Output(Tracer::Kopf2011::to_voronoi(input.pixbuf, + lastOptions), + input.x, input.y)); } else { - out = Tracer::Kopf2011::to_splines(pixbuf, options()); + output.push_back(Output(Tracer::Kopf2011::to_splines(input.pixbuf, + lastOptions), + input.x, input.y)); } +} +void PixelArtDialogImpl::importOutput(const Output &output) +{ Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc(); Inkscape::XML::Node *group = xml_doc->createElement("svg:g"); - for ( Tracer::Splines::iterator it = out.begin(), end = out.end() - ; it != end ; ++it ) { + for ( Tracer::Splines::const_iterator it = output.splines.begin(), + end = output.splines.end() ; it != end ; ++it ) { Inkscape::XML::Node *repr = xml_doc->createElement("svg:path"); { @@ -421,7 +474,7 @@ void PixelArtDialogImpl::processLibdepixelize(SPImage *img) sp_repr_css_attr_unref(css); } - gchar *str = sp_svg_write_path(Dialog::move(it->pathVector)); + gchar *str = sp_svg_write_path(it->pathVector); repr->setAttribute("d", str); g_free(str); @@ -433,14 +486,20 @@ void PixelArtDialogImpl::processLibdepixelize(SPImage *img) { group->setAttribute("transform", (std::string("translate(") - + sp_svg_length_write_with_units(img->x) - + ' ' + sp_svg_length_write_with_units(img->y) + + sp_svg_length_write_with_units(output.x) + + ' ' + sp_svg_length_write_with_units(output.y) + ')').c_str()); } desktop->currentLayer()->appendChildRepr(group); Inkscape::GC::release(group); + + DocumentUndo::done(desktop->doc(), SP_VERB_SELECTION_PIXEL_ART, + _("Trace pixel art")); + + // Flush pending updates + desktop->doc()->ensureUpToDate(); } void PixelArtDialogImpl::setDefaults() @@ -481,6 +540,29 @@ void PixelArtDialogImpl::updatePreview() pendingPreview = false; } +void PixelArtDialogImpl::workerThread() +{ + for ( std::vector<Input>::iterator it = queue.begin(), end = queue.end() + ; it != end && !g_atomic_int_get(&abortThread) ; ++it ) { + processLibdepixelize(*it); + } + queue.clear(); + dispatcher(); +} + +void PixelArtDialogImpl::onWorkerThreadFinished() +{ + thread->join(); + thread = NULL; + for ( std::vector<Output>::const_iterator it = output.begin(), + end = output.end() ; it != end ; ++it ) { + importOutput(*it); + } + output.clear(); + mainCancelButton->set_sensitive(false); + mainOkButton->set_sensitive(true); +} + /** * Factory method. Use this to create a new PixelArtDialog */ diff --git a/src/ui/dialog/polar-arrange-tab.cpp b/src/ui/dialog/polar-arrange-tab.cpp new file mode 100644 index 000000000..a00b8fc02 --- /dev/null +++ b/src/ui/dialog/polar-arrange-tab.cpp @@ -0,0 +1,414 @@ +/** + * @brief Arranges Objects into a Circle/Ellipse + */ +/* Authors: + * Declara Denis + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "ui/dialog/polar-arrange-tab.h" +#include "ui/dialog/tile.h" + +#include <2geom/transforms.h> +#include <glibmm/i18n.h> + +#include "verbs.h" +#include "preferences.h" +#include "inkscape.h" +#include "desktop-handles.h" +#include "selection.h" +#include "document.h" +#include "document-undo.h" +#include "sp-item.h" +#include "widgets/icon.h" +#include "desktop.h" +#include "sp-ellipse.h" +#include "sp-item-transform.h" + +namespace Inkscape { +namespace UI { +namespace Dialog { + +PolarArrangeTab::PolarArrangeTab(ArrangeDialog *parent_) + : parent(parent_), + parametersTable(3, 3, false), + centerY("", "Y coordinate of the center", UNIT_TYPE_LINEAR), + centerX("", "X coordinate of the center", centerY), + radiusY("", "Y coordinate of the radius", UNIT_TYPE_LINEAR), + radiusX("", "X coordinate of the radius", radiusY), + angleY("", "Starting angle", UNIT_TYPE_RADIAL), + angleX("", "End angle", angleY) +{ + anchorPointLabel.set_text(C_("Polar arrange tab", "Anchor point:")); + anchorPointLabel.set_alignment(Gtk::ALIGN_START); + pack_start(anchorPointLabel, false, false); + + anchorBoundingBoxRadio.set_label(C_("Polar arrange tab", "Object's bounding box:")); + anchorRadioGroup = anchorBoundingBoxRadio.get_group(); + anchorBoundingBoxRadio.signal_toggled().connect(sigc::mem_fun(*this, &PolarArrangeTab::on_anchor_radio_changed)); + pack_start(anchorBoundingBoxRadio, false, false); + + pack_start(anchorSelector, false, false); + + anchorObjectPivotRadio.set_label(C_("Polar arrange tab", "Object's rotational center")); + anchorObjectPivotRadio.set_group(anchorRadioGroup); + anchorObjectPivotRadio.signal_toggled().connect(sigc::mem_fun(*this, &PolarArrangeTab::on_anchor_radio_changed)); + pack_start(anchorObjectPivotRadio, false, false); + + arrangeOnLabel.set_text(C_("Polar arrange tab", "Arrange on:")); + arrangeOnLabel.set_alignment(Gtk::ALIGN_START); + pack_start(arrangeOnLabel, false, false); + + arrangeOnFirstCircleRadio.set_label(C_("Polar arrange tab", "First selected circle/ellipse/arc")); + arrangeRadioGroup = arrangeOnFirstCircleRadio.get_group(); + arrangeOnFirstCircleRadio.signal_toggled().connect(sigc::mem_fun(*this, &PolarArrangeTab::on_arrange_radio_changed)); + pack_start(arrangeOnFirstCircleRadio, false, false); + + arrangeOnLastCircleRadio.set_label(C_("Polar arrange tab", "Last selected circle/ellipse/arc")); + arrangeOnLastCircleRadio.set_group(arrangeRadioGroup); + arrangeOnLastCircleRadio.signal_toggled().connect(sigc::mem_fun(*this, &PolarArrangeTab::on_arrange_radio_changed)); + pack_start(arrangeOnLastCircleRadio, false, false); + + arrangeOnParametersRadio.set_label(C_("Polar arrange tab", "Parameterized:")); + arrangeOnParametersRadio.set_group(arrangeRadioGroup); + arrangeOnParametersRadio.signal_toggled().connect(sigc::mem_fun(*this, &PolarArrangeTab::on_arrange_radio_changed)); + pack_start(arrangeOnParametersRadio, false, false); + + centerLabel.set_text(_("Center X/Y:")); + parametersTable.attach(centerLabel, 0, 1, 0, 1, Gtk::FILL); + centerX.setDigits(2); + centerX.setIncrements(0.2, 0); + centerX.setRange(-10000, 10000); + centerX.setValue(0, "px"); + centerY.setDigits(2); + centerY.setIncrements(0.2, 0); + centerY.setRange(-10000, 10000); + centerY.setValue(0, "px"); + parametersTable.attach(centerX, 1, 2, 0, 1, Gtk::FILL); + parametersTable.attach(centerY, 2, 3, 0, 1, Gtk::FILL); + + radiusLabel.set_text(_("Radius X/Y:")); + parametersTable.attach(radiusLabel, 0, 1, 1, 2, Gtk::FILL); + radiusX.setDigits(2); + radiusX.setIncrements(0.2, 0); + radiusX.setRange(0.001, 10000); + radiusX.setValue(100, "px"); + radiusY.setDigits(2); + radiusY.setIncrements(0.2, 0); + radiusY.setRange(0.001, 10000); + radiusY.setValue(100, "px"); + parametersTable.attach(radiusX, 1, 2, 1, 2, Gtk::FILL); + parametersTable.attach(radiusY, 2, 3, 1, 2, Gtk::FILL); + + angleLabel.set_text(_("Angle X/Y:")); + parametersTable.attach(angleLabel, 0, 1, 2, 3, Gtk::FILL); + angleX.setDigits(2); + angleX.setIncrements(0.2, 0); + angleX.setRange(-10000, 10000); + angleX.setValue(0, "°"); + angleY.setDigits(2); + angleY.setIncrements(0.2, 0); + angleY.setRange(-10000, 10000); + angleY.setValue(180, "°"); + parametersTable.attach(angleX, 1, 2, 2, 3, Gtk::FILL); + parametersTable.attach(angleY, 2, 3, 2, 3, Gtk::FILL); + pack_start(parametersTable, false, false); + + rotateObjectsCheckBox.set_label(_("Rotate objects")); + rotateObjectsCheckBox.set_active(true); + pack_start(rotateObjectsCheckBox, false, false); + + centerX.set_sensitive(false); + centerY.set_sensitive(false); + angleX.set_sensitive(false); + angleY.set_sensitive(false); + radiusX.set_sensitive(false); + radiusY.set_sensitive(false); +} + +/** + * This function rotates an item around a given point by a given amount + * @param item item to rotate + * @param center center of the rotation to perform + * @param rotation amount to rotate the object by + */ +static void rotateAround(SPItem *item, Geom::Point center, Geom::Rotate const &rotation) +{ + Geom::Translate const s(center); + Geom::Affine affine = Geom::Affine(s).inverse() * Geom::Affine(rotation) * Geom::Affine(s); + + // Save old center + center = item->getCenter(); + + item->set_i2d_affine(item->i2dt_affine() * affine); + item->doWriteTransform(item->getRepr(), item->transform); + + if(item->isCenterSet()) + { + item->setCenter(center * affine); + item->updateRepr(); + } +} + +/** + * Calculates the angle at which to put an object given the total amount + * of objects, the index of the objects as well as the arc start and end + * points + * @param arcBegin angle at which the arc begins + * @param arcEnd angle at which the arc ends + * @param count number of objects in the selection + * @param n index of the object in the selection + */ +static float calcAngle(float arcBegin, float arcEnd, int count, int n) +{ + float arcLength = arcEnd - arcBegin; + float delta = std::abs(std::abs(arcLength) - 2*M_PI); + if(delta > 0.01) count--; // If not a complete circle, put an object also at the extremes of the arc; + + float angle = n / (float)count; + // Normalize for arcLength: + angle = angle * arcLength; + angle += arcBegin; + + return angle; +} + +/** + * Calculates the point at which an object needs to be, given the center of the ellipse, + * it's radius (x and y), as well as the angle + */ +static Geom::Point calcPoint(float cx, float cy, float rx, float ry, float angle) +{ + return Geom::Point(cx + cos(angle) * rx, cy + sin(angle) * ry); +} + +/** + * Returns the selected anchor point in document coordinates. If anchor + * is 0 to 8, then a bounding box point has been choosen. If it is 9 however + * the rotational center is chosen. + * @todo still using a hack to get the real coordinate space (subtracting document height + * and inverting axes) + */ +static Geom::Point getAnchorPoint(int anchor, SPItem *item) +{ + Geom::Point source; + + Geom::OptRect bbox = item->documentVisualBounds(); + + switch(anchor) + { + case 0: // Top - Left + case 3: // Middle - Left + case 6: // Bottom - Left + source[0] = bbox->min()[Geom::X]; + break; + case 1: // Top - Middle + case 4: // Middle - Middle + case 7: // Bottom - Middle + source[0] = (bbox->min()[Geom::X] + bbox->max()[Geom::X]) / 2.0f; + break; + case 2: // Top - Right + case 5: // Middle - Right + case 8: // Bottom - Right + source[0] = bbox->max()[Geom::X]; + break; + }; + + switch(anchor) + { + case 0: // Top - Left + case 1: // Top - Middle + case 2: // Top - Right + source[1] = bbox->min()[Geom::Y]; + break; + case 3: // Middle - Left + case 4: // Middle - Middle + case 5: // Middle - Right + source[1] = (bbox->min()[Geom::Y] + bbox->max()[Geom::Y]) / 2.0f; + break; + case 6: // Bottom - Left + case 7: // Bottom - Middle + case 8: // Bottom - Right + source[1] = bbox->max()[Geom::Y]; + break; + }; + + // If using center + if(anchor == 9) + source = item->getCenter(); + else + { + // FIXME: + source[1] -= item->document->getHeight().value("px"); + source[1] *= -1; + } + + return source; +} + +/** + * Moves an SPItem to a given location, the location is based on the given anchor point. + * @param anchor 0 to 8 are the various bounding box points like follows: + * 0 1 2 + * 3 4 5 + * 6 7 8 + * Anchor mode 9 is the rotational center of the object + * @param item Item to move + * @param p point at which to move the object + */ +static void moveToPoint(int anchor, SPItem *item, Geom::Point p) +{ + sp_item_move_rel(item, Geom::Translate(p - getAnchorPoint(anchor, item))); +} + +void PolarArrangeTab::arrange() +{ + Inkscape::Selection *selection = sp_desktop_selection(parent->getDesktop()); + const GSList *items, *tmp; + tmp = items = selection->itemList(); + SPGenericEllipse *referenceEllipse = NULL; // Last ellipse in selection + + bool arrangeOnEllipse = !arrangeOnParametersRadio.get_active(); + bool arrangeOnFirstEllipse = arrangeOnEllipse && arrangeOnFirstCircleRadio.get_active(); + + int count = 0; + while(tmp) + { + if(arrangeOnEllipse) + { + SPItem *item = SP_ITEM(tmp->data); + + if(arrangeOnFirstEllipse) + { + // The first selected ellipse is actually the last one in the list + if(SP_IS_GENERICELLIPSE(item)) + referenceEllipse = SP_GENERICELLIPSE(item); + } else { + // The last selected ellipse is actually the first in list + if(SP_IS_GENERICELLIPSE(item) && referenceEllipse == NULL) + referenceEllipse = SP_GENERICELLIPSE(item); + } + } + tmp = tmp->next; + ++count; + } + + float cx, cy; // Center of the ellipse + float rx, ry; // Radiuses of the ellipse in x and y direction + float arcBeg, arcEnd; // begin and end angles for arcs + Geom::Affine transformation; // Any additional transformation to apply to the objects + + if(arrangeOnEllipse) + { + if(referenceEllipse == NULL) + { + Gtk::MessageDialog dialog(_("Couldn't find an ellipse in selection"), false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_CLOSE, true); + dialog.run(); + return; + } else { + cx = referenceEllipse->cx.value; + cy = referenceEllipse->cy.value; + rx = referenceEllipse->rx.value; + ry = referenceEllipse->ry.value; + arcBeg = referenceEllipse->start; + arcEnd = referenceEllipse->end; + + transformation = referenceEllipse->i2dt_affine(); + + // We decrement the count by 1 as we are not going to lay + // out the reference ellipse + --count; + } + + } else { + // Read options from UI + cx = centerX.getValue("px"); + cy = centerY.getValue("px"); + rx = radiusX.getValue("px"); + ry = radiusY.getValue("px"); + arcBeg = angleX.getValue("rad"); + arcEnd = angleY.getValue("rad"); + transformation.setIdentity(); + referenceEllipse = NULL; + } + + int anchor = 9; + if(anchorBoundingBoxRadio.get_active()) + { + anchor = anchorSelector.getHorizontalAlignment() + + anchorSelector.getVerticalAlignment() * 3; + } + + Geom::Point realCenter = Geom::Point(cx, cy) * transformation; + + tmp = items; + int i = 0; + while(tmp) + { + SPItem *item = SP_ITEM(tmp->data); + + // Ignore the reference ellipse if any + if(item != referenceEllipse) + { + float angle = calcAngle(arcBeg, arcEnd, count, i); + Geom::Point newLocation = calcPoint(cx, cy, rx, ry, angle) * transformation; + + moveToPoint(anchor, item, newLocation); + + if(rotateObjectsCheckBox.get_active()) { + // Calculate the angle by which to rotate each object + angle = -atan2f(newLocation.x() - realCenter.x(), newLocation.y() - realCenter.y()); + rotateAround(item, newLocation, Geom::Rotate(angle)); + } + + ++i; + } + tmp = tmp->next; + } + + DocumentUndo::done(sp_desktop_document(parent->getDesktop()), SP_VERB_SELECTION_ARRANGE, + _("Arrange on ellipse")); +} + +void PolarArrangeTab::updateSelection() +{ +} + +void PolarArrangeTab::on_arrange_radio_changed() +{ + bool arrangeParametric = arrangeOnParametersRadio.get_active(); + + centerX.set_sensitive(arrangeParametric); + centerY.set_sensitive(arrangeParametric); + + angleX.set_sensitive(arrangeParametric); + angleY.set_sensitive(arrangeParametric); + + radiusX.set_sensitive(arrangeParametric); + radiusY.set_sensitive(arrangeParametric); + + parametersTable.set_visible(arrangeParametric); +} + +void PolarArrangeTab::on_anchor_radio_changed() +{ + bool anchorBoundingBox = anchorBoundingBoxRadio.get_active(); + + anchorSelector.set_sensitive(anchorBoundingBox); +} + +} //namespace Dialog +} //namespace UI +} //namespace Inkscape + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + 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:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/dialog/polar-arrange-tab.h b/src/ui/dialog/polar-arrange-tab.h new file mode 100644 index 000000000..f6c3b2906 --- /dev/null +++ b/src/ui/dialog/polar-arrange-tab.h @@ -0,0 +1,99 @@ +/** + * @brief Arranges Objects into a Circle/Ellipse + */ +/* Authors: + * Declara Denis + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef INKSCAPE_UI_DIALOG_POLAR_ARRANGE_TAB_H +#define INKSCAPE_UI_DIALOG_POLAR_ARRANGE_TAB_H + +#include "ui/widget/anchor-selector.h" +#include "ui/dialog/arrange-tab.h" +#include "ui/widget/scalar-unit.h" + +namespace Inkscape { +namespace UI { +namespace Dialog { + +class ArrangeDialog; + +/** + * PolarArrangeTab is a Tab displayed in the Arrange dialog and contains + * enables the user to arrange objects on a circular or elliptical shape + */ +class PolarArrangeTab : public ArrangeTab { +public: + PolarArrangeTab(ArrangeDialog *parent_); + virtual ~PolarArrangeTab() {}; + + /** + * Do the actual arrangement + */ + virtual void arrange(); + + /** + * Respond to selection change + */ + void updateSelection(); + + void on_anchor_radio_changed(); + void on_arrange_radio_changed(); + +private: + PolarArrangeTab(PolarArrangeTab const &d); // no copy + void operator=(PolarArrangeTab const &d); // no assign + + ArrangeDialog *parent; + + Gtk::Label anchorPointLabel; + + Gtk::RadioButtonGroup anchorRadioGroup; + Gtk::RadioButton anchorBoundingBoxRadio; + Gtk::RadioButton anchorObjectPivotRadio; + Inkscape::UI::Widget::AnchorSelector anchorSelector; + + Gtk::Label arrangeOnLabel; + + Gtk::RadioButtonGroup arrangeRadioGroup; + Gtk::RadioButton arrangeOnFirstCircleRadio; + Gtk::RadioButton arrangeOnLastCircleRadio; + Gtk::RadioButton arrangeOnParametersRadio; + + Gtk::Table parametersTable; + + Gtk::Label centerLabel; + Inkscape::UI::Widget::ScalarUnit centerY; + Inkscape::UI::Widget::ScalarUnit centerX; + + Gtk::Label radiusLabel; + Inkscape::UI::Widget::ScalarUnit radiusY; + Inkscape::UI::Widget::ScalarUnit radiusX; + + Gtk::Label angleLabel; + Inkscape::UI::Widget::ScalarUnit angleY; + Inkscape::UI::Widget::ScalarUnit angleX; + + Gtk::CheckButton rotateObjectsCheckBox; + + +}; + +} //namespace Dialog +} //namespace UI +} //namespace Inkscape + +#endif /* INKSCAPE_UI_DIALOG_POLAR_ARRANGE_TAB_H */ + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + 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:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/dialog/spellcheck.cpp b/src/ui/dialog/spellcheck.cpp index 00bd445bf..8a4ddc57e 100644 --- a/src/ui/dialog/spellcheck.cpp +++ b/src/ui/dialog/spellcheck.cpp @@ -590,52 +590,54 @@ SpellCheck::nextWord() // draw rect std::vector<Geom::Point> points = _layout->createSelectionShape(_begin_w, _end_w, _text->i2dt_affine()); - Geom::Point tl, br; - tl = br = points.front(); - for (unsigned i = 0 ; i < points.size() ; i ++) { - if (points[i][Geom::X] < tl[Geom::X]) - tl[Geom::X] = points[i][Geom::X]; - if (points[i][Geom::Y] < tl[Geom::Y]) - tl[Geom::Y] = points[i][Geom::Y]; - if (points[i][Geom::X] > br[Geom::X]) - br[Geom::X] = points[i][Geom::X]; - if (points[i][Geom::Y] > br[Geom::Y]) - br[Geom::Y] = points[i][Geom::Y]; - } + if (points.size() >= 4) { // we may not have a single quad if this is a clipped part of text on path; in that case skip drawing the rect + Geom::Point tl, br; + tl = br = points.front(); + for (unsigned i = 0 ; i < points.size() ; i ++) { + if (points[i][Geom::X] < tl[Geom::X]) + tl[Geom::X] = points[i][Geom::X]; + if (points[i][Geom::Y] < tl[Geom::Y]) + tl[Geom::Y] = points[i][Geom::Y]; + if (points[i][Geom::X] > br[Geom::X]) + br[Geom::X] = points[i][Geom::X]; + if (points[i][Geom::Y] > br[Geom::Y]) + br[Geom::Y] = points[i][Geom::Y]; + } - // expand slightly - Geom::Rect area = Geom::Rect(tl, br); - double mindim = fabs(tl[Geom::Y] - br[Geom::Y]); - if (fabs(tl[Geom::X] - br[Geom::X]) < mindim) - mindim = fabs(tl[Geom::X] - br[Geom::X]); - area.expandBy(MAX(0.05 * mindim, 1)); - - // create canvas path rectangle, red stroke - SPCanvasItem *rect = sp_canvas_bpath_new(sp_desktop_sketch(desktop), NULL); - sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(rect), 0xff0000ff, 3.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); - sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(rect), 0, SP_WIND_RULE_NONZERO); - SPCurve *curve = new SPCurve(); - curve->moveto(area.corner(0)); - curve->lineto(area.corner(1)); - curve->lineto(area.corner(2)); - curve->lineto(area.corner(3)); - curve->lineto(area.corner(0)); - sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(rect), curve); - sp_canvas_item_show(rect); - _rects = g_slist_prepend(_rects, rect); - - // scroll to make it all visible - Geom::Point const center = desktop->get_display_area().midpoint(); - area.expandBy(0.5 * mindim); - Geom::Point scrollto; - double dist = 0; - for (unsigned corner = 0; corner < 4; corner ++) { - if (Geom::L2(area.corner(corner) - center) > dist) { - dist = Geom::L2(area.corner(corner) - center); - scrollto = area.corner(corner); + // expand slightly + Geom::Rect area = Geom::Rect(tl, br); + double mindim = fabs(tl[Geom::Y] - br[Geom::Y]); + if (fabs(tl[Geom::X] - br[Geom::X]) < mindim) + mindim = fabs(tl[Geom::X] - br[Geom::X]); + area.expandBy(MAX(0.05 * mindim, 1)); + + // create canvas path rectangle, red stroke + SPCanvasItem *rect = sp_canvas_bpath_new(sp_desktop_sketch(desktop), NULL); + sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(rect), 0xff0000ff, 3.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); + sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(rect), 0, SP_WIND_RULE_NONZERO); + SPCurve *curve = new SPCurve(); + curve->moveto(area.corner(0)); + curve->lineto(area.corner(1)); + curve->lineto(area.corner(2)); + curve->lineto(area.corner(3)); + curve->lineto(area.corner(0)); + sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(rect), curve); + sp_canvas_item_show(rect); + _rects = g_slist_prepend(_rects, rect); + + // scroll to make it all visible + Geom::Point const center = desktop->get_display_area().midpoint(); + area.expandBy(0.5 * mindim); + Geom::Point scrollto; + double dist = 0; + for (unsigned corner = 0; corner < 4; corner ++) { + if (Geom::L2(area.corner(corner) - center) > dist) { + dist = Geom::L2(area.corner(corner) - center); + scrollto = area.corner(corner); + } } + desktop->scroll_to_point (scrollto, 1.0); } - desktop->scroll_to_point (scrollto, 1.0); // select text; if in Text tool, position cursor to the beginning of word // unless it is already in the word diff --git a/src/ui/dialog/swatches.cpp b/src/ui/dialog/swatches.cpp index 3f161ad28..4f0cb211a 100644 --- a/src/ui/dialog/swatches.cpp +++ b/src/ui/dialog/swatches.cpp @@ -645,7 +645,7 @@ SwatchesPanel::SwatchesPanel(gchar const* prefsPath) : std::vector<SwatchPage*> swatchSets = _getSwatchSets(); for ( std::vector<SwatchPage*>::iterator it = swatchSets.begin(); it != swatchSets.end(); ++it) { SwatchPage* curr = *it; - Gtk::RadioMenuItem* single = manage(new Gtk::RadioMenuItem(groupOne, curr->_name)); + Gtk::RadioMenuItem* single = Gtk::manage(new Gtk::RadioMenuItem(groupOne, curr->_name)); if ( curr == first ) { hotItem = single; } @@ -745,10 +745,11 @@ void SwatchesPanel::setDesktop( SPDesktop* desktop ) class DocTrack { public: - DocTrack(SPDocument *doc, sigc::connection &gradientRsrcChanged, sigc::connection &defsChanged, sigc::connection &defsModified) : + DocTrack(SPDocument *doc, sigc::connection &docDestroy, sigc::connection &gradientRsrcChanged, sigc::connection &defsChanged, sigc::connection &defsModified) : doc(doc), updatePending(false), lastGradientUpdate(0.0), + docDestroy(docDestroy), gradientRsrcChanged(gradientRsrcChanged), defsChanged(defsChanged), defsModified(defsModified) @@ -773,9 +774,11 @@ public: } } if (doc) { + docDestroy.disconnect(); gradientRsrcChanged.disconnect(); defsChanged.disconnect(); defsModified.disconnect(); + doc = NULL; } } @@ -795,6 +798,7 @@ public: SPDocument *doc; bool updatePending; double lastGradientUpdate; + sigc::connection docDestroy; sigc::connection gradientRsrcChanged; sigc::connection defsChanged; sigc::connection defsModified; @@ -858,7 +862,7 @@ bool DocTrack::queueUpdateIfNeeded( SPDocument *doc ) void SwatchesPanel::_trackDocument( SwatchesPanel *panel, SPDocument *document ) { - SPDocument *oldDoc = 0; + SPDocument *oldDoc = NULL; if (docPerPanel.find(panel) != docPerPanel.end()) { oldDoc = docPerPanel[panel]; if (!oldDoc) { @@ -867,7 +871,7 @@ void SwatchesPanel::_trackDocument( SwatchesPanel *panel, SPDocument *document ) } if (oldDoc != document) { if (oldDoc) { - docPerPanel[panel] = 0; + docPerPanel[panel] = NULL; bool found = false; for (std::map<SwatchesPanel*, SPDocument*>::iterator it = docPerPanel.begin(); (it != docPerPanel.end()) && !found; ++it) { found = (it->second == document); @@ -890,11 +894,12 @@ void SwatchesPanel::_trackDocument( SwatchesPanel *panel, SPDocument *document ) } docPerPanel[panel] = document; if (!found) { + sigc::connection conn0 = document->connectDestroy(sigc::bind(sigc::ptr_fun(&SwatchesPanel::handleDocumentDestroy), document)); sigc::connection conn1 = document->connectResourcesChanged( "gradient", sigc::bind(sigc::ptr_fun(&SwatchesPanel::handleGradientsChange), document) ); sigc::connection conn2 = document->getDefs()->connectRelease( sigc::hide(sigc::bind(sigc::ptr_fun(&SwatchesPanel::handleDefsModified), document)) ); sigc::connection conn3 = document->getDefs()->connectModified( sigc::hide(sigc::hide(sigc::bind(sigc::ptr_fun(&SwatchesPanel::handleDefsModified), document))) ); - DocTrack *dt = new DocTrack(document, conn1, conn2, conn3); + DocTrack *dt = new DocTrack(document, conn0, conn1, conn2, conn3); docTrackings.push_back(dt); if (docPalettes.find(document) == docPalettes.end()) { @@ -905,11 +910,6 @@ void SwatchesPanel::_trackDocument( SwatchesPanel *panel, SPDocument *document ) } } } - - std::set<SPDocument*> docs; - for (std::map<SwatchesPanel*, SPDocument*>::iterator it = docPerPanel.begin(); it != docPerPanel.end(); ++it) { - docs.insert(it->second); - } } void SwatchesPanel::_setDocument( SPDocument *document ) @@ -928,11 +928,13 @@ static void recalcSwatchContents(SPDocument* doc, { std::vector<SPGradient*> newList; - const GSList *gradients = doc->getResourceList("gradient"); - for (const GSList *item = gradients; item; item = item->next) { - SPGradient* grad = SP_GRADIENT(item->data); - if ( grad->isSwatch() ) { - newList.push_back(SP_GRADIENT(item->data)); + if (doc) { + const GSList *gradients = doc->getResourceList("gradient"); + for (const GSList *item = gradients; item; item = item->next) { + SPGradient* grad = SP_GRADIENT(item->data); + if ( grad->isSwatch() ) { + newList.push_back(SP_GRADIENT(item->data)); + } } } @@ -971,6 +973,37 @@ static void recalcSwatchContents(SPDocument* doc, } } +void SwatchesPanel::handleDocumentDestroy(SPDocument *document) +{ + if (document) { + for (std::vector<DocTrack*>::iterator it = docTrackings.begin(); it != docTrackings.end(); ++it){ + if ((*it)->doc == document) { + delete *it; + docTrackings.erase(it); + break; + } + } + + if (docPalettes.find(document) != docPalettes.end()) { + docPalettes.erase(document); + } + + for (std::map<SwatchesPanel*, SPDocument*>::iterator it = docPerPanel.begin(); it != docPerPanel.end(); ++it) { + if (it->second == document) { + SwatchesPanel* swp = it->first; + std::vector<SwatchPage*> pages = swp->_getSwatchSets(); + if ((swp->_currentIndex >= static_cast<int>(pages.size())) && (pages.size() > 0)) + { + swp->_setSelectedIndex(swp->_getSwatchSets().size() - 1); + } + swp->_rebuild(); + docPerPanel.erase(it); + break; + } + } + } +} + void SwatchesPanel::handleGradientsChange(SPDocument *document) { SwatchPage *docPalette = (docPalettes.find(document) != docPalettes.end()) ? docPalettes[document] : 0; @@ -1145,38 +1178,45 @@ void SwatchesPanel::_handleAction( int setId, int itemId ) switch( setId ) { case 3: { - std::vector<SwatchPage*> pages = _getSwatchSets(); - if ( itemId >= 0 && itemId < static_cast<int>(pages.size()) ) { - _currentIndex = itemId; + _setSelectedIndex(itemId); + } + break; + } +} - if ( !_prefs_path.empty() ) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setString(_prefs_path + "/palette", pages[_currentIndex]->_name); - } +void SwatchesPanel::_setSelectedIndex( int index ) +{ + std::vector<SwatchPage*> pages = _getSwatchSets(); + if ( index >= 0 && index < static_cast<int>(pages.size()) ) { + _currentIndex = index; - _rebuild(); - } + if ( !_prefs_path.empty() ) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setString(_prefs_path + "/palette", pages[_currentIndex]->_name); } - break; + + _rebuild(); } } void SwatchesPanel::_rebuild() { std::vector<SwatchPage*> pages = _getSwatchSets(); - SwatchPage* curr = pages[_currentIndex]; - _holder->clear(); + if (_currentIndex < static_cast<int>(pages.size())) { + SwatchPage* curr = pages[_currentIndex]; + _holder->clear(); - if ( curr->_prefWidth > 0 ) { - _holder->setColumnPref( curr->_prefWidth ); - } - _holder->freezeUpdates(); - // TODO restore once 'clear' works _holder->addPreview(_clear); - _holder->addPreview(_remove); - for ( boost::ptr_vector<ColorItem>::iterator it = curr->_colors.begin(); it != curr->_colors.end(); ++it) { - _holder->addPreview(&*it); + if ( curr->_prefWidth > 0 ) { + _holder->setColumnPref( curr->_prefWidth ); + } + _holder->freezeUpdates(); + // TODO restore once 'clear' works _holder->addPreview(_clear); + _holder->addPreview(_remove); + for ( boost::ptr_vector<ColorItem>::iterator it = curr->_colors.begin(); it != curr->_colors.end(); ++it) { + _holder->addPreview(&*it); + } + _holder->thawUpdates(); } - _holder->thawUpdates(); } } //namespace Dialogs diff --git a/src/ui/dialog/swatches.h b/src/ui/dialog/swatches.h index ca4c1687d..3abb81d98 100644 --- a/src/ui/dialog/swatches.h +++ b/src/ui/dialog/swatches.h @@ -43,11 +43,13 @@ public: virtual int getSelectedIndex() {return _currentIndex;} // temporary protected: + static void handleDocumentDestroy(SPDocument *document); static void handleGradientsChange(SPDocument *document); virtual void _updateFromSelection(); virtual void _handleAction( int setId, int itemId ); virtual void _setDocument( SPDocument *document ); + virtual void _setSelectedIndex( int index ); virtual void _rebuild(); virtual std::vector<SwatchPage*> _getSwatchSets() const; diff --git a/src/ui/dialog/symbols.cpp b/src/ui/dialog/symbols.cpp index fb353fec1..8e0d085a4 100644 --- a/src/ui/dialog/symbols.cpp +++ b/src/ui/dialog/symbols.cpp @@ -38,7 +38,8 @@ #include <gtkmm/liststore.h> #include <gtkmm/treemodelcolumn.h> #include <gtkmm/clipboard.h> - +#include <glibmm/stringutils.h> +#include <glibmm/markup.h> #include <glibmm/i18n.h> #include "path-prefix.h" #include "io/sys.h" @@ -73,11 +74,9 @@ namespace Inkscape { namespace UI { -static Cache::SvgPreview svg_preview_cache; - namespace Dialog { - // See: http://developer.gnome.org/gtkmm/stable/classGtk_1_1TreeModelColumnRecord.html +// See: http://developer.gnome.org/gtkmm/stable/classGtk_1_1TreeModelColumnRecord.html class SymbolColumns : public Gtk::TreeModel::ColumnRecord { public: @@ -276,7 +275,7 @@ SymbolsDialog::SymbolsDialog( gchar const* prefsPath ) : instanceConns.push_back(documentReplacedConn); get_symbols(); - draw_symbols( currentDocument ); /* Defaults to current document */ + add_symbols( currentDocument ); /* Defaults to current document */ sigc::connection desktopChangeConn = deskTrack.connectDesktopChanged( sigc::mem_fun(*this, &SymbolsDialog::setTargetDesktop) ); @@ -329,7 +328,7 @@ void SymbolsDialog::rebuild() { addSymbol->set_sensitive( false ); removeSymbol->set_sensitive( false ); } - draw_symbols( symbolDocument ); + add_symbols( symbolDocument ); } void SymbolsDialog::insertSymbol() { @@ -382,8 +381,10 @@ void SymbolsDialog::selectionChanged(Inkscape::Selection *selection) { } } -void SymbolsDialog::documentReplaced(SPDesktop */*desktop*/, SPDocument */*document*/) +void SymbolsDialog::documentReplaced(SPDesktop *desktop, SPDocument *document) { + currentDesktop = desktop; + currentDocument = document; rebuild(); } @@ -400,11 +401,13 @@ SPDocument* SymbolsDialog::selectedSymbols() { } Glib::ustring SymbolsDialog::selectedSymbolId() { - #if WITH_GTKMM_3_0 - std::vector<Gtk::TreePath> iconArray = iconView->get_selected_items(); - #else - Gtk::IconView::ArrayHandle_TreePaths iconArray = iconView->get_selected_items(); - #endif + +#if WITH_GTKMM_3_0 + std::vector<Gtk::TreePath> iconArray = iconView->get_selected_items(); +#else + Gtk::IconView::ArrayHandle_TreePaths iconArray = iconView->get_selected_items(); +#endif + if( !iconArray.empty() ) { Gtk::TreeModel::Path const & path = *iconArray.begin(); Gtk::ListStore::iterator row = store->get_iter(path); @@ -429,12 +432,12 @@ void SymbolsDialog::iconChanged() { // First look for default style stored in <symbol> gchar const* style = symbol->getAttribute("inkscape:symbol-style"); if( !style ) { - // If no default style in <symbol>, look in documents. - if( symbolDocument == currentDocument ) { - style = style_from_use( symbol_id.c_str(), currentDocument ); - } else { - style = symbolDocument->getReprRoot()->attribute("style"); - } + // If no default style in <symbol>, look in documents. + if( symbolDocument == currentDocument ) { + style = style_from_use( symbol_id.c_str(), currentDocument ); + } else { + style = symbolDocument->getReprRoot()->attribute("style"); + } } ClipboardManager *cm = ClipboardManager::get(); @@ -498,8 +501,8 @@ SPDocument* read_vss( gchar* fullname, gchar* filename ) { while( std::getline( iss, line ) ) { // std::cout << line << std::endl; if( line.find( "svg:svg" ) == std::string::npos ) { - tmpSVGOutput += line; - tmpSVGOutput += "\n"; + tmpSVGOutput += line; + tmpSVGOutput += "\n"; } } @@ -520,11 +523,11 @@ void SymbolsDialog::get_symbols() { std::list<Glib::ustring> directories; if( Inkscape::IO::file_test( INKSCAPE_SYMBOLSDIR, G_FILE_TEST_EXISTS ) && - Inkscape::IO::file_test( INKSCAPE_SYMBOLSDIR, G_FILE_TEST_IS_DIR ) ) { + Inkscape::IO::file_test( INKSCAPE_SYMBOLSDIR, G_FILE_TEST_IS_DIR ) ) { directories.push_back( INKSCAPE_SYMBOLSDIR ); } if( Inkscape::IO::file_test( profile_path("symbols"), G_FILE_TEST_EXISTS ) && - Inkscape::IO::file_test( profile_path("symbols"), G_FILE_TEST_IS_DIR ) ) { + Inkscape::IO::file_test( profile_path("symbols"), G_FILE_TEST_IS_DIR ) ) { directories.push_back( profile_path("symbols") ); } @@ -535,46 +538,53 @@ void SymbolsDialog::get_symbols() { GDir *dir = g_dir_open( (*it).c_str(), 0, &err ); if( dir ) { - gchar *filename = 0; - while( (filename = (gchar *)g_dir_read_name( dir ) ) != NULL) { + gchar *filename = 0; + while( (filename = (gchar *)g_dir_read_name( dir ) ) != NULL) { - gchar *fullname = g_build_filename((*it).c_str(), filename, NULL); + gchar *fullname = g_build_filename((*it).c_str(), filename, NULL); - if ( !Inkscape::IO::file_test( fullname, G_FILE_TEST_IS_DIR ) ) { + if ( !Inkscape::IO::file_test( fullname, G_FILE_TEST_IS_DIR ) + && ( Glib::str_has_suffix(fullname, ".svg") || Glib::str_has_suffix(fullname, ".vss") ) ) { - Glib::ustring fn( filename ); - Glib::ustring tag = fn.substr( fn.find_last_of(".") + 1 ); + Glib::ustring fn( filename ); + Glib::ustring tag = fn.substr( fn.find_last_of(".") + 1 ); - SPDocument* symbol_doc = NULL; + SPDocument* symbol_doc = NULL; #ifdef WITH_LIBVISIO - if( tag.compare( "vss" ) == 0 ) { - - symbol_doc = read_vss( fullname, filename ); - if( symbol_doc ) { - symbolSets[Glib::ustring(filename)]= symbol_doc; - symbolSet->append(filename); - } - } + if( tag.compare( "vss" ) == 0 ) { + + symbol_doc = read_vss( fullname, filename ); + if( symbol_doc ) { + symbolSets[Glib::ustring(filename)]= symbol_doc; + symbolSet->append(filename); + } + } #endif - // Try to read all remaining files as SVG - if( !symbol_doc ) { - - symbol_doc = SPDocument::createNewDoc( fullname, FALSE ); - if( symbol_doc ) { - gchar *title = symbol_doc->getRoot()->title(); - if( title == NULL ) { - title = _("Unnamed Symbols"); + // Try to read all remaining files as SVG + if( !symbol_doc ) { + + symbol_doc = SPDocument::createNewDoc( fullname, FALSE ); + if( symbol_doc ) { + + const gchar *title = symbol_doc->getRoot()->title(); + + // A user provided file may not have a title + if( title != NULL ) { + title = g_dpgettext2(NULL, "Symbol", title); // Translate + } else { + title = _("Unnamed Symbols"); } - symbolSets[Glib::ustring(title)] = symbol_doc; - symbolSet->append(title); + + symbolSets[Glib::ustring(title)] = symbol_doc; + symbolSet->append(title); + } + } + } + g_free( fullname ); } - - } - g_free( fullname ); - } - g_dir_close( dir ); + g_dir_close( dir ); } } } @@ -636,33 +646,33 @@ gchar const* SymbolsDialog::style_from_use( gchar const* id, SPDocument* documen for( ; l != NULL; l = l->next ) { SPObject* use = SP_OBJECT(l->data); if( SP_IS_USE( use ) ) { - gchar const *href = use->getRepr()->attribute("xlink:href"); - if( href ) { - Glib::ustring href2(href); - Glib::ustring id2(id); - id2 = "#" + id2; - if( !href2.compare(id2) ) { - style = use->getRepr()->attribute("style"); - break; - } - } + gchar const *href = use->getRepr()->attribute("xlink:href"); + if( href ) { + Glib::ustring href2(href); + Glib::ustring id2(id); + id2 = "#" + id2; + if( !href2.compare(id2) ) { + style = use->getRepr()->attribute("style"); + break; + } + } } } return style; } -void SymbolsDialog::draw_symbols( SPDocument* symbolDocument ) { +void SymbolsDialog::add_symbols( SPDocument* symbolDocument ) { GSList* l = symbols_in_doc( symbolDocument ); for( ; l != NULL; l = l->next ) { SPObject* symbol = SP_OBJECT(l->data); if (SP_IS_SYMBOL(symbol)) { - draw_symbol( symbol ); + add_symbol( symbol ); } } } -void SymbolsDialog::draw_symbol( SPObject* symbol ) { +void SymbolsDialog::add_symbol( SPObject* symbol ) { SymbolColumns* columns = getColumns(); @@ -672,12 +682,12 @@ void SymbolsDialog::draw_symbol( SPObject* symbol ) { title = id; } - Glib::RefPtr<Gdk::Pixbuf> pixbuf = create_symbol_image(id, symbol ); + Glib::RefPtr<Gdk::Pixbuf> pixbuf = draw_symbol( symbol ); if( pixbuf ) { Gtk::ListStore::iterator row = store->append(); (*row)[columns->symbol_id] = Glib::ustring( id ); - (*row)[columns->symbol_title] = Glib::ustring( title ); + (*row)[columns->symbol_title] = Glib::Markup::escape_text(Glib::ustring( g_dpgettext2(NULL, "Symbol", title) )); (*row)[columns->symbol_image] = pixbuf; } @@ -694,7 +704,7 @@ void SymbolsDialog::draw_symbol( SPObject* symbol ) { * the temporary document is rendered. */ Glib::RefPtr<Gdk::Pixbuf> -SymbolsDialog::create_symbol_image(gchar const *symbol_id, SPObject *symbol) +SymbolsDialog::draw_symbol(SPObject *symbol) { // Create a copy repr of the symbol with id="the_symbol" Inkscape::XML::Document *xml_doc = previewDocument->getReprDoc(); @@ -713,7 +723,8 @@ SymbolsDialog::create_symbol_image(gchar const *symbol_id, SPObject *symbol) if( !style ) { // If no default style in <symbol>, look in documents. if( symbol->document == currentDocument ) { - style = style_from_use( symbol_id, symbol->document ); + gchar const *id = symbol->getRepr()->attribute("id"); + style = style_from_use( id, symbol->document ); } else { style = symbol->document->getReprRoot()->attribute("style"); } @@ -722,9 +733,7 @@ SymbolsDialog::create_symbol_image(gchar const *symbol_id, SPObject *symbol) if( !style ) style = "fill:#bbbbbb;stroke:#808080"; // This is for display in Symbols dialog only - if( style ) { - repr->setAttribute( "style", style ); - } + if( style ) repr->setAttribute( "style", style ); // BUG: Symbols don't work if defined outside of <defs>. Causes Inkscape // crash when trying to read in such a file. @@ -733,7 +742,7 @@ SymbolsDialog::create_symbol_image(gchar const *symbol_id, SPObject *symbol) Inkscape::GC::release(repr); // Uncomment this to get the previewDocument documents saved (useful for debugging) - // FILE *fp = fopen (g_strconcat(symbol_id, ".svg", NULL), "w"); + // FILE *fp = fopen (g_strconcat(id, ".svg", NULL), "w"); // sp_repr_save_stream(previewDocument->getReprDoc(), fp); // fclose (fp); @@ -746,55 +755,31 @@ SymbolsDialog::create_symbol_image(gchar const *symbol_id, SPObject *symbol) previewDocument->getRoot()->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); previewDocument->ensureUpToDate(); - // if( object_temp == NULL || !SP_IS_ITEM(object_temp) ) { - // //std::cout << " previewDocument broken?" << std::endl; - // //return 0; - // } - SPItem *item = SP_ITEM(object_temp); - unsigned psize = SYMBOL_ICON_SIZES[in_sizes]; - /* Update to renderable state */ - Glib::ustring key = svg_preview_cache.cache_key(previewDocument->getURI(), symbol_id, psize); - //std::cout << " Key: " << key << std::endl; - Glib::RefPtr<Gdk::Pixbuf> pixbuf(NULL); - GdkPixbuf *pixbuf_gobj = svg_preview_cache.get_preview_from_cache(key); - if (pixbuf_gobj) { - g_object_ref(pixbuf_gobj); // the reference in svg_preview_cache will get destroyed when it's freed - pixbuf = Glib::wrap(pixbuf_gobj); - } + // We could use cache here, but it doesn't really work with the structure + // of this user interface and we've already cached the pixbuf in the gtklist // Find object's bbox in document. // Note symbols can have own viewport... ignore for now. //Geom::OptRect dbox = item->geometricBounds(); Geom::OptRect dbox = item->documentVisualBounds(); - if (!dbox) { - //std::cout << " No dbox" << std::endl; - return pixbuf; - } - - if (!pixbuf) { + if (dbox) { /* Scale symbols to fit */ double scale = 1.0; double width = dbox->width(); double height = dbox->height(); - if( width == 0.0 ) { - width = 1.0; - } - if( height == 0.0 ) { - height = 1.0; - } - if( fitSymbol->get_active() ) { - /* Fit */ - scale = psize/std::max(width,height); - } + if( width == 0.0 ) width = 1.0; + if( height == 0.0 ) height = 1.0; + + if( fitSymbol->get_active() ) + scale = psize / std::max(width, height); pixbuf = Glib::wrap(render_pixbuf(renderDrawing, scale, *dbox, psize)); - svg_preview_cache.set_preview_in_cache(key, pixbuf->gobj()); } return pixbuf; @@ -827,8 +812,8 @@ void SymbolsDialog::setTargetDesktop(SPDesktop *desktop) if (this->currentDesktop != desktop) { this->currentDesktop = desktop; if( !symbolSets[symbolSet->get_active_text()] ) { - // Symbol set is from Current document, update - rebuild(); + // Symbol set is from Current document, update + rebuild(); } } } @@ -836,3 +821,15 @@ void SymbolsDialog::setTargetDesktop(SPDesktop *desktop) } //namespace Dialogs } //namespace UI } //namespace Inkscape + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-basic-offset:2 + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=2:tabstop=8:softtabstop=2:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/dialog/symbols.h b/src/ui/dialog/symbols.h index 074af6764..8021fb0c1 100644 --- a/src/ui/dialog/symbols.h +++ b/src/ui/dialog/symbols.h @@ -79,8 +79,8 @@ private: void iconDragDataGet(const Glib::RefPtr<Gdk::DragContext>& context, Gtk::SelectionData& selection_data, guint info, guint time); void get_symbols(); - void draw_symbols( SPDocument* symbol_document ); - void draw_symbol( SPObject* symbol_document ); + void add_symbols( SPDocument* symbol_document ); + void add_symbol( SPObject* symbol_document ); SPDocument* symbols_preview_doc(); GSList* symbols_in_doc_recursive(SPObject *r, GSList *l); @@ -89,8 +89,7 @@ private: GSList* use_in_doc( SPDocument* document ); gchar const* style_from_use( gchar const* id, SPDocument* document); - Glib::RefPtr<Gdk::Pixbuf> - create_symbol_image(gchar const *symbol_name, SPObject *symbol); + Glib::RefPtr<Gdk::Pixbuf> draw_symbol(SPObject *symbol); /* Keep track of all symbol template documents */ std::map<Glib::ustring, SPDocument*> symbolSets; diff --git a/src/ui/dialog/template-load-tab.cpp b/src/ui/dialog/template-load-tab.cpp index 057eff337..d75f81456 100644 --- a/src/ui/dialog/template-load-tab.cpp +++ b/src/ui/dialog/template-load-tab.cpp @@ -10,6 +10,7 @@ #include "template-widget.h" #include "template-load-tab.h" +#include "new-from-template.h" #include <gtkmm/messagedialog.h> #include <gtkmm/scrolledwindow.h> @@ -31,10 +32,8 @@ #include "xml/document.h" #include "xml/node.h" - namespace Inkscape { namespace UI { - TemplateLoadTab::TemplateLoadTab() : _current_keyword("") @@ -43,10 +42,10 @@ TemplateLoadTab::TemplateLoadTab() { set_border_width(10); - _info_widget = manage(new TemplateWidget()); + _info_widget = Gtk::manage(new TemplateWidget()); Gtk::Label *title; - title = manage(new Gtk::Label(_("Search:"))); + title = Gtk::manage(new Gtk::Label(_("Search:"))); _search_box.pack_start(*title, Gtk::PACK_SHRINK); _search_box.pack_start(_keywords_combo, Gtk::PACK_SHRINK, 5); @@ -56,7 +55,7 @@ TemplateLoadTab::TemplateLoadTab() pack_start(*_info_widget, Gtk::PACK_EXPAND_WIDGET, 5); Gtk::ScrolledWindow *scrolled; - scrolled = manage(new Gtk::ScrolledWindow()); + scrolled = Gtk::manage(new Gtk::ScrolledWindow()); scrolled->set_policy(Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC); scrolled->add(_tlist_view); _tlist_box.pack_start(*scrolled, Gtk::PACK_EXPAND_WIDGET, 5); @@ -84,7 +83,9 @@ void TemplateLoadTab::createTemplate() void TemplateLoadTab::_onRowActivated(const Gtk::TreeModel::Path &, Gtk::TreeViewColumn*) { - _info_widget->create(); + createTemplate(); + NewFromTemplate* parent = static_cast<NewFromTemplate*> (this->get_toplevel()); + parent->_onClose(); } void TemplateLoadTab::_displayTemplateInfo() @@ -219,12 +220,9 @@ TemplateLoadTab::TemplateData TemplateLoadTab::_processTemplateFile(const std::s n = result.display_name.rfind(".svg"); result.display_name.replace(n, 4, 1, ' '); - Inkscape::XML::Document *rdoc; - rdoc = sp_repr_read_file(path.data(), SP_SVG_NS_URI); - Inkscape::XML::Node *myRoot; - + Inkscape::XML::Document *rdoc = sp_repr_read_file(path.data(), SP_SVG_NS_URI); if (rdoc){ - myRoot = rdoc->root(); + Inkscape::XML::Node *myRoot = rdoc->root(); if (strcmp(myRoot->name(), "svg:svg") != 0){ // Wrong file format return result; } @@ -290,26 +288,26 @@ void TemplateLoadTab::_getDataFromNode(Inkscape::XML::Node *dataNode, TemplateDa { Inkscape::XML::Node *currentData; if ((currentData = sp_repr_lookup_name(dataNode, "inkscape:_name")) != NULL) - data.display_name = dgettext("Document template name", currentData->firstChild()->content()); + data.display_name = _(currentData->firstChild()->content()); if ((currentData = sp_repr_lookup_name(dataNode, "inkscape:author")) != NULL) data.author = currentData->firstChild()->content(); if ((currentData = sp_repr_lookup_name(dataNode, "inkscape:_shortdesc")) != NULL) - data.short_description = dgettext("Document template short description", currentData->firstChild()->content()); + data.short_description = _( currentData->firstChild()->content()); if ((currentData = sp_repr_lookup_name(dataNode, "inkscape:_long") )!= NULL) - data.long_description = dgettext("Document template long description", currentData->firstChild()->content()); + data.long_description = _(currentData->firstChild()->content()); if ((currentData = sp_repr_lookup_name(dataNode, "inkscape:preview")) != NULL) data.preview_name = currentData->firstChild()->content(); if ((currentData = sp_repr_lookup_name(dataNode, "inkscape:date")) != NULL) data.creation_date = currentData->firstChild()->content(); if ((currentData = sp_repr_lookup_name(dataNode, "inkscape:_keywords")) != NULL){ - Glib::ustring tplKeywords = currentData->firstChild()->content(); + Glib::ustring tplKeywords = _(currentData->firstChild()->content()); while (!tplKeywords.empty()){ std::size_t pos = tplKeywords.find_first_of(" "); if (pos == Glib::ustring::npos) pos = tplKeywords.size(); - Glib::ustring keyword = dgettext("Document template keyword", tplKeywords.substr(0, pos).data()); + Glib::ustring keyword = tplKeywords.substr(0, pos).data(); data.keywords.insert(keyword.lowercase()); _keywords.insert(keyword.lowercase()); diff --git a/src/ui/dialog/template-widget.cpp b/src/ui/dialog/template-widget.cpp index d1697244e..ef91962d4 100644 --- a/src/ui/dialog/template-widget.cpp +++ b/src/ui/dialog/template-widget.cpp @@ -34,7 +34,7 @@ namespace UI { TemplateWidget::TemplateWidget() : _more_info_button(_("More info")) - , _short_description_label(_(" ")) + , _short_description_label(" ") , _template_name_label(_("no template selected")) , _effect_prefs(NULL) { @@ -47,7 +47,7 @@ TemplateWidget::TemplateWidget() _short_description_label.set_line_wrap(true); Gtk::Alignment *align; - align = manage(new Gtk::Alignment(Gtk::ALIGN_END, Gtk::ALIGN_CENTER, 0.0, 0.0)); + align = Gtk::manage(new Gtk::Alignment(Gtk::ALIGN_END, Gtk::ALIGN_CENTER, 0.0, 0.0)); pack_end(*align, Gtk::PACK_SHRINK); align->add(_more_info_button); diff --git a/src/ui/dialog/tile.cpp b/src/ui/dialog/tile.cpp index c35d3b554..a3cffb3d4 100644 --- a/src/ui/dialog/tile.cpp +++ b/src/ui/dialog/tile.cpp @@ -6,878 +6,62 @@ * John Cliff * Other dudes from The Inkscape Organization * Abhishek Sharma + * Declara Denis * * Copyright (C) 2004 Bob Jamison * Copyright (C) 2004 John Cliff * * Released under GNU GPL, read the file 'COPYING' for more information */ -//#define DEBUG_GRID_ARRANGE 1 -#include "tile.h" -#include <gtk/gtk.h> //for GTK_RESPONSE* types -#include <glibmm/i18n.h> -#include <gtkmm/stock.h> +#include "ui/dialog/grid-arrange-tab.h" +#include "ui/dialog/polar-arrange-tab.h" -#if WITH_GTKMM_3_0 -# include <gtkmm/grid.h> -#else -# include <gtkmm/table.h> -#endif - -#include <2geom/transforms.h> +#include <glibmm/i18n.h> +#include "tile.h" #include "verbs.h" -#include "preferences.h" -#include "inkscape.h" -#include "desktop-handles.h" -#include "selection.h" -#include "document.h" -#include "document-undo.h" -#include "sp-item.h" -#include "widgets/icon.h" -#include "desktop.h" - -/* - * Sort items by their x co-ordinates, taking account of y (keeps rows intact) - * - * <0 *elem1 goes before *elem2 - * 0 *elem1 == *elem2 - * >0 *elem1 goes after *elem2 - */ -static int sp_compare_x_position(SPItem *first, SPItem *second) -{ - using Geom::X; - using Geom::Y; - - Geom::OptRect a = first->documentVisualBounds(); - Geom::OptRect b = second->documentVisualBounds(); - - if ( !a || !b ) { - // FIXME? - return 0; - } - - double const a_height = a->dimensions()[Y]; - double const b_height = b->dimensions()[Y]; - - bool a_in_b_vert = false; - if ((a->min()[Y] < b->min()[Y] + 0.1) && (a->min()[Y] > b->min()[Y] - b_height)) { - a_in_b_vert = true; - } else if ((b->min()[Y] < a->min()[Y] + 0.1) && (b->min()[Y] > a->min()[Y] - a_height)) { - a_in_b_vert = true; - } else if (b->min()[Y] == a->min()[Y]) { - a_in_b_vert = true; - } else { - a_in_b_vert = false; - } - - if (!a_in_b_vert) { - return -1; - } - if (a_in_b_vert && a->min()[X] > b->min()[X]) { - return 1; - } - if (a_in_b_vert && a->min()[X] < b->min()[X]) { - return -1; - } - return 0; -} - -/* - * Sort items by their y co-ordinates. - */ -static int -sp_compare_y_position(SPItem *first, SPItem *second) -{ - Geom::OptRect a = first->documentVisualBounds(); - Geom::OptRect b = second->documentVisualBounds(); - - if ( !a || !b ) { - // FIXME? - return 0; - } - - if (a->min()[Geom::Y] > b->min()[Geom::Y]) { - return 1; - } - if (a->min()[Geom::Y] < b->min()[Geom::Y]) { - return -1; - } - - return 0; -} namespace Inkscape { namespace UI { namespace Dialog { - -//######################################################################### -//## E V E N T S -//######################################################################### - -/* - * - * This arranges the selection in a grid pattern. - * - */ - -void TileDialog::Grid_Arrange () +ArrangeDialog::ArrangeDialog() + : UI::Widget::Panel("", "/dialogs/gridtiler", SP_VERB_SELECTION_ARRANGE), + _gridArrangeTab(new GridArrangeTab(this)), + _polarArrangeTab(new PolarArrangeTab(this)) { + Gtk::Box *contents = this->_getContents(); - int cnt,row_cnt,col_cnt,a,row,col; - double grid_left,grid_top,col_width,row_height,paddingx,paddingy,width, height, new_x, new_y; - double total_col_width,total_row_height; - col_width = 0; - row_height = 0; - total_col_width=0; - total_row_height=0; - - // check for correct numbers in the row- and col-spinners - on_col_spinbutton_changed(); - on_row_spinbutton_changed(); - - // set padding to manual values - paddingx = XPadding.getValue("px"); - paddingy = YPadding.getValue("px"); - - std::vector<double> row_heights; - std::vector<double> col_widths; - std::vector<double> row_ys; - std::vector<double> col_xs; - - int NoOfCols = NoOfColsSpinner.get_value_as_int(); - int NoOfRows = NoOfRowsSpinner.get_value_as_int(); - - width = 0; - for (a=0;a<NoOfCols; a++){ - col_widths.push_back(width); - } - - height = 0; - for (a=0;a<NoOfRows; a++){ - row_heights.push_back(height); - } - grid_left = 99999; - grid_top = 99999; - - SPDesktop *desktop = getDesktop(); - sp_desktop_document(desktop)->ensureUpToDate(); - - Inkscape::Selection *selection = sp_desktop_selection (desktop); - const GSList *items = selection ? selection->itemList() : 0; - cnt=0; - for (; items != NULL; items = items->next) { - SPItem *item = SP_ITEM(items->data); - Geom::OptRect b = item->documentVisualBounds(); - if (!b) { - continue; - } - - width = b->dimensions()[Geom::X]; - height = b->dimensions()[Geom::Y]; - - if (b->min()[Geom::X] < grid_left) { - grid_left = b->min()[Geom::X]; - } - if (b->min()[Geom::Y] < grid_top) { - grid_top = b->min()[Geom::Y]; - } - if (width > col_width) { - col_width = width; - } - if (height > row_height) { - row_height = height; - } - } - - - // require the sorting done before we can calculate row heights etc. - - g_return_if_fail(selection); - const GSList *items2 = selection->itemList(); - GSList *rev = g_slist_copy(const_cast<GSList *>(items2)); - GSList *sorted = NULL; - rev = g_slist_sort(rev, (GCompareFunc) sp_compare_y_position); - sorted = g_slist_sort(rev, (GCompareFunc) sp_compare_x_position); - - - // Calculate individual Row and Column sizes if necessary - - - cnt=0; - const GSList *sizes = sorted; - for (; sizes != NULL; sizes = sizes->next) { - SPItem *item = SP_ITEM(sizes->data); - Geom::OptRect b = item->documentVisualBounds(); - if (b) { - width = b->dimensions()[Geom::X]; - height = b->dimensions()[Geom::Y]; - if (width > col_widths[(cnt % NoOfCols)]) { - col_widths[(cnt % NoOfCols)] = width; - } - if (height > row_heights[(cnt / NoOfCols)]) { - row_heights[(cnt / NoOfCols)] = height; - } - } - - cnt++; - } - - - /// Make sure the top and left of the grid dont move by compensating for align values. - if (RowHeightButton.get_active()){ - grid_top = grid_top - (((row_height - row_heights[0]) / 2)*(VertAlign)); - } - if (ColumnWidthButton.get_active()){ - grid_left = grid_left - (((col_width - col_widths[0]) /2)*(HorizAlign)); - } - - #ifdef DEBUG_GRID_ARRANGE - g_print("\n cx = %f cy= %f gridleft=%f",cx,cy,grid_left); - #endif - - // Calculate total widths and heights, allowing for columns and rows non uniformly sized. + _notebook.append_page(*_gridArrangeTab, C_("Arrange dialog", "Rectangular grid")); + _notebook.append_page(*_polarArrangeTab, C_("Arrange dialog", "Polar Coordinates")); + _arrangeBox.pack_start(_notebook); - if (ColumnWidthButton.get_active()){ - total_col_width = col_width * NoOfCols; - col_widths.clear(); - for (a=0;a<NoOfCols; a++){ - col_widths.push_back(col_width); - } - } else { - for (a = 0; a < (int)col_widths.size(); a++) - { - total_col_width += col_widths[a] ; - } - } - - if (RowHeightButton.get_active()){ - total_row_height = row_height * NoOfRows; - row_heights.clear(); - for (a=0;a<NoOfRows; a++){ - row_heights.push_back(row_height); - } - } else { - for (a = 0; a < (int)row_heights.size(); a++) - { - total_row_height += row_heights[a] ; - } - } - - - Geom::OptRect sel_bbox = selection->visualBounds(); - // Fit to bbox, calculate padding between rows accordingly. - if ( sel_bbox && !SpaceManualRadioButton.get_active() ){ -#ifdef DEBUG_GRID_ARRANGE -g_print("\n row = %f col = %f selection x= %f selection y = %f", total_row_height,total_col_width, b.extent(Geom::X), b.extent(Geom::Y)); -#endif - paddingx = (sel_bbox->width() - total_col_width) / (NoOfCols -1); - paddingy = (sel_bbox->height() - total_row_height) / (NoOfRows -1); - } - -/* - Horizontal align - Left = 0 - Centre = 1 - Right = 2 - - Vertical align - Top = 0 - Middle = 1 - Bottom = 2 - - X position is calculated by taking the grids left co-ord, adding the distance to the column, - then adding 1/2 the spacing multiplied by the align variable above, - Y position likewise, takes the top of the grid, adds the y to the current row then adds the padding in to align it. - -*/ - - // Calculate row and column x and y coords required to allow for columns and rows which are non uniformly sized. - - for (a=0;a<NoOfCols; a++){ - if (a<1) col_xs.push_back(0); - else col_xs.push_back(col_widths[a-1]+paddingx+col_xs[a-1]); - } - - - for (a=0;a<NoOfRows; a++){ - if (a<1) row_ys.push_back(0); - else row_ys.push_back(row_heights[a-1]+paddingy+row_ys[a-1]); - } - - cnt=0; - for (row_cnt=0; ((sorted != NULL) && (row_cnt<NoOfRows)); row_cnt++) { - - GSList *current_row = NULL; - for (col_cnt = 0; ((sorted != NULL) && (col_cnt<NoOfCols)); col_cnt++) { - current_row = g_slist_append (current_row, sorted->data); - sorted = sorted->next; - } - - for (; current_row != NULL; current_row = current_row->next) { - SPItem *item=SP_ITEM(current_row->data); - Inkscape::XML::Node *repr = item->getRepr(); - Geom::OptRect b = item->documentVisualBounds(); - Geom::Point min; - if (b) { - width = b->dimensions()[Geom::X]; - height = b->dimensions()[Geom::Y]; - min = b->min(); - } else { - width = height = 0; - min = Geom::Point(0, 0); - } - - row = cnt / NoOfCols; - col = cnt % NoOfCols; - - new_x = grid_left + (((col_widths[col] - width)/2)*HorizAlign) + col_xs[col]; - new_y = grid_top + (((row_heights[row] - height)/2)*VertAlign) + row_ys[row]; - - // signs are inverted between x and y due to y inversion - Geom::Point move = Geom::Point(new_x - min[Geom::X], min[Geom::Y] - new_y); - Geom::Affine const affine = Geom::Affine(Geom::Translate(move)); - item->set_i2d_affine(item->i2dt_affine() * affine); - item->doWriteTransform(repr, item->transform, NULL); - SP_OBJECT (current_row->data)->updateRepr(); - cnt +=1; - } - g_slist_free (current_row); - } - - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_SELECTION_GRIDTILE, - _("Arrange in a grid")); - -} - - -//######################################################################### -//## E V E N T S -//######################################################################### - - -void TileDialog::_apply() -{ - Grid_Arrange(); -} - - -/** - * changed value in # of columns spinbox. - */ -void TileDialog::on_row_spinbutton_changed() -{ - // quit if run by the attr_changed listener - if (updating) { - return; - } - - // in turn, prevent listener from responding - updating = true; - SPDesktop *desktop = getDesktop(); - - Inkscape::Selection *selection = desktop ? desktop->selection : 0; - g_return_if_fail( selection ); - - GSList const *items = selection->itemList(); - int selcount = g_slist_length((GSList *)items); - - double PerCol = ceil(selcount / NoOfColsSpinner.get_value()); - NoOfRowsSpinner.set_value(PerCol); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble("/dialogs/gridtiler/NoOfCols", NoOfColsSpinner.get_value()); - updating=false; -} - -/** - * changed value in # of rows spinbox. - */ -void TileDialog::on_col_spinbutton_changed() -{ - // quit if run by the attr_changed listener - if (updating) { - return; - } - - // in turn, prevent listener from responding - updating = true; - SPDesktop *desktop = getDesktop(); - Inkscape::Selection *selection = desktop ? desktop->selection : 0; - g_return_if_fail(selection); - - GSList const *items = selection->itemList(); - int selcount = g_slist_length((GSList *)items); - - double PerRow = ceil(selcount / NoOfRowsSpinner.get_value()); - NoOfColsSpinner.set_value(PerRow); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble("/dialogs/gridtiler/NoOfCols", PerRow); - - updating=false; + _arrangeButton = this->addResponseButton(C_("Arrange dialog","_Arrange"), GTK_RESPONSE_APPLY); + _arrangeButton->set_use_underline(true); + _arrangeButton->set_tooltip_text(_("Arrange selected objects")); + contents->pack_start(_arrangeBox); + //show_all_children(); } -/** - * changed value in x padding spinbox. - */ -void TileDialog::on_xpad_spinbutton_changed() -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble("/dialogs/gridtiler/XPad", XPadding.getValue("px")); -} - -/** - * changed value in y padding spinbox. - */ -void TileDialog::on_ypad_spinbutton_changed() +void ArrangeDialog::on_show() { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble("/dialogs/gridtiler/YPad", YPadding.getValue("px")); + UI::Widget::Panel::on_show(); + _polarArrangeTab->on_arrange_radio_changed(); } - -/** - * checked/unchecked autosize Rows button. - */ -void TileDialog::on_RowSize_checkbutton_changed() +void ArrangeDialog::_apply() { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - if (RowHeightButton.get_active()) { - prefs->setDouble("/dialogs/gridtiler/AutoRowSize", 20); - } else { - prefs->setDouble("/dialogs/gridtiler/AutoRowSize", -20); - } - RowHeightBox.set_sensitive ( !RowHeightButton.get_active()); -} - -/** - * checked/unchecked autosize Rows button. - */ -void TileDialog::on_ColSize_checkbutton_changed() -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - if (ColumnWidthButton.get_active()) { - prefs->setDouble("/dialogs/gridtiler/AutoColSize", 20); - } else { - prefs->setDouble("/dialogs/gridtiler/AutoColSize", -20); - } - ColumnWidthBox.set_sensitive ( !ColumnWidthButton.get_active()); -} - -/** - * changed value in columns spinbox. - */ -void TileDialog::on_rowSize_spinbutton_changed() -{ - // quit if run by the attr_changed listener - if (updating) { - return; - } - - // in turn, prevent listener from responding - updating = true; - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble("/dialogs/gridtiler/RowHeight", RowHeightSpinner.get_value()); - updating=false; - -} - -/** - * changed value in rows spinbox. - */ -void TileDialog::on_colSize_spinbutton_changed() -{ - // quit if run by the attr_changed listener - if (updating) { - return; - } - - // in turn, prevent listener from responding - updating = true; - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble("/dialogs/gridtiler/ColWidth", ColumnWidthSpinner.get_value()); - updating=false; - -} - -/** - * changed Radio button in Spacing group. - */ -void TileDialog::Spacing_button_changed() -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - if (SpaceManualRadioButton.get_active()) { - prefs->setDouble("/dialogs/gridtiler/SpacingType", 20); - } else { - prefs->setDouble("/dialogs/gridtiler/SpacingType", -20); - } - - XPadding.set_sensitive ( SpaceManualRadioButton.get_active()); - YPadding.set_sensitive ( SpaceManualRadioButton.get_active()); -} - -/** - * changed Radio button in Vertical Align group. - */ -void TileDialog::VertAlign_changed() -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - if (VertTopRadioButton.get_active()) { - VertAlign = 0; - prefs->setInt("/dialogs/gridtiler/VertAlign", 0); - } else if (VertCentreRadioButton.get_active()){ - VertAlign = 1; - prefs->setInt("/dialogs/gridtiler/VertAlign", 1); - } else if (VertBotRadioButton.get_active()){ - VertAlign = 2; - prefs->setInt("/dialogs/gridtiler/VertAlign", 2); - } -} - -/** - * changed Radio button in Vertical Align group. - */ -void TileDialog::HorizAlign_changed() -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - if (HorizLeftRadioButton.get_active()) { - HorizAlign = 0; - prefs->setInt("/dialogs/gridtiler/HorizAlign", 0); - } else if (HorizCentreRadioButton.get_active()){ - HorizAlign = 1; - prefs->setInt("/dialogs/gridtiler/HorizAlign", 1); - } else if (HorizRightRadioButton.get_active()){ - HorizAlign = 2; - prefs->setInt("/dialogs/gridtiler/HorizAlign", 2); - } -} - -/** - * Desktop selection changed - */ -void TileDialog::updateSelection() -{ - // quit if run by the attr_changed listener - if (updating) { - return; - } - - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - // in turn, prevent listener from responding - updating = true; - SPDesktop *desktop = getDesktop(); - Inkscape::Selection *selection = desktop ? desktop->selection : 0; - GSList const *items = selection ? selection->itemList() : 0; - - if (items) { - int selcount = g_slist_length((GSList *)items); - - if (NoOfColsSpinner.get_value() > 1 && NoOfRowsSpinner.get_value() > 1){ - // Update the number of rows assuming number of columns wanted remains same. - double NoOfRows = ceil(selcount / NoOfColsSpinner.get_value()); - NoOfRowsSpinner.set_value(NoOfRows); - - // if the selection has less than the number set for one row, reduce it appropriately - if (selcount < NoOfColsSpinner.get_value()) { - double NoOfCols = ceil(selcount / NoOfRowsSpinner.get_value()); - NoOfColsSpinner.set_value(NoOfCols); - prefs->setInt("/dialogs/gridtiler/NoOfCols", NoOfCols); - } - } else { - double PerRow = ceil(sqrt(selcount)); - double PerCol = ceil(sqrt(selcount)); - NoOfRowsSpinner.set_value(PerRow); - NoOfColsSpinner.set_value(PerCol); - prefs->setInt("/dialogs/gridtiler/NoOfCols", static_cast<int>(PerCol)); - } - } - - updating = false; -} - - - -/*########################## -## Experimental -##########################*/ - -static void updateSelectionCallback(Inkscape::Application */*inkscape*/, Inkscape::Selection */*selection*/, TileDialog *dlg) -{ - dlg->updateSelection(); -} - - -//######################################################################### -//## C O N S T R U C T O R / D E S T R U C T O R -//######################################################################### -/** - * Constructor - */ -TileDialog::TileDialog() - : UI::Widget::Panel("", "/dialogs/gridtiler", SP_VERB_SELECTION_GRIDTILE), - XPadding(_("X:"), _("Horizontal spacing between columns."), UNIT_TYPE_LINEAR, "", "object-columns", &PaddingUnitMenu), - YPadding(_("Y:"), _("Vertical spacing between rows."), UNIT_TYPE_LINEAR, "", "object-rows", &PaddingUnitMenu), -#if WITH_GTKMM_3_0 - PaddingTable(Gtk::manage(new Gtk::Grid())) -#else - PaddingTable(Gtk::manage(new Gtk::Table(2, 2, false))) -#endif -{ - // bool used by spin button callbacks to stop loops where they change each other. - updating = false; - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - - // could not do this in gtkmm - there's no Gtk::SizeGroup public constructor (!) - GtkSizeGroup *_col1 = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); - GtkSizeGroup *_col2 = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); - GtkSizeGroup *_col3 = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); - - { - // Selection Change signal - g_signal_connect ( G_OBJECT (INKSCAPE), "change_selection", G_CALLBACK (updateSelectionCallback), this); - } - - Gtk::Box *contents = _getContents(); - -#define MARGIN 2 - - //##Set up the panel - - SPDesktop *desktop = getDesktop(); - - Inkscape::Selection *selection = desktop ? desktop->selection : 0; - g_return_if_fail( selection ); - int selcount = 1; - if (!selection->isEmpty()) { - GSList const *items = selection->itemList(); - selcount = g_slist_length((GSList *)items); - } - - - /*#### Number of Rows ####*/ - - double PerRow = ceil(sqrt(selcount)); - double PerCol = ceil(sqrt(selcount)); - - #ifdef DEBUG_GRID_ARRANGE - g_print("/n PerRox = %f PerCol = %f selcount = %d",PerRow,PerCol,selcount); - #endif - - NoOfRowsLabel.set_text_with_mnemonic(_("_Rows:")); - NoOfRowsLabel.set_mnemonic_widget(NoOfRowsSpinner); - NoOfRowsBox.pack_start(NoOfRowsLabel, false, false, MARGIN); - - NoOfRowsSpinner.set_digits(0); - NoOfRowsSpinner.set_increments(1, 0); - NoOfRowsSpinner.set_range(1.0, 10000.0); - NoOfRowsSpinner.set_value(PerCol); - NoOfRowsSpinner.signal_changed().connect(sigc::mem_fun(*this, &TileDialog::on_col_spinbutton_changed)); - NoOfRowsSpinner.set_tooltip_text(_("Number of rows")); - NoOfRowsBox.pack_start(NoOfRowsSpinner, false, false, MARGIN); - gtk_size_group_add_widget(_col1, GTK_WIDGET(NoOfRowsBox.gobj())); - - RowHeightButton.set_label(_("Equal _height")); - RowHeightButton.set_use_underline(true); - double AutoRow = prefs->getDouble("/dialogs/gridtiler/AutoRowSize", 15); - if (AutoRow>0) - AutoRowSize=true; - else - AutoRowSize=false; - RowHeightButton.set_active(AutoRowSize); - - NoOfRowsBox.pack_start(RowHeightButton, false, false, MARGIN); - - RowHeightButton.set_tooltip_text(_("If not set, each row has the height of the tallest object in it")); - RowHeightButton.signal_toggled().connect(sigc::mem_fun(*this, &TileDialog::on_RowSize_checkbutton_changed)); - - { - /*#### Radio buttons to control vertical alignment ####*/ - - VertAlignLabel.set_label(_("Align:")); - VertAlignHBox.pack_start(VertAlignLabel, false, false, MARGIN); - - VertTopRadioButton.signal_toggled().connect(sigc::mem_fun(*this, &TileDialog::VertAlign_changed)); - VertAlignGroup = VertTopRadioButton.get_group(); - VertAlignVBox.pack_start(VertTopRadioButton, false, false, 0); - - VertCentreRadioButton.set_group(VertAlignGroup); - VertCentreRadioButton.signal_toggled().connect(sigc::mem_fun(*this, &TileDialog::VertAlign_changed)); - VertAlignVBox.pack_start(VertCentreRadioButton, false, false, 0); - - VertBotRadioButton.set_group(VertAlignGroup); - VertBotRadioButton.signal_toggled().connect(sigc::mem_fun(*this, &TileDialog::VertAlign_changed)); - VertAlignVBox.pack_start(VertBotRadioButton, false, false, 0); - - VertAlign = prefs->getInt("/dialogs/gridtiler/VertAlign", 1); - if (VertAlign == 0) { - VertTopRadioButton.set_active(TRUE); - } - else if (VertAlign == 1) { - VertCentreRadioButton.set_active(TRUE); - } - else if (VertAlign == 2){ - VertBotRadioButton.set_active(TRUE); - } - VertAlignHBox.pack_start(VertAlignVBox, false, false, MARGIN); - NoOfRowsBox.pack_start(VertAlignHBox, false, false, MARGIN); - } - - SpinsHBox.pack_start(NoOfRowsBox, false, false, MARGIN); - - - /*#### Label for X ####*/ - padXByYLabel.set_label(" "); - XByYLabelVBox.pack_start(padXByYLabel, false, false, MARGIN); - XByYLabel.set_markup(" × "); - XByYLabelVBox.pack_start(XByYLabel, false, false, MARGIN); - SpinsHBox.pack_start(XByYLabelVBox, false, false, MARGIN); - gtk_size_group_add_widget(_col2, GTK_WIDGET(XByYLabelVBox.gobj())); - - /*#### Number of columns ####*/ - - NoOfColsLabel.set_text_with_mnemonic(_("_Columns:")); - NoOfColsLabel.set_mnemonic_widget(NoOfColsSpinner); - NoOfColsBox.pack_start(NoOfColsLabel, false, false, MARGIN); - - NoOfColsSpinner.set_digits(0); - NoOfColsSpinner.set_increments(1, 0); - NoOfColsSpinner.set_range(1.0, 10000.0); - NoOfColsSpinner.set_value(PerRow); - NoOfColsSpinner.signal_changed().connect(sigc::mem_fun(*this, &TileDialog::on_row_spinbutton_changed)); - NoOfColsSpinner.set_tooltip_text(_("Number of columns")); - NoOfColsBox.pack_start(NoOfColsSpinner, false, false, MARGIN); - gtk_size_group_add_widget(_col3, GTK_WIDGET(NoOfColsBox.gobj())); - - ColumnWidthButton.set_label(_("Equal _width")); - ColumnWidthButton.set_use_underline(true); - double AutoCol = prefs->getDouble("/dialogs/gridtiler/AutoColSize", 15); - if (AutoCol>0) - AutoColSize=true; - else - AutoColSize=false; - ColumnWidthButton.set_active(AutoColSize); - NoOfColsBox.pack_start(ColumnWidthButton, false, false, MARGIN); - - ColumnWidthButton.set_tooltip_text(_("If not set, each column has the width of the widest object in it")); - ColumnWidthButton.signal_toggled().connect(sigc::mem_fun(*this, &TileDialog::on_ColSize_checkbutton_changed)); - - - { - /*#### Radio buttons to control horizontal alignment ####*/ - - HorizAlignLabel.set_label(_("Align:")); - HorizAlignVBox.pack_start(HorizAlignLabel, false, false, MARGIN); - - HorizAlignHBox.pack_start(*(new Gtk::HBox()), true, true, 0); // centering strut - - HorizLeftRadioButton.signal_toggled().connect(sigc::mem_fun(*this, &TileDialog::HorizAlign_changed)); - HorizAlignGroup = HorizLeftRadioButton.get_group(); - HorizAlignHBox.pack_start(HorizLeftRadioButton, false, false, 0); - - HorizCentreRadioButton.set_group(HorizAlignGroup); - HorizCentreRadioButton.signal_toggled().connect(sigc::mem_fun(*this, &TileDialog::HorizAlign_changed)); - HorizAlignHBox.pack_start(HorizCentreRadioButton, false, false, 0); - - HorizRightRadioButton.set_group(HorizAlignGroup); - HorizRightRadioButton.signal_toggled().connect(sigc::mem_fun(*this, &TileDialog::HorizAlign_changed)); - HorizAlignHBox.pack_start(HorizRightRadioButton, false, false, 0); - - HorizAlignHBox.pack_start(*(new Gtk::HBox()), true, true, 0); // centering strut - - HorizAlign = prefs->getInt("/dialogs/gridtiler/HorizAlign", 1); - if (HorizAlign == 0) { - HorizLeftRadioButton.set_active(TRUE); - } - else if (HorizAlign == 1) { - HorizCentreRadioButton.set_active(TRUE); - } - else if (HorizAlign == 2) { - HorizRightRadioButton.set_active(TRUE); - } - HorizAlignVBox.pack_start(HorizAlignHBox, false, false, MARGIN); - NoOfColsBox.pack_start(HorizAlignVBox, false, false, MARGIN); - } - - SpinsHBox.pack_start(NoOfColsBox, false, false, MARGIN); - - TileBox.pack_start(SpinsHBox, false, false, MARGIN); - - { - /*#### Radio buttons to control spacing manually or to fit selection bbox ####*/ - SpaceByBBoxRadioButton.set_label(_("_Fit into selection box")); - SpaceByBBoxRadioButton.set_use_underline (true); - SpaceByBBoxRadioButton.signal_toggled().connect(sigc::mem_fun(*this, &TileDialog::Spacing_button_changed)); - SpacingGroup = SpaceByBBoxRadioButton.get_group(); - - SpacingVBox.pack_start(SpaceByBBoxRadioButton, false, false, MARGIN); - - SpaceManualRadioButton.set_label(_("_Set spacing:")); - SpaceManualRadioButton.set_use_underline (true); - SpaceManualRadioButton.set_group(SpacingGroup); - SpaceManualRadioButton.signal_toggled().connect(sigc::mem_fun(*this, &TileDialog::Spacing_button_changed)); - SpacingVBox.pack_start(SpaceManualRadioButton, false, false, MARGIN); - - TileBox.pack_start(SpacingVBox, false, false, MARGIN); - } - - { - /*#### Padding ####*/ - PaddingUnitMenu.setUnitType(UNIT_TYPE_LINEAR); - PaddingUnitMenu.setUnit("px"); - - YPadding.setDigits(5); - YPadding.setIncrements(0.2, 0); - YPadding.setRange(-10000, 10000); - double yPad = prefs->getDouble("/dialogs/gridtiler/YPad", 15); - YPadding.setValue(yPad, "px"); - YPadding.signal_value_changed().connect(sigc::mem_fun(*this, &TileDialog::on_ypad_spinbutton_changed)); - - XPadding.setDigits(5); - XPadding.setIncrements(0.2, 0); - XPadding.setRange(-10000, 10000); - double xPad = prefs->getDouble("/dialogs/gridtiler/XPad", 15); - XPadding.setValue(xPad, "px"); - - XPadding.signal_value_changed().connect(sigc::mem_fun(*this, &TileDialog::on_xpad_spinbutton_changed)); - } - - PaddingTable->set_border_width(MARGIN); - -#if WITH_GTKMM_3_0 - PaddingTable->set_row_spacing(MARGIN); - PaddingTable->set_column_spacing(MARGIN); - PaddingTable->attach(XPadding, 0, 0, 1, 1); - PaddingTable->attach(PaddingUnitMenu, 1, 0, 1, 1); - PaddingTable->attach(YPadding, 0, 1, 1, 1); -#else - PaddingTable->set_row_spacings(MARGIN); - PaddingTable->set_col_spacings(MARGIN); - PaddingTable->attach(XPadding, 0, 1, 0, 1, Gtk::SHRINK, Gtk::SHRINK); - PaddingTable->attach(PaddingUnitMenu, 1, 2, 0, 1, Gtk::SHRINK, Gtk::SHRINK); - PaddingTable->attach(YPadding, 0, 1, 1, 2, Gtk::SHRINK, Gtk::SHRINK); -#endif - - TileBox.pack_start(*PaddingTable, false, false, MARGIN); - - contents->pack_start(TileBox); - - double SpacingType = prefs->getDouble("/dialogs/gridtiler/SpacingType", 15); - if (SpacingType>0) { - ManualSpacing=true; - } else { - ManualSpacing=false; - } - SpaceManualRadioButton.set_active(ManualSpacing); - SpaceByBBoxRadioButton.set_active(!ManualSpacing); - XPadding.set_sensitive (ManualSpacing); - YPadding.set_sensitive (ManualSpacing); - - //## The OK button - TileOkButton = addResponseButton(C_("Rows and columns dialog","_Arrange"), GTK_RESPONSE_APPLY); - TileOkButton->set_use_underline(true); - TileOkButton->set_tooltip_text(_("Arrange selected objects")); - - show_all_children(); + switch(_notebook.get_current_page()) + { + case 0: + _gridArrangeTab->arrange(); + break; + case 1: + _polarArrangeTab->arrange(); + break; + } } } //namespace Dialog diff --git a/src/ui/dialog/tile.h b/src/ui/dialog/tile.h index 6e41723fd..2f75a8922 100644 --- a/src/ui/dialog/tile.h +++ b/src/ui/dialog/tile.h @@ -5,6 +5,7 @@ * Bob Jamison ( based off trace dialog) * John Cliff * Other dudes from The Inkscape Organization + * Declara Denis * * Copyright (C) 2004 Bob Jamison * Copyright (C) 2004 John Cliff @@ -29,8 +30,6 @@ #include <gtkmm/radiobutton.h> #include "ui/widget/panel.h" -#include "ui/widget/spinbutton.h" -#include "ui/widget/scalar-unit.h" namespace Gtk { class Button; @@ -46,134 +45,34 @@ namespace Inkscape { namespace UI { namespace Dialog { +class ArrangeTab; +class GridArrangeTab; +class PolarArrangeTab; -/** - * Dialog for tiling an object - */ -class TileDialog : public UI::Widget::Panel { -public: - TileDialog() ; - virtual ~TileDialog() {}; +class ArrangeDialog : public UI::Widget::Panel { +private: + Gtk::VBox _arrangeBox; + Gtk::Notebook _notebook; - /** - * Do the actual work - */ - void Grid_Arrange(); + GridArrangeTab *_gridArrangeTab; + PolarArrangeTab *_polarArrangeTab; - /** - * Respond to selection change - */ - void updateSelection(); + Gtk::Button *_arrangeButton; + +public: + ArrangeDialog(); + virtual ~ArrangeDialog() {}; /** * Callback from Apply */ virtual void _apply(); - // Callbacks from spinbuttons - void on_row_spinbutton_changed(); - void on_col_spinbutton_changed(); - void on_xpad_spinbutton_changed(); - void on_ypad_spinbutton_changed(); - void on_RowSize_checkbutton_changed(); - void on_ColSize_checkbutton_changed(); - void on_rowSize_spinbutton_changed(); - void on_colSize_spinbutton_changed(); - void Spacing_button_changed(); - void VertAlign_changed(); - void HorizAlign_changed(); - - static TileDialog& getInstance() { return *new TileDialog(); } - -private: - TileDialog(TileDialog const &d); // no copy - void operator=(TileDialog const &d); // no assign - - bool userHidden; - bool updating; - - Gtk::Notebook notebook; - - Gtk::VBox TileBox; - Gtk::Button *TileOkButton; - Gtk::Button *TileCancelButton; - - // Number selected label - Gtk::Label SelectionContentsLabel; - - - Gtk::HBox AlignHBox; - Gtk::HBox SpinsHBox; - - // Number per Row - Gtk::VBox NoOfColsBox; - Gtk::Label NoOfColsLabel; - Inkscape::UI::Widget::SpinButton NoOfColsSpinner; - bool AutoRowSize; - Gtk::CheckButton RowHeightButton; - - Gtk::VBox XByYLabelVBox; - Gtk::Label padXByYLabel; - Gtk::Label XByYLabel; - - // Number per Column - Gtk::VBox NoOfRowsBox; - Gtk::Label NoOfRowsLabel; - Inkscape::UI::Widget::SpinButton NoOfRowsSpinner; - bool AutoColSize; - Gtk::CheckButton ColumnWidthButton; - - // Vertical align - Gtk::Label VertAlignLabel; - Gtk::HBox VertAlignHBox; - Gtk::VBox VertAlignVBox; - Gtk::RadioButtonGroup VertAlignGroup; - Gtk::RadioButton VertCentreRadioButton; - Gtk::RadioButton VertTopRadioButton; - Gtk::RadioButton VertBotRadioButton; - double VertAlign; - - // Horizontal align - Gtk::Label HorizAlignLabel; - Gtk::VBox HorizAlignVBox; - Gtk::HBox HorizAlignHBox; - Gtk::RadioButtonGroup HorizAlignGroup; - Gtk::RadioButton HorizCentreRadioButton; - Gtk::RadioButton HorizLeftRadioButton; - Gtk::RadioButton HorizRightRadioButton; - double HorizAlign; - - Inkscape::UI::Widget::UnitMenu PaddingUnitMenu; - Inkscape::UI::Widget::ScalarUnit XPadding; - Inkscape::UI::Widget::ScalarUnit YPadding; - -#if WITH_GTKMM_3_0 - Gtk::Grid *PaddingTable; -#else - Gtk::Table *PaddingTable; -#endif + virtual void on_show(); - // BBox or manual spacing - Gtk::VBox SpacingVBox; - Gtk::RadioButtonGroup SpacingGroup; - Gtk::RadioButton SpaceByBBoxRadioButton; - Gtk::RadioButton SpaceManualRadioButton; - bool ManualSpacing; - - // Row height - Gtk::VBox RowHeightVBox; - Gtk::HBox RowHeightBox; - Gtk::Label RowHeightLabel; - Inkscape::UI::Widget::SpinButton RowHeightSpinner; - - // Column width - Gtk::VBox ColumnWidthVBox; - Gtk::HBox ColumnWidthBox; - Gtk::Label ColumnWidthLabel; - Inkscape::UI::Widget::SpinButton ColumnWidthSpinner; + static ArrangeDialog& getInstance() { return *new ArrangeDialog(); } }; - } //namespace Dialog } //namespace UI } //namespace Inkscape diff --git a/src/ui/dialog/tracedialog.cpp b/src/ui/dialog/tracedialog.cpp index bd467555e..11e75391b 100644 --- a/src/ui/dialog/tracedialog.cpp +++ b/src/ui/dialog/tracedialog.cpp @@ -778,7 +778,7 @@ TraceDialogImpl::TraceDialogImpl() : rightVBox.pack_start(sioxBox, false, false, 0); //## preview - Gtk::HBox *previewButtonHBox = manage(new Gtk::HBox(false, MARGIN )); + Gtk::HBox *previewButtonHBox = Gtk::manage(new Gtk::HBox(false, MARGIN )); previewLiveButton.set_label(_("Live Preview")); previewLiveButton.set_use_underline(true); previewLiveCallback(); diff --git a/src/ui/dialog/undo-history.cpp b/src/ui/dialog/undo-history.cpp index a487eb930..53691cd37 100644 --- a/src/ui/dialog/undo-history.cpp +++ b/src/ui/dialog/undo-history.cpp @@ -5,8 +5,9 @@ /* Author: * Gustav Broberg <broberg@kth.se> * Abhishek Sharma + * Jon A. Cruz <jon@joncruz.org> * - * Copyright (C) 2006 Authors + * Copyright (C) 2014 Authors * Released under GNU GPL. Read the file 'COPYING' for more information. */ @@ -24,6 +25,7 @@ #include "inkscape.h" #include "verbs.h" #include "desktop-handles.h" +#include "util/signal-blocker.h" #include "desktop.h" #include <gtkmm/invisible.h> @@ -131,39 +133,19 @@ UndoHistory& UndoHistory::getInstance() return *new UndoHistory(); } -void -UndoHistory::setDesktop(SPDesktop* desktop) -{ - Panel::setDesktop(desktop); - - if (!desktop) return; - - _document = sp_desktop_document(desktop); - - _event_log = desktop->event_log; - - _callback_connections[EventLog::CALLB_SELECTION_CHANGE].block(); - - _event_list_store = _event_log->getEventListStore(); - _event_list_view.set_model(_event_list_store); - _event_list_selection = _event_list_view.get_selection(); - - _event_log->connectWithDialog(&_event_list_view, &_callback_connections); - _event_list_view.scroll_to_row(_event_list_store->get_path(_event_list_selection->get_selected())); - - _callback_connections[EventLog::CALLB_SELECTION_CHANGE].block(false); -} - UndoHistory::UndoHistory() : UI::Widget::Panel ("", "/dialogs/undo-history", SP_VERB_DIALOG_UNDO_HISTORY), - _document (sp_desktop_document(getDesktop())), - _event_log (getDesktop() ? getDesktop()->event_log : NULL), - _columns (_event_log ? &_event_log->getColumns() : NULL), - _event_list_selection (_event_list_view.get_selection()), - _desktop(NULL), + _document_replaced_connection(), + _desktop(getDesktop()), + _document(_desktop ? _desktop->doc() : NULL), + _event_log(_desktop ? _desktop->event_log : NULL), + _columns(_event_log ? &_event_log->getColumns() : NULL), + _scrolled_window(), + _event_list_store(), + _event_list_selection(_event_list_view.get_selection()), _deskTrack(), - _desktopChangeConn() - + _desktopChangeConn(), + _callback_connections() { if ( !_document || !_event_log || !_columns ) return; @@ -172,9 +154,9 @@ UndoHistory::UndoHistory() _getContents()->pack_start(_scrolled_window); _scrolled_window.set_policy(Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC); - _event_list_store = _event_log->getEventListStore(); + // connect with the EventLog + _connectEventLog(); - _event_list_view.set_model(_event_list_store); _event_list_view.set_rules_hint(false); _event_list_view.set_enable_search(false); _event_list_view.set_headers_visible(false); @@ -221,12 +203,12 @@ UndoHistory::UndoHistory() _callback_connections[EventLog::CALLB_COLLAPSE] = _event_list_view.signal_row_collapsed().connect(sigc::mem_fun(*this, &Inkscape::UI::Dialog::UndoHistory::_onCollapseEvent)); - // connect with the EventLog - _event_log->connectWithDialog(&_event_list_view, &_callback_connections); - _desktopChangeConn = _deskTrack.connectDesktopChanged( sigc::mem_fun(*this, &UndoHistory::setDesktop) ); _deskTrack.connect(GTK_WIDGET(gobj())); + // connect to be informed of document changes + signalDocumentReplaced().connect(sigc::mem_fun(*this, &UndoHistory::_handleDocumentReplaced)); + show_all_children(); // scroll to the selected row @@ -239,6 +221,82 @@ UndoHistory::~UndoHistory() } +void UndoHistory::setDesktop(SPDesktop* desktop) +{ + Panel::setDesktop(desktop); + + EventLog *newEventLog = desktop ? desktop->event_log : NULL; + if ((_desktop == desktop) && (_event_log == newEventLog)) { + // same desktop set + } + else + { + _connectDocument(desktop, desktop ? desktop->doc() : NULL); + } +} + +void UndoHistory::_connectDocument(SPDesktop* desktop, SPDocument * /*document*/) +{ + // disconnect from prior + if (_event_log) { + _event_log->removeDialogConnection(&_event_list_view, &_callback_connections); + } + + SignalBlocker blocker(&_callback_connections[EventLog::CALLB_SELECTION_CHANGE]); + + _event_list_view.unset_model(); + + // connect to new EventLog/Desktop + _desktop = desktop; + _event_log = desktop ? desktop->event_log : NULL; + _document = desktop ? desktop->doc() : NULL; + _connectEventLog(); +} + +void UndoHistory::_connectEventLog() +{ + if (_event_log) { + _event_log->add_destroy_notify_callback(this, &_handleEventLogDestroyCB); + _event_list_store = _event_log->getEventListStore(); + + _event_list_view.set_model(_event_list_store); + + _event_log->addDialogConnection(&_event_list_view, &_callback_connections); + _event_list_view.scroll_to_row(_event_list_store->get_path(_event_list_selection->get_selected())); + } +} + +void UndoHistory::_handleDocumentReplaced(SPDesktop* desktop, SPDocument *document) +{ + if ((desktop != _desktop) || (document != _document)) { + _connectDocument(desktop, document); + } +} + +void *UndoHistory::_handleEventLogDestroyCB(void *data) +{ + void *result = NULL; + if (data) { + UndoHistory *self = reinterpret_cast<UndoHistory*>(data); + result = self->_handleEventLogDestroy(); + } + return result; +} + +// called *after* _event_log has been destroyed. +void *UndoHistory::_handleEventLogDestroy() +{ + if (_event_log) { + SignalBlocker blocker(&_callback_connections[EventLog::CALLB_SELECTION_CHANGE]); + + _event_list_view.unset_model(); + _event_list_store.reset(); + _event_log = NULL; + } + + return NULL; +} + void UndoHistory::_onListSelectionChange() { diff --git a/src/ui/dialog/undo-history.h b/src/ui/dialog/undo-history.h index adf4f1936..b0cc283cf 100644 --- a/src/ui/dialog/undo-history.h +++ b/src/ui/dialog/undo-history.h @@ -3,8 +3,9 @@ */ /* Author: * Gustav Broberg <broberg@kth.se> + * Jon A. Cruz <jon@joncruz.org> * - * Copyright (C) 2006 Authors + * Copyright (C) 2014 Authors * Released under GNU GPL. Read the file 'COPYING' for more information. */ @@ -134,6 +135,7 @@ public: protected: + SPDesktop *_desktop; SPDocument *_document; EventLog *_event_log; @@ -146,12 +148,17 @@ protected: Gtk::TreeView _event_list_view; Glib::RefPtr<Gtk::TreeSelection> _event_list_selection; - SPDesktop *_desktop; DesktopTracker _deskTrack; sigc::connection _desktopChangeConn; EventLog::CallbackMap _callback_connections; + static void *_handleEventLogDestroyCB(void *data); + + void _connectDocument(SPDesktop* desktop, SPDocument *document); + void _connectEventLog(); + void _handleDocumentReplaced(SPDesktop* desktop, SPDocument *document); + void *_handleEventLogDestroy(); void _onListSelectionChange(); void _onExpandEvent(const Gtk::TreeModel::iterator &iter, const Gtk::TreeModel::Path &path); void _onCollapseEvent(const Gtk::TreeModel::iterator &iter, const Gtk::TreeModel::Path &path); diff --git a/src/ui/dialog/xml-tree.cpp b/src/ui/dialog/xml-tree.cpp index 0e1e9f7a6..55d0aff09 100644 --- a/src/ui/dialog/xml-tree.cpp +++ b/src/ui/dialog/xml-tree.cpp @@ -100,6 +100,9 @@ XmlTree::XmlTree (void) : status.set_alignment( 0.0, 0.5); status.set_size_request(1, -1); status.set_markup(""); +#if WITH_GTKMM_3_0 + status.set_line_wrap(true); +#endif status_box.pack_start( status, TRUE, TRUE, 0); contents->pack_end(status_box, false, false, 2); |
