diff options
| author | Krzysztof Kosi??ski <tweenk.pl@gmail.com> | 2011-04-07 23:42:04 +0000 |
|---|---|---|
| committer | Krzysztof Kosiński <tweenk.pl@gmail.com> | 2011-04-07 23:42:04 +0000 |
| commit | 945ce419c806c73d70203dec33ececafbe108a92 (patch) | |
| tree | cfcdb59bf47e9db7f9e01f7eebb59924bdeaea94 /src/ui | |
| parent | Merge from trunk (again) (diff) | |
| parent | Extensions. SVG+media fix (see Bug #400356). (diff) | |
| download | inkscape-945ce419c806c73d70203dec33ececafbe108a92.tar.gz inkscape-945ce419c806c73d70203dec33ececafbe108a92.zip | |
Merge from trunk
(bzr r9508.1.73)
Diffstat (limited to 'src/ui')
64 files changed, 1467 insertions, 959 deletions
diff --git a/src/ui/cache/svg_preview_cache.cpp b/src/ui/cache/svg_preview_cache.cpp index 5a03366fc..fd7070bab 100644 --- a/src/ui/cache/svg_preview_cache.cpp +++ b/src/ui/cache/svg_preview_cache.cpp @@ -35,7 +35,7 @@ GdkPixbuf* render_pixbuf(NRArenaItem* root, double scale_factor, const Geom::Rect& dbox, unsigned psize) { NRGC gc(NULL); - Geom::Matrix t(Geom::Scale(scale_factor, scale_factor)); + Geom::Affine t(Geom::Scale(scale_factor, scale_factor)); nr_arena_item_set_transform(root, t); gc.transform.setIdentity(); diff --git a/src/ui/clipboard.cpp b/src/ui/clipboard.cpp index d405afb8f..4f4f8a022 100644 --- a/src/ui/clipboard.cpp +++ b/src/ui/clipboard.cpp @@ -82,6 +82,7 @@ #include "svg/svg-color.h" #include "sp-namedview.h" #include "snap.h" +#include "persp3d.h" /// @brief Made up mimetype to represent Gdk::Pixbuf clipboard contents #define CLIPBOARD_GDK_PIXBUF_TARGET "image/x-gdk-pixbuf" @@ -602,7 +603,7 @@ void ClipboardManagerImpl::_copySelection(Inkscape::Selection *selection) if (!SP_IS_ITEM(i->data)) { continue; } - Inkscape::XML::Node *obj = SP_OBJECT_REPR(i->data); + Inkscape::XML::Node *obj = reinterpret_cast<SPObject *>(i->data)->getRepr(); Inkscape::XML::Node *obj_copy = _copyNode(obj, _doc, _root); // copy complete inherited style @@ -628,7 +629,7 @@ void ClipboardManagerImpl::_copySelection(Inkscape::Selection *selection) // copy path effect from the first path if (SP_IS_OBJECT(sorted_items->data)) { - gchar const *effect = SP_OBJECT_REPR(sorted_items->data)->attribute("inkscape:path-effect"); + gchar const *effect = reinterpret_cast<SPObject *>(sorted_items->data)->getRepr()->attribute("inkscape:path-effect"); if (effect) { _clipnode->setAttribute("inkscape:path-effect", effect); } @@ -677,7 +678,7 @@ void ClipboardManagerImpl::_copyUsedDefs(SPItem *item) SPShape *shape = SP_SHAPE (item); for (int i = 0 ; i < SP_MARKER_LOC_QTY ; i++) { if (shape->marker[i]) { - _copyNode(SP_OBJECT_REPR(SP_OBJECT(shape->marker[i])), _doc, _defs); + _copyNode(shape->marker[i]->getRepr(), _doc, _defs); } } } @@ -689,14 +690,14 @@ void ClipboardManagerImpl::_copyUsedDefs(SPItem *item) { LivePathEffectObject *lpeobj = (*it)->lpeobject; if (lpeobj) { - _copyNode(SP_OBJECT_REPR(SP_OBJECT(lpeobj)), _doc, _defs); + _copyNode(lpeobj->getRepr(), _doc, _defs); } } } } // For 3D boxes, copy perspectives if (SP_IS_BOX3D(item)) { - _copyNode(SP_OBJECT_REPR(SP_OBJECT(box3d_get_perspective(SP_BOX3D(item)))), _doc, _defs); + _copyNode(box3d_get_perspective(SP_BOX3D(item))->getRepr(), _doc, _defs); } // Copy text paths if (SP_IS_TEXT_TEXTPATH(item)) { @@ -704,14 +705,14 @@ void ClipboardManagerImpl::_copyUsedDefs(SPItem *item) } // Copy clipping objects if (item->clip_ref->getObject()) { - _copyNode(SP_OBJECT_REPR(item->clip_ref->getObject()), _doc, _defs); + _copyNode(item->clip_ref->getObject()->getRepr(), _doc, _defs); } // Copy mask objects if (item->mask_ref->getObject()) { SPObject *mask = item->mask_ref->getObject(); - _copyNode(SP_OBJECT_REPR(mask), _doc, _defs); + _copyNode(mask->getRepr(), _doc, _defs); // recurse into the mask for its gradients etc. - for (SPObject *o = SP_OBJECT(mask)->children ; o != NULL ; o = o->next) { + for (SPObject *o = mask->children ; o != NULL ; o = o->next) { if (SP_IS_ITEM(o)) { _copyUsedDefs(SP_ITEM(o)); } @@ -721,12 +722,12 @@ void ClipboardManagerImpl::_copyUsedDefs(SPItem *item) if (style->getFilter()) { SPObject *filter = style->getFilter(); if (SP_IS_FILTER(filter)) { - _copyNode(SP_OBJECT_REPR(filter), _doc, _defs); + _copyNode(filter->getRepr(), _doc, _defs); } } // recurse - for (SPObject *o = SP_OBJECT(item)->children ; o != NULL ; o = o->next) { + for (SPObject *o = item->children ; o != NULL ; o = o->next) { if (SP_IS_ITEM(o)) { _copyUsedDefs(SP_ITEM(o)); } @@ -741,7 +742,7 @@ void ClipboardManagerImpl::_copyGradient(SPGradient *gradient) { while (gradient) { // climb up the refs, copying each one in the chain - _copyNode(SP_OBJECT_REPR(gradient), _doc, _defs); + _copyNode(gradient->getRepr(), _doc, _defs); gradient = gradient->ref->getObject(); } } @@ -754,7 +755,7 @@ void ClipboardManagerImpl::_copyPattern(SPPattern *pattern) { // climb up the references, copying each one in the chain while (pattern) { - _copyNode(SP_OBJECT_REPR(pattern), _doc, _defs); + _copyNode(pattern->getRepr(), _doc, _defs); // items in the pattern may also use gradients and other patterns, so recurse for ( SPObject *child = pattern->firstChild() ; child ; child = child->getNext() ) { @@ -777,7 +778,7 @@ void ClipboardManagerImpl::_copyTextPath(SPTextPath *tp) if (!path) { return; } - Inkscape::XML::Node *path_node = SP_OBJECT_REPR(path); + Inkscape::XML::Node *path_node = path->getRepr(); // Do not copy the text path to defs if it's already copied if (sp_repr_lookup_child(_root, "id", path_node->attribute("id"))) { @@ -813,7 +814,7 @@ void ClipboardManagerImpl::_pasteDocument(SPDesktop *desktop, SPDocument *clipdo { SPDocument *target_document = sp_desktop_document(desktop); Inkscape::XML::Node *root = clipdoc->getReprRoot(); - Inkscape::XML::Node *target_parent = SP_OBJECT_REPR(desktop->currentLayer()); + Inkscape::XML::Node *target_parent = desktop->currentLayer()->getRepr(); Inkscape::XML::Document *target_xmldoc = target_document->getReprDoc(); // copy definitions @@ -844,7 +845,7 @@ void ClipboardManagerImpl::_pasteDocument(SPDesktop *desktop, SPDocument *clipdo selection->setReprList(pasted_objects); // invers apply parent transform - Geom::Matrix doc2parent = SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse(); + Geom::Affine doc2parent = SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse(); sp_selection_apply_affine(selection, desktop->dt2doc() * doc2parent * desktop->doc2dt(), true, false); // Update (among other things) all curves in paths, for bounds() to work @@ -893,7 +894,7 @@ void ClipboardManagerImpl::_pasteDefs(SPDesktop *desktop, SPDocument *clipdoc) SPDocument *target_document = sp_desktop_document(desktop); Inkscape::XML::Node *root = clipdoc->getReprRoot(); Inkscape::XML::Node *defs = sp_repr_lookup_name(root, "svg:defs", 1); - Inkscape::XML::Node *target_defs = SP_OBJECT_REPR(SP_DOCUMENT_DEFS(target_document)); + Inkscape::XML::Node *target_defs = SP_DOCUMENT_DEFS(target_document)->getRepr(); Inkscape::XML::Document *target_xmldoc = target_document->getReprDoc(); prevent_id_clashes(clipdoc, target_document); @@ -1253,7 +1254,7 @@ void ClipboardManagerImpl::_createInternalClipboard() if ( _clipboardSPDoc == NULL ) { _clipboardSPDoc = SPDocument::createNewDoc(NULL, false, true); //g_assert( _clipboardSPDoc != NULL ); - _defs = SP_OBJECT_REPR(SP_DOCUMENT_DEFS(_clipboardSPDoc)); + _defs = SP_DOCUMENT_DEFS(_clipboardSPDoc)->getRepr(); _doc = _clipboardSPDoc->getReprDoc(); _root = _clipboardSPDoc->getReprRoot(); diff --git a/src/ui/context-menu.cpp b/src/ui/context-menu.cpp index c544d1999..05fe9a459 100644 --- a/src/ui/context-menu.cpp +++ b/src/ui/context-menu.cpp @@ -278,20 +278,20 @@ sp_item_create_link(GtkMenuItem *menuitem, SPItem *item) Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc(); Inkscape::XML::Node *repr = xml_doc->createElement("svg:a"); - SP_OBJECT_REPR(SP_OBJECT_PARENT(item))->addChild(repr, SP_OBJECT_REPR(item)); - SPObject *object = SP_OBJECT_DOCUMENT(item)->getObjectByRepr(repr); + item->parent->getRepr()->addChild(repr, item->getRepr()); + SPObject *object = item->document->getObjectByRepr(repr); g_return_if_fail(SP_IS_ANCHOR(object)); - const char *id = SP_OBJECT_REPR(item)->attribute("id"); - Inkscape::XML::Node *child = SP_OBJECT_REPR(item)->duplicate(xml_doc); - SP_OBJECT(item)->deleteObject(false); + const char *id = item->getRepr()->attribute("id"); + Inkscape::XML::Node *child = item->getRepr()->duplicate(xml_doc); + item->deleteObject(false); repr->addChild(child, NULL); child->setAttribute("id", id); Inkscape::GC::release(repr); Inkscape::GC::release(child); - DocumentUndo::done(SP_OBJECT_DOCUMENT(object), SP_VERB_NONE, + DocumentUndo::done(object->document, SP_VERB_NONE, _("Create link")); sp_object_attributes_dialog(object, "SPAnchor"); @@ -371,7 +371,7 @@ sp_anchor_menu(SPObject *object, SPDesktop *desktop, GtkMenu *m) static void sp_anchor_link_properties(GtkMenuItem */*menuitem*/, SPAnchor *anchor) { - sp_object_attributes_dialog(SP_OBJECT(anchor), "Link"); + sp_object_attributes_dialog(anchor, "Link"); } static void @@ -420,7 +420,7 @@ sp_image_menu(SPObject *object, SPDesktop *desktop, GtkMenu *m) gtk_signal_connect(GTK_OBJECT(w), "activate", GTK_SIGNAL_FUNC(sp_image_image_edit), item); gtk_widget_show(w); gtk_menu_append(GTK_MENU(m), w); - Inkscape::XML::Node *ir = SP_OBJECT_REPR(object); + Inkscape::XML::Node *ir = object->getRepr(); const gchar *href = ir->attribute("xlink:href"); if ( (!href) || ((strncmp(href, "data:", 5) == 0)) ) { gtk_widget_set_sensitive( w, FALSE ); @@ -430,23 +430,16 @@ sp_image_menu(SPObject *object, SPDesktop *desktop, GtkMenu *m) static void sp_image_image_properties(GtkMenuItem */*menuitem*/, SPAnchor *anchor) { - sp_object_attributes_dialog(SP_OBJECT(anchor), "Image"); + sp_object_attributes_dialog(anchor, "Image"); } static gchar* getImageEditorName() { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); gchar* value = 0; - Glib::ustring choices = prefs->getString("/options/bitmapeditor/choices"); + Glib::ustring choices = prefs->getString("/options/bitmapeditor/value"); if (!choices.empty()) { - gchar** splits = g_strsplit(choices.data(), ",", 0); - gint numIems = g_strv_length(splits); - - int setting = prefs->getIntLimited("/options/bitmapeditor/value", 0, 0, numIems); - value = g_strdup(splits[setting]); - - g_strfreev(splits); + value = g_strdup(choices.c_str()); } - if (!value) { value = g_strdup("gimp"); } @@ -455,21 +448,51 @@ static gchar* getImageEditorName() { static void sp_image_image_edit(GtkMenuItem *menuitem, SPAnchor *anchor) { - SPObject* obj = SP_OBJECT(anchor); - Inkscape::XML::Node *ir = SP_OBJECT_REPR(obj); + SPObject* obj = anchor; + Inkscape::XML::Node *ir = obj->getRepr(); const gchar *href = ir->attribute("xlink:href"); GError* errThing = 0; - gchar* editorBin = getImageEditorName(); - gchar const* args[] = {editorBin, href, 0}; - g_spawn_async(0, // working dir - const_cast<gchar **>(args), - 0, //envp - G_SPAWN_SEARCH_PATH, - 0, // child_setup - 0, // user_data - 0, //GPid *child_pid - &errThing); + Glib::ustring cmdline = getImageEditorName(); + Glib::ustring fullname; + +#ifdef WIN32 + // g_spawn_command_line_sync parsing is done according to Unix shell rules, + // not Windows command interpreter rules. Thus we need to enclose the + // executable path with sigle quotes. + int index = cmdline.find(".exe"); + if ( index < 0 ) index = cmdline.find(".bat"); + if ( index < 0 ) index = cmdline.find(".com"); + if ( index >= 0 ) { + Glib::ustring editorBin = cmdline.substr(0, index + 4).c_str(); + Glib::ustring args = cmdline.substr(index + 4, cmdline.length()).c_str(); + editorBin.insert(0, "'"); + editorBin.append("'"); + cmdline = editorBin; + cmdline.append(args); + } else { + // Enclose the whole command line if no executable path can be extracted. + cmdline.insert(0, "'"); + cmdline.append("'"); + } +#endif + + if (strncmp (href,"file:",5) == 0) { + // URI to filename conversion + fullname = g_filename_from_uri(href, NULL, NULL); + } else { + fullname.append(href); + } + + cmdline.append(" '"); + cmdline.append(fullname.c_str()); + cmdline.append("'"); + + //printf("##Command line: %s\n", cmdline.c_str()); + + g_spawn_command_line_async(cmdline.c_str(), + &errThing); + if ( errThing ) { g_warning("Problem launching editor (%d). %s", errThing->code, errThing->message); SPDesktop *desktop = (SPDesktop*)gtk_object_get_data(GTK_OBJECT(menuitem), "desktop"); @@ -477,7 +500,6 @@ static void sp_image_image_edit(GtkMenuItem *menuitem, SPAnchor *anchor) g_error_free(errThing); errThing = 0; } - g_free(editorBin); } /* Fill and Stroke entry */ diff --git a/src/ui/dialog/aboutbox.cpp b/src/ui/dialog/aboutbox.cpp index 8db5e7c0b..d1bc255b0 100644 --- a/src/ui/dialog/aboutbox.cpp +++ b/src/ui/dialog/aboutbox.cpp @@ -104,10 +104,11 @@ AboutBox::AboutBox() : Gtk::Dialog(_("About Inkscape")) { Gtk::Label *label=new Gtk::Label(); gchar *label_text = - g_strdup_printf("<small><i>Inkscape %s</i></small>", + g_strdup_printf("<small>Inkscape %s</small>", Inkscape::version_string); label->set_markup(label_text); label->set_alignment(Gtk::ALIGN_RIGHT, Gtk::ALIGN_CENTER); + label->set_padding(5,0); g_free(label_text); label->set_selectable(true); label->show(); @@ -165,7 +166,7 @@ Gtk::Widget *build_splash_widget() { doc->doUnref(); - sp_svg_view_widget_set_resize(SP_SVG_VIEW_WIDGET(v), FALSE, (int)width, (int)height); + SP_SVG_VIEW_WIDGET(v)->setResize(false, static_cast<int>(width), static_cast<int>(height)); Gtk::AspectFrame *frame=new Gtk::AspectFrame(); frame->unset_label(); @@ -225,152 +226,155 @@ void AboutBox::initStrings() { * and paste the result from the combo box here. */ authors_text = - "Maximilian Albert\n" - "Josh Andler\n" - "Tavmjong Bah\n" - "Pierre Barbry-Blot\n" - "Jean-François Barraud\n" - "Bill Baxter\n" - "John Beard\n" - "John Bintz\n" - "Arpad Biro\n" - "Nicholas Bishop\n" - "Joshua L. Blocher\n" - "Henrik Bohre\n" - "Boldewyn\n" - "Daniel Borgmann\n" - "Bastien Bouclet\n" - "Hans Breuer\n" - "Gustav Broberg\n" - "Christopher Brown\n" - "Marcus Brubaker\n" - "Luca Bruno\n" - "Nicu Buculei\n" - "Bulia Byak\n" - "Pierre Caclin\n" - "Ian Caldwell\n" - "Gail Carmichael\n" - "Ed Catmur\n" - "Chema Celorio\n" - "Johan Ceuppens\n" - "Zbigniew Chyla\n" - "Alexander Clausen\n" - "John Cliff\n" - "Kees Cook\n" - "Ben Cromwell\n" - "Robert Crosbie\n" - "Jon Cruz\n" - "Aurélie De-Cooman\n" - "Milosz Derezynski\n" - "Daniel Díaz\n" - "Bruno Dilly\n" - "Larry Doolittle\n" - "Tim Dwyer\n" - "Maxim V. Dziumanenko\n" - "Johan Engelen\n" - "Miklos Erdelyi\n" - "Ulf Erikson\n" - "Noé Falzon\n" - "Frank Felfe\n" - "Andrew Fitzsimon\n" - "Edward Flick\n" - "Marcin Floryan\n" - "Ben Fowler\n" - "Fred\n" - "Cedric Gemy\n" - "Steren Giannini\n" - "Olivier Gondouin\n" - "Ted Gould\n" - "Toine de Greef\n" - "Michael Grosberg\n" - "Bryce Harrington\n" - "Dale Harvey\n" - "Aurélio A. Heckert\n" - "Carl Hetherington\n" - "Jos Hirth\n" - "Hannes Hochreiner\n" - "Thomas Holder\n" - "Joel Holdsworth\n" - "Alan Horkan\n" - "Karl Ove Hufthammer\n" - "Richard Hughes\n" - "Nathan Hurst\n" - "inductiveload\n" - "Thomas Ingham\n" - "Jean-Olivier Irisson\n" - "Bob Jamison\n" - "jEsuSdA\n" - "Lauris Kaplinski\n" - "Lynn Kerby\n" - "Niko Kiirala\n" - "James Kilfiger\n" - "Jason Kivlighn\n" - "Adrian Knoth\n" - "Krzysztof Kosiński\n" - "Petr Kovar\n" - "Benoît Lavorata\n" - "Alex Leone\n" - "Julien Leray\n" - "Raph Levien\n" - "Diederik van Lierop\n" - "Nicklas Lindgren\n" - "Vitaly Lipatov\n" - "Ivan Louette\n" - "Pierre-Antoine Marc\n" - "Aurel-Aimé Marmion\n" - "Colin Marquardt\n" - "Dmitry G. Mastrukov\n" - "Matiphas\n" - "Michael Meeks\n" - "Federico Mena\n" - "MenTaLguY\n" - "Aubanel Monnier\n" - "Vincent Montagne\n" - "Tim Mooney\n" - "Derek P. Moore\n" - "Peter Moulder\n" - "Jörg Müller\n" - "Yukihiro Nakai\n" - "Victor Navez\n" - "Christian Neumair\n" - "Andreas Nilsson\n" - "Mitsuru Oka\n" - "Marten Owens\n" - "Alvin Penner\n" - "Jon Phillips\n" - "Zdenko Podobny\n" - "Alexandre Prokoudine\n" - "Jean-René Reinhard\n" - "Alexey Remizov\n" - "Frederic Rodrigo\n" - "Hugo Rodrigues\n" - "Juarez Rudsatz\n" - "Xavier Conde Rueda\n" - "Felipe Corrêa da Silva Sanches\n" - "Christian Schaller\n" - "Marco Scholten\n" - "Tom von Schwerdtner\n" - "Danilo Šegan\n" - "Shivaken\n" - "Michael Sloan\n" - "Boštjan Špetič\n" - "Aaron Spike\n" - "Kaushik Sridharan\n" - "Ralf Stephan\n" - "Dariusz Stojek\n" - "Martin Sucha\n" - "Pat Suwalski\n" - "Adib Taraben\n" - "Hugh Tebby\n" - "Jonas Termeau\n" - "David Turner\n" - "Andre Twupack\n" - "Aleksandar Urošević\n" - "Lucas Vieites\n" - "Michael Wybrow\n" - "Daniel Yacob\n" - "Masatake Yamato\n" - "David Yip"; +"Maximilian Albert\n" +"Josh Andler\n" +"Tavmjong Bah\n" +"Pierre Barbry-Blot\n" +"Jean-François Barraud\n" +"Bill Baxter\n" +"John Beard\n" +"John Bintz\n" +"Arpad Biro\n" +"Nicholas Bishop\n" +"Joshua L. Blocher\n" +"Henrik Bohre\n" +"Boldewyn\n" +"Daniel Borgmann\n" +"Bastien Bouclet\n" +"Hans Breuer\n" +"Gustav Broberg\n" +"Christopher Brown\n" +"Marcus Brubaker\n" +"Luca Bruno\n" +"Nicu Buculei\n" +"Bulia Byak\n" +"Pierre Caclin\n" +"Ian Caldwell\n" +"Gail Carmichael\n" +"Ed Catmur\n" +"Chema Celorio\n" +"Johan Ceuppens\n" +"Zbigniew Chyla\n" +"Alexander Clausen\n" +"John Cliff\n" +"Kees Cook\n" +"Ben Cromwell\n" +"Robert Crosbie\n" +"Jon Cruz\n" +"Aurélie De-Cooman\n" +"Milosz Derezynski\n" +"Daniel Díaz\n" +"Bruno Dilly\n" +"Larry Doolittle\n" +"Nicolas Dufour\n" +"Tim Dwyer\n" +"Maxim V. Dziumanenko\n" +"Johan Engelen\n" +"Miklos Erdelyi\n" +"Ulf Erikson\n" +"Noé Falzon\n" +"Frank Felfe\n" +"Andrew Fitzsimon\n" +"Edward Flick\n" +"Marcin Floryan\n" +"Ben Fowler\n" +"Fred\n" +"Cedric Gemy\n" +"Steren Giannini\n" +"Olivier Gondouin\n" +"Ted Gould\n" +"Toine de Greef\n" +"Michael Grosberg\n" +"Bryce Harrington\n" +"Dale Harvey\n" +"Aurélio Adnauer Heckert\n" +"Carl Hetherington\n" +"Jos Hirth\n" +"Hannes Hochreiner\n" +"Thomas Holder\n" +"Joel Holdsworth\n" +"Alan Horkan\n" +"Karl Ove Hufthammer\n" +"Richard Hughes\n" +"Nathan Hurst\n" +"inductiveload\n" +"Thomas Ingham\n" +"Jean-Olivier Irisson\n" +"Bob Jamison\n" +"jEsuSdA\n" +"Lauris Kaplinski\n" +"Lynn Kerby\n" +"Niko Kiirala\n" +"James Kilfiger\n" +"Jason Kivlighn\n" +"Adrian Knoth\n" +"Krzysztof Kosiński\n" +"Petr Kovar\n" +"Benoît Lavorata\n" +"Alex Leone\n" +"Julien Leray\n" +"Raph Levien\n" +"Diederik van Lierop\n" +"Nicklas Lindgren\n" +"Vitaly Lipatov\n" +"Ivan Louette\n" +"Pierre-Antoine Marc\n" +"Aurel-Aimé Marmion\n" +"Colin Marquardt\n" +"Craig Marshall\n" +"Dmitry G. Mastrukov\n" +"Matiphas\n" +"Michael Meeks\n" +"Federico Mena\n" +"MenTaLguY\n" +"Aubanel Monnier\n" +"Vincent Montagne\n" +"Tim Mooney\n" +"Derek P. Moore\n" +"Peter Moulder\n" +"Jörg Müller\n" +"Yukihiro Nakai\n" +"Victor Navez\n" +"Christian Neumair\n" +"Andreas Nilsson\n" +"Mitsuru Oka\n" +"Marten Owens\n" +"Alvin Penner\n" +"Jon Phillips\n" +"Zdenko Podobny\n" +"Alexandre Prokoudine\n" +"Jean-René Reinhard\n" +"Alexey Remizov\n" +"Frederic Rodrigo\n" +"Hugo Rodrigues\n" +"Juarez Rudsatz\n" +"Xavier Conde Rueda\n" +"Felipe Corrêa da Silva Sanches\n" +"Christian Schaller\n" +"Marco Scholten\n" +"Tom von Schwerdtner\n" +"Danilo Šegan\n" +"Abhishek Sharma\n" +"Shivaken\n" +"Michael Sloan\n" +"Boštjan Špetič\n" +"Aaron Spike\n" +"Kaushik Sridharan\n" +"Ralf Stephan\n" +"Dariusz Stojek\n" +"Martin Sucha\n" +"Pat Suwalski\n" +"Adib Taraben\n" +"Hugh Tebby\n" +"Jonas Termeau\n" +"David Turner\n" +"Andre Twupack\n" +"Aleksandar Urošević\n" +"Lucas Vieites\n" +"Michael Wybrow\n" +"Daniel Yacob\n" +"Masatake Yamato\n" +"David Yip"; //############################## //# T R A N S L A T O R S @@ -409,133 +413,136 @@ void AboutBox::initStrings() { * and paste the result from the combo box here. */ gchar const *allTranslators = - "3ARRANO.com <3arrano@3arrano.com>, 2005.\n" - "Adib Taraben <theadib@googlemail.com>, 2004.\n" - "Alan Monfort <alan.monfort@free.fr>, 2009-2010.\n" - "Alastair McKinstry <mckinstry@computer.org>, 2000.\n" - "Aleksandar Urošević <urke@users.sourceforge.net>, 2004, 2005, 2006.\n" - "Alessio Frusciante <algol@firenze.linux.it>, 2002, 2003.\n" - "Alexander Shopov <ash@contact.bg>, 2006.\n" - "Alexandre Prokoudine <alexandre.prokoudine@gmail.com>, 2005.\n" - "Alexey Remizov <alexey@remizov.pp.ru>, 2004.\n" - "Ali Ghanavatian <ghanvatian.ali@gmail.com>, 2010.\n" - "Álvaro Lopes <alvieboy@alvie.com>, 2001, 2002.\n" - "Andreas Hyden <a.hyden@cyberpoint.se>, 2000.\n" - "Andrius Ramanauskas <knutux@gmail.com>, 2006.\n" - "Antonio Codazzi <f_sophia@libero.it>, 2006, 2007.\n" - "Antônio Cláudio (LedStyle) <ledstyle@gmail.com>, 2006.\n" - "Amanpreet Singh Brar Alamwalia <apbrar@gmail.com>, 2005.\n" - "Arman Aksoy <armish@linux-sevenler.de>, 2003.\n" - "Arpad Biro <biro_arpad@yahoo.com>, 2004, 2005.\n" - "Benedikt Roth <Benedikt.Roth@gmx.net>, 2000.\n" - "Benno Schulenberg <benno@vertaalt.nl>, 2008.\n" - "Boštjan Špetič <igzebedze@cyberpipe.org>, 2004, 2005.\n" - "Brisa Francesco <fbrisa@yahoo.it>, 2000.\n" - "bulia byak <buliabyak@users.sf.net>, 2004.\n" - "Chris jia <Chrisjiasl@gmail.com>, 2006.\n" - "Christian Meyer <chrisime@gnome.org>, 2000-2002.\n" - "Christian Neumair <chris@gnome-de.org>, 2002, 2003.\n" - "Christian Rose <menthos@menthos.com>, 2000, 2001, 2002, 2003.\n" - "Cristian Secară <cristi@secarica.ro>, 2010.\n" - "Christophe Merlet (RedFox) <redfox@redfoxcenter.org>, 2000-2002.\n" - "Clytie Siddall <clytie@riverland.net.au>, 2004-2008.\n" - "Colin Marquardt <colin@marquardt-home.de>, 2004-2006.\n" - "Cédric Gemy <radar.map35@free.fr>, 2006.\n" - "Daniel Díaz <yosoy@danieldiaz.org>, 2004.\n" - "Didier Conchaudron <conchaudron@free.fr>, 2003.\n" - "Dorji Tashi <dorjee_doss@hotmail.com>, 2006.\n" - "Duarte Loreto <happyguy_pt@hotmail.com> 2002, 2003 (Maintainer).\n" - "Equipe de Tradução Inkscape Brasil <www.inkscapebrasil.org>, 2007.\n" - "Fatih Demir <kabalak@gtranslator.org>, 2000.\n" - "Foppe Benedictus <foppe.benedictus@gmail.com>, 2007-2009.\n" - "Francesc Dorca <f.dorca@filnet.es>, 2003. Traducció sodipodi.\n" - "Francisco Javier F. Serrador <serrador@arrakis.es>, 2003.\n" - "Francisco Xosé Vázquez Grandal <fxvazquez@arrakis.es>, 2001.\n" - "Frederic Rodrigo <f.rodrigo free.fr>, 2004-2005.\n" - "Ge'ez Frontier Foundation <locales@geez.org>, 2002.\n" - "Hleb Valoshka <375gnu@gmail.com>, 2008-2009.\n" - "Hizkuntza Politikarako Sailburuordetza <hizkpol@ej-gv.es>, 2005.\n" - "Ilia Penev <lichopicho@gmail.com>, 2006.\n" - "Ivan Masár <helix84@centrum.sk>, 2006, 2007, 2008, 2009, 2010. \n" - "Iñaki Larrañaga <dooteo@euskalgnu.org>, 2006.\n" - "Jeffrey Steve Borbón Sanabria <jeff_kerokid@yahoo.com>, 2005.\n" - "Joaquim Perez i Noguer <noguer@gmail.com>, 2008-2009.\n" - "Jörg Müller <jfm@ram-brand.de>, 2005.\n" - "Jeroen van der Vegt <jvdvegt@gmail.com>, 2003, 2005, 2008.\n" - "Jin-Hwan Jeong <yongdoria@gmail.com>, 2009.\n" - "Jonathan Ernst <jernst@users.sourceforge.net>, 2006.\n" - "Jose Antonio Salgueiro Aquino <developer@telefonica.net>, 2003.\n" - "Josef Vybiral <josef.vybiral@gmail.com>, 2005-2006.\n" - "Juarez Rudsatz <juarez@correio.com>, 2004.\n" - "Junichi Uekawa <dancer@debian.org>, 2002.\n" - "Jurmey Rabgay <jur_gay@yahoo.com>, 2006.\n" - "Kai Lahmann <kailahmann@01019freenet.de>, 2000.\n" - "Karl Ove Hufthammer <karl@huftis.org>, 2004, 2005.\n" - "KATSURAGAWA Naoki <naopon@private.email.ne.jp>, 2006.\n" - "Keld Simonsen <keld@dkuug.dk>, 2000, 2001.\n" - "Kenji Inoue <kenz@oct.zaq.ne.jp>, 2006-2007.\n" - "Khandakar Mujahidul Islam <suzan@bengalinux.org>, 2006.\n" - "Kitae <bluetux@gmail.com>, 2006.\n" - "Kjartan Maraas <kmaraas@gnome.org>, 2000-2002.\n" - "Kris De Gussem <kris.DeGussem@gmail.com>, 2008-2010.\n" - "Lauris Kaplinski <lauris@ariman.ee>, 2000.\n" - "Leandro Regueiro <leandro.regueiro@gmail.com>, 2006-2008,2010.\n" - "Liu Xiaoqin <liuxqsmile@gmail.com>, 2008.\n" - "Luca Bruno <luca.br@uno.it>, 2005.\n" - "Lucas Vieites Fariña<lucas@codexion.com>, 2003-2010.\n" - "Mahesh subedi <submanesh@hotmail.com>, 2006.\n" - "Martin Srebotnjak, <miles@filmsi.net>, 2005, 2010.\n" - "Masatake YAMATO <jet@gyve.org>, 2002.\n" - "Masato Hashimoto <cabezon.hashimoto@gmail.com>, 2009-2010.\n" - "Matiphas <matiphas _a_ free _point_ fr>, 2004-2006.\n" - "Mattias Hultgren <mattias_hultgren@tele2.se>, 2005.\n" - "Maxim Dziumanenko <mvd@mylinux.com.ua>, 2004.\n" - "Mətin Əmirov <metin@karegen.com>, 2003.\n" - "Mitsuru Oka <oka326@parkcity.ne.jp>, 2002.\n" - "Morphix User <pchitrakar@gmail.com>, 2006.\n" - "Mufit Eribol <meribol@ere.com.tr>, 2000.\n" - "Muhammad Bashir Al-Noimi <mhdbnoimi@gmail.com>, 2008.\n" - "Myckel Habets <myckel@sdf.lonestar.org>, 2008.\n" - "Nguyen Dinh Trung <nguyendinhtrung141@gmail.com>, 2007, 2008.\n" - "Nicolas Dufour <nicoduf@yahoo.fr>, 2008-2010.\n" - "Pawan Chitrakar <pchitrakar@gmail.com>, 2006.\n" - "Przemysław Loesch <p_loesch@poczta.onet.pl>, 2005.\n" - "Quico Llach <quico@softcatala.org>, 2000. Traducció sodipodi.\n" - "Raymond Ostertag <raymond@linuxgraphic.org>, 2002, 2003.\n" - "Riku Leino <tsoots@gmail.com>, 2006.\n" - "Rune Rønde Laursen <runerl@skjoldhoej.dk>, 2006.\n" - "Ruud Steltenpool <svg@steltenpower.com>, 2006.\n" - "Serdar Soytetir <sendirom@gmail.com>, 2005.\n" - "shivaken <shivaken@owls-nest.net>, 2004.\n" - "Shyam Krishna Bal <shyamkrishna_bal@yahoo.com>, 2006.\n" - "Simos Xenitellis <simos@hellug.gr>, 2001.\n" - "Spyros Blanas <cid_e@users.sourceforge.net>, 2006.\n" - "Stefan Graubner <pflaumenmus92@gmx.net>, 2005.\n" - "Supranee Thirawatthanasuk <supranee@opentle.org>, 2006.\n" - "Takeshi Aihana <aihana@muc.biglobe.ne.jp>, 2000, 2001.\n" - "Tim Sheridan <tim.sheridan@gmail.com>, 2007-2010.\n" - "Theppitak Karoonboonyanan <thep@linux.thai.net>, 2006.\n" - "Thiago Pimentel <thiago.merces@gmail.com>, 2006.\n" - "Toshifumi Sato <sato@centrosystem.com>, 2005.\n" - "Jon South <striker@lunar-linux.org>, 2006. \n" - "Uwe Schöler <oss@oss-marketplace.com>, 2006.\n" - "Valek Filippov <frob@df.ru>, 2000, 2003.\n" - "Victor Dachev <vdachev@gmail.com>, 2006.\n" - "Vincent van Adrighem <V.vanAdrighem@dirck.mine.nu>, 2003.\n" - "Vital Khilko <dojlid@mova.org>, 2003.\n" - "Vitaly Lipatov <lav@altlinux.ru>, 2002, 2004.\n" - "vonHalenbach <vonHalenbach@users.sourceforge.net>, 2005.\n" - "Wang Li <charlesw1234@163.com>, 2002.\n" - "Wei-Lun Chao <william.chao@ossii.com.tw>, 2006.\n" - "Wolfram Strempfer <wolfram@strempfer.de>, 2006.\n" - "Xavier Conde Rueda <xavi.conde@gmail.com>, 2004-2008.\n" - "Yaron Shahrabani <sh.yaron@gmail.com>, 2009.\n" - "Yukihiro Nakai <nakai@gnome.gr.jp>, 2000, 2003.\n" - "Yuri Beznos <zhiz0id@gmail.com>, 2006.\n" - "Yuri Chornoivan <yurchor@ukr.net>, 2007-2010.\n" - "Yuri Syrota <rasta@renome.rovno.ua>, 2000.\n" - "Yves Guillou <yvesguillou@users.sourceforge.net>, 2004.\n" - "Zdenko Podobný <zdpo@mailbox.sk>, 2003, 2004." +"3ARRANO.com <3arrano@3arrano.com>, 2005.\n" +"Adib Taraben <theadib@googlemail.com>, 2004.\n" +"Alan Monfort <alan.monfort@free.fr>, 2009-2010.\n" +"Alastair McKinstry <mckinstry@computer.org>, 2000.\n" +"Aleksandar Urošević <urke@users.sourceforge.net>, 2004-2006.\n" +"Alessio Frusciante <algol@firenze.linux.it>, 2002, 2003.\n" +"Alexander Shopov <ash@contact.bg>, 2006.\n" +"Alexandre Prokoudine <alexandre.prokoudine@gmail.com>, 2005.\n" +"Alexey Remizov <alexey@remizov.pp.ru>, 2004.\n" +"Ali Ghanavatian <ghanvatian.ali@gmail.com>, 2010.\n" +"Álvaro Lopes <alvieboy@alvie.com>, 2001, 2002.\n" +"Andreas Hyden <a.hyden@cyberpoint.se>, 2000.\n" +"Andrius Ramanauskas <knutux@gmail.com>, 2006.\n" +"Antonio Codazzi <f_sophia@libero.it>, 2006, 2007.\n" +"Antônio Cláudio (LedStyle) <ledstyle@gmail.com>, 2006.\n" +"Amanpreet Singh Brar Alamwalia <apbrar@gmail.com>, 2005.\n" +"Arman Aksoy <armish@linux-sevenler.de>, 2003.\n" +"Arpad Biro <biro_arpad@yahoo.com>, 2004, 2005.\n" +"Benedikt Roth <Benedikt.Roth@gmx.net>, 2000.\n" +"Benno Schulenberg <benno@vertaalt.nl>, 2008.\n" +"Boštjan Špetič <igzebedze@cyberpipe.org>, 2004, 2005.\n" +"Brisa Francesco <fbrisa@yahoo.it>, 2000.\n" +"bulia byak <buliabyak@users.sf.net>, 2004.\n" +"Chris jia <Chrisjiasl@gmail.com>, 2006.\n" +"Christian Meyer <chrisime@gnome.org>, 2000-2002.\n" +"Christian Neumair <chris@gnome-de.org>, 2002, 2003.\n" +"Christian Rose <menthos@menthos.com>, 2000-2003.\n" +"Cristian Secară <cristi@secarica.ro>, 2010.\n" +"Christophe Merlet (RedFox) <redfox@redfoxcenter.org>, 2000-2002.\n" +"Clytie Siddall <clytie@riverland.net.au>, 2004-2008.\n" +"Colin Marquardt <colin@marquardt-home.de>, 2004-2006.\n" +"Cédric Gemy <radar.map35@free.fr>, 2006.\n" +"Daniel Díaz <yosoy@danieldiaz.org>, 2004.\n" +"Didier Conchaudron <conchaudron@free.fr>, 2003.\n" +"Dorji Tashi <dorjee_doss@hotmail.com>, 2006.\n" +"Duarte Loreto <happyguy_pt@hotmail.com> 2002, 2003 (Maintainer).\n" +"Elias Norberg <elno0959 at student.su.se>, 2009.\n" +"Equipe de Tradução Inkscape Brasil <www.inkscapebrasil.org>, 2007.\n" +"Fatih Demir <kabalak@gtranslator.org>, 2000.\n" +"Foppe Benedictus <foppe.benedictus@gmail.com>, 2007-2009.\n" +"Francesc Dorca <f.dorca@filnet.es>, 2003. Traducció sodipodi.\n" +"Francisco Javier F. Serrador <serrador@arrakis.es>, 2003.\n" +"Francisco Xosé Vázquez Grandal <fxvazquez@arrakis.es>, 2001.\n" +"Frederic Rodrigo <f.rodrigo free.fr>, 2004-2005.\n" +"Ge'ez Frontier Foundation <locales@geez.org>, 2002.\n" +"George Boukeas <boukeas@gmail.com>, 2011.\n" +"Hleb Valoshka <375gnu@gmail.com>, 2008-2009.\n" +"Hizkuntza Politikarako Sailburuordetza <hizkpol@ej-gv.es>, 2005.\n" +"Ilia Penev <lichopicho@gmail.com>, 2006.\n" +"Ivan Masár <helix84@centrum.sk>, 2006, 2007, 2008, 2009, 2010. \n" +"Iñaki Larrañaga <dooteo@euskalgnu.org>, 2006.\n" +"Jeffrey Steve Borbón Sanabria <jeff_kerokid@yahoo.com>, 2005.\n" +"Jesper Öqvist <jesper@llbit.se>, 2010, 2011.\n" +"Joaquim Perez i Noguer <noguer@gmail.com>, 2008-2009.\n" +"Jörg Müller <jfm@ram-brand.de>, 2005.\n" +"Jeroen van der Vegt <jvdvegt@gmail.com>, 2003, 2005, 2008.\n" +"Jin-Hwan Jeong <yongdoria@gmail.com>, 2009.\n" +"Jonathan Ernst <jernst@users.sourceforge.net>, 2006.\n" +"Jose Antonio Salgueiro Aquino <developer@telefonica.net>, 2003.\n" +"Josef Vybiral <josef.vybiral@gmail.com>, 2005-2006.\n" +"Juarez Rudsatz <juarez@correio.com>, 2004.\n" +"Junichi Uekawa <dancer@debian.org>, 2002.\n" +"Jurmey Rabgay <jur_gay@yahoo.com>, 2006.\n" +"Kai Lahmann <kailahmann@01019freenet.de>, 2000.\n" +"Karl Ove Hufthammer <karl@huftis.org>, 2004, 2005.\n" +"KATSURAGAWA Naoki <naopon@private.email.ne.jp>, 2006.\n" +"Keld Simonsen <keld@dkuug.dk>, 2000, 2001.\n" +"Kenji Inoue <kenz@oct.zaq.ne.jp>, 2006-2007.\n" +"Khandakar Mujahidul Islam <suzan@bengalinux.org>, 2006.\n" +"Kitae <bluetux@gmail.com>, 2006.\n" +"Kjartan Maraas <kmaraas@gnome.org>, 2000-2002.\n" +"Kris De Gussem <kris.DeGussem@gmail.com>, 2008-2010.\n" +"Lauris Kaplinski <lauris@ariman.ee>, 2000.\n" +"Leandro Regueiro <leandro.regueiro@gmail.com>, 2006-2008, 2010.\n" +"Liu Xiaoqin <liuxqsmile@gmail.com>, 2008.\n" +"Luca Bruno <luca.br@uno.it>, 2005.\n" +"Lucas Vieites Fariña<lucas@codexion.com>, 2003-2010.\n" +"Mahesh subedi <submanesh@hotmail.com>, 2006.\n" +"Martin Srebotnjak, <miles@filmsi.net>, 2005, 2010.\n" +"Masatake YAMATO <jet@gyve.org>, 2002.\n" +"Masato Hashimoto <cabezon.hashimoto@gmail.com>, 2009-2011.\n" +"Matiphas <matiphas _a_ free _point_ fr>, 2004-2006.\n" +"Mattias Hultgren <mattias_hultgren@tele2.se>, 2005, 2006.\n" +"Maxim Dziumanenko <mvd@mylinux.com.ua>, 2004.\n" +"Mətin Əmirov <metin@karegen.com>, 2003.\n" +"Mitsuru Oka <oka326@parkcity.ne.jp>, 2002.\n" +"Morphix User <pchitrakar@gmail.com>, 2006.\n" +"Mufit Eribol <meribol@ere.com.tr>, 2000.\n" +"Muhammad Bashir Al-Noimi <mhdbnoimi@gmail.com>, 2008.\n" +"Myckel Habets <myckel@sdf.lonestar.org>, 2008.\n" +"Nguyen Dinh Trung <nguyendinhtrung141@gmail.com>, 2007, 2008.\n" +"Nicolas Dufour <nicoduf@yahoo.fr>, 2008-2011.\n" +"Pawan Chitrakar <pchitrakar@gmail.com>, 2006.\n" +"Przemysław Loesch <p_loesch@poczta.onet.pl>, 2005.\n" +"Quico Llach <quico@softcatala.org>, 2000. Traducció sodipodi.\n" +"Raymond Ostertag <raymond@linuxgraphic.org>, 2002, 2003.\n" +"Riku Leino <tsoots@gmail.com>, 2006.\n" +"Rune Rønde Laursen <runerl@skjoldhoej.dk>, 2006.\n" +"Ruud Steltenpool <svg@steltenpower.com>, 2006.\n" +"Serdar Soytetir <sendirom@gmail.com>, 2005.\n" +"shivaken <shivaken@owls-nest.net>, 2004.\n" +"Shyam Krishna Bal <shyamkrishna_bal@yahoo.com>, 2006.\n" +"Simos Xenitellis <simos@hellug.gr>, 2001, 2011.\n" +"Spyros Blanas <cid_e@users.sourceforge.net>, 2006, 2011.\n" +"Stefan Graubner <pflaumenmus92@gmx.net>, 2005.\n" +"Supranee Thirawatthanasuk <supranee@opentle.org>, 2006.\n" +"Takeshi Aihana <aihana@muc.biglobe.ne.jp>, 2000, 2001.\n" +"Tim Sheridan <tim.sheridan@gmail.com>, 2007-2010.\n" +"Theppitak Karoonboonyanan <thep@linux.thai.net>, 2006.\n" +"Thiago Pimentel <thiago.merces@gmail.com>, 2006.\n" +"Toshifumi Sato <sato@centrosystem.com>, 2005.\n" +"Jon South <striker@lunar-linux.org>, 2006. \n" +"Uwe Schöler <oss@oss-marketplace.com>, 2006.\n" +"Valek Filippov <frob@df.ru>, 2000, 2003.\n" +"Victor Dachev <vdachev@gmail.com>, 2006.\n" +"Vincent van Adrighem <V.vanAdrighem@dirck.mine.nu>, 2003.\n" +"Vital Khilko <dojlid@mova.org>, 2003.\n" +"Vitaly Lipatov <lav@altlinux.ru>, 2002, 2004.\n" +"vonHalenbach <vonHalenbach@users.sourceforge.net>, 2005.\n" +"Wang Li <charlesw1234@163.com>, 2002.\n" +"Wei-Lun Chao <william.chao@ossii.com.tw>, 2006.\n" +"Wolfram Strempfer <wolfram@strempfer.de>, 2006.\n" +"Xavier Conde Rueda <xavi.conde@gmail.com>, 2004-2008.\n" +"Yaron Shahrabani <sh.yaron@gmail.com>, 2009.\n" +"Yukihiro Nakai <nakai@gnome.gr.jp>, 2000, 2003.\n" +"Yuri Beznos <zhiz0id@gmail.com>, 2006.\n" +"Yuri Chornoivan <yurchor@ukr.net>, 2007-2010.\n" +"Yuri Syrota <rasta@renome.rovno.ua>, 2000.\n" +"Yves Guillou <yvesguillou@users.sourceforge.net>, 2004.\n" +"Zdenko Podobný <zdpo@mailbox.sk>, 2003, 2004." ; translators_text.append(allTranslators); diff --git a/src/ui/dialog/align-and-distribute.cpp b/src/ui/dialog/align-and-distribute.cpp index 48f0fbf22..f974ec6ce 100644 --- a/src/ui/dialog/align-and-distribute.cpp +++ b/src/ui/dialog/align-and-distribute.cpp @@ -467,7 +467,8 @@ public: dialog.tooltips().set_tip(removeOverlapXGap, _("Minimum horizontal gap (in px units) between bounding boxes")); //TRANSLATORS: "H:" stands for horizontal gap - removeOverlapXGapLabel.set_label(C_("Gap", "H:")); + removeOverlapXGapLabel.set_text_with_mnemonic(C_("Gap", "_H:")); + removeOverlapXGapLabel.set_mnemonic_widget(removeOverlapXGap); removeOverlapYGap.set_digits(1); removeOverlapYGap.set_size_request(60, -1); @@ -477,7 +478,8 @@ public: dialog.tooltips().set_tip(removeOverlapYGap, _("Minimum vertical gap (in px units) between bounding boxes")); /* TRANSLATORS: Vertical gap */ - removeOverlapYGapLabel.set_label(C_("Gap", "V:")); + removeOverlapYGapLabel.set_text_with_mnemonic(C_("Gap", "_V:")); + removeOverlapYGapLabel.set_mnemonic_widget(removeOverlapYGap); dialog.removeOverlap_table().attach(removeOverlapXGapLabel, column, column+1, row, row+1, Gtk::FILL, Gtk::FILL); dialog.removeOverlap_table().attach(removeOverlapXGap, column+1, column+2, row, row+1, Gtk::FILL, Gtk::FILL); @@ -896,7 +898,7 @@ AlignAndDistribute::AlignAndDistribute() _removeOverlapTable(1, 5, false), _nodesTable(1, 4, true), _anchorLabel(_("Relative to: ")), - _selgrpLabel(_("Treat selection as group: ")) + _selgrpLabel(_("_Treat selection as group: "), 1) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); @@ -1038,6 +1040,7 @@ AlignAndDistribute::AlignAndDistribute() _anchorBox.pack_start(_anchorLabel); _anchorBox.pack_start(_combo); + _selgrpLabel.set_mnemonic_widget(_selgrp); _selgrpBox.pack_start(_selgrpLabel); _selgrpBox.pack_start(_selgrp); _selgrp.set_active(prefs->getBool("/dialogs/align/sel-as-groups")); diff --git a/src/ui/dialog/desktop-tracker.h b/src/ui/dialog/desktop-tracker.h index edde110af..d73071194 100644 --- a/src/ui/dialog/desktop-tracker.h +++ b/src/ui/dialog/desktop-tracker.h @@ -11,6 +11,7 @@ #ifndef SEEN_DIALOG_DESKTOP_TRACKER #define SEEN_DIALOG_DESKTOP_TRACKER +#include <stddef.h> #include <sigc++/connection.h> #include <glib/gtypes.h> diff --git a/src/ui/dialog/dialog-manager.cpp b/src/ui/dialog/dialog-manager.cpp index ff31c91c4..0c49690cc 100644 --- a/src/ui/dialog/dialog-manager.cpp +++ b/src/ui/dialog/dialog-manager.cpp @@ -42,6 +42,7 @@ #include "ui/dialog/floating-behavior.h" #include "ui/dialog/dock-behavior.h" //#include "ui/dialog/print-colors-preview-dialog.h" +#include "util/ege-appear-time-tracker.h" #include "preferences.h" #ifdef ENABLE_SVG_FONTS @@ -232,10 +233,23 @@ void DialogManager::showDialog(gchar const *name) { * Shows the named dialog, creating it if necessary. */ void DialogManager::showDialog(GQuark name) { - Dialog *dialog=getDialog(name); - if (dialog) { + bool wantTiming = Inkscape::Preferences::get()->getBool("/dialogs/debug/trackAppear", false); + GTimer *timer = (wantTiming) ? g_timer_new() : 0; // if needed, must be created/started before getDialog() + Dialog *dialog = getDialog(name); + if ( dialog ) { + if ( wantTiming ) { + gchar const * nameStr = g_quark_to_string(name); + ege::AppearTimeTracker *tracker = new ege::AppearTimeTracker(timer, dialog->gobj(), nameStr); + tracker->setAutodelete(true); + timer = 0; + } dialog->present(); } + + if ( timer ) { + g_timer_destroy(timer); + timer = 0; + } } } // namespace Dialog diff --git a/src/ui/dialog/dialog.cpp b/src/ui/dialog/dialog.cpp index 43863625f..88724a90c 100644 --- a/src/ui/dialog/dialog.cpp +++ b/src/ui/dialog/dialog.cpp @@ -93,15 +93,22 @@ void unhideCallback(GtkObject */*object*/, gpointer dlgPtr) Dialog::Dialog(Behavior::BehaviorFactory behavior_factory, const char *prefs_path, int verb_num, Glib::ustring const &apply_label) - : _hiddenF12 (false), - _prefs_path (prefs_path), + : _user_hidden(false), + _hiddenF12(false), + retransientize_suppress(false), + // + _prefs_path(prefs_path), _verb_num(verb_num), - _apply_label (apply_label) + _title(), + _apply_label(apply_label), + tooltips(), + _behavior(0) { gchar title[500]; - if (verb_num) + if (verb_num) { sp_ui_dialog_title_string (Inkscape::Verb::get(verb_num), title); + } _title = title; diff --git a/src/ui/dialog/document-metadata.cpp b/src/ui/dialog/document-metadata.cpp index a8a0fa191..08479275b 100644 --- a/src/ui/dialog/document-metadata.cpp +++ b/src/ui/dialog/document-metadata.cpp @@ -85,7 +85,7 @@ DocumentMetadata::init() { update(); - Inkscape::XML::Node *repr = SP_OBJECT_REPR(sp_desktop_namedview(getDesktop())); + Inkscape::XML::Node *repr = sp_desktop_namedview(getDesktop())->getRepr(); repr->addListener (&_repr_events, this); show_all_children(); @@ -93,7 +93,7 @@ DocumentMetadata::init() DocumentMetadata::~DocumentMetadata() { - Inkscape::XML::Node *repr = SP_OBJECT_REPR(sp_desktop_namedview(getDesktop())); + Inkscape::XML::Node *repr = sp_desktop_namedview(getDesktop())->getRepr(); repr->removeListenerByData (this); for (RDElist::iterator it = _rdflist.begin(); it != _rdflist.end(); it++) @@ -211,7 +211,7 @@ DocumentMetadata::update() void DocumentMetadata::_handleDocumentReplaced(SPDesktop* desktop, SPDocument *) { - Inkscape::XML::Node *repr = SP_OBJECT_REPR(sp_desktop_namedview(desktop)); + Inkscape::XML::Node *repr = sp_desktop_namedview(desktop)->getRepr(); repr->addListener (&_repr_events, this); update(); } @@ -219,7 +219,7 @@ DocumentMetadata::_handleDocumentReplaced(SPDesktop* desktop, SPDocument *) void DocumentMetadata::_handleActivateDesktop(Inkscape::Application *, SPDesktop *desktop) { - Inkscape::XML::Node *repr = SP_OBJECT_REPR(sp_desktop_namedview(desktop)); + Inkscape::XML::Node *repr = sp_desktop_namedview(desktop)->getRepr(); repr->addListener(&_repr_events, this); update(); } @@ -227,7 +227,7 @@ DocumentMetadata::_handleActivateDesktop(Inkscape::Application *, SPDesktop *des void DocumentMetadata::_handleDeactivateDesktop(Inkscape::Application *, SPDesktop *desktop) { - Inkscape::XML::Node *repr = SP_OBJECT_REPR(sp_desktop_namedview(desktop)); + Inkscape::XML::Node *repr = sp_desktop_namedview(desktop)->getRepr(); repr->removeListenerByData(this); } diff --git a/src/ui/dialog/document-metadata.h b/src/ui/dialog/document-metadata.h index 21915c00f..8194b9920 100644 --- a/src/ui/dialog/document-metadata.h +++ b/src/ui/dialog/document-metadata.h @@ -14,6 +14,7 @@ #define INKSCAPE_UI_DIALOG_DOCUMENT_METADATA_H #include <list> +#include <stddef.h> #include <sigc++/sigc++.h> #include <gtkmm/notebook.h> #include <glibmm/i18n.h> diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp index 16212bef7..0c001da4b 100644 --- a/src/ui/dialog/document-properties.cpp +++ b/src/ui/dialog/document-properties.cpp @@ -143,9 +143,9 @@ DocumentProperties::init() { update(); - Inkscape::XML::Node *repr = SP_OBJECT_REPR(sp_desktop_namedview(getDesktop())); + Inkscape::XML::Node *repr = sp_desktop_namedview(getDesktop())->getRepr(); repr->addListener (&_repr_events, this); - Inkscape::XML::Node *root = SP_OBJECT_REPR(sp_desktop_document(getDesktop())->root); + Inkscape::XML::Node *root = sp_desktop_document(getDesktop())->root->getRepr(); root->addListener (&_repr_events, this); show_all_children(); @@ -154,9 +154,9 @@ DocumentProperties::init() DocumentProperties::~DocumentProperties() { - Inkscape::XML::Node *repr = SP_OBJECT_REPR(sp_desktop_namedview(getDesktop())); + Inkscape::XML::Node *repr = sp_desktop_namedview(getDesktop())->getRepr(); repr->removeListenerByData (this); - Inkscape::XML::Node *root = SP_OBJECT_REPR(sp_desktop_document(getDesktop())->root); + Inkscape::XML::Node *root = sp_desktop_document(getDesktop())->root->getRepr(); root->removeListenerByData (this); } @@ -439,7 +439,9 @@ DocumentProperties::populate_linked_profiles_box() { _LinkedProfilesListStore->clear(); const GSList *current = SP_ACTIVE_DOCUMENT->getResourceList( "iccprofile" ); - if (current) _emb_profiles_observer.set(SP_OBJECT(current->data)->parent); + if (current) { + _emb_profiles_observer.set(SP_OBJECT(current->data)->parent); + } while ( current ) { SPObject* obj = SP_OBJECT(current->data); Inkscape::ColorProfile* prof = reinterpret_cast<Inkscape::ColorProfile*>(obj); @@ -807,7 +809,7 @@ DocumentProperties::update() double const doc_w_px = sp_desktop_document(dt)->getWidth(); double const doc_h_px = sp_desktop_document(dt)->getHeight(); _page_sizer.setDim (doc_w_px, doc_h_px); - _page_sizer.updateFitMarginsUI(SP_OBJECT_REPR(nv)); + _page_sizer.updateFitMarginsUI(nv->getRepr()); //-----------------------------------------------------------guide page @@ -873,9 +875,9 @@ DocumentProperties::on_response (int id) void DocumentProperties::_handleDocumentReplaced(SPDesktop* desktop, SPDocument *document) { - Inkscape::XML::Node *repr = SP_OBJECT_REPR(sp_desktop_namedview(desktop)); + Inkscape::XML::Node *repr = sp_desktop_namedview(desktop)->getRepr(); repr->addListener(&_repr_events, this); - Inkscape::XML::Node *root = SP_OBJECT_REPR(document->root); + Inkscape::XML::Node *root = document->root->getRepr(); root->addListener(&_repr_events, this); update(); } @@ -883,9 +885,9 @@ DocumentProperties::_handleDocumentReplaced(SPDesktop* desktop, SPDocument *docu void DocumentProperties::_handleActivateDesktop(Inkscape::Application *, SPDesktop *desktop) { - Inkscape::XML::Node *repr = SP_OBJECT_REPR(sp_desktop_namedview(desktop)); + Inkscape::XML::Node *repr = sp_desktop_namedview(desktop)->getRepr(); repr->addListener(&_repr_events, this); - Inkscape::XML::Node *root = SP_OBJECT_REPR(sp_desktop_document(desktop)->root); + Inkscape::XML::Node *root = sp_desktop_document(desktop)->root->getRepr(); root->addListener(&_repr_events, this); update(); } @@ -893,9 +895,9 @@ DocumentProperties::_handleActivateDesktop(Inkscape::Application *, SPDesktop *d void DocumentProperties::_handleDeactivateDesktop(Inkscape::Application *, SPDesktop *desktop) { - Inkscape::XML::Node *repr = SP_OBJECT_REPR(sp_desktop_namedview(desktop)); + Inkscape::XML::Node *repr = sp_desktop_namedview(desktop)->getRepr(); repr->removeListenerByData(this); - Inkscape::XML::Node *root = SP_OBJECT_REPR(sp_desktop_document(desktop)->root); + Inkscape::XML::Node *root = sp_desktop_document(desktop)->root->getRepr(); root->removeListenerByData(this); } @@ -934,7 +936,7 @@ void DocumentProperties::onNewGrid() { SPDesktop *dt = getDesktop(); - Inkscape::XML::Node *repr = SP_OBJECT_REPR(sp_desktop_namedview(dt)); + Inkscape::XML::Node *repr = sp_desktop_namedview(dt)->getRepr(); SPDocument *doc = sp_desktop_document(dt); Glib::ustring typestring = _grids_combo_gridtype.get_active_text(); diff --git a/src/ui/dialog/document-properties.h b/src/ui/dialog/document-properties.h index dbefca235..b88f0db26 100644 --- a/src/ui/dialog/document-properties.h +++ b/src/ui/dialog/document-properties.h @@ -15,6 +15,7 @@ #define INKSCAPE_UI_DIALOG_DOCUMENT_PREFERENCES_H #include <list> +#include <stddef.h> #include <sigc++/sigc++.h>// #include <gtkmm/notebook.h> #include <glibmm/i18n.h> diff --git a/src/ui/dialog/filedialog.h b/src/ui/dialog/filedialog.h index 9f13308fb..a7441e9bb 100644 --- a/src/ui/dialog/filedialog.h +++ b/src/ui/dialog/filedialog.h @@ -46,7 +46,8 @@ namespace Dialog typedef enum { SVG_TYPES, IMPORT_TYPES, - EXPORT_TYPES + EXPORT_TYPES, + EXE_TYPES } FileDialogType; /** diff --git a/src/ui/dialog/filedialogimpl-gtkmm.cpp b/src/ui/dialog/filedialogimpl-gtkmm.cpp index 855d5a223..8e0b9294b 100644 --- a/src/ui/dialog/filedialogimpl-gtkmm.cpp +++ b/src/ui/dialog/filedialogimpl-gtkmm.cpp @@ -572,32 +572,36 @@ SVGPreview::~SVGPreview() void FileDialogBaseGtk::internalSetup() { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - bool enablePreview = prefs->getBool( preferenceBase + "/enable_preview", true); - - previewCheckbox.set_label( Glib::ustring(_("Enable preview")) ); - previewCheckbox.set_active( enablePreview ); + // 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); - previewCheckbox.signal_toggled().connect( - sigc::mem_fun(*this, &FileDialogBaseGtk::_previewEnabledCB) ); + previewCheckbox.set_label( Glib::ustring(_("Enable preview")) ); + previewCheckbox.set_active( enablePreview ); - //Catch selection-changed events, so we can adjust the text widget - signal_update_preview().connect( - sigc::mem_fun(*this, &FileDialogBaseGtk::_updatePreviewCallback) ); + previewCheckbox.signal_toggled().connect( + sigc::mem_fun(*this, &FileDialogBaseGtk::_previewEnabledCB) ); - //###### Add a preview widget - set_preview_widget(svgPreview); - set_preview_widget_active( enablePreview ); - set_use_preview_label (false); + //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); + } } void FileDialogBaseGtk::cleanup( bool showConfirmed ) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - if ( showConfirmed ) - prefs->setBool( preferenceBase + "/enable_preview", previewCheckbox.get_active() ); + if (_dialogType != EXE_TYPES) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + if ( showConfirmed ) + prefs->setBool( preferenceBase + "/enable_preview", previewCheckbox.get_active() ); + } } @@ -648,9 +652,13 @@ FileOpenDialogImplGtk::FileOpenDialogImplGtk(Gtk::Window& parentWindow, { - /* One file at a time */ - /* And also Multiple Files */ - set_select_multiple(true); + if (_dialogType == EXE_TYPES) { + /* One file at a time */ + set_select_multiple(false); + } else { + /* And also Multiple Files */ + set_select_multiple(true); + } #ifdef WITH_GNOME_VFS if (gnome_vfs_initialized()) { @@ -668,19 +676,22 @@ FileOpenDialogImplGtk::FileOpenDialogImplGtk(Gtk::Window& parentWindow, /* 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); - set_current_folder(udir.c_str()); + if (_dialogType == EXE_TYPES) { + set_filename(udir.c_str()); + } else { + set_current_folder(udir.c_str()); } + } - - set_extra_widget( previewCheckbox ); - + if (_dialogType != EXE_TYPES) { + set_extra_widget( previewCheckbox ); + } //###### Add the file types menu createFilterMenu(); @@ -708,84 +719,91 @@ FileOpenDialogImplGtk::~FileOpenDialogImplGtk() void FileOpenDialogImplGtk::createFilterMenu() { - Gtk::FileFilter allInkscapeFilter; - allInkscapeFilter.set_name(_("All Inkscape Files")); - extensionMap[Glib::ustring(_("All Inkscape Files"))]=NULL; - add_filter(allInkscapeFilter); - - Gtk::FileFilter allFilter; - allFilter.set_name(_("All Files")); - extensionMap[Glib::ustring(_("All Files"))]=NULL; - allFilter.add_pattern("*"); - add_filter(allFilter); - - Gtk::FileFilter allImageFilter; - allImageFilter.set_name(_("All Images")); - extensionMap[Glib::ustring(_("All Images"))]=NULL; - add_filter(allImageFilter); - - Gtk::FileFilter allVectorFilter; - allVectorFilter.set_name(_("All Vectors")); - extensionMap[Glib::ustring(_("All Vectors"))]=NULL; - add_filter(allVectorFilter); - - Gtk::FileFilter allBitmapFilter; - allBitmapFilter.set_name(_("All Bitmaps")); - extensionMap[Glib::ustring(_("All Bitmaps"))]=NULL; - add_filter(allBitmapFilter); - - //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; - - // FIXME: would be nice to grey them out instead of not listing them - if (imod->deactivated()) continue; - - Glib::ustring upattern("*"); - Glib::ustring extension = imod->get_extension(); - fileDialogExtensionToPattern(upattern, extension); - - Gtk::FileFilter filter; - Glib::ustring uname(_(imod->get_filetypename())); - filter.set_name(uname); - filter.add_pattern(upattern); - add_filter(filter); - extensionMap[uname] = imod; - - //g_message("ext %s:%s '%s'\n", ioext->name, ioext->mimetype, upattern.c_str()); - allInkscapeFilter.add_pattern(upattern); - if ( strncmp("image", imod->get_mimetype(), 5)==0 ) - allImageFilter.add_pattern(upattern); - - // uncomment this to find out all mime types supported by Inkscape import/open - // 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 - ) - allBitmapFilter.add_pattern(upattern); - else - allVectorFilter.add_pattern(upattern); + if (_dialogType == EXE_TYPES) { + Gtk::FileFilter allFilter; + allFilter.set_name(_("All Files")); + extensionMap[Glib::ustring(_("All Files"))]=NULL; + allFilter.add_pattern("*"); + add_filter(allFilter); + } else { + Gtk::FileFilter allInkscapeFilter; + allInkscapeFilter.set_name(_("All Inkscape Files")); + extensionMap[Glib::ustring(_("All Inkscape Files"))]=NULL; + add_filter(allInkscapeFilter); + + Gtk::FileFilter allFilter; + allFilter.set_name(_("All Files")); + extensionMap[Glib::ustring(_("All Files"))]=NULL; + allFilter.add_pattern("*"); + add_filter(allFilter); + + Gtk::FileFilter allImageFilter; + allImageFilter.set_name(_("All Images")); + extensionMap[Glib::ustring(_("All Images"))]=NULL; + add_filter(allImageFilter); + + Gtk::FileFilter allVectorFilter; + allVectorFilter.set_name(_("All Vectors")); + extensionMap[Glib::ustring(_("All Vectors"))]=NULL; + add_filter(allVectorFilter); + + Gtk::FileFilter allBitmapFilter; + allBitmapFilter.set_name(_("All Bitmaps")); + extensionMap[Glib::ustring(_("All Bitmaps"))]=NULL; + add_filter(allBitmapFilter); + + //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; + + // FIXME: would be nice to grey them out instead of not listing them + if (imod->deactivated()) continue; + + Glib::ustring upattern("*"); + Glib::ustring extension = imod->get_extension(); + fileDialogExtensionToPattern(upattern, extension); + + Gtk::FileFilter filter; + Glib::ustring uname(_(imod->get_filetypename())); + filter.set_name(uname); + filter.add_pattern(upattern); + add_filter(filter); + extensionMap[uname] = imod; + + //g_message("ext %s:%s '%s'\n", ioext->name, ioext->mimetype, upattern.c_str()); + allInkscapeFilter.add_pattern(upattern); + if ( strncmp("image", imod->get_mimetype(), 5)==0 ) + allImageFilter.add_pattern(upattern); + + // uncomment this to find out all mime types supported by Inkscape import/open + // 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 + ) + allBitmapFilter.add_pattern(upattern); + else + allVectorFilter.add_pattern(upattern); + } } - return; } diff --git a/src/ui/dialog/filedialogimpl-win32.cpp b/src/ui/dialog/filedialogimpl-win32.cpp index 9f33d8838..b3c71e8c8 100644 --- a/src/ui/dialog/filedialogimpl-win32.cpp +++ b/src/ui/dialog/filedialogimpl-win32.cpp @@ -122,11 +122,11 @@ FileDialogBaseWin32::FileDialogBaseWin32(Gtk::Window &parent, { _main_loop = NULL; - _filter_index = 1; - _filter_count = 0; + _filter_index = 1; + _filter_count = 0; _title = (wchar_t*)g_utf8_to_utf16(title, -1, NULL, NULL, NULL); - g_assert(_title != NULL); + g_assert(_title != NULL); Glib::RefPtr<const Gdk::Window> parentWindow = parent.get_window(); g_assert(parentWindow->gobj() != NULL); @@ -183,7 +183,7 @@ FileOpenDialogImplWin32::FileOpenDialogImplWin32(Gtk::Window &parent, _preview_image_height = 0; _preview_emf_image = false; - _mutex = NULL; + _mutex = NULL; createFilterMenu(); } @@ -204,143 +204,180 @@ void FileOpenDialogImplWin32::createFilterMenu() { list<Filter> filter_list; - // Compose the filter string - Inkscape::Extension::DB::InputList extension_list; - Inkscape::Extension::db.get_input_list(extension_list); - - ustring all_inkscape_files_filter, all_image_files_filter, all_vectors_filter, all_bitmaps_filter; - Filter all_files, all_inkscape_files, all_image_files, all_vectors, all_bitmaps; - - const gchar *all_files_filter_name = _("All Files"); - const gchar *all_inkscape_files_filter_name = _("All Inkscape Files"); - const gchar *all_image_files_filter_name = _("All Images"); - const gchar *all_vectors_filter_name = _("All Vectors"); - const gchar *all_bitmaps_filter_name = _("All Bitmaps"); - - // Calculate the amount of memory required - int filter_count = 5; // 5 - one for each filter type + int extension_index = 0; int filter_length = 1; + + if (dialogType != EXE_TYPES) { + // Compose the filter string + Inkscape::Extension::DB::InputList extension_list; + Inkscape::Extension::db.get_input_list(extension_list); + + ustring all_inkscape_files_filter, all_image_files_filter, all_vectors_filter, all_bitmaps_filter; + Filter all_files, all_inkscape_files, all_image_files, all_vectors, all_bitmaps; + + const gchar *all_files_filter_name = _("All Files"); + const gchar *all_inkscape_files_filter_name = _("All Inkscape Files"); + const gchar *all_image_files_filter_name = _("All Images"); + const gchar *all_vectors_filter_name = _("All Vectors"); + const gchar *all_bitmaps_filter_name = _("All Bitmaps"); + + // Calculate the amount of memory required + int filter_count = 5; // 5 - one for each filter type + + for (Inkscape::Extension::DB::InputList::iterator current_item = extension_list.begin(); + current_item != extension_list.end(); current_item++) + { + Filter filter; - for (Inkscape::Extension::DB::InputList::iterator current_item = extension_list.begin(); - current_item != extension_list.end(); current_item++) - { - Filter filter; + Inkscape::Extension::Input *imod = *current_item; + if (imod->deactivated()) continue; - Inkscape::Extension::Input *imod = *current_item; - if (imod->deactivated()) continue; + // Type + filter.name = g_utf8_to_utf16(_(imod->get_filetypename()), + -1, NULL, &filter.name_length, NULL); - // Type - filter.name = g_utf8_to_utf16(_(imod->get_filetypename()), - -1, NULL, &filter.name_length, NULL); + // Extension + const gchar *file_extension_name = imod->get_extension(); + filter.filter = g_utf8_to_utf16(file_extension_name, + -1, NULL, &filter.filter_length, NULL); - // Extension - const gchar *file_extension_name = imod->get_extension(); - filter.filter = g_utf8_to_utf16(file_extension_name, - -1, NULL, &filter.filter_length, NULL); + filter.mod = imod; + filter_list.push_back(filter); - filter.mod = imod; - filter_list.push_back(filter); + filter_length += filter.name_length + + filter.filter_length + 3; // Add 3 for two \0s and a * - filter_length += filter.name_length + - filter.filter_length + 3; // Add 3 for two \0s and a * + // Add to the "All Inkscape Files" Entry + if(all_inkscape_files_filter.length() > 0) + all_inkscape_files_filter += ";*"; + all_inkscape_files_filter += file_extension_name; + if( strncmp("image", imod->get_mimetype(), 5) == 0) + { + // Add to the "All Image Files" Entry + if(all_image_files_filter.length() > 0) + all_image_files_filter += ";*"; + all_image_files_filter += file_extension_name; + } - // Add to the "All Inkscape Files" Entry - if(all_inkscape_files_filter.length() > 0) - all_inkscape_files_filter += ";*"; - all_inkscape_files_filter += file_extension_name; - if( strncmp("image", imod->get_mimetype(), 5) == 0) - { - // Add to the "All Image Files" Entry - if(all_image_files_filter.length() > 0) - all_image_files_filter += ";*"; - all_image_files_filter += file_extension_name; - } + // I don't know of any other way to define "bitmap" formats other than by listing them + // if you change it here, do the same change in filedialogimpl-gtkmm + 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(all_bitmaps_filter.length() > 0) + all_bitmaps_filter += ";*"; + all_bitmaps_filter += file_extension_name; + } else { + if(all_vectors_filter.length() > 0) + all_vectors_filter += ";*"; + all_vectors_filter += file_extension_name; + } - // I don't know of any other way to define "bitmap" formats other than by listing them - // if you change it here, do the same change in filedialogimpl-gtkmm - 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(all_bitmaps_filter.length() > 0) - all_bitmaps_filter += ";*"; - all_bitmaps_filter += file_extension_name; - } else { - if(all_vectors_filter.length() > 0) - all_vectors_filter += ";*"; - all_vectors_filter += file_extension_name; + filter_count++; } - filter_count++; + _extension_map = new Inkscape::Extension::Extension*[filter_count]; + + // Filter bitmap files + all_bitmaps.name = g_utf8_to_utf16(all_bitmaps_filter_name, + -1, NULL, &all_bitmaps.name_length, NULL); + all_bitmaps.filter = g_utf8_to_utf16(all_bitmaps_filter.data(), + -1, NULL, &all_bitmaps.filter_length, NULL); + all_bitmaps.mod = NULL; + filter_list.push_front(all_bitmaps); + + // Filter vector files + all_vectors.name = g_utf8_to_utf16(all_vectors_filter_name, + -1, NULL, &all_vectors.name_length, NULL); + all_vectors.filter = g_utf8_to_utf16(all_vectors_filter.data(), + -1, NULL, &all_vectors.filter_length, NULL); + all_vectors.mod = NULL; + filter_list.push_front(all_vectors); + + // Filter Image Files + all_image_files.name = g_utf8_to_utf16(all_image_files_filter_name, + -1, NULL, &all_image_files.name_length, NULL); + all_image_files.filter = g_utf8_to_utf16(all_image_files_filter.data(), + -1, NULL, &all_image_files.filter_length, NULL); + all_image_files.mod = NULL; + filter_list.push_front(all_image_files); + + // Filter Inkscape Files + all_inkscape_files.name = g_utf8_to_utf16(all_inkscape_files_filter_name, + -1, NULL, &all_inkscape_files.name_length, NULL); + all_inkscape_files.filter = g_utf8_to_utf16(all_inkscape_files_filter.data(), + -1, NULL, &all_inkscape_files.filter_length, NULL); + all_inkscape_files.mod = NULL; + filter_list.push_front(all_inkscape_files); + + // Filter All Files + all_files.name = g_utf8_to_utf16(all_files_filter_name, + -1, NULL, &all_files.name_length, NULL); + all_files.filter = NULL; + all_files.filter_length = 0; + all_files.mod = NULL; + filter_list.push_front(all_files); + + filter_length += all_files.name_length + 3 + + all_inkscape_files.filter_length + + all_inkscape_files.name_length + 3 + + all_image_files.filter_length + + all_image_files.name_length + 3 + + all_vectors.filter_length + + all_vectors.name_length + 3 + + all_bitmaps.filter_length + + all_bitmaps.name_length + 3 + + 1; + // Add 3 for 2*2 \0s and a *, and 1 for a trailing \0 + } else { + // Executables only + ustring all_exe_files_filter = "*.exe;*.bat;*.com"; + Filter all_exe_files, all_files; + + const gchar *all_files_filter_name = _("All Files"); + const gchar *all_exe_files_filter_name = _("All Executable Files"); + + // Calculate the amount of memory required + int filter_count = 2; // 2 - All Files and All Executable Files + + _extension_map = new Inkscape::Extension::Extension*[filter_count]; + + // Filter Executable Files + all_exe_files.name = g_utf8_to_utf16(all_exe_files_filter_name, + -1, NULL, &all_exe_files.name_length, NULL); + all_exe_files.filter = g_utf8_to_utf16(all_exe_files_filter.data(), + -1, NULL, &all_exe_files.filter_length, NULL); + all_exe_files.mod = NULL; + filter_list.push_front(all_exe_files); + + // Filter All Files + all_files.name = g_utf8_to_utf16(all_files_filter_name, + -1, NULL, &all_files.name_length, NULL); + all_files.filter = NULL; + all_files.filter_length = 0; + all_files.mod = NULL; + filter_list.push_front(all_files); + + filter_length += all_files.name_length + 3 + + all_exe_files.filter_length + + all_exe_files.name_length + 3 + + 1; + // Add 3 for 2*2 \0s and a *, and 1 for a trailing \0 } - - int extension_index = 0; - _extension_map = new Inkscape::Extension::Extension*[filter_count]; - - // Filter bitmap files - all_bitmaps.name = g_utf8_to_utf16(all_bitmaps_filter_name, - -1, NULL, &all_bitmaps.name_length, NULL); - all_bitmaps.filter = g_utf8_to_utf16(all_bitmaps_filter.data(), - -1, NULL, &all_bitmaps.filter_length, NULL); - all_bitmaps.mod = NULL; - filter_list.push_front(all_bitmaps); - - // Filter vector files - all_vectors.name = g_utf8_to_utf16(all_vectors_filter_name, - -1, NULL, &all_vectors.name_length, NULL); - all_vectors.filter = g_utf8_to_utf16(all_vectors_filter.data(), - -1, NULL, &all_vectors.filter_length, NULL); - all_vectors.mod = NULL; - filter_list.push_front(all_vectors); - - // Filter Image Files - all_image_files.name = g_utf8_to_utf16(all_image_files_filter_name, - -1, NULL, &all_image_files.name_length, NULL); - all_image_files.filter = g_utf8_to_utf16(all_image_files_filter.data(), - -1, NULL, &all_image_files.filter_length, NULL); - all_image_files.mod = NULL; - filter_list.push_front(all_image_files); - - // Filter Inkscape Files - all_inkscape_files.name = g_utf8_to_utf16(all_inkscape_files_filter_name, - -1, NULL, &all_inkscape_files.name_length, NULL); - all_inkscape_files.filter = g_utf8_to_utf16(all_inkscape_files_filter.data(), - -1, NULL, &all_inkscape_files.filter_length, NULL); - all_inkscape_files.mod = NULL; - filter_list.push_front(all_inkscape_files); - - // Filter All Files - all_files.name = g_utf8_to_utf16(all_files_filter_name, - -1, NULL, &all_files.name_length, NULL); - all_files.filter = NULL; - all_files.filter_length = 0; - all_files.mod = NULL; - filter_list.push_front(all_files); - - filter_length += all_files.name_length + 3 + - all_inkscape_files.filter_length + - all_inkscape_files.name_length + 3 + - all_image_files.filter_length + - all_image_files.name_length + 3 + - all_vectors.filter_length + - all_vectors.name_length + 3 + - all_bitmaps.filter_length + - all_bitmaps.name_length + 3 + - 1; - // Add 3 for 2*2 \0s and a *, and 1 for a trailing \0 - - _filter = new wchar_t[filter_length]; + + _filter = new wchar_t[filter_length]; wchar_t *filterptr = _filter; for(list<Filter>::iterator filter_iterator = filter_list.begin(); @@ -369,7 +406,7 @@ void FileOpenDialogImplWin32::createFilterMenu() } *(filterptr++) = L'\0'; - _filter_count = extension_index; + _filter_count = extension_index; _filter_index = 2; // Select the 2nd filter in the list - 2 is NOT the 3rd } @@ -378,7 +415,7 @@ void FileOpenDialogImplWin32::GetOpenFileName_thread() OPENFILENAMEEXW ofn; g_assert(this != NULL); - g_assert(_mutex != NULL); + g_assert(_mutex != NULL); WCHAR* current_directory_string = (WCHAR*)g_utf8_to_utf16( _current_directory.data(), _current_directory.length(), @@ -409,7 +446,7 @@ void FileOpenDialogImplWin32::GetOpenFileName_thread() _result = GetOpenFileNameW(&ofn) != 0; - g_assert(ofn.nFilterIndex >= 1 && ofn.nFilterIndex <= _filter_count); + g_assert(ofn.nFilterIndex >= 1 && ofn.nFilterIndex <= _filter_count); _filter_index = ofn.nFilterIndex; _extension = _extension_map[ofn.nFilterIndex - 1]; @@ -457,56 +494,70 @@ UINT_PTR CALLBACK FileOpenDialogImplWin32::GetOpenFileName_hookproc( HWND hParentWnd = GetParent(hdlg); HINSTANCE hInstance = GetModuleHandle(NULL); - // Make the window a bit wider - RECT rcRect; - GetWindowRect(hParentWnd, &rcRect); - MoveWindow(hParentWnd, rcRect.left, rcRect.top, - rcRect.right - rcRect.left + PREVIEW_WIDENING, - rcRect.bottom - rcRect.top, - FALSE); - // Set the pointer to the object OPENFILENAMEW *ofn = (OPENFILENAMEW*)lParam; SetWindowLongPtr(hdlg, GWLP_USERDATA, ofn->lCustData); SetWindowLongPtr(hParentWnd, GWLP_USERDATA, ofn->lCustData); pImpl = (FileOpenDialogImplWin32*)ofn->lCustData; + + // Make the window a bit wider + RECT rcRect; + GetWindowRect(hParentWnd, &rcRect); + + // Don't show the preview when opening executable files + if ( pImpl->dialogType == EXE_TYPES) { + MoveWindow(hParentWnd, rcRect.left, rcRect.top, + rcRect.right - rcRect.left, + rcRect.bottom - rcRect.top, + FALSE); + } else { + MoveWindow(hParentWnd, rcRect.left, rcRect.top, + rcRect.right - rcRect.left + PREVIEW_WIDENING, + rcRect.bottom - rcRect.top, + FALSE); + } // Subclass the parent pImpl->_base_window_proc = (WNDPROC)GetWindowLongPtr(hParentWnd, GWLP_WNDPROC); SetWindowLongPtr(hParentWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(file_dialog_subclass_proc)); - // Add a button to the toolbar - pImpl->_toolbar_wnd = FindWindowEx(hParentWnd, NULL, "ToolbarWindow32", NULL); - - pImpl->_show_preview_button_bitmap = LoadBitmap( - hInstance, MAKEINTRESOURCE(IDC_SHOW_PREVIEW)); - TBADDBITMAP tbAddBitmap = {NULL, reinterpret_cast<UINT_PTR>(pImpl->_show_preview_button_bitmap)}; - const int iBitmapIndex = SendMessage(pImpl->_toolbar_wnd, - TB_ADDBITMAP, 1, (LPARAM)&tbAddBitmap); - - TBBUTTON tbButton; - memset(&tbButton, 0, sizeof(TBBUTTON)); - tbButton.iBitmap = iBitmapIndex; - tbButton.idCommand = IDC_SHOW_PREVIEW; - tbButton.fsState = (pImpl->_show_preview ? TBSTATE_CHECKED : 0) - | TBSTATE_ENABLED; - tbButton.fsStyle = TBSTYLE_CHECK; - tbButton.iString = (INT_PTR)_("Show Preview"); - SendMessage(pImpl->_toolbar_wnd, TB_ADDBUTTONS, 1, (LPARAM)&tbButton); - - // Create preview pane - register_preview_wnd_class(); + if ( pImpl->dialogType != EXE_TYPES) { + // Add a button to the toolbar + pImpl->_toolbar_wnd = FindWindowEx(hParentWnd, NULL, "ToolbarWindow32", NULL); + + pImpl->_show_preview_button_bitmap = LoadBitmap( + hInstance, MAKEINTRESOURCE(IDC_SHOW_PREVIEW)); + TBADDBITMAP tbAddBitmap = {NULL, reinterpret_cast<UINT_PTR>(pImpl->_show_preview_button_bitmap)}; + const int iBitmapIndex = SendMessage(pImpl->_toolbar_wnd, + TB_ADDBITMAP, 1, (LPARAM)&tbAddBitmap); + + + TBBUTTON tbButton; + memset(&tbButton, 0, sizeof(TBBUTTON)); + tbButton.iBitmap = iBitmapIndex; + tbButton.idCommand = IDC_SHOW_PREVIEW; + tbButton.fsState = (pImpl->_show_preview ? TBSTATE_CHECKED : 0) + | TBSTATE_ENABLED; + tbButton.fsStyle = TBSTYLE_CHECK; + tbButton.iString = (INT_PTR)_("Show Preview"); + SendMessage(pImpl->_toolbar_wnd, TB_ADDBUTTONS, 1, (LPARAM)&tbButton); + + // Create preview pane + register_preview_wnd_class(); + } pImpl->_mutex->lock(); - pImpl->_file_dialog_wnd = hParentWnd; + pImpl->_file_dialog_wnd = hParentWnd; + if ( pImpl->dialogType != EXE_TYPES) { pImpl->_preview_wnd = CreateWindowA(PreviewWindowClassName, "", WS_CHILD | WS_VISIBLE, 0, 0, 100, 100, hParentWnd, NULL, hInstance, NULL); SetWindowLongPtr(pImpl->_preview_wnd, GWLP_USERDATA, ofn->lCustData); - + } + pImpl->_mutex->unlock(); pImpl->layout_dialog(); @@ -773,7 +824,7 @@ void FileOpenDialogImplWin32::layout_dialog() rcClient.right - iPadding, rcFileList.r.bottom}; rcFileList.r.right = rcBody.right; - if(_show_preview) + if(_show_preview && dialogType != EXE_TYPES) { rcPreview.top = rcBody.top; rcPreview.left = rcClient.right - (rcBody.bottom - rcBody.top); @@ -951,7 +1002,7 @@ bool FileOpenDialogImplWin32::set_svg_preview() arena, key, SP_ITEM_SHOW_DISPLAY); NRGC gc(NULL); - gc.transform = Geom::Matrix(Geom::Scale(scaleFactor, scaleFactor)); + gc.transform = Geom::Affine(Geom::Scale(scaleFactor, scaleFactor)); nr_arena_item_invoke_update (root, NULL, &gc, NR_ARENA_ITEM_STATE_ALL, NR_ARENA_ITEM_STATE_NONE); @@ -1529,6 +1580,17 @@ FileSaveDialogImplWin32::FileSaveDialogImplWin32(Gtk::Window &parent, { FileSaveDialog::myDocTitle = docTitle; createFilterMenu(); + + /* The code below sets the default file name */ + myFilename = ""; + 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.substr(0, udir.find_last_of( '.' ) ); // this removes the extension, or actually, removes everything past the last dot (hopefully this is what most people want) + } } FileSaveDialogImplWin32::~FileSaveDialogImplWin32() @@ -1606,7 +1668,7 @@ void FileSaveDialogImplWin32::createFilterMenu() } *(filterptr++) = 0; - _filter_count = extension_index; + _filter_count = extension_index; _filter_index = 1; // A value of 1 selects the 1st filter - NOT the 2nd } @@ -1646,7 +1708,7 @@ void FileSaveDialogImplWin32::GetSaveFileName_thread() _result = GetSaveFileNameW(&ofn) != 0; - g_assert(ofn.nFilterIndex >= 1 && ofn.nFilterIndex <= _filter_count); + g_assert(ofn.nFilterIndex >= 1 && ofn.nFilterIndex <= _filter_count); _filter_index = ofn.nFilterIndex; _extension = _extension_map[ofn.nFilterIndex - 1]; diff --git a/src/ui/dialog/filedialogimpl-win32.h b/src/ui/dialog/filedialogimpl-win32.h index 00d9cf37f..a6f7d6239 100644 --- a/src/ui/dialog/filedialogimpl-win32.h +++ b/src/ui/dialog/filedialogimpl-win32.h @@ -150,9 +150,10 @@ public: private: - /// Create a filter menu for this type of dialog + /// Create filter menu for this type of dialog void createFilterMenu(); + /// The handle of the preview pane window HWND _preview_wnd; diff --git a/src/ui/dialog/fill-and-stroke.cpp b/src/ui/dialog/fill-and-stroke.cpp index 0c234003e..19bcadc00 100644 --- a/src/ui/dialog/fill-and-stroke.cpp +++ b/src/ui/dialog/fill-and-stroke.cpp @@ -54,7 +54,7 @@ FillAndStroke::FillAndStroke() contents->pack_start(_notebook, true, true); - _notebook.append_page(_page_fill, _createPageTabLabel(_("Fill"), INKSCAPE_ICON_OBJECT_FILL)); + _notebook.append_page(_page_fill, _createPageTabLabel(_("_Fill"), INKSCAPE_ICON_OBJECT_FILL)); _notebook.append_page(_page_stroke_paint, _createPageTabLabel(_("Stroke _paint"), INKSCAPE_ICON_OBJECT_STROKE)); _notebook.append_page(_page_stroke_style, _createPageTabLabel(_("Stroke st_yle"), INKSCAPE_ICON_OBJECT_STROKE_STYLE)); diff --git a/src/ui/dialog/filter-effects-dialog.cpp b/src/ui/dialog/filter-effects-dialog.cpp index 63f387911..f7911f79a 100644 --- a/src/ui/dialog/filter-effects-dialog.cpp +++ b/src/ui/dialog/filter-effects-dialog.cpp @@ -1181,29 +1181,32 @@ void FilterEffectsDialog::FilterModifier::update_selection(Selection *sel) { std::set<SPObject*> used; - for(GSList const *i = sel->itemList(); i != NULL; i = i->next) { + for (GSList const *i = sel->itemList(); i != NULL; i = i->next) { SPObject *obj = SP_OBJECT (i->data); - SPStyle *style = SP_OBJECT_STYLE (obj); - if(!style || !SP_IS_ITEM(obj)) continue; + SPStyle *style = obj->style; + if (!style || !SP_IS_ITEM(obj)) { + continue; + } - if(style->filter.set && style->getFilter()) + if (style->filter.set && style->getFilter()) { used.insert(style->getFilter()); - else + } else { used.insert(0); + } } const int size = used.size(); - for(Gtk::TreeIter iter = _model->children().begin(); - iter != _model->children().end(); ++iter) { - if(used.find((*iter)[_columns.filter]) != used.end()) { + for (Gtk::TreeIter iter = _model->children().begin(); iter != _model->children().end(); ++iter) { + if (used.find((*iter)[_columns.filter]) != used.end()) { // If only one filter is in use by the selection, select it - if(size == 1) + if (size == 1) { _list.get_selection()->select(iter); + } (*iter)[_columns.sel] = size; - } - else + } else { (*iter)[_columns.sel] = 0; + } } } @@ -1244,15 +1247,16 @@ void FilterEffectsDialog::FilterModifier::on_selection_toggled(const Glib::ustri for (GSList const *i = items; i != NULL; i = i->next) { SPItem * item = SP_ITEM(i->data); - SPStyle *style = SP_OBJECT_STYLE(item); + SPStyle *style = item->style; g_assert(style != NULL); - if(filter) - sp_style_set_property_url(SP_OBJECT(item), "filter", SP_OBJECT(filter), false); - else + if (filter) { + sp_style_set_property_url(item, "filter", filter, false); + } else { ::remove_filter(item, false); + } - SP_OBJECT(item)->requestDisplayUpdate((SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG )); + item->requestDisplayUpdate((SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG )); } update_selection(sel); @@ -1355,8 +1359,9 @@ void FilterEffectsDialog::FilterModifier::duplicate_filter() { SPFilter* filter = get_selected_filter(); - if(filter) { - Inkscape::XML::Node* repr = SP_OBJECT_REPR(filter), *parent = repr->parent(); + if (filter) { + Inkscape::XML::Node *repr = filter->getRepr(); + Inkscape::XML::Node *parent = repr->parent(); repr = repr->duplicate(repr->document()); parent->appendChild(repr); @@ -1902,7 +1907,7 @@ bool FilterEffectsDialog::PrimitiveList::on_button_release_event(GdkEventButton* for(Gtk::TreeIter iter = _model->children().begin(); iter != get_selection()->get_selected(); ++iter) { if(iter == target_iter) { - Inkscape::XML::Node *repr = SP_OBJECT_REPR(target); + Inkscape::XML::Node *repr = target->getRepr(); // Make sure the target has a result const gchar *gres = repr->attribute("result"); if(!gres) { @@ -1979,22 +1984,23 @@ bool FilterEffectsDialog::PrimitiveList::on_button_release_event(GdkEventButton* // Checks all of prim's inputs, removes any that use result void check_single_connection(SPFilterPrimitive* prim, const int result) { - if(prim && result >= 0) { - - if(prim->image_in == result) - SP_OBJECT_REPR(prim)->setAttribute("in", 0); - - if(SP_IS_FEBLEND(prim)) { - if(SP_FEBLEND(prim)->in2 == result) - SP_OBJECT_REPR(prim)->setAttribute("in2", 0); + if (prim && (result >= 0)) { + if (prim->image_in == result) { + prim->getRepr()->setAttribute("in", 0); } - else if(SP_IS_FECOMPOSITE(prim)) { - if(SP_FECOMPOSITE(prim)->in2 == result) - SP_OBJECT_REPR(prim)->setAttribute("in2", 0); - } - else if(SP_IS_FEDISPLACEMENTMAP(prim)) { - if(SP_FEDISPLACEMENTMAP(prim)->in2 == result) - SP_OBJECT_REPR(prim)->setAttribute("in2", 0); + + if (SP_IS_FEBLEND(prim)) { + if (SP_FEBLEND(prim)->in2 == result) { + prim->getRepr()->setAttribute("in2", 0); + } + } else if (SP_IS_FECOMPOSITE(prim)) { + if (SP_FECOMPOSITE(prim)->in2 == result) { + prim->getRepr()->setAttribute("in2", 0); + } + } else if (SP_IS_FEDISPLACEMENTMAP(prim)) { + if (SP_FEDISPLACEMENTMAP(prim)->in2 == result) { + prim->getRepr()->setAttribute("in2", 0); + } } } } @@ -2025,19 +2031,19 @@ void FilterEffectsDialog::PrimitiveList::on_drag_end(const Glib::RefPtr<Gdk::Dra SPFilter* filter = _dialog._filter_modifier.get_selected_filter(); int ndx = 0; - for(Gtk::TreeModel::iterator iter = _model->children().begin(); + for (Gtk::TreeModel::iterator iter = _model->children().begin(); iter != _model->children().end(); ++iter, ++ndx) { SPFilterPrimitive* prim = (*iter)[_columns.primitive]; - if(prim && prim == _drag_prim) { - SP_OBJECT_REPR(prim)->setPosition(ndx); + if (prim && prim == _drag_prim) { + prim->getRepr()->setPosition(ndx); break; } } - for(Gtk::TreeModel::iterator iter = _model->children().begin(); + for (Gtk::TreeModel::iterator iter = _model->children().begin(); iter != _model->children().end(); ++iter, ++ndx) { SPFilterPrimitive* prim = (*iter)[_columns.primitive]; - if(prim && prim == _drag_prim) { + if (prim && prim == _drag_prim) { sanitize_connections(iter); get_selection()->select(iter); break; @@ -2369,10 +2375,10 @@ void FilterEffectsDialog::duplicate_primitive() SPFilter* filter = _filter_modifier.get_selected_filter(); SPFilterPrimitive* origprim = _primitive_list.get_selected(); - if(filter && origprim) { + if (filter && origprim) { Inkscape::XML::Node *repr; - repr = SP_OBJECT_REPR(origprim)->duplicate(SP_OBJECT_REPR(origprim)->document()); - SP_OBJECT_REPR(filter)->appendChild(repr); + repr = origprim->getRepr()->duplicate(origprim->getRepr()->document()); + filter->getRepr()->appendChild(repr); DocumentUndo::done(filter->document, SP_VERB_DIALOG_FILTER_EFFECTS, _("Duplicate filter primitive")); @@ -2382,7 +2388,7 @@ void FilterEffectsDialog::duplicate_primitive() void FilterEffectsDialog::convolve_order_changed() { - _convolve_matrix->set_from_attribute(SP_OBJECT(_primitive_list.get_selected())); + _convolve_matrix->set_from_attribute(_primitive_list.get_selected()); _convolve_target->get_spinbuttons()[0]->get_adjustment()->set_upper(_convolve_order->get_spinbutton1().get_value() - 1); _convolve_target->get_spinbuttons()[1]->get_adjustment()->set_upper(_convolve_order->get_spinbutton2().get_value() - 1); } @@ -2398,8 +2404,8 @@ void FilterEffectsDialog::set_filternode_attr(const AttrWidget* input) _attr_lock = true; SPFilter *filter = _filter_modifier.get_selected_filter(); const gchar* name = (const gchar*)sp_attribute_name(input->get_attribute()); - if (filter && name && SP_OBJECT_REPR(filter)){ - SP_OBJECT_REPR(filter)->setAttribute(name, input->get_as_attribute().c_str()); + if (filter && name && filter->getRepr()){ + filter->getRepr()->setAttribute(name, input->get_as_attribute().c_str()); filter->requestModified(SP_OBJECT_MODIFIED_FLAG); } _attr_lock = false; @@ -2421,7 +2427,7 @@ void FilterEffectsDialog::set_attr(SPObject* o, const SPAttributeEnum attr, cons if(filter && name && o) { update_settings_sensitivity(); - SP_OBJECT_REPR(o)->setAttribute(name, val); + o->getRepr()->setAttribute(name, val); filter->requestModified(SP_OBJECT_MODIFIED_FLAG); Glib::ustring undokey = "filtereffects:"; diff --git a/src/ui/dialog/find.cpp b/src/ui/dialog/find.cpp index b6d6a0319..bdae14c62 100644 --- a/src/ui/dialog/find.cpp +++ b/src/ui/dialog/find.cpp @@ -142,15 +142,18 @@ Find::~Find() bool Find::item_id_match (SPItem *item, const gchar *id, bool exact) { - if (SP_OBJECT_REPR (item) == NULL) + if (item->getRepr() == NULL) { return false; + } - if (SP_IS_STRING(item)) // SPStrings have "on demand" ids which are useless for searching + if (SP_IS_STRING(item)) { // SPStrings have "on demand" ids which are useless for searching return false; + } - const gchar *item_id = (SP_OBJECT_REPR (item))->attribute("id"); - if (item_id == NULL) + const gchar *item_id = item->getRepr()->attribute("id"); + if (item_id == NULL) { return false; + } if (exact) { return ((bool) !strcmp(item_id, id)); @@ -163,8 +166,9 @@ Find::item_id_match (SPItem *item, const gchar *id, bool exact) bool Find::item_text_match (SPItem *item, const gchar *text, bool exact) { - if (SP_OBJECT_REPR (item) == NULL) + if (item->getRepr() == NULL) { return false; + } if (SP_IS_TEXT(item) || SP_IS_FLOWTEXT(item)) { const gchar *item_text = sp_te_get_string_multiline (item); @@ -186,12 +190,14 @@ Find::item_text_match (SPItem *item, const gchar *text, bool exact) bool Find::item_style_match (SPItem *item, const gchar *text, bool exact) { - if (SP_OBJECT_REPR (item) == NULL) + if (item->getRepr() == NULL) { return false; + } - const gchar *item_text = (SP_OBJECT_REPR (item))->attribute("style"); - if (item_text == NULL) + const gchar *item_text = item->getRepr()->attribute("style"); + if (item_text == NULL) { return false; + } if (exact) { return ((bool) !strcmp(item_text, text)); @@ -200,18 +206,18 @@ Find::item_style_match (SPItem *item, const gchar *text, bool exact) } } -bool -Find::item_attr_match (SPItem *item, const gchar *name, bool exact) +bool Find::item_attr_match(SPItem *item, const gchar *name, bool exact) { - if (SP_OBJECT_REPR (item) == NULL) - return false; - - if (exact) { - const gchar *attr_value = (SP_OBJECT_REPR (item))->attribute(name); - return ((bool) (attr_value != NULL)); - } else { - return SP_OBJECT_REPR (item)->matchAttributeName(name); + bool result = false; + if (item->getRepr()) { + if (exact) { + const gchar *attr_value = item->getRepr()->attribute(name); + result = (attr_value != NULL); + } else { + result = item->getRepr()->matchAttributeName(name); + } } + return result; } @@ -342,17 +348,20 @@ Find::all_items (SPObject *r, GSList *l, bool hidden, bool locked) { SPDesktop *desktop = getDesktop(); - if (SP_IS_DEFS(r)) + if (SP_IS_DEFS(r)) { return l; // we're not interested in items in defs + } - if (!strcmp (SP_OBJECT_REPR (r)->name(), "svg:metadata")) + if (!strcmp(r->getRepr()->name(), "svg:metadata")) { return l; // we're not interested in metadata + } for (SPObject *child = r->firstChild(); child; child = child->getNext()) { - if (SP_IS_ITEM (child) && !SP_OBJECT_IS_CLONED (child) && !desktop->isLayer(SP_ITEM(child))) { - if ((hidden || !desktop->itemIsHidden(SP_ITEM(child))) && (locked || !SP_ITEM(child)->isLocked())) { - l = g_slist_prepend (l, child); - } + if (SP_IS_ITEM(child) && !child->cloned && !desktop->isLayer(SP_ITEM(child))) { + SPItem *item = reinterpret_cast<SPItem *>(child); + if ((hidden || !desktop->itemIsHidden(item)) && (locked || !item->isLocked())) { + l = g_slist_prepend (l, child); + } } l = all_items (child, l, hidden, locked); } @@ -365,9 +374,10 @@ Find::all_selection_items (Inkscape::Selection *s, GSList *l, SPObject *ancestor SPDesktop *desktop = getDesktop(); for (GSList *i = (GSList *) s->itemList(); i != NULL; i = i->next) { - if (SP_IS_ITEM (i->data) && !SP_OBJECT_IS_CLONED (i->data) && !desktop->isLayer(SP_ITEM(i->data))) { - if (!ancestor || ancestor->isAncestorOf(SP_OBJECT (i->data))) { - if ((hidden || !desktop->itemIsHidden(SP_ITEM(i->data))) && (locked || !SP_ITEM(i->data)->isLocked())) { + if (SP_IS_ITEM (i->data) && !reinterpret_cast<SPItem *>(i->data)->cloned && !desktop->isLayer(SP_ITEM(i->data))) { + SPItem *item = reinterpret_cast<SPItem *>(i->data); + if (!ancestor || ancestor->isAncestorOf(item)) { + if ((hidden || !desktop->itemIsHidden(item)) && (locked || !item->isLocked())) { l = g_slist_prepend (l, i->data); } } @@ -524,3 +534,14 @@ Find::squeeze_window() } // 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/guides.cpp b/src/ui/dialog/guides.cpp index 1ab0d51bc..bd9777048 100644 --- a/src/ui/dialog/guides.cpp +++ b/src/ui/dialog/guides.cpp @@ -109,7 +109,7 @@ void GuidelinePropertiesDialog::_onApply() sp_guide_moveto(*_guide, newpos, true); - DocumentUndo::done(SP_OBJECT_DOCUMENT(_guide), SP_VERB_NONE, + DocumentUndo::done(_guide->document, SP_VERB_NONE, _("Set guide properties")); } @@ -120,7 +120,7 @@ void GuidelinePropertiesDialog::_onOK() void GuidelinePropertiesDialog::_onDelete() { - SPDocument *doc = SP_OBJECT_DOCUMENT(_guide); + SPDocument *doc = _guide->document; sp_guide_remove(_guide); DocumentUndo::done(doc, SP_VERB_NONE, _("Delete guide")); @@ -235,7 +235,7 @@ void GuidelinePropertiesDialog::_setup() { } { - Inkscape::XML::Node *repr = SP_OBJECT_REPR (_guide); + Inkscape::XML::Node *repr = _guide->getRepr(); const gchar *guide_id = repr->attribute("id"); gchar *label = g_strdup_printf(_("Guideline ID: %s"), guide_id); _label_name.set_label(label); diff --git a/src/ui/dialog/icon-preview.cpp b/src/ui/dialog/icon-preview.cpp index 4ba63b448..4d98793bb 100644 --- a/src/ui/dialog/icon-preview.cpp +++ b/src/ui/dialog/icon-preview.cpp @@ -356,7 +356,7 @@ void IconPreviewPanel::refreshPreview() GSList const *items = sel->itemList(); while ( items && !target ) { SPItem* item = SP_ITEM( items->data ); - SPObject * obj = SP_OBJECT(item); + SPObject * obj = item; gchar const *id = obj->getId(); if ( id ) { targetId = id; @@ -428,7 +428,7 @@ void IconPreviewPanel::modeToggled() void IconPreviewPanel::renderPreview( SPObject* obj ) { - SPDocument * doc = SP_OBJECT_DOCUMENT(obj); + SPDocument * doc = obj->document; gchar const * id = obj->getId(); if ( !renderTimer ) { renderTimer = new Glib::Timer(); diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp index 13491312a..8681ed98f 100644 --- a/src/ui/dialog/inkscape-preferences.cpp +++ b/src/ui/dialog/inkscape-preferences.cpp @@ -393,7 +393,7 @@ void InkscapePreferences::initPageTools() Gtk::TreeModel::iterator iter_tools = this->AddPage(_page_tools, _("Tools"), PREFS_PAGE_TOOLS); _path_tools = _page_list.get_model()->get_path(iter_tools); - _page_tools.add_group_header( _("Bounding box to use:")); + _page_tools.add_group_header( _("Bounding box to use")); _t_bbox_visual.init ( _("Visual bounding box"), "/tools/bounding_box", 0, false, 0); // 0 means visual _page_tools.add_line( true, "", _t_bbox_visual, "", _("This bounding box includes stroke width, markers, filter margins, etc.")); @@ -401,7 +401,7 @@ void InkscapePreferences::initPageTools() _page_tools.add_line( true, "", _t_bbox_geometric, "", _("This bounding box includes only the bare path")); - _page_tools.add_group_header( _("Conversion to guides:")); + _page_tools.add_group_header( _("Conversion to guides")); _t_cvg_keep_objects.init ( _("Keep objects after conversion to guides"), "/tools/cvg_keep_objects", false); _page_tools.add_line( true, "", _t_cvg_keep_objects, "", _("When converting an object to guides, don't delete the object after the conversion")); @@ -418,14 +418,14 @@ void InkscapePreferences::initPageTools() this->AddPage(_page_selector, _("Selector"), iter_tools, PREFS_PAGE_TOOLS_SELECTOR); AddSelcueCheckbox(_page_selector, "/tools/select", false); - _page_selector.add_group_header( _("When transforming, show:")); + _page_selector.add_group_header( _("When transforming, show")); _t_sel_trans_obj.init ( _("Objects"), "/tools/select/show", "content", true, 0); _page_selector.add_line( true, "", _t_sel_trans_obj, "", _("Show the actual objects when moving or transforming")); _t_sel_trans_outl.init ( _("Box outline"), "/tools/select/show", "outline", false, &_t_sel_trans_obj); _page_selector.add_line( true, "", _t_sel_trans_outl, "", _("Show only a box outline of the objects when moving or transforming")); - _page_selector.add_group_header( _("Per-object selection cue:")); + _page_selector.add_group_header( _("Per-object selection cue")); _t_sel_cue_none.init ( _("None"), "/options/selcue/value", Inkscape::SelCue::NONE, false, 0); _page_selector.add_line( true, "", _t_sel_cue_none, "", _("No per-object selection indication")); @@ -646,20 +646,20 @@ void InkscapePreferences::initPageClones() _clone_option_delete.init ( _("Are deleted"), "/options/cloneorphans/value", SP_CLONE_ORPHANS_DELETE, false, &_clone_option_unlink); - _page_clones.add_group_header( _("When the original moves, its clones and linked offsets:")); + _page_clones.add_group_header( _("Moving original: clones and linked offsets")); _page_clones.add_line( true, "", _clone_option_parallel, "", _("Clones are translated by the same vector as their original")); _page_clones.add_line( true, "", _clone_option_stay, "", _("Clones preserve their positions when their original is moved")); _page_clones.add_line( true, "", _clone_option_transform, "", _("Each clone moves according to the value of its transform= attribute; for example, a rotated clone will move in a different direction than its original")); - _page_clones.add_group_header( _("When the original is deleted, its clones:")); + _page_clones.add_group_header( _("Deleting original: clones")); _page_clones.add_line( true, "", _clone_option_unlink, "", _("Orphaned clones are converted to regular objects")); _page_clones.add_line( true, "", _clone_option_delete, "", _("Orphaned clones are deleted along with their original")); - _page_clones.add_group_header( _("When duplicating original+clones:")); + _page_clones.add_group_header( _("Duplicating original+clones/linked offset")); _clone_relink_on_duplicate.init ( _("Relink duplicated clones"), "/options/relinkclonesonduplicate/value", false); _page_clones.add_line(true, "", _clone_relink_on_duplicate, "", @@ -1220,24 +1220,8 @@ void InkscapePreferences::initPageBitmaps() _misc_bitmap_autoreload.init(_("Automatically reload bitmaps"), "/options/bitmapautoreload/value", true); _page_bitmaps.add_line( false, "", _misc_bitmap_autoreload, "", _("Automatically reload linked images when file is changed on disk")); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - Glib::ustring choices = prefs->getString("/options/bitmapeditor/choices"); - if (!choices.empty()) { - gchar** splits = g_strsplit(choices.data(), ",", 0); - gint numIems = g_strv_length(splits); - - Glib::ustring labels[numIems]; - int values[numIems]; - for ( gint i = 0; i < numIems; i++) { - values[i] = i; - labels[i] = splits[i]; - } - _misc_bitmap_editor.init("/options/bitmapeditor/value", labels, values, numIems, 0); - _page_bitmaps.add_line( false, _("Bitmap editor:"), _misc_bitmap_editor, "", "", false); - - g_strfreev(splits); - } - + _misc_bitmap_editor.init("/options/bitmapeditor/value", true); + _page_bitmaps.add_line( false, _("Bitmap editor:"), _misc_bitmap_editor, "", "", true); _bitmap_copy_res.init("/options/createbitmap/resolution", 1.0, 6000.0, 1.0, 1.0, PX_PER_IN, true, false); _page_bitmaps.add_line( false, _("Resolution for Create Bitmap Copy:"), _bitmap_copy_res, _("dpi"), _("Resolution used by the Create Bitmap Copy command"), false); diff --git a/src/ui/dialog/inkscape-preferences.h b/src/ui/dialog/inkscape-preferences.h index 5ee916e4c..a20278551 100644 --- a/src/ui/dialog/inkscape-preferences.h +++ b/src/ui/dialog/inkscape-preferences.h @@ -28,6 +28,7 @@ #include <gtkmm/frame.h> #include <gtkmm/notebook.h> #include "ui/widget/preferences-widget.h" +#include <stddef.h> #include <sigc++/sigc++.h> #include <glibmm/i18n.h> #include <gtkmm/textview.h> @@ -297,7 +298,7 @@ protected: UI::Widget::PrefCheckButton _spell_ignoreallcaps; UI::Widget::PrefCombo _misc_overs_bitmap; - UI::Widget::PrefCombo _misc_bitmap_editor; + UI::Widget::PrefEntryFileButtonHBox _misc_bitmap_editor; UI::Widget::PrefCheckButton _misc_bitmap_autoreload; UI::Widget::PrefSpinButton _bitmap_copy_res; diff --git a/src/ui/dialog/input.cpp b/src/ui/dialog/input.cpp index 8f19c90c4..6869aa97b 100644 --- a/src/ui/dialog/input.cpp +++ b/src/ui/dialog/input.cpp @@ -347,7 +347,7 @@ static std::map<Gdk::InputMode, Glib::ustring> &getModeToString() static std::map<Gdk::InputMode, Glib::ustring> mapping; if (mapping.empty()) { mapping[Gdk::MODE_DISABLED] = _("Disabled"); - mapping[Gdk::MODE_SCREEN] = _("Screen"); + mapping[Gdk::MODE_SCREEN] = C_("Input device", "Screen"); mapping[Gdk::MODE_WINDOW] = _("Window"); } @@ -877,8 +877,8 @@ InputDialogImpl::ConfPanel::ConfPanel() : tree(store), treeScroller(), watcher(*this), - useExt(_("Use pressure-sensitive tablet (requires restart)")), - save(_("Save")) + useExt(_("_Use pressure-sensitive tablet (requires restart)"), true), + save(_("_Save"), true) { pack_start(treeScroller); diff --git a/src/ui/dialog/ocaldialogs.cpp b/src/ui/dialog/ocaldialogs.cpp index d3887b1ca..2ae7d6989 100644 --- a/src/ui/dialog/ocaldialogs.cpp +++ b/src/ui/dialog/ocaldialogs.cpp @@ -470,7 +470,7 @@ void FileImportFromOCALDialog::searchTagEntryChangedCallback() doc = xmlReadIO ((xmlInputReadCallback) vfs_read_callback, (xmlInputCloseCallback) gnome_vfs_close, from_handle, uri.c_str(), NULL, - XML_PARSE_RECOVER); + XML_PARSE_RECOVER + XML_PARSE_NOWARNING + XML_PARSE_NOERROR); if (doc == NULL) { sp_ui_error_dialog(_("Server supplied malformed Clip Art feed")); g_warning("Failed to parse %s\n", uri.c_str()); diff --git a/src/ui/dialog/svg-fonts-dialog.cpp b/src/ui/dialog/svg-fonts-dialog.cpp index 042acb6e1..2d1b5ae39 100644 --- a/src/ui/dialog/svg-fonts-dialog.cpp +++ b/src/ui/dialog/svg-fonts-dialog.cpp @@ -114,7 +114,7 @@ void SvgFontsDialog::AttrEntry::on_attr_changed(){ const gchar* name = (const gchar*)sp_attribute_name(this->attr); if(name && o) { - SP_OBJECT_REPR(o)->setAttribute((const gchar*) name, this->entry.get_text().c_str()); + o->getRepr()->setAttribute((const gchar*) name, this->entry.get_text().c_str()); o->parent->requestModified(SP_OBJECT_MODIFIED_FLAG); Glib::ustring undokey = "svgfonts:"; @@ -438,7 +438,7 @@ SPGlyph *new_glyph(SPDocument* document, SPFont *font, const int count) repr->setAttribute("glyph-name", os.str().c_str()); // Append the new glyph node to the current font - SP_OBJECT_REPR(font)->appendChild(repr); + font->getRepr()->appendChild(repr); Inkscape::GC::release(repr); // get corresponding object @@ -498,7 +498,7 @@ void SvgFontsDialog::set_glyph_description_from_selected_path(){ Geom::PathVector pathv = sp_svg_read_pathv(node->attribute("d")); //This matrix flips the glyph vertically - Geom::Matrix m(Geom::Coord(1),Geom::Coord(0),Geom::Coord(0),Geom::Coord(-1),Geom::Coord(0),Geom::Coord(0)); + Geom::Affine m(Geom::Coord(1),Geom::Coord(0),Geom::Coord(0),Geom::Coord(-1),Geom::Coord(0),Geom::Coord(0)); pathv*=m; //then we offset it pathv+=Geom::Point(Geom::Coord(0),Geom::Coord(get_selected_spfont()->horiz_adv_x)); @@ -543,7 +543,7 @@ void SvgFontsDialog::missing_glyph_description_from_selected_path(){ Geom::PathVector pathv = sp_svg_read_pathv(node->attribute("d")); //This matrix flips the glyph vertically - Geom::Matrix m(Geom::Coord(1),Geom::Coord(0),Geom::Coord(0),Geom::Coord(-1),Geom::Coord(0),Geom::Coord(0)); + Geom::Affine m(Geom::Coord(1),Geom::Coord(0),Geom::Coord(0),Geom::Coord(-1),Geom::Coord(0),Geom::Coord(0)); pathv*=m; //then we offset it // pathv+=Geom::Point(Geom::Coord(0),Geom::Coord(get_selected_spfont()->horiz_adv_x)); @@ -732,7 +732,7 @@ void SvgFontsDialog::add_kerning_pair(){ repr->setAttribute("k", "0"); // Append the new hkern node to the current font - SP_OBJECT_REPR(get_selected_spfont())->appendChild(repr); + get_selected_spfont()->getRepr()->appendChild(repr); Inkscape::GC::release(repr); // get corresponding object @@ -797,7 +797,7 @@ SPFont *new_font(SPDocument *document) repr->setAttribute("horiz-adv-x", "1024"); // Append the new font node to defs - SP_OBJECT_REPR(defs)->appendChild(repr); + defs->getRepr()->appendChild(repr); //create a missing glyph Inkscape::XML::Node *fontface; diff --git a/src/ui/dialog/tile.cpp b/src/ui/dialog/tile.cpp index fccf5c105..b0a39bd0e 100644 --- a/src/ui/dialog/tile.cpp +++ b/src/ui/dialog/tile.cpp @@ -316,7 +316,7 @@ g_print("\n row = %f col = %f selection x= %f selection y = %f", total_row_h for (; current_row != NULL; current_row = current_row->next) { SPItem *item=SP_ITEM(current_row->data); - Inkscape::XML::Node *repr = SP_OBJECT_REPR(item); + Inkscape::XML::Node *repr = item->getRepr(); Geom::OptRect b = item->getBounds(item->i2doc_affine()); Geom::Point min; if (b) { @@ -336,7 +336,7 @@ g_print("\n row = %f col = %f selection x= %f selection y = %f", total_row_h // 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::Matrix const affine = Geom::Matrix(Geom::Translate(move)); + Geom::Affine const affine = Geom::Affine(Geom::Translate(move)); item->set_i2d_affine(item->i2d_affine() * affine); item->doWriteTransform(repr, item->transform, NULL); SP_OBJECT (current_row->data)->updateRepr(); @@ -656,7 +656,8 @@ TileDialog::TileDialog() g_print("/n PerRox = %f PerCol = %f selcount = %d",PerRow,PerCol,selcount); #endif - NoOfRowsLabel.set_label(_("Rows:")); + NoOfRowsLabel.set_text_with_mnemonic(_("_Rows:")); + NoOfRowsLabel.set_mnemonic_widget(NoOfRowsSpinner); NoOfRowsBox.pack_start(NoOfRowsLabel, false, false, MARGIN); NoOfRowsSpinner.set_digits(0); @@ -668,7 +669,8 @@ TileDialog::TileDialog() NoOfRowsBox.pack_start(NoOfRowsSpinner, false, false, MARGIN); gtk_size_group_add_widget(_col1, (GtkWidget *) NoOfRowsBox.gobj()); - RowHeightButton.set_label(_("Equal height")); + RowHeightButton.set_label(_("Equal _height")); + RowHeightButton.set_use_underline(true); double AutoRow = prefs->getDouble("/dialogs/gridtiler/AutoRowSize", 15); if (AutoRow>0) AutoRowSize=true; @@ -726,7 +728,8 @@ TileDialog::TileDialog() /*#### Number of columns ####*/ - NoOfColsLabel.set_label(_("Columns:")); + NoOfColsLabel.set_text_with_mnemonic(_("_Columns:")); + NoOfColsLabel.set_mnemonic_widget(NoOfColsSpinner); NoOfColsBox.pack_start(NoOfColsLabel, false, false, MARGIN); NoOfColsSpinner.set_digits(0); @@ -738,7 +741,8 @@ TileDialog::TileDialog() NoOfColsBox.pack_start(NoOfColsSpinner, false, false, MARGIN); gtk_size_group_add_widget(_col3, (GtkWidget *) NoOfColsBox.gobj()); - ColumnWidthButton.set_label(_("Equal width")); + ColumnWidthButton.set_label(_("Equal _width")); + ColumnWidthButton.set_use_underline(true); double AutoCol = prefs->getDouble("/dialogs/gridtiler/AutoColSize", 15); if (AutoCol>0) AutoColSize=true; @@ -793,13 +797,15 @@ TileDialog::TileDialog() { /*#### Radio buttons to control spacing manually or to fit selection bbox ####*/ - SpaceByBBoxRadioButton.set_label(_("Fit into selection box")); + 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_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); @@ -867,7 +873,8 @@ TileDialog::TileDialog() SizesHBox.set_sensitive (ManualSpacing); //## The OK button - TileOkButton = addResponseButton(Q_("tileClonesDialog|Arrange"), GTK_RESPONSE_APPLY); + TileOkButton = addResponseButton(C_("Rows and columns dialog","_Arrange"), GTK_RESPONSE_APPLY); + TileOkButton->set_use_underline(true); tips.set_tip((*TileOkButton), _("Arrange selected objects")); show_all_children(); diff --git a/src/ui/dialog/transformation.cpp b/src/ui/dialog/transformation.cpp index 1bca2ffff..901d02240 100644 --- a/src/ui/dialog/transformation.cpp +++ b/src/ui/dialog/transformation.cpp @@ -103,7 +103,7 @@ Transformation::Transformation() _scalar_transform_f ("_F:", _("Transformation matrix element F")), _check_move_relative (_("Rela_tive move"), _("Add the specified relative displacement to the current position; otherwise, edit the current absolute position directly")), - _check_scale_proportional (_("Scale proportionally"), _("Preserve the width/height ratio of the scaled objects")), + _check_scale_proportional (_("_Scale proportionally"), _("Preserve the width/height ratio of the scaled objects")), _check_apply_separately (_("Apply to each _object separately"), _("Apply the scale/rotate/skew to each selected object separately; otherwise, transform the selection as a whole")), _check_replace_matrix (_("Edit c_urrent matrix"), _("Edit the current transform= matrix; otherwise, post-multiply transform= by this matrix")) @@ -538,9 +538,9 @@ Transformation::updatePageTransform(Inkscape::Selection *selection) { if (selection && !selection->isEmpty()) { if (_check_replace_matrix.get_active()) { - Geom::Matrix current (SP_ITEM(selection->itemList()->data)->transform); // take from the first item in selection + Geom::Affine current (SP_ITEM(selection->itemList()->data)->transform); // take from the first item in selection - Geom::Matrix new_displayed = current; + Geom::Affine new_displayed = current; _scalar_transform_a.setValue(new_displayed[0]); _scalar_transform_b.setValue(new_displayed[1]); @@ -840,7 +840,7 @@ Transformation::applyPageTransform(Inkscape::Selection *selection) double e = _scalar_transform_e.getValue(); double f = _scalar_transform_f.getValue(); - Geom::Matrix displayed(a, b, c, d, e, f); + Geom::Affine displayed(a, b, c, d, e, f); if (_check_replace_matrix.get_active()) { for (GSList const *l = selection->itemList(); l != NULL; l = l->next) { @@ -988,10 +988,10 @@ Transformation::onReplaceMatrixToggled() double e = _scalar_transform_e.getValue(); double f = _scalar_transform_f.getValue(); - Geom::Matrix displayed (a, b, c, d, e, f); - Geom::Matrix current = SP_ITEM(selection->itemList()->data)->transform; // take from the first item in selection + Geom::Affine displayed (a, b, c, d, e, f); + Geom::Affine current = SP_ITEM(selection->itemList()->data)->transform; // take from the first item in selection - Geom::Matrix new_displayed; + Geom::Affine new_displayed; if (_check_replace_matrix.get_active()) { new_displayed = current; } else { diff --git a/src/ui/dialog/undo-history.cpp b/src/ui/dialog/undo-history.cpp index 17d032758..e6f113e48 100644 --- a/src/ui/dialog/undo-history.cpp +++ b/src/ui/dialog/undo-history.cpp @@ -15,6 +15,7 @@ #include <glibmm/i18n.h> #include <gtk/gtkimage.h> +#include <stddef.h> #include <sigc++/sigc++.h> diff --git a/src/ui/tool/control-point-selection.cpp b/src/ui/tool/control-point-selection.cpp index 91e0bc2c2..1fb98d78f 100644 --- a/src/ui/tool/control-point-selection.cpp +++ b/src/ui/tool/control-point-selection.cpp @@ -166,7 +166,7 @@ void ControlPointSelection::spatialGrow(SelectableControlPoint *origin, int dir) } /** Transform all selected control points by the given affine transformation. */ -void ControlPointSelection::transform(Geom::Matrix const &m) +void ControlPointSelection::transform(Geom::Affine const &m) { for (iterator i = _points.begin(); i != _points.end(); ++i) { SelectableControlPoint *cur = *i; @@ -273,7 +273,7 @@ void ControlPointSelection::_pointGrabbed(SelectableControlPoint *point) _grabbed_point = point; _farthest_point = point; double maxdist = 0; - Geom::Matrix m; + Geom::Affine m; m.setIdentity(); for (iterator i = _points.begin(); i != _points.end(); ++i) { _original_positions.insert(std::make_pair(*i, (*i)->position())); @@ -290,11 +290,11 @@ void ControlPointSelection::_pointDragged(Geom::Point &new_pos, GdkEventMotion * { Geom::Point abs_delta = new_pos - _original_positions[_grabbed_point]; double fdist = Geom::distance(_original_positions[_grabbed_point], _original_positions[_farthest_point]); - if (held_alt(*event) && fdist > 0) { + if (held_only_alt(*event) && fdist > 0) { // Sculpting for (iterator i = _points.begin(); i != _points.end(); ++i) { SelectableControlPoint *cur = (*i); - Geom::Matrix trans; + Geom::Affine trans; trans.setIdentity(); double dist = Geom::distance(_original_positions[cur], _original_positions[_grabbed_point]); double deltafrac = 0.5 + 0.5 * cos(M_PI * dist/fdist); @@ -323,7 +323,7 @@ void ControlPointSelection::_pointDragged(Geom::Point &new_pos, GdkEventMotion * Geom::Point newdx = (newpx - newp) / Geom::EPSILON; Geom::Point newdy = (newpy - newp) / Geom::EPSILON; - Geom::Matrix itrans(newdx[Geom::X], newdx[Geom::Y], newdy[Geom::X], newdy[Geom::Y], 0, 0); + Geom::Affine itrans(newdx[Geom::X], newdx[Geom::Y], newdy[Geom::X], newdy[Geom::Y], 0, 0); if (itrans.isSingular()) itrans.setIdentity(); @@ -502,7 +502,7 @@ bool ControlPointSelection::_keyboardRotate(GdkEventKey const &event, int dir) } // translate to origin, rotate, translate back to original position - Geom::Matrix m = Geom::Translate(-rc) + Geom::Affine m = Geom::Translate(-rc) * Geom::Rotate(angle) * Geom::Translate(rc); transform(m); signal_commit.emit(COMMIT_KEYBOARD_ROTATE); @@ -538,7 +538,7 @@ bool ControlPointSelection::_keyboardScale(GdkEventKey const &event, int dir) } double scale = (maxext + length_change) / maxext; - Geom::Matrix m = Geom::Translate(-center) * Geom::Scale(scale) * Geom::Translate(center); + Geom::Affine m = Geom::Translate(-center) * Geom::Scale(scale) * Geom::Translate(center); transform(m); signal_commit.emit(COMMIT_KEYBOARD_SCALE_UNIFORM); return true; @@ -559,7 +559,7 @@ bool ControlPointSelection::_keyboardFlip(Geom::Dim2 d) dynamic_cast<SelectableControlPoint*>(ControlPoint::mouseovered_point); Geom::Point center = scp ? scp->position() : _handles->rotationCenter().position(); - Geom::Matrix m = Geom::Translate(-center) * scale_transform * Geom::Translate(center); + Geom::Affine m = Geom::Translate(-center) * scale_transform * Geom::Translate(center); transform(m); signal_commit.emit(d == Geom::X ? COMMIT_FLIP_X : COMMIT_FLIP_Y); return true; @@ -642,6 +642,24 @@ bool ControlPointSelection::event(GdkEvent *event) return false; } +std::vector<Inkscape::SnapCandidatePoint> ControlPointSelection::getOriginalPoints() +{ + std::vector<Inkscape::SnapCandidatePoint> points; + for (iterator i = _points.begin(); i != _points.end(); ++i) { + points.push_back(Inkscape::SnapCandidatePoint(_original_positions[*i], SNAPSOURCE_NODE_HANDLE)); + } + return points; +} + +void ControlPointSelection::setOriginalPoints() +{ + _original_positions.clear(); + for (iterator i = _points.begin(); i != _points.end(); ++i) { + _original_positions.insert(std::make_pair(*i, (*i)->position())); + } +} + + } // namespace UI } // namespace Inkscape diff --git a/src/ui/tool/control-point-selection.h b/src/ui/tool/control-point-selection.h index 3aed6ae93..7e09d50f5 100644 --- a/src/ui/tool/control-point-selection.h +++ b/src/ui/tool/control-point-selection.h @@ -14,17 +14,19 @@ #include <memory> #include <boost/optional.hpp> +#include <stddef.h> #include <sigc++/sigc++.h> #include <2geom/forward.h> #include <2geom/point.h> #include <2geom/rect.h> -#include "display/display-forward.h" #include "util/accumulators.h" #include "util/unordered-containers.h" #include "ui/tool/commit-events.h" #include "ui/tool/manipulator.h" +#include "snap-candidate.h" class SPDesktop; +struct SPCanvasGroup; namespace Inkscape { namespace UI { @@ -90,7 +92,7 @@ public: virtual bool event(GdkEvent *); - void transform(Geom::Matrix const &m); + void transform(Geom::Affine const &m); void align(Geom::Dim2 d); void distribute(Geom::Dim2 d); @@ -108,6 +110,10 @@ public: sigc::signal<void> signal_update; sigc::signal<void, SelectableControlPoint *, bool> signal_point_changed; sigc::signal<void, CommitEvent> signal_commit; + + std::vector<Inkscape::SnapCandidatePoint> getOriginalPoints(); + void setOriginalPoints(); + private: // The functions below are invoked from SelectableControlPoint. // Previously they were connected to handlers when selecting, but this @@ -125,14 +131,14 @@ private: bool _keyboardRotate(GdkEventKey const &, int); bool _keyboardScale(GdkEventKey const &, int); bool _keyboardFlip(Geom::Dim2); - void _keyboardTransform(Geom::Matrix const &); + void _keyboardTransform(Geom::Affine const &); void _commitHandlesTransform(CommitEvent ce); double _rotationRadius(Geom::Point const &); set_type _points; set_type _all_points; INK_UNORDERED_MAP<SelectableControlPoint *, Geom::Point> _original_positions; - INK_UNORDERED_MAP<SelectableControlPoint *, Geom::Matrix> _last_trans; + INK_UNORDERED_MAP<SelectableControlPoint *, Geom::Affine> _last_trans; boost::optional<double> _rot_radius; boost::optional<double> _mouseover_rot_radius; Geom::OptRect _bounds; diff --git a/src/ui/tool/control-point.cpp b/src/ui/tool/control-point.cpp index d5e5b7dfe..bece1324b 100644 --- a/src/ui/tool/control-point.cpp +++ b/src/ui/tool/control-point.cpp @@ -14,6 +14,7 @@ #include <2geom/point.h> #include "desktop.h" #include "desktop-handles.h" +#include "display/sp-canvas.h" #include "display/snap-indicator.h" #include "event-context.h" #include "message-context.h" @@ -213,7 +214,7 @@ void ControlPoint::move(Geom::Point const &pos) /** Apply an arbitrary affine transformation to a control point. This is used * by ControlPointSelection, and is important for things like nodes with handles. * The default implementation simply moves the point according to the transform. */ -void ControlPoint::transform(Geom::Matrix const &m) { +void ControlPoint::transform(Geom::Affine const &m) { move(position() * m); } diff --git a/src/ui/tool/control-point.h b/src/ui/tool/control-point.h index 4de5e5847..9f62fca42 100644 --- a/src/ui/tool/control-point.h +++ b/src/ui/tool/control-point.h @@ -12,12 +12,12 @@ #define SEEN_UI_TOOL_CONTROL_POINT_H #include <boost/utility.hpp> +#include <stddef.h> #include <sigc++/sigc++.h> #include <gdkmm.h> #include <gtkmm.h> #include <2geom/point.h> -#include "display/display-forward.h" #include "forward.h" #include "util/accumulators.h" #include "display/sodipodi-ctrl.h" @@ -57,7 +57,7 @@ public: operator Geom::Point const &() { return _position; } virtual void move(Geom::Point const &pos); virtual void setPosition(Geom::Point const &pos); - virtual void transform(Geom::Matrix const &m); + virtual void transform(Geom::Affine const &m); /// @} /// @name Toggle the point's visibility diff --git a/src/ui/tool/manipulator.h b/src/ui/tool/manipulator.h index fd24e7b61..6866ec9dd 100644 --- a/src/ui/tool/manipulator.h +++ b/src/ui/tool/manipulator.h @@ -13,6 +13,7 @@ #include <set> #include <map> +#include <stddef.h> #include <sigc++/sigc++.h> #include <glib.h> #include <gdk/gdk.h> diff --git a/src/ui/tool/multi-path-manipulator.cpp b/src/ui/tool/multi-path-manipulator.cpp index ef1c764bb..082ac194b 100644 --- a/src/ui/tool/multi-path-manipulator.cpp +++ b/src/ui/tool/multi-path-manipulator.cpp @@ -210,7 +210,78 @@ void MultiPathManipulator::selectSubpaths() void MultiPathManipulator::shiftSelection(int dir) { - invokeForAll(&PathManipulator::shiftSelection, dir); + if (empty()) return; + + // 1. find last selected node + // 2. select the next node; if the last node or nothing is selected, + // select first node + MapType::iterator last_i; + SubpathList::iterator last_j; + NodeList::iterator last_k; + bool anything_found = false; + + for (MapType::iterator i = _mmap.begin(); i != _mmap.end(); ++i) { + SubpathList &sp = i->second->subpathList(); + for (SubpathList::iterator j = sp.begin(); j != sp.end(); ++j) { + for (NodeList::iterator k = (*j)->begin(); k != (*j)->end(); ++k) { + if (k->selected()) { + last_i = i; + last_j = j; + last_k = k; + anything_found = true; + // when tabbing backwards, we want the first node + if (dir == -1) goto exit_loop; + } + } + } + } + exit_loop: + + // NOTE: we should not assume the _selection contains only nodes + // in future it might also contain handles and other types of control points + // this is why we use a flag instead in the loop above, instead of calling + // selection.empty() + if (!anything_found) { + // select first / last node + // this should never fail because there must be at least 1 non-empty manipulator + if (dir == 1) { + _selection.insert((*_mmap.begin()->second->subpathList().begin())->begin().ptr()); + } else { + _selection.insert((--(*--(--_mmap.end())->second->subpathList().end())->end()).ptr()); + } + return; + } + + // three levels deep - w00t! + if (dir == 1) { + if (++last_k == (*last_j)->end()) { + // here, last_k points to the node to be selected + ++last_j; + if (last_j == last_i->second->subpathList().end()) { + ++last_i; + if (last_i == _mmap.end()) { + last_i = _mmap.begin(); + } + last_j = last_i->second->subpathList().begin(); + } + last_k = (*last_j)->begin(); + } + } else { + if (!last_k || last_k == (*last_j)->begin()) { + if (last_j == last_i->second->subpathList().begin()) { + if (last_i == _mmap.begin()) { + last_i = _mmap.end(); + } + --last_i; + last_j = last_i->second->subpathList().end(); + } + --last_j; + last_k = (*last_j)->end(); + } + --last_k; + } + _selection.clear(); + _selection.insert(last_k.ptr()); } void MultiPathManipulator::invertSelectionInSubpaths() @@ -695,6 +766,14 @@ void MultiPathManipulator::_commit(CommitEvent cps) reason = _("Scale nodes vertically"); key = "node:scale:y"; break; + case COMMIT_MOUSE_SKEW_X: + reason = _("Skew nodes horizontally"); + key = "node:skew:x"; + break; + case COMMIT_MOUSE_SKEW_Y: + reason = _("Skew nodes vertically"); + key = "node:skew:y"; + break; case COMMIT_FLIP_X: reason = _("Flip nodes horizontally"); break; diff --git a/src/ui/tool/multi-path-manipulator.h b/src/ui/tool/multi-path-manipulator.h index ddb74c1bc..c25719790 100644 --- a/src/ui/tool/multi-path-manipulator.h +++ b/src/ui/tool/multi-path-manipulator.h @@ -11,8 +11,8 @@ #ifndef SEEN_UI_TOOL_MULTI_PATH_MANIPULATOR_H #define SEEN_UI_TOOL_MULTI_PATH_MANIPULATOR_H +#include <stddef.h> #include <sigc++/connection.h> -#include "display/display-forward.h" #include "forward.h" #include "ui/tool/commit-events.h" #include "ui/tool/manipulator.h" diff --git a/src/ui/tool/node-tool.cpp b/src/ui/tool/node-tool.cpp index 8661e7946..f83f8c473 100644 --- a/src/ui/tool/node-tool.cpp +++ b/src/ui/tool/node-tool.cpp @@ -13,6 +13,7 @@ #include <glib/gi18n.h> #include "desktop.h" #include "desktop-handles.h" +#include "display/sp-canvas-group.h" #include "display/canvas-bpath.h" #include "display/curve.h" #include "display/sp-canvas.h" @@ -479,10 +480,11 @@ gint ink_node_tool_root_handler(SPEventContext *event_context, GdkEvent *event) nt->flash_tempitem = NULL; nt->flashed_item = NULL; } - if (!SP_IS_PATH(over_item)) break; // for now, handle only paths + if (!SP_IS_SHAPE(over_item)) break; // for now, handle only shapes nt->flashed_item = over_item; - SPCurve *c = sp_path_get_curve_for_edit(SP_PATH(over_item)); + SPCurve *c = SP_SHAPE(over_item)->getCurveBeforeLPE(); + if (!c) break; // break out when curve doesn't exist c->transform(over_item->i2d_affine()); SPCanvasItem *flash = sp_canvas_bpath_new(sp_desktop_tempgroup(desktop), c); sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(flash), diff --git a/src/ui/tool/node-tool.h b/src/ui/tool/node-tool.h index 4d38e69e2..d005a0bdf 100644 --- a/src/ui/tool/node-tool.h +++ b/src/ui/tool/node-tool.h @@ -14,10 +14,10 @@ #include <memory> #include <boost/ptr_container/ptr_map.hpp> #include <glib.h> +#include <stddef.h> #include <sigc++/sigc++.h> #include "event-context.h" #include "forward.h" -#include "display/display-forward.h" #include "ui/tool/node-types.h" #define INK_TYPE_NODE_TOOL (ink_node_tool_get_type ()) @@ -30,13 +30,17 @@ class InkNodeTool; class InkNodeToolClass; namespace Inkscape { + +namespace Display { +class TemporaryItem; +} // namespace Display namespace UI { class MultiPathManipulator; class ControlPointSelection; class Selector; struct PathSharedData; -} -} +} // namespace UI +} // namespace Inkscape typedef std::auto_ptr<Inkscape::UI::MultiPathManipulator> MultiPathPtr; typedef std::auto_ptr<Inkscape::UI::ControlPointSelection> CSelPtr; diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp index 12d04dd2b..8e3da266b 100644 --- a/src/ui/tool/node.cpp +++ b/src/ui/tool/node.cpp @@ -113,12 +113,29 @@ void Handle::move(Geom::Point const &new_pos) Handle *towards_second = node_towards ? node_towards->handleToward(_parent) : NULL; if (Geom::are_near(new_pos, _parent->position())) { - // The handle becomes degenerate. If the segment between it and the node + // The handle becomes degenerate. + // Adjust node type as necessary. + if (other->isDegenerate()) { + // If both handles become degenerate, convert to parent cusp node + _parent->setType(NODE_CUSP, false); + } else { + // Only 1 handle becomes degenerate + switch (_parent->type()) { + case NODE_AUTO: + case NODE_SYMMETRIC: + _parent->setType(NODE_SMOOTH, false); + break; + default: + // do nothing for other node types + break; + } + } + // If the segment between the handle and the node // in its direction becomes linear and there are smooth nodes // at its ends, make their handles colinear with the segment - if (towards && towards->isDegenerate()) { + if (towards && towards_second->isDegenerate()) { if (node_towards->type() == NODE_SMOOTH) { - towards_second->setDirection(*_parent, *node_towards); + towards->setDirection(*_parent, *node_towards); } if (_parent->type() == NODE_SMOOTH) { other->setDirection(*node_towards, *_parent); @@ -160,6 +177,7 @@ void Handle::move(Geom::Point const &new_pos) void Handle::setPosition(Geom::Point const &p) { + Geom::Point old_pos = position(); ControlPoint::setPosition(p); sp_ctrlline_set_coords(SP_CTRLLINE(_handle_line), _parent->position(), position()); @@ -167,15 +185,12 @@ void Handle::setPosition(Geom::Point const &p) if (Geom::are_near(position(), _parent->position())) _degenerate = true; else _degenerate = false; + if (_parent->_handles_shown && _parent->visible() && !_degenerate) { setVisible(true); } else { setVisible(false); } - // If both handles become degenerate, convert to parent cusp node - if (_parent->isDegenerate()) { - _parent->setType(NODE_CUSP, false); - } } void Handle::setLength(double len) @@ -187,7 +202,7 @@ void Handle::setLength(double len) void Handle::retract() { - setPosition(_parent->position()); + move(_parent->position()); } void Handle::setDirection(Geom::Point const &from, Geom::Point const &to) @@ -212,6 +227,35 @@ char const *Handle::handle_type_to_localized_string(NodeType type) } } +bool Handle::_eventHandler(GdkEvent *event) +{ + switch (event->type) + { + case GDK_KEY_PRESS: + switch (shortcut_key(event->key)) + { + case GDK_s: + case GDK_S: + if (held_only_shift(event->key) && _parent->_type == NODE_CUSP) { + // when Shift+S is pressed when hovering over a handle belonging to a cusp node, + // hold this handle in place; otherwise process normally + // this handle is guaranteed not to be degenerate + other()->move(_parent->position() - (position() - _parent->position())); + _parent->setType(NODE_SMOOTH, false); + _parent->_pm().update(); // magic triple combo to add undo event + _parent->_pm().writeXML(); + _parent->_pm()._commit(_("Change node type")); + return true; + } + break; + default: break; + } + default: break; + } + + return ControlPoint::_eventHandler(event); +} + bool Handle::grabbed(GdkEventMotion *) { _saved_other_pos = other()->position(); @@ -226,6 +270,7 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) Geom::Point origin = _last_drag_origin(); SnapManager &sm = _desktop->namedview->snap_manager; bool snap = sm.someSnapperMightSnap(); + boost::optional<Inkscape::Snapper::SnapConstraint> ctrl_constraint; // with Alt, preserve length if (held_alt(*event)) { @@ -241,16 +286,23 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) // note: if snapping to the original position is only desired in the original // direction of the handle, change to Ray instead of Line Geom::Line original_line(parent_pos, origin); + Geom::Line perp_line(parent_pos, parent_pos + Geom::rot90(origin - parent_pos)); Geom::Point snap_pos = parent_pos + Geom::constrain_angle( Geom::Point(0,0), new_pos - parent_pos, snaps, Geom::Point(1,0)); Geom::Point orig_pos = original_line.pointAt(original_line.nearestPoint(new_pos)); + Geom::Point perp_pos = perp_line.pointAt(perp_line.nearestPoint(new_pos)); - if (Geom::distance(snap_pos, new_pos) < Geom::distance(orig_pos, new_pos)) { - new_pos = snap_pos; - } else { - new_pos = orig_pos; + Geom::Point result = snap_pos; + ctrl_constraint = Inkscape::Snapper::SnapConstraint(parent_pos, parent_pos - snap_pos); + if (Geom::distance(orig_pos, new_pos) < Geom::distance(result, new_pos)) { + result = orig_pos; + ctrl_constraint = Inkscape::Snapper::SnapConstraint(parent_pos, parent_pos - orig_pos); } - snap = false; + if (Geom::distance(perp_pos, new_pos) < Geom::distance(result, new_pos)) { + result = perp_pos; + ctrl_constraint = Inkscape::Snapper::SnapConstraint(parent_pos, parent_pos - perp_pos); + } + new_pos = result; } std::vector<Inkscape::SnapCandidatePoint> unselected; @@ -264,13 +316,20 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event) } sm.setupIgnoreSelection(_desktop, true, &unselected); - Node *node_away = (this == &_parent->_front ? _parent->_prev() : _parent->_next()); + Node *node_away = _parent->nodeAwayFrom(this); if (_parent->type() == NODE_SMOOTH && Node::_is_line_segment(_parent, node_away)) { Inkscape::Snapper::SnapConstraint cl(_parent->position(), _parent->position() - node_away->position()); Inkscape::SnappedPoint p; p = sm.constrainedSnap(Inkscape::SnapCandidatePoint(new_pos, SNAPSOURCE_NODE_HANDLE), cl); new_pos = p.getPoint(); + } else if (ctrl_constraint) { + // NOTE: this is subtly wrong. + // We should get all possible constraints and snap along them using + // multipleConstrainedSnaps, instead of first snapping to angle and the to objects + Inkscape::SnappedPoint p; + p = sm.constrainedSnap(Inkscape::SnapCandidatePoint(new_pos, SNAPSOURCE_NODE_HANDLE), *ctrl_constraint); + new_pos = p.getPoint(); } else { sm.freeSnapReturnByRef(new_pos, SNAPSOURCE_NODE_HANDLE); } @@ -455,7 +514,7 @@ void Node::move(Geom::Point const &new_pos) _fixNeighbors(old_pos, new_pos); } -void Node::transform(Geom::Matrix const &m) +void Node::transform(Geom::Affine const &m) { Geom::Point old_pos = position(); setPosition(position() * m); @@ -770,26 +829,6 @@ bool Node::_eventHandler(GdkEvent *event) return ControlPoint::_eventHandler(event); } -// TODO Move this to 2Geom! -static double bezier_length (Geom::Point a0, Geom::Point a1, Geom::Point a2, Geom::Point a3) -{ - double lower = Geom::distance(a0, a3); - double upper = Geom::distance(a0, a1) + Geom::distance(a1, a2) + Geom::distance(a2, a3); - - if (upper - lower < Geom::EPSILON) return (lower + upper)/2; - - Geom::Point // Casteljau subdivision - b0 = a0, - c0 = a3, - b1 = 0.5*(a0 + a1), - t0 = 0.5*(a1 + a2), - c1 = 0.5*(a2 + a3), - b2 = 0.5*(b1 + t0), - c2 = 0.5*(t0 + c1), - b3 = 0.5*(b2 + c2); // == c3 - return bezier_length(b0, b1, b2, b3) + bezier_length(b3, c2, c1, c0); -} - /** Select or deselect a node in this node's subpath based on its path distance from this node. * @param dir If negative, shrink selection by one node; if positive, grow by one node */ void Node::_linearGrow(int dir) @@ -816,7 +855,7 @@ void Node::_linearGrow(int dir) // find first unselected nodes on both sides while (fwd && fwd->selected()) { NodeList::iterator n = fwd.next(); - distance_front += bezier_length(*fwd, fwd->_front, n->_back, *n); + distance_front += Geom::bezier_length(*fwd, fwd->_front, n->_back, *n); fwd = n; if (fwd == this_iter) // there is no unselected node in this cyclic subpath @@ -827,7 +866,7 @@ void Node::_linearGrow(int dir) // so we are guaranteed to stop. while (rev && rev->selected()) { NodeList::iterator p = rev.prev(); - distance_back += bezier_length(*rev, rev->_back, p->_front, *p); + distance_back += Geom::bezier_length(*rev, rev->_back, p->_front, *p); rev = p; } @@ -858,7 +897,7 @@ void Node::_linearGrow(int dir) last_distance_front = distance_front; } NodeList::iterator n = fwd.next(); - if (n) distance_front += bezier_length(*fwd, fwd->_front, n->_back, *n); + if (n) distance_front += Geom::bezier_length(*fwd, fwd->_front, n->_back, *n); fwd = n; } else if (rev && (!fwd || distance_front > distance_back)) { if (rev->selected()) { @@ -866,7 +905,7 @@ void Node::_linearGrow(int dir) last_distance_back = distance_back; } NodeList::iterator p = rev.prev(); - if (p) distance_back += bezier_length(*rev, rev->_back, p->_front, *p); + if (p) distance_back += Geom::bezier_length(*rev, rev->_back, p->_front, *p); rev = p; } // Check whether we walked the entire cyclic subpath. @@ -876,8 +915,8 @@ void Node::_linearGrow(int dir) if (fwd && fwd == rev) { if (!fwd->selected()) break; NodeList::iterator fwdp = fwd.prev(), revn = rev.next(); - double df = distance_front + bezier_length(*fwdp, fwdp->_front, fwd->_back, *fwd); - double db = distance_back + bezier_length(*revn, revn->_back, rev->_front, *rev); + double df = distance_front + Geom::bezier_length(*fwdp, fwdp->_front, fwd->_back, *fwd); + double db = distance_back + Geom::bezier_length(*revn, revn->_back, rev->_front, *rev); if (df > db) { last_fwd = fwd; last_distance_front = df; diff --git a/src/ui/tool/node.h b/src/ui/tool/node.h index 0194f5053..b7145790b 100644 --- a/src/ui/tool/node.h +++ b/src/ui/tool/node.h @@ -15,6 +15,7 @@ #include <iterator> #include <iosfwd> #include <stdexcept> +#include <cstddef> #include <tr1/functional> #include <boost/utility.hpp> #include <boost/shared_ptr.hpp> @@ -102,6 +103,7 @@ public: protected: Handle(NodeSharedData const &data, Geom::Point const &initial_pos, Node *parent); + virtual bool _eventHandler(GdkEvent *event); virtual void dragged(Geom::Point &, GdkEventMotion *); virtual bool grabbed(GdkEventMotion *); virtual void ungrabbed(GdkEventButton *); @@ -127,7 +129,7 @@ class Node : ListNode, public SelectableControlPoint { public: Node(NodeSharedData const &data, Geom::Point const &pos); virtual void move(Geom::Point const &p); - virtual void transform(Geom::Matrix const &m); + virtual void transform(Geom::Affine const &m); virtual Geom::Rect bounds(); NodeType type() { return _type; } diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp index 5ae9c4137..7c2013872 100644 --- a/src/ui/tool/path-manipulator.cpp +++ b/src/ui/tool/path-manipulator.cpp @@ -102,14 +102,14 @@ private: void build_segment(Geom::PathBuilder &, Node *, Node *); PathManipulator::PathManipulator(MultiPathManipulator &mpm, SPPath *path, - Geom::Matrix const &et, guint32 outline_color, Glib::ustring lpe_key) + Geom::Affine const &et, guint32 outline_color, Glib::ustring lpe_key) : PointManipulator(mpm._path_data.node_data.desktop, *mpm._path_data.node_data.selection) , _subpaths(*this) , _multi_path_manipulator(mpm) , _path(path) , _spcurve(new SPCurve()) , _dragpoint(new CurveDragPoint(*this)) - , /* XML Tree being used here directly while it shouldn't be*/_observer(new PathManipulatorObserver(this, SP_OBJECT(path)->getRepr())) + , /* XML Tree being used here directly while it shouldn't be*/_observer(new PathManipulatorObserver(this, path->getRepr())) , _edit_transform(et) , _num_selected(0) , _show_handles(true) @@ -191,7 +191,7 @@ void PathManipulator::writeXML() if (!_path) return; _observer->block(); if (!empty()) { - SP_OBJECT(_path)->updateRepr(); + _path->updateRepr(); _getXMLNode()->setAttribute(_nodetypesKey().data(), _createTypeString().data()); } else { // this manipulator will have to be destroyed right after this call @@ -215,7 +215,7 @@ void PathManipulator::clear() /** Select all nodes in subpaths that have something selected. */ void PathManipulator::selectSubpaths() { - for (std::list<SubpathPtr>::iterator i = _subpaths.begin(); i != _subpaths.end(); ++i) { + for (SubpathList::iterator i = _subpaths.begin(); i != _subpaths.end(); ++i) { NodeList::iterator sp_start = (*i)->begin(), sp_end = (*i)->end(); for (NodeList::iterator j = sp_start; j != sp_end; ++j) { if (j->selected()) { @@ -229,63 +229,6 @@ void PathManipulator::selectSubpaths() } } -/** Move the selection forward or backward by one node in each subpath, based on the sign - * of the parameter. */ -void PathManipulator::shiftSelection(int dir) -{ - if (dir == 0) return; - if (_num_selected == 0) { - // select the first node of the path. - SubpathList::iterator s = _subpaths.begin(); - if (s == _subpaths.end()) return; - NodeList::iterator n = (*s)->begin(); - if (n != (*s)->end()) - _selection.insert(n.ptr()); - return; - } - // We cannot do any tricks here, like iterating in different directions based on - // the sign and only setting the selection of nodes behind us, because it would break - // for closed paths. - for (SubpathList::iterator i = _subpaths.begin(); i != _subpaths.end(); ++i) { - std::deque<bool> sels; // I hope this is specialized for bools! - unsigned num = 0; - - for (NodeList::iterator j = (*i)->begin(); j != (*i)->end(); ++j) { - sels.push_back(j->selected()); - _selection.erase(j.ptr()); - ++num; - } - if (num == 0) continue; // should never happen! zero-node subpaths are not allowed - - num = 0; - // In closed subpath, shift the selection cyclically. In an open one, - // let the selection 'slide into nothing' at ends. - if (dir > 0) { - if ((*i)->closed()) { - bool last = sels.back(); - sels.pop_back(); - sels.push_front(last); - } else { - sels.push_front(false); - } - } else { - if ((*i)->closed()) { - bool first = sels.front(); - sels.pop_front(); - sels.push_back(first); - } else { - sels.push_back(false); - num = 1; - } - } - - for (NodeList::iterator j = (*i)->begin(); j != (*i)->end(); ++j) { - if (sels[num]) _selection.insert(j.ptr()); - ++num; - } - } -} - /** Invert selection in the selected subpaths. */ void PathManipulator::invertSelectionInSubpaths() { @@ -332,22 +275,31 @@ void PathManipulator::duplicateNodes() NodeList::iterator k = j.next(); Node *n = new Node(_multi_path_manipulator._path_data.node_data, *j); - // Move the new node to the bottom of the Z-order. This way you can drag all - // nodes that were selected before this operation without deselecting - // everything because there is a new node above. - n->sink(); + if (k) { + // Move the new node to the bottom of the Z-order. This way you can drag all + // nodes that were selected before this operation without deselecting + // everything because there is a new node above. + n->sink(); + } n->front()->setPosition(*j->front()); j->front()->retract(); j->setType(NODE_CUSP, false); (*i)->insert(k, n); - // We need to manually call the selection change callback to refresh - // the handle display correctly. - // This call changes num_selected, but we call this once for a selected node - // and once for an unselected node, so in the end the number stays correct. - _selectionChanged(j.ptr(), true); - _selectionChanged(n, false); + if (k) { + // We need to manually call the selection change callback to refresh + // the handle display correctly. + // This call changes num_selected, but we call this once for a selected node + // and once for an unselected node, so in the end the number stays correct. + _selectionChanged(j.ptr(), true); + _selectionChanged(n, false); + } else { + // select the new end node instead of the node just before it + _selection.erase(j.ptr()); + _selection.insert(n); + break; // this was the end node, nothing more to do + } } } } @@ -895,9 +847,9 @@ void PathManipulator::setLiveObjects(bool set) _live_objects = set; } -void PathManipulator::setControlsTransform(Geom::Matrix const &tnew) +void PathManipulator::setControlsTransform(Geom::Affine const &tnew) { - Geom::Matrix delta = _i2d_transform.inverse() * _edit_transform.inverse() * tnew * _i2d_transform; + Geom::Affine delta = _i2d_transform.inverse() * _edit_transform.inverse() * tnew * _i2d_transform; _edit_transform = tnew; for (SubpathList::iterator i = _subpaths.begin(); i != _subpaths.end(); ++i) { for (NodeList::iterator j = (*i)->begin(); j != (*i)->end(); ++j) { @@ -1023,7 +975,7 @@ void PathManipulator::_externalChange(unsigned type) _updateOutline(); } break; case PATH_CHANGE_TRANSFORM: { - Geom::Matrix i2d_change = _d2i_transform; + Geom::Affine i2d_change = _d2i_transform; _i2d_transform = SP_ITEM(_path)->i2d_affine(); _d2i_transform = _i2d_transform.inverse(); i2d_change *= _i2d_transform; @@ -1087,13 +1039,14 @@ void PathManipulator::_createControlPointsFromGeometry() subpath->push_back(current_node); } // if this is a bezier segment, move handles appropriately - if (Geom::CubicBezier const *cubic_bezier = - dynamic_cast<Geom::CubicBezier const*>(&*cit)) + // TODO: I don't know why the dynamic cast below doesn't want to work + // when I replace BezierCurve with CubicBezier. Might be a bug + // somewhere in pathv_to_linear_and_cubic_beziers + Geom::BezierCurve const *bezier = dynamic_cast<Geom::BezierCurve const*>(&*cit); + if (bezier && bezier->order() == 3) { - std::vector<Geom::Point> points = cubic_bezier->points(); - - previous_node->front()->setPosition(points[1]); - current_node ->back() ->setPosition(points[2]); + previous_node->front()->setPosition((*bezier)[1]); + current_node ->back() ->setPosition((*bezier)[2]); } previous_node = current_node; } @@ -1436,7 +1389,7 @@ void PathManipulator::_commit(Glib::ustring const &annotation, gchar const *key) * point of the path. */ void PathManipulator::_updateDragPoint(Geom::Point const &evp) { - Geom::Matrix to_desktop = _edit_transform * _i2d_transform; + Geom::Affine to_desktop = _edit_transform * _i2d_transform; Geom::PathVector pv = _spcurve->get_pathvector(); boost::optional<Geom::PathVectorPosition> pvp = Geom::nearestPoint(pv, _desktop->w2d(evp) * to_desktop.inverse()); @@ -1477,8 +1430,8 @@ double PathManipulator::_getStrokeTolerance() * drag tolerance setting. */ Inkscape::Preferences *prefs = Inkscape::Preferences::get(); double ret = prefs->getIntLimited("/options/dragtolerance/value", 2, 0, 100); - if (_path && SP_OBJECT_STYLE(_path) && !SP_OBJECT_STYLE(_path)->stroke.isNone()) { - ret += SP_OBJECT_STYLE(_path)->stroke_width.computed * 0.5 + if (_path && _path->style && !_path->style->stroke.isNone()) { + ret += _path->style->stroke_width.computed * 0.5 * (_edit_transform * _i2d_transform).descrim() // scale to desktop coords * _desktop->current_zoom(); // == _d2w.descrim() - scale to window coords } diff --git a/src/ui/tool/path-manipulator.h b/src/ui/tool/path-manipulator.h index 87b88fc77..27a83f06b 100644 --- a/src/ui/tool/path-manipulator.h +++ b/src/ui/tool/path-manipulator.h @@ -14,15 +14,15 @@ #include <string> #include <memory> #include <2geom/pathvector.h> -#include <2geom/matrix.h> +#include <2geom/affine.h> #include <boost/shared_ptr.hpp> #include <boost/weak_ptr.hpp> -#include "display/display-forward.h" #include "forward.h" #include "ui/tool/node.h" #include "ui/tool/manipulator.h" struct SPCanvasItem; +struct SPCurve; namespace Inkscape { namespace XML { class Node; } @@ -53,7 +53,7 @@ class PathManipulator : public PointManipulator { public: typedef SPPath *ItemType; - PathManipulator(MultiPathManipulator &mpm, SPPath *path, Geom::Matrix const &edit_trans, + PathManipulator(MultiPathManipulator &mpm, SPPath *path, Geom::Affine const &edit_trans, guint32 outline_color, Glib::ustring lpe_key); ~PathManipulator(); virtual bool event(GdkEvent *); @@ -65,7 +65,6 @@ public: SPPath *item() { return _path; } void selectSubpaths(); - void shiftSelection(int dir); void invertSelectionInSubpaths(); void insertNodes(); @@ -86,7 +85,7 @@ public: void showPathDirection(bool show); void setLiveOutline(bool set); void setLiveObjects(bool set); - void setControlsTransform(Geom::Matrix const &); + void setControlsTransform(Geom::Affine const &); void hideDragPoint(); MultiPathManipulator &mpm() { return _multi_path_manipulator; } @@ -94,6 +93,9 @@ public: NodeList::iterator extremeNode(NodeList::iterator origin, bool search_selected, bool search_unselected, bool closest); + // this is necessary for Tab-selection in MultiPathManipulator + SubpathList &subpathList() { return _subpaths; } + static bool is_item_type(void *item); private: typedef NodeList Subpath; @@ -132,9 +134,9 @@ private: SPCanvasItem *_outline; CurveDragPoint *_dragpoint; // an invisible control point hoverng over curve PathManipulatorObserver *_observer; - Geom::Matrix _d2i_transform; ///< desktop-to-item transform - Geom::Matrix _i2d_transform; ///< item-to-desktop transform, inverse of _d2i_transform - Geom::Matrix _edit_transform; ///< additional transform to apply to editing controls + Geom::Affine _d2i_transform; ///< desktop-to-item transform + Geom::Affine _i2d_transform; ///< item-to-desktop transform, inverse of _d2i_transform + Geom::Affine _edit_transform; ///< additional transform to apply to editing controls unsigned _num_selected; ///< number of selected nodes bool _show_handles; bool _show_outline; diff --git a/src/ui/tool/selector.h b/src/ui/tool/selector.h index e61668d9e..05d72c208 100644 --- a/src/ui/tool/selector.h +++ b/src/ui/tool/selector.h @@ -14,7 +14,6 @@ #include <memory> #include <gdk/gdk.h> #include <2geom/rect.h> -#include "display/display-forward.h" #include "ui/tool/manipulator.h" class SPDesktop; diff --git a/src/ui/tool/shape-record.h b/src/ui/tool/shape-record.h index 893231404..646e6f4f6 100644 --- a/src/ui/tool/shape-record.h +++ b/src/ui/tool/shape-record.h @@ -14,7 +14,7 @@ #include <glibmm/ustring.h> #include <boost/operators.hpp> -#include <2geom/matrix.h> +#include <2geom/affine.h> class SPItem; namespace Inkscape { @@ -32,7 +32,7 @@ struct ShapeRecord : public boost::totally_ordered<ShapeRecord> { SPItem *item; // SP node for the edited shape - Geom::Matrix edit_transform; // how to transform controls - used for clipping paths and masks + Geom::Affine edit_transform; // how to transform controls - used for clipping paths and masks ShapeRole role; Glib::ustring lpe_key; // name of LPE shape param being edited diff --git a/src/ui/tool/transform-handle-set.cpp b/src/ui/tool/transform-handle-set.cpp index ef93a3767..26263c26b 100644 --- a/src/ui/tool/transform-handle-set.cpp +++ b/src/ui/tool/transform-handle-set.cpp @@ -18,10 +18,16 @@ #include "desktop-handles.h" #include "display/sodipodi-ctrlrect.h" #include "preferences.h" +#include "snap.h" +#include "snap-candidate.h" +#include "sp-namedview.h" #include "ui/tool/commit-events.h" #include "ui/tool/control-point.h" +#include "ui/tool/control-point-selection.h" +#include "ui/tool/selectable-control-point.h" #include "ui/tool/event-utils.h" #include "ui/tool/transform-handle-set.h" +#include "ui/tool/node-tool.h" // FIXME BRAIN DAMAGE WARNING: this is a global variable in select-context.cpp // It should be moved to a header @@ -88,12 +94,14 @@ public: protected: virtual void startTransform() {} virtual void endTransform() {} - virtual Geom::Matrix computeTransform(Geom::Point const &pos, GdkEventMotion *event) = 0; + virtual Geom::Affine computeTransform(Geom::Point const &pos, GdkEventMotion *event) = 0; virtual CommitEvent getCommitEvent() = 0; - Geom::Matrix _last_transform; + Geom::Affine _last_transform; Geom::Point _origin; TransformHandleSet &_th; + std::vector<Inkscape::SnapCandidatePoint> _snap_points; + private: virtual bool grabbed(GdkEventMotion *) { _origin = position(); @@ -103,19 +111,34 @@ private: _th._setActiveHandle(this); _cset = &invisible_cset; _setState(_state); + + // Collect the snap-candidates, one for each selected node. These will be stored in the _snap_points vector. + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + SnapManager &m = desktop->namedview->snap_manager; + InkNodeTool *nt = INK_NODE_TOOL(_desktop->event_context); + ControlPointSelection *selection = nt->_selected_nodes.get(); + + _snap_points = selection->getOriginalPoints(); + + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + if (prefs->getBool("/options/snapclosestonly/value", false)) { + m.keepClosestPointOnly(_snap_points, _origin); + } + return false; } virtual void dragged(Geom::Point &new_pos, GdkEventMotion *event) { - Geom::Matrix t = computeTransform(new_pos, event); + Geom::Affine t = computeTransform(new_pos, event); // protect against degeneracies if (t.isSingular()) return; - Geom::Matrix incr = _last_transform.inverse() * t; + Geom::Affine incr = _last_transform.inverse() * t; if (incr.isSingular()) return; _th.signal_transform.emit(incr); _last_transform = t; } virtual void ungrabbed(GdkEventButton *) { + _snap_points.clear(); _th._clearActiveHandle(); _cset = &thandle_cset; _setState(_state); @@ -175,26 +198,66 @@ protected: _sc_center = _th.rotationCenter(); _sc_opposite = _th.bounds().corner(_corner + 2); _last_scale_x = _last_scale_y = 1.0; + InkNodeTool *nt = INK_NODE_TOOL(_desktop->event_context); + ControlPointSelection *selection = nt->_selected_nodes.get(); + selection->setOriginalPoints(); } - virtual Geom::Matrix computeTransform(Geom::Point const &new_pos, GdkEventMotion *event) { + virtual Geom::Affine computeTransform(Geom::Point const &new_pos, GdkEventMotion *event) { Geom::Point scc = held_shift(*event) ? _sc_center : _sc_opposite; Geom::Point vold = _origin - scc, vnew = new_pos - scc; + // avoid exploding the selection if (Geom::are_near(vold[Geom::X], 0) || Geom::are_near(vold[Geom::Y], 0)) return Geom::identity(); double scale[2] = { vnew[Geom::X] / vold[Geom::X], vnew[Geom::Y] / vold[Geom::Y] }; + if (held_alt(*event)) { for (unsigned i = 0; i < 2; ++i) { if (scale[i] >= 1.0) scale[i] = round(scale[i]); else scale[i] = 1.0 / round(1.0 / scale[i]); } - } else if (held_control(*event)) { - scale[0] = scale[1] = std::min(scale[0], scale[1]); + } else { + //SPDesktop *desktop = _th._desktop; // Won't work as _desktop is protected + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + SnapManager &m = desktop->namedview->snap_manager; + + // The lines below have been copied from Handle::dragged() in node.cpp, and need to be + // activated if we want to snap to unselected (i.e. stationary) nodes and stationary pieces of paths of the + // path that's currently being edited + /* + std::vector<Inkscape::SnapCandidatePoint> unselected; + typedef ControlPointSelection::Set Set; + Set &nodes = _parent->_selection.allPoints(); + for (Set::iterator i = nodes.begin(); i != nodes.end(); ++i) { + Node *n = static_cast<Node*>(*i); + Inkscape::SnapCandidatePoint p(n->position(), n->_snapSourceType(), n->_snapTargetType()); + unselected.push_back(p); + } + m.setupIgnoreSelection(_desktop, true, &unselected); + */ + + m.setupIgnoreSelection(_desktop); + + Inkscape::SnappedPoint sp; + if (held_control(*event)) { + scale[0] = scale[1] = std::min(scale[0], scale[1]); + sp = m.constrainedSnapScale(_snap_points, _origin, Geom::Scale(scale[0], scale[1]), scc); + } else { + sp = m.freeSnapScale(_snap_points, _origin, Geom::Scale(scale[0], scale[1]), scc); + } + m.unSetup(); + + if (sp.getSnapped()) { + Geom::Point result = sp.getTransformation(); + scale[0] = result[0]; + scale[1] = result[1]; + } } + _last_scale_x = scale[0]; _last_scale_y = scale[1]; - Geom::Matrix t = Geom::Translate(-scc) + Geom::Affine t = Geom::Translate(-scc) * Geom::Scale(scale[0], scale[1]) * Geom::Translate(scc); return t; @@ -231,7 +294,7 @@ protected: _sc_opposite = Geom::middle_point(b.corner(_side + 2), b.corner(_side + 3)); _last_scale_x = _last_scale_y = 1.0; } - virtual Geom::Matrix computeTransform(Geom::Point const &new_pos, GdkEventMotion *event) { + virtual Geom::Affine computeTransform(Geom::Point const &new_pos, GdkEventMotion *event) { Geom::Point scc = held_shift(*event) ? _sc_center : _sc_opposite; Geom::Point vs; Geom::Dim2 d1 = static_cast<Geom::Dim2>((_side + 1) % 2); @@ -250,7 +313,7 @@ protected: _last_scale_x = vs[Geom::X]; _last_scale_y = vs[Geom::Y]; - Geom::Matrix t = Geom::Translate(-scc) + Geom::Affine t = Geom::Translate(-scc) * Geom::Scale(vs) * Geom::Translate(scc); return t; @@ -288,7 +351,7 @@ protected: _last_angle = 0; } - virtual Geom::Matrix computeTransform(Geom::Point const &new_pos, GdkEventMotion *event) + virtual Geom::Affine computeTransform(Geom::Point const &new_pos, GdkEventMotion *event) { Geom::Point rotc = held_shift(*event) ? _rot_opposite : _rot_center; double angle = Geom::angle_between(_origin - rotc, new_pos - rotc); @@ -296,7 +359,7 @@ protected: angle = snap_angle(angle); } _last_angle = angle; - Geom::Matrix t = Geom::Translate(-rotc) + Geom::Affine t = Geom::Translate(-rotc) * Geom::Rotate(angle) * Geom::Translate(rotc); return t; @@ -362,7 +425,7 @@ protected: _last_horizontal = _side % 2; } - virtual Geom::Matrix computeTransform(Geom::Point const &new_pos, GdkEventMotion *event) + virtual Geom::Affine computeTransform(Geom::Point const &new_pos, GdkEventMotion *event) { Geom::Point scc = held_shift(*event) ? _skew_center : _skew_opposite; // d1 and d2 are reversed with respect to ScaleSideHandle @@ -395,12 +458,12 @@ protected: // skew matrix has the from [[1, k],[0, 1]] for horizontal skew // and [[1,0],[k,1]] for vertical skew. - Geom::Matrix skew = Geom::identity(); + Geom::Affine skew = Geom::identity(); // correct the sign of the tangent skew[d2 + 1] = (d1 == Geom::X ? -1.0 : 1.0) * tan(angle); _last_angle = angle; - Geom::Matrix t = Geom::Translate(-scc) + Geom::Affine t = Geom::Translate(-scc) * Geom::Scale(scale) * skew * Geom::Translate(scc); return t; @@ -473,7 +536,23 @@ public: } protected: - + virtual void dragged(Geom::Point &new_pos, GdkEventMotion *event) { + SnapManager &sm = _desktop->namedview->snap_manager; + sm.setup(_desktop); + bool snap = !held_shift(*event) && sm.someSnapperMightSnap(); + if (held_control(*event)) { + // constrain to axes + Geom::Point origin = _last_drag_origin(); + std::vector<Inkscape::Snapper::SnapConstraint> constraints; + constraints.push_back(Inkscape::Snapper::SnapConstraint(origin, Geom::Point(1, 0))); + constraints.push_back(Inkscape::Snapper::SnapConstraint(origin, Geom::Point(0, 1))); + new_pos = sm.multipleConstrainedSnaps(Inkscape::SnapCandidatePoint(new_pos, + SNAPSOURCE_ROTATION_CENTER), constraints, held_shift(*event)).getPoint(); + } else if (snap) { + sm.freeSnapReturnByRef(new_pos, SNAPSOURCE_ROTATION_CENTER); + } + sm.unSetup(); + } virtual Glib::ustring _getTip(unsigned /*state*/) { return C_("Transform handle tip", "<b>Rotation center</b>: drag to change the origin of transforms"); @@ -566,7 +645,7 @@ bool TransformHandleSet::event(GdkEvent*) return false; } -void TransformHandleSet::_emitTransform(Geom::Matrix const &t) +void TransformHandleSet::_emitTransform(Geom::Affine const &t) { signal_transform.emit(t); _center->transform(t); diff --git a/src/ui/tool/transform-handle-set.h b/src/ui/tool/transform-handle-set.h index 2a4df8751..0557b1278 100644 --- a/src/ui/tool/transform-handle-set.h +++ b/src/ui/tool/transform-handle-set.h @@ -14,12 +14,11 @@ #include <memory> #include <gdk/gdk.h> #include <2geom/forward.h> -#include "display/display-forward.h" #include "ui/tool/commit-events.h" #include "ui/tool/manipulator.h" class SPDesktop; -class CtrlRect; // this is not present in display-forward.h! +class CtrlRect; namespace Inkscape { namespace UI { @@ -51,10 +50,10 @@ public: bool transforming() { return _in_transform; } ControlPoint &rotationCenter(); - sigc::signal<void, Geom::Matrix const &> signal_transform; + sigc::signal<void, Geom::Affine const &> signal_transform; sigc::signal<void, CommitEvent> signal_commit; private: - void _emitTransform(Geom::Matrix const &); + void _emitTransform(Geom::Affine const &); void _setActiveHandle(ControlPoint *h); void _clearActiveHandle(); void _updateVisibility(bool v); diff --git a/src/ui/view/view.h b/src/ui/view/view.h index 882746cea..e6853555f 100644 --- a/src/ui/view/view.h +++ b/src/ui/view/view.h @@ -15,6 +15,7 @@ */ #include <gdk/gdktypes.h> +#include <stddef.h> #include <sigc++/connection.h> #include "message.h" #include "gc-managed.h" diff --git a/src/ui/widget/attr-widget.h b/src/ui/widget/attr-widget.h index b9924a2ef..7b9c35ab7 100644 --- a/src/ui/widget/attr-widget.h +++ b/src/ui/widget/attr-widget.h @@ -149,7 +149,7 @@ protected: { const gchar* name = (const gchar*)sp_attribute_name(_attr); if(name && o) { - const gchar* val = SP_OBJECT_REPR(o)->attribute(name); + const gchar* val = o->getRepr()->attribute(name); return val; } return 0; diff --git a/src/ui/widget/color-picker.h b/src/ui/widget/color-picker.h index 2c246aaa3..346ce5121 100644 --- a/src/ui/widget/color-picker.h +++ b/src/ui/widget/color-picker.h @@ -13,6 +13,7 @@ #ifndef __COLOR_PICKER_H__ #define __COLOR_PICKER_H__ +#include <stddef.h> #include <sigc++/sigc++.h> #include <gtkmm/button.h> #include <gtkmm/dialog.h> diff --git a/src/ui/widget/filter-effect-chooser.cpp b/src/ui/widget/filter-effect-chooser.cpp index 309730600..37202c8b4 100644 --- a/src/ui/widget/filter-effect-chooser.cpp +++ b/src/ui/widget/filter-effect-chooser.cpp @@ -22,8 +22,8 @@ namespace UI { namespace Widget { SimpleFilterModifier::SimpleFilterModifier(int flags) - : _lb_blend(_("_Blend mode:")), - _lb_blur(_("Blur:"), Gtk::ALIGN_LEFT), + : _lb_blend(_("Blend mode:")), + _lb_blur(_("_Blur:"), Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER, true), _blend(BlendModeConverter, SP_ATTR_INVALID, false), _blur(0, 0, 100, 1, 0.01, 1) { diff --git a/src/ui/widget/layer-selector.cpp b/src/ui/widget/layer-selector.cpp index 6d1da0af0..ba4629c82 100644 --- a/src/ui/widget/layer-selector.cpp +++ b/src/ui/widget/layer-selector.cpp @@ -236,6 +236,8 @@ void LayerSelector::_selectLayer(SPObject *layer) { using Inkscape::Util::reverse_list; _selection_changed_connection.block(); + _visibility_toggled_connection.block(); + _lock_toggled_connection.block(); while (!_layer_model->children().empty()) { Gtk::ListStore::iterator first_row(_layer_model->children().begin()); @@ -285,6 +287,8 @@ void LayerSelector::_selectLayer(SPObject *layer) { _lock_toggle.set_active(( SP_IS_ITEM(layer) ? SP_ITEM(layer)->isLocked() : false )); } + _lock_toggled_connection.unblock(); + _visibility_toggled_connection.unblock(); _selection_changed_connection.unblock(); } @@ -460,7 +464,7 @@ void LayerSelector::_buildEntry(unsigned depth, SPObject &object) { ); SPObject *layer=_desktop->currentLayer(); - if ( &object == layer || &object == SP_OBJECT_PARENT(layer) ) { + if ( (&object == layer) || (&object == layer->parent) ) { callbacks->update_list = sigc::bind( sigc::mem_fun(*this, &LayerSelector::_protectUpdate), sigc::bind( @@ -498,12 +502,12 @@ void LayerSelector::_buildEntry(unsigned depth, SPObject &object) { sp_object_ref(&object, NULL); row->set_value(_model_columns.object, &object); - Inkscape::GC::anchor(SP_OBJECT_REPR(&object)); - row->set_value(_model_columns.repr, SP_OBJECT_REPR(&object)); + Inkscape::GC::anchor(object.getRepr()); + row->set_value(_model_columns.repr, object.getRepr()); row->set_value(_model_columns.callbacks, reinterpret_cast<void *>(callbacks)); - sp_repr_add_listener(SP_OBJECT_REPR(&object), vector, callbacks); + sp_repr_add_listener(object.getRepr(), vector, callbacks); } /** Removes a row from the _model_columns object, disconnecting listeners @@ -536,13 +540,13 @@ void LayerSelector::_prepareLabelRenderer( // (or before one has been selected) something appears to // "invent" an iterator with null data and try to render it; // where does it come from, and how can we avoid it? - if ( object && SP_OBJECT_REPR(object) ) { + if ( object && object->getRepr() ) { SPObject *layer=( _desktop ? _desktop->currentLayer() : NULL ); SPObject *root=( _desktop ? _desktop->currentRoot() : NULL ); - bool isancestor = !( (layer && (SP_OBJECT_PARENT(object) == SP_OBJECT_PARENT(layer))) || ((layer == root) && (SP_OBJECT_PARENT(object) == root))); + bool isancestor = !( (layer && (object->parent == layer->parent)) || ((layer == root) && (object->parent == root))); - bool iscurrent = ( object == layer && object != root ); + bool iscurrent = ( (object == layer) && (object != root) ); gchar *format = g_strdup_printf ( "<span size=\"smaller\" %s><tt>%*s%s</tt>%s%s%s%%s%s%s%s</span>", diff --git a/src/ui/widget/object-composite-settings.cpp b/src/ui/widget/object-composite-settings.cpp index 1de425da3..06d57c4ac 100644 --- a/src/ui/widget/object-composite-settings.cpp +++ b/src/ui/widget/object-composite-settings.cpp @@ -60,7 +60,7 @@ ObjectCompositeSettings::ObjectCompositeSettings(unsigned int verb_code, char co _opacity_tag(Glib::ustring(history_prefix) + ":opacity"), _opacity_vbox(false, 0), _opacity_label_box(false, 0), - _opacity_label(_("Opacity (%):"), 0.0, 1.0, true), + _opacity_label(_("_Opacity (%):"), 0.0, 1.0, true), _opacity_adjustment(100.0, 0.0, 100.0, 1.0, 1.0, 0.0), _opacity_hscale(_opacity_adjustment), _opacity_spin_button(_opacity_adjustment, 0.01, 1), @@ -86,6 +86,7 @@ ObjectCompositeSettings::ObjectCompositeSettings(unsigned int verb_code, char co _opacity_hscale.set_draw_value(false); _opacity_hscale.set_update_policy(Gtk::UPDATE_DELAYED); _opacity_adjustment.signal_value_changed().connect(sigc::mem_fun(*this, &ObjectCompositeSettings::_opacityValueChanged)); + _opacity_label.set_mnemonic_widget(_opacity_hscale); show_all_children(); @@ -145,7 +146,7 @@ ObjectCompositeSettings::_blendBlurValueChanged() } SPItem * item = SP_ITEM(*i); - SPStyle *style = SP_OBJECT_STYLE(item); + SPStyle *style = item->style; g_assert(style != NULL); if (blendmode != "normal") { diff --git a/src/ui/widget/page-sizer.cpp b/src/ui/widget/page-sizer.cpp index f7cb6f145..f306b9eea 100644 --- a/src/ui/widget/page-sizer.cpp +++ b/src/ui/widget/page-sizer.cpp @@ -422,7 +422,7 @@ PageSizer::setDim (double w, double h, bool changeList) // The origin for the user is in the lower left corner; this point should remain stationary when // changing the page size. The SVG's origin however is in the upper left corner, so we must compensate for this Geom::Translate const vert_offset(Geom::Point(0, (old_height - h))); - SP_GROUP(SP_ROOT(doc->root))->translateChildItems(vert_offset); + SP_GROUP(SP_ROOT(doc->root))->translateChildItems(vert_offset); DocumentUndo::done(doc, SP_VERB_NONE, _("Set page size")); } @@ -538,8 +538,8 @@ PageSizer::fire_fit_canvas_to_selection_or_drawing() SPNamedView *nv; Inkscape::XML::Node *nv_repr; if ((doc = sp_desktop_document(SP_ACTIVE_DESKTOP)) - && (nv = sp_document_namedview(doc, 0)) - && (nv_repr = SP_OBJECT_REPR(nv))) { + && (nv = sp_document_namedview(doc, 0)) + && (nv_repr = nv->getRepr())) { sp_repr_set_svg_double(nv_repr, "fit-margin-top", _marginTop.getValue()); sp_repr_set_svg_double(nv_repr, "fit-margin-left", _marginLeft.getValue()); sp_repr_set_svg_double(nv_repr, "fit-margin-right", _marginRight.getValue()); diff --git a/src/ui/widget/page-sizer.h b/src/ui/widget/page-sizer.h index ba6c8dd13..2072aeccd 100644 --- a/src/ui/widget/page-sizer.h +++ b/src/ui/widget/page-sizer.h @@ -13,6 +13,7 @@ #define INKSCAPE_UI_WIDGET_PAGE_SIZER__H #include <gtkmm.h> +#include <stddef.h> #include <sigc++/sigc++.h> #include "helper/units.h" diff --git a/src/ui/widget/preferences-widget.cpp b/src/ui/widget/preferences-widget.cpp index 4816304db..afcaa338e 100644 --- a/src/ui/widget/preferences-widget.cpp +++ b/src/ui/widget/preferences-widget.cpp @@ -14,6 +14,10 @@ # include <config.h> #endif +#ifdef WIN32 +#include <windows.h> +#endif + #include <gtkmm/frame.h> #include <gtkmm/alignment.h> #include <gtkmm/box.h> @@ -22,7 +26,9 @@ #include "ui/widget/preferences-widget.h" #include "verbs.h" #include "selcue.h" +#include "io/sys.h" #include <iostream> +#include "desktop.h" #include "enums.h" #include "inkscape.h" #include "desktop-handles.h" @@ -30,6 +36,7 @@ #include "style.h" #include "selection.h" #include "selection-chemistry.h" +#include "ui/dialog/filedialog.h" #include "xml/repr.h" using namespace Inkscape::UI::Widget; @@ -618,6 +625,137 @@ void PrefEntryButtonHBox::onRelatedButtonClickedCallback() } } +void PrefEntryFileButtonHBox::init(Glib::ustring const &prefs_path, + bool visibility) +{ + _prefs_path = prefs_path; + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + + relatedEntry = new Gtk::Entry(); + relatedEntry->set_invisible_char('*'); + relatedEntry->set_visibility(visibility); + relatedEntry->set_text(prefs->getString(_prefs_path)); + + relatedButton = new Gtk::Button(); + Gtk::HBox* pixlabel = new Gtk::HBox(false, 3); + Gtk::Image *im = new Gtk::Image(Gtk::StockID(Gtk::Stock::INDEX), + Gtk::ICON_SIZE_BUTTON); + pixlabel->pack_start(*im); + Gtk::Label *l = new Gtk::Label(); + l->set_markup_with_mnemonic(_("_Browse...")); + pixlabel->pack_start(*l); + relatedButton->add(*pixlabel); + + this->pack_end(*relatedButton, false, false, 4); + this->pack_start(*relatedEntry, true, true, 0); + + relatedButton->signal_clicked().connect( + sigc::mem_fun(*this, &PrefEntryFileButtonHBox::onRelatedButtonClickedCallback)); + relatedEntry->signal_changed().connect( + sigc::mem_fun(*this, &PrefEntryFileButtonHBox::onRelatedEntryChangedCallback)); +} + +void PrefEntryFileButtonHBox::onRelatedEntryChangedCallback() +{ + if (this->is_visible()) //only take action if user changed value + { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setString(_prefs_path, relatedEntry->get_text()); + } +} + +static Inkscape::UI::Dialog::FileOpenDialog * selectPrefsFileInstance = NULL; + +void PrefEntryFileButtonHBox::onRelatedButtonClickedCallback() +{ + if (this->is_visible()) //only take action if user changed value + { + //# Get the current directory for finding files + static Glib::ustring open_path; + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + + + Glib::ustring attr = prefs->getString(_prefs_path); + if (!attr.empty()) open_path = attr; + + //# Test if the open_path directory exists + if (!Inkscape::IO::file_test(open_path.c_str(), + (GFileTest)(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) + open_path = ""; + +#ifdef WIN32 + //# If no open path, default to our win32 documents folder + if (open_path.empty()) + { + // The path to the My Documents folder is read from the + // value "HKEY_CURRENT_USER\Software\Windows\CurrentVersion\Explorer\Shell Folders\Personal" + HKEY key = NULL; + if(RegOpenKeyExA(HKEY_CURRENT_USER, + "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", + 0, KEY_QUERY_VALUE, &key) == ERROR_SUCCESS) + { + WCHAR utf16path[_MAX_PATH]; + DWORD value_type; + DWORD data_size = sizeof(utf16path); + if(RegQueryValueExW(key, L"Personal", NULL, &value_type, + (BYTE*)utf16path, &data_size) == ERROR_SUCCESS) + { + g_assert(value_type == REG_SZ); + gchar *utf8path = g_utf16_to_utf8( + (const gunichar2*)utf16path, -1, NULL, NULL, NULL); + if(utf8path) + { + open_path = Glib::ustring(utf8path); + g_free(utf8path); + } + } + } + } +#endif + + //# If no open path, default to our home directory + if (open_path.empty()) + { + open_path = g_get_home_dir(); + open_path.append(G_DIR_SEPARATOR_S); + } + + //# Create a dialog + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if (!selectPrefsFileInstance) { + selectPrefsFileInstance = + Inkscape::UI::Dialog::FileOpenDialog::create( + *desktop->getToplevel(), + open_path, + Inkscape::UI::Dialog::EXE_TYPES, + _("Select a bitmap editor")); + } + + //# Show the dialog + bool const success = selectPrefsFileInstance->show(); + + if (!success) { + return; + } + + //# User selected something. Get name and type + Glib::ustring fileName = selectPrefsFileInstance->getFilename(); + + if (!fileName.empty()) + { + Glib::ustring newFileName = Glib::filename_to_utf8(fileName); + + if ( newFileName.size() > 0) + open_path = newFileName; + else + g_warning( "ERROR CONVERTING OPEN FILENAME TO UTF-8" ); + + prefs->setString(_prefs_path, open_path); + } + + relatedEntry->set_text(fileName); + } +} void PrefFileButton::init(Glib::ustring const &prefs_path) { diff --git a/src/ui/widget/preferences-widget.h b/src/ui/widget/preferences-widget.h index 6c4533451..6c7f9ce4a 100644 --- a/src/ui/widget/preferences-widget.h +++ b/src/ui/widget/preferences-widget.h @@ -26,6 +26,7 @@ #include <gtkmm/drawingarea.h> #include <gtkmm/frame.h> #include <gtkmm/filechooserbutton.h> +#include <stddef.h> #include <sigc++/sigc++.h> #include <glibmm/i18n.h> @@ -176,6 +177,19 @@ protected: void onRelatedButtonClickedCallback(); }; +class PrefEntryFileButtonHBox : public Gtk::HBox +{ +public: + void init(Glib::ustring const &prefs_path, + bool mask); +protected: + Glib::ustring _prefs_path; + Gtk::Button *relatedButton; + Gtk::Entry *relatedEntry; + void onRelatedEntryChangedCallback(); + void onRelatedButtonClickedCallback(); +}; + class PrefFileButton : public Gtk::FileChooserButton { public: diff --git a/src/ui/widget/registered-widget.cpp b/src/ui/widget/registered-widget.cpp index 04bd27285..c2580013a 100644 --- a/src/ui/widget/registered-widget.cpp +++ b/src/ui/widget/registered-widget.cpp @@ -344,7 +344,7 @@ RegisteredColorPicker::on_changed (guint32 rgba) SPDesktop *dt = SP_ACTIVE_DESKTOP; if (!dt) return; - local_repr = SP_OBJECT_REPR (sp_desktop_namedview(dt)); + local_repr = sp_desktop_namedview(dt)->getRepr(); local_doc = sp_desktop_document(dt); } @@ -553,7 +553,7 @@ RegisteredTransformedPoint::setValue(Geom::Point const & p) } void -RegisteredTransformedPoint::setTransform(Geom::Matrix const & canvas_to_svg) +RegisteredTransformedPoint::setTransform(Geom::Affine const & canvas_to_svg) { // check if matrix is singular / has inverse if ( ! canvas_to_svg.isSingular() ) { diff --git a/src/ui/widget/registered-widget.h b/src/ui/widget/registered-widget.h index efb5eb70e..560c63dd4 100644 --- a/src/ui/widget/registered-widget.h +++ b/src/ui/widget/registered-widget.h @@ -18,7 +18,7 @@ #include <gtkmm/adjustment.h> #include <gtkmm/tooltips.h> #include <gtkmm/togglebutton.h> -#include <2geom/matrix.h> +#include <2geom/affine.h> #include "xml/node.h" #include "registry.h" @@ -101,7 +101,7 @@ protected: if (!local_repr) { // no repr specified, use active desktop's namedview's repr SPDesktop* dt = SP_ACTIVE_DESKTOP; - local_repr = SP_OBJECT_REPR (sp_desktop_namedview(dt)); + local_repr = reinterpret_cast<SPObject *>(sp_desktop_namedview(dt))->getRepr(); local_doc = sp_desktop_document(dt); } @@ -326,14 +326,14 @@ public: // redefine setValue, because transform must be applied void setValue(Geom::Point const & p); - void setTransform(Geom::Matrix const & canvas_to_svg); + void setTransform(Geom::Affine const & canvas_to_svg); protected: sigc::connection _value_x_changed_connection; sigc::connection _value_y_changed_connection; void on_value_changed(); - Geom::Matrix to_svg; + Geom::Affine to_svg; }; diff --git a/src/ui/widget/ruler.cpp b/src/ui/widget/ruler.cpp index 107f4e8c6..a220a54ad 100644 --- a/src/ui/widget/ruler.cpp +++ b/src/ui/widget/ruler.cpp @@ -26,6 +26,7 @@ #include "ui/widget/ruler.h" #include "xml/repr.h" +#include "display/sp-canvas.h" #include "display/guideline.h" #include "desktop.h" #include "desktop-handles.h" @@ -101,7 +102,7 @@ Ruler::on_button_press_event(GdkEventButton *evb) { g_assert(_dt); Geom::Point const &event_dt = get_event_dt(); - Inkscape::XML::Node *repr = SP_OBJECT_REPR(_dt->namedview); + Inkscape::XML::Node *repr = _dt->namedview->getRepr(); if (evb->button == 1) { _dragging = true; @@ -152,7 +153,7 @@ Ruler::on_button_release_event(GdkEventButton *evb) repr->setAttribute("orientation", _horiz_f ? "horizontal" : "vertical"); double const guide_pos_dt = event_dt[ _horiz_f ? Geom::Y : Geom::X ]; sp_repr_set_svg_double(repr, "position", guide_pos_dt); - SP_OBJECT_REPR(_dt->namedview)->appendChild(repr); + _dt->namedview->getRepr()->appendChild(repr); Inkscape::GC::release(repr); DocumentUndo::done(sp_desktop_document(_dt), SP_VERB_NONE, /* TODO: annotate */ "ruler.cpp:157"); diff --git a/src/ui/widget/selected-style.cpp b/src/ui/widget/selected-style.cpp index e7d8ac5a3..50476dc65 100644 --- a/src/ui/widget/selected-style.cpp +++ b/src/ui/widget/selected-style.cpp @@ -950,7 +950,7 @@ SelectedStyle::update() if (paint->set && paint->isPaintserver()) { SPPaintServer *server = (i == SS_FILL)? SP_STYLE_FILL_SERVER (query) : SP_STYLE_STROKE_SERVER (query); if ( server ) { - Inkscape::XML::Node *srepr = SP_OBJECT_REPR(server); + Inkscape::XML::Node *srepr = server->getRepr(); _paintserver_id[i] += "url(#"; _paintserver_id[i] += srepr->attribute("id"); _paintserver_id[i] += ")"; diff --git a/src/ui/widget/selected-style.h b/src/ui/widget/selected-style.h index 0229364c7..e74d5b1ae 100644 --- a/src/ui/widget/selected-style.h +++ b/src/ui/widget/selected-style.h @@ -23,6 +23,7 @@ #include <gtkmm/adjustment.h> #include <gtkmm/spinbutton.h> +#include <stddef.h> #include <sigc++/sigc++.h> #include <glibmm/i18n.h> diff --git a/src/ui/widget/style-subject.h b/src/ui/widget/style-subject.h index 77e4c4846..6d5c96350 100644 --- a/src/ui/widget/style-subject.h +++ b/src/ui/widget/style-subject.h @@ -14,6 +14,7 @@ #include "libnr/nr-rect.h" #include <2geom/rect.h> #include "sp-item.h" +#include <stddef.h> #include <sigc++/sigc++.h> class SPDesktop; diff --git a/src/ui/widget/svg-canvas.cpp b/src/ui/widget/svg-canvas.cpp index 64657296d..7d37ec355 100644 --- a/src/ui/widget/svg-canvas.cpp +++ b/src/ui/widget/svg-canvas.cpp @@ -12,8 +12,8 @@ #include <gtkmm/widget.h> #include "desktop.h" #include "desktop-events.h" +#include "display/sp-canvas.h" #include "display/canvas-arena.h" -#include "display/display-forward.h" #include "ui/widget/svg-canvas.h" namespace Inkscape { diff --git a/src/ui/widget/tolerance-slider.cpp b/src/ui/widget/tolerance-slider.cpp index cc179ddbc..51e0a262f 100644 --- a/src/ui/widget/tolerance-slider.cpp +++ b/src/ui/widget/tolerance-slider.cpp @@ -189,7 +189,7 @@ ToleranceSlider::update (double val) SPDocument *doc = sp_desktop_document(dt); bool saved = DocumentUndo::getUndoSensitive(doc); DocumentUndo::setUndoSensitive(doc, false); - Inkscape::XML::Node *repr = SP_OBJECT_REPR (sp_desktop_namedview(dt)); + Inkscape::XML::Node *repr = sp_desktop_namedview(dt)->getRepr(); repr->setAttribute(_key.c_str(), os.str().c_str()); DocumentUndo::setUndoSensitive(doc, saved); |
