From a06fa77beffc04a6caa4bafc4d9881f699f6914c Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Wed, 21 Mar 2012 21:20:13 +0100 Subject: give error when function does not return something while it should (bzr r11110) --- build.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/build.xml b/build.xml index 3a45ca93e..c7ce9514c 100755 --- a/build.xml +++ b/build.xml @@ -340,6 +340,7 @@ -Wall -Wformat -Werror=format-security -W -Wpointer-arith -Wcast-align -Wsign-compare -Woverloaded-virtual -Wswitch + -Werror=return-type -O2 -mms-bitfields -fopenmp -- cgit v1.2.3 From b573d09df3fa3cb0496366b46b0b57a0db727db2 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Wed, 21 Mar 2012 23:33:52 +0100 Subject: powerstroke: properly implement rounded joins. brain buster!! (bzr r11111) --- src/live_effects/lpe-powerstroke.cpp | 93 +++++++++++++++++++++++++++++++----- 1 file changed, 81 insertions(+), 12 deletions(-) diff --git a/src/live_effects/lpe-powerstroke.cpp b/src/live_effects/lpe-powerstroke.cpp index 257dba8ea..6cc2d2368 100644 --- a/src/live_effects/lpe-powerstroke.cpp +++ b/src/live_effects/lpe-powerstroke.cpp @@ -26,9 +26,10 @@ #include <2geom/svg-path.h> #include <2geom/path-intersection.h> #include <2geom/crossing.h> +#include <2geom/ellipse.h> namespace Geom { - +// should all be moved to 2geom at some point Point unitTangentAt( D2 const & a, Coord t, unsigned n = 3) { std::vector derivs = a.valueAndDerivatives(t, n); @@ -55,8 +56,48 @@ boost::optional intersection_point( Point const & origin_a, Point const & return boost::none; } +Geom::CubicBezier sbasis_to_cubicbezier(Geom::D2 const & sbasis_in) +{ + std::vector temp; + sbasis_to_bezier(temp, sbasis_in, 4); + return Geom::CubicBezier( temp ); } +/** + * document this! + * very quick: this finds the ellipse with minimum eccentricity + passing through point P and Q, with tangent PO at P and QO at Q + http://mathforum.org/kb/message.jspa?messageID=7471596&tstart=0 + */ +static Ellipse find_ellipse(Point P, Point Q, Point O) +{ + Point p = P - O; + Point q = Q - O; + Coord K = 4 * dot(p,q) / (L2sq(p) + L2sq(q)); + + double cross = p[Y]*q[X] - p[X]*q[Y]; + double a = -q[Y]/cross; + double b = q[X]/cross; + double c = (O[X]*q[Y] - O[Y]*q[X])/cross; + + double d = p[Y]/cross; + double e = -p[X]/cross; + double f = (-O[X]*p[Y] + O[Y]*p[X])/cross; + + // Ax^2 + Bxy + Cy^2 + Dx + Ey + F = 0 + double A = (a*d*K+d*d+a*a); + double B = (a*e*K+b*d*K+2*d*e+2*a*b); + double C = (b*e*K+e*e+b*b); + double D = (a*f*K+c*d*K+2*d*f-2*d+2*a*c-2*a); + double E = (b*f*K+c*e*K+2*e*f-2*e+2*b*c-2*b); + double F = c*f*K+f*f-2*f+c*c-2*c+1; + + return Ellipse(A, B, C, D, E, F); +} + + +} // namespace Geom + namespace Inkscape { namespace LivePathEffect { @@ -176,8 +217,16 @@ std::vector find_discontinuities( Geom::Piecewise rts = roots (x - t); /// @todo this has multiple solutions for general strokewidth paths (generated by spiro interpolator...), ignore for now if (!rts.empty()) { @@ -224,11 +273,36 @@ Geom::Path path_from_piecewise_fix_cusps( Geom::Piecewise discontinuity_data cusp = cusps[cusp_i]; switch (cusp_linecap) { - case LINECUSP_ROUND: // properly bugged ^_^ - pb.arcTo( abs(cusp.width), abs(cusp.width), - angle_between(cusp.der0, cusp.der1), false, cusp.width < 0, - B[i].at0() ); + case LINECUSP_ROUND: { + if ( sign*cusp.width*angle_between(cusp.der0, cusp.der1) < 0.) { + // we are on the outside: round corner + /* for constant width paths, the rounding is a circular arc (rx == ry), + for non-constant width paths, the rounding can be done with an ellipse but is hard and ambiguous. + The elliptical arc should go through the discontinuity's start and end points (of course!) + and also should match the discontinuity tangents at those start and end points. + To resolve the ambiguity, the elliptical arc with minimal eccentricity should be chosen. + A 2Geom method was created to do exactly this :) + */ + + Geom::Point tang1 = unitTangentAt(B[prev_i],1); + Geom::Point tang2 = unitTangentAt(B[i],0); + boost::optional O = intersection_point( B[prev_i].at1(), tang1, + B[i].at0(), tang2 ); + if (!O) { + // no center found, i.e. 180 degrees round + pb.lineTo(B[i].at0()); // default to bevel for too shallow cusp angles + break; + } + + Geom::Ellipse ellipse = find_ellipse(B[prev_i].at1(), B[i].at0(), *O); + pb.arcTo( ellipse.ray(Geom::X), ellipse.ray(Geom::Y), ellipse.rot_angle(), + false, cusp.width < 0, B[i].at0() ); + } else { + // we are on the inside, do a simple bevel to connect the paths + pb.lineTo(B[i].at0()); // default to bevel for too shallow cusp angles + } break; + } /* case LINECUSP_NONE: { if ( sign*cusp.width*angle_between(cusp.der0, cusp.der1) < 0.) { // we are on the outside @@ -250,15 +324,10 @@ Geom::Path path_from_piecewise_fix_cusps( Geom::Piecewise Geom::Point der2 = unitTangentAt(B[i],0); Geom::D2 newcurve1 = B[prev_i] * Geom::reflection(rot90(der1), B[prev_i].at1()); - newcurve1 = reverse(newcurve1); - std::vector temp; - sbasis_to_bezier(temp, newcurve1, 4); - Geom::CubicBezier bzr1( temp ); + Geom::CubicBezier bzr1 = sbasis_to_cubicbezier( reverse(newcurve1) ); Geom::D2 newcurve2 = B[i] * Geom::reflection(rot90(der2), B[i].at0()); - newcurve2 = reverse(newcurve2); - sbasis_to_bezier(temp, newcurve2, 4); - Geom::CubicBezier bzr2( temp ); + Geom::CubicBezier bzr2 = sbasis_to_cubicbezier( reverse(newcurve2) ); Geom::Crossings cross = crossings(bzr1, bzr2); if (cross.empty()) { -- cgit v1.2.3 From c556a7f645c32b7b15a3e711d4e4c84b38b7625b Mon Sep 17 00:00:00 2001 From: Alvin Penner Date: Wed, 21 Mar 2012 18:45:11 -0400 Subject: pdf import. improve upon rev 11094. transform four corners of bbox separately (Bug 919176) Fixed bugs: - https://launchpad.net/bugs/919176 (bzr r11112) --- src/extension/internal/pdfinput/pdf-parser.cpp | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/extension/internal/pdfinput/pdf-parser.cpp b/src/extension/internal/pdfinput/pdf-parser.cpp index 3b19f925e..5347a85ac 100644 --- a/src/extension/internal/pdfinput/pdf-parser.cpp +++ b/src/extension/internal/pdfinput/pdf-parser.cpp @@ -1672,17 +1672,23 @@ void PdfParser::opShFill(Object args[], int /*numArgs*/) if (matrix != NULL) { xTemp = matrix[0]*xMin + matrix[2]*yMin + matrix[4]; yTemp = matrix[1]*xMin + matrix[3]*yMin + matrix[5]; - xMin = xTemp; - yMin = yTemp; + state->moveTo(xTemp, yTemp); + xTemp = matrix[0]*xMax + matrix[2]*yMin + matrix[4]; + yTemp = matrix[1]*xMax + matrix[3]*yMin + matrix[5]; + state->lineTo(xTemp, yTemp); xTemp = matrix[0]*xMax + matrix[2]*yMax + matrix[4]; yTemp = matrix[1]*xMax + matrix[3]*yMax + matrix[5]; - xMax = xTemp; - yMax = yTemp; + state->lineTo(xTemp, yTemp); + xTemp = matrix[0]*xMin + matrix[2]*yMax + matrix[4]; + yTemp = matrix[1]*xMin + matrix[3]*yMax + matrix[5]; + state->lineTo(xTemp, yTemp); + } + else { + state->moveTo(xMin, yMin); + state->lineTo(xMax, yMin); + state->lineTo(xMax, yMax); + state->lineTo(xMin, yMax); } - state->moveTo(xMin, yMin); - state->lineTo(xMax, yMin); - state->lineTo(xMax, yMax); - state->lineTo(xMin, yMax); state->closePath(); state->clip(); if (savedState) -- cgit v1.2.3 From f948b873b90ef44e1eda1fe7d99a8ea0221c4daf Mon Sep 17 00:00:00 2001 From: John Smith Date: Thu, 22 Mar 2012 14:04:44 +0900 Subject: Fix for 903676 : Replace GtkCList with GtkTreeView in XML Tree, reduce list padding (bzr r11113) --- src/widgets/sp-xmlview-attr-list.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/widgets/sp-xmlview-attr-list.cpp b/src/widgets/sp-xmlview-attr-list.cpp index 1dd1f79bc..b2d22754d 100644 --- a/src/widgets/sp-xmlview-attr-list.cpp +++ b/src/widgets/sp-xmlview-attr-list.cpp @@ -54,11 +54,13 @@ sp_xmlview_attr_list_new (Inkscape::XML::Node * repr) gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE); gtk_tree_view_column_set_sort_column_id (column, COL_NAME); gtk_tree_sortable_set_sort_column_id ( GTK_TREE_SORTABLE(attr_list->store), COL_NAME, GTK_SORT_ASCENDING); + gtk_cell_renderer_set_padding (cell, 2, 0); cell = gtk_cell_renderer_text_new (); gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(attr_list), COL_VALUE, _("Value"), cell, "text", COL_VALUE, NULL); column = gtk_tree_view_get_column (GTK_TREE_VIEW(attr_list), COL_VALUE); gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE); + gtk_cell_renderer_set_padding (cell, 2, 0); sp_xmlview_attr_list_set_repr (attr_list, repr); -- cgit v1.2.3 From ba3ed10a77ace0385c2c2838a407a9a303395d40 Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Thu, 22 Mar 2012 17:40:00 +0100 Subject: Reverting unwanted dos format convertion. (bzr r11114) --- src/ui/context-menu.cpp | 1358 +++++++++++++++++++++++------------------------ 1 file changed, 679 insertions(+), 679 deletions(-) diff --git a/src/ui/context-menu.cpp b/src/ui/context-menu.cpp index bf116f5fb..6688185a1 100644 --- a/src/ui/context-menu.cpp +++ b/src/ui/context-menu.cpp @@ -1,679 +1,679 @@ -/* - * Unser-interface related object extension - * - * Authors: - * Lauris Kaplinski - * Jon A. Cruz - * Abhishek Sharma - * - * This code is in public domain - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include "ui/dialog/dialog-manager.h" -#include "context-menu.h" -#include "../xml/repr.h" -#include "desktop.h" -#include "document.h" -#include "document-undo.h" -#include "helper/action.h" //sp_action_perform -#include "inkscape.h" -#include "message-stack.h" -#include "preferences.h" -#include "verbs.h" - -using Inkscape::DocumentUndo; - -static void sp_object_type_menu(GType type, SPObject *object, SPDesktop *desktop, GtkMenu *menu); - -/* Append object-specific part to context menu */ - -void sp_object_menu(SPObject *object, SPDesktop *desktop, GtkMenu *menu) -{ - GObjectClass *klass; - klass = G_OBJECT_GET_CLASS(object); - while (G_TYPE_CHECK_CLASS_TYPE((klass), SP_TYPE_OBJECT)) { - GType type; - type = G_TYPE_FROM_CLASS(klass); - sp_object_type_menu(type, object, desktop, menu); - klass = (GObjectClass*)g_type_class_peek_parent(klass); - } -} - -/* Implementation */ - -#include -#include - -#include "selection.h" -#include "selection-chemistry.h" -#include "sp-anchor.h" -#include "sp-clippath.h" -#include "sp-image.h" -#include "sp-mask.h" -#include "sp-path.h" -#include "sp-text.h" -#include "desktop-handles.h" -#include "ui/dialog/object-attributes.h" -#include "ui/dialog/object-properties.h" -#include "ui/dialog/spellcheck.h" - - -static void sp_item_menu(SPObject *object, SPDesktop *desktop, GtkMenu *menu); -static void sp_group_menu(SPObject *object, SPDesktop *desktop, GtkMenu *menu); -static void sp_anchor_menu(SPObject *object, SPDesktop *desktop, GtkMenu *menu); -static void sp_image_menu(SPObject *object, SPDesktop *desktop, GtkMenu *menu); -static void sp_shape_menu(SPObject *object, SPDesktop *desktop, GtkMenu *menu); -static void sp_text_menu(SPObject *object, SPDesktop *desktop, GtkMenu *menu); - -static void sp_object_type_menu(GType type, SPObject *object, SPDesktop *desktop, GtkMenu *menu) -{ - static GHashTable *t2m = NULL; - void (* handler)(SPObject *object, SPDesktop *desktop, GtkMenu *menu); - if (!t2m) { - t2m = g_hash_table_new(NULL, NULL); - g_hash_table_insert(t2m, GUINT_TO_POINTER(SP_TYPE_ITEM), (void*)sp_item_menu); - g_hash_table_insert(t2m, GUINT_TO_POINTER(SP_TYPE_GROUP), (void*)sp_group_menu); - g_hash_table_insert(t2m, GUINT_TO_POINTER(SP_TYPE_ANCHOR), (void*)sp_anchor_menu); - g_hash_table_insert(t2m, GUINT_TO_POINTER(SP_TYPE_IMAGE), (void*)sp_image_menu); - g_hash_table_insert(t2m, GUINT_TO_POINTER(SP_TYPE_SHAPE), (void*)sp_shape_menu); - g_hash_table_insert(t2m, GUINT_TO_POINTER(SP_TYPE_TEXT), (void*)sp_text_menu); - } - handler = (void (*)(SPObject*, SPDesktop*, GtkMenu*))g_hash_table_lookup(t2m, GUINT_TO_POINTER(type)); - if (handler) handler(object, desktop, menu); -} - -/* SPItem */ - -static void sp_item_properties(GtkMenuItem *menuitem, SPItem *item); -static void sp_item_select_this(GtkMenuItem *menuitem, SPItem *item); -static void sp_item_create_link(GtkMenuItem *menuitem, SPItem *item); -static void sp_set_mask(GtkMenuItem *menuitem, SPItem *item); -static void sp_release_mask(GtkMenuItem *menuitem, SPItem *item); -static void sp_set_clip(GtkMenuItem *menuitem, SPItem *item); -static void sp_release_clip(GtkMenuItem *menuitem, SPItem *item); - -/* Generate context menu item section */ -static void sp_item_menu(SPObject *object, SPDesktop *desktop, GtkMenu *m) -{ - SPItem *item; - GtkWidget *w; - - item = (SPItem *) object; - - /* Item dialog */ - w = gtk_menu_item_new_with_mnemonic(_("_Object Properties...")); - g_object_set_data(G_OBJECT(w), "desktop", desktop); - g_signal_connect(G_OBJECT(w), "activate", G_CALLBACK(sp_item_properties), item); - gtk_widget_show(w); - gtk_menu_shell_append(GTK_MENU_SHELL(m), w); - /* Separator */ - w = gtk_menu_item_new(); - gtk_widget_show(w); - gtk_menu_shell_append(GTK_MENU_SHELL(m), w); - /* Select item */ - w = gtk_menu_item_new_with_mnemonic(_("_Select This")); - if (sp_desktop_selection(desktop)->includes(item)) { - gtk_widget_set_sensitive(w, FALSE); - } else { - g_object_set_data(G_OBJECT(w), "desktop", desktop); - g_signal_connect(G_OBJECT(w), "activate", G_CALLBACK(sp_item_select_this), item); - } - gtk_widget_show(w); - gtk_menu_shell_append(GTK_MENU_SHELL(m), w); - /* Create link */ - w = gtk_menu_item_new_with_mnemonic(_("_Create Link")); - g_object_set_data(G_OBJECT(w), "desktop", desktop); - g_signal_connect(G_OBJECT(w), "activate", G_CALLBACK(sp_item_create_link), item); - gtk_widget_set_sensitive(w, !SP_IS_ANCHOR(item)); - gtk_widget_show(w); - gtk_menu_shell_append(GTK_MENU_SHELL(m), w); - /* Set mask */ - w = gtk_menu_item_new_with_mnemonic(_("Set Mask")); - g_object_set_data(G_OBJECT(w), "desktop", desktop); - g_signal_connect(G_OBJECT(w), "activate", G_CALLBACK(sp_set_mask), item); - if ((item && item->mask_ref && item->mask_ref->getObject()) || (item->clip_ref && item->clip_ref->getObject())) { - gtk_widget_set_sensitive(w, FALSE); - } else { - gtk_widget_set_sensitive(w, TRUE); - } - gtk_widget_show(w); - gtk_menu_shell_append(GTK_MENU_SHELL(m), w); - /* Release mask */ - w = gtk_menu_item_new_with_mnemonic(_("Release Mask")); - g_object_set_data(G_OBJECT(w), "desktop", desktop); - g_signal_connect(G_OBJECT(w), "activate", G_CALLBACK(sp_release_mask), item); - if (item && item->mask_ref && item->mask_ref->getObject()) { - gtk_widget_set_sensitive(w, TRUE); - } else { - gtk_widget_set_sensitive(w, FALSE); - } - gtk_widget_show(w); - gtk_menu_shell_append(GTK_MENU_SHELL(m), w); - /* Set Clip */ - w = gtk_menu_item_new_with_mnemonic(_("Set _Clip")); - g_object_set_data(G_OBJECT(w), "desktop", desktop); - g_signal_connect(G_OBJECT(w), "activate", G_CALLBACK(sp_set_clip), item); - if ((item && item->mask_ref && item->mask_ref->getObject()) || (item->clip_ref && item->clip_ref->getObject())) { - gtk_widget_set_sensitive(w, FALSE); - } else { - gtk_widget_set_sensitive(w, TRUE); - } - gtk_widget_show(w); - gtk_menu_shell_append(GTK_MENU_SHELL(m), w); - /* Release Clip */ - w = gtk_menu_item_new_with_mnemonic(_("Release C_lip")); - g_object_set_data(G_OBJECT(w), "desktop", desktop); - g_signal_connect(G_OBJECT(w), "activate", G_CALLBACK(sp_release_clip), item); - if (item && item->clip_ref && item->clip_ref->getObject()) { - gtk_widget_set_sensitive(w, TRUE); - } else { - gtk_widget_set_sensitive(w, FALSE); - } - gtk_widget_show(w); - gtk_menu_shell_append(GTK_MENU_SHELL(m), w); - -} - -static void sp_item_properties(GtkMenuItem *menuitem, SPItem *item) -{ - SPDesktop *desktop; - - g_assert(SP_IS_ITEM(item)); - - desktop = (SPDesktop*)g_object_get_data(G_OBJECT(menuitem), "desktop"); - g_return_if_fail(desktop != NULL); - - sp_desktop_selection(desktop)->set(item); - - // sp_item_dialog(); - desktop->_dlg_mgr->showDialog("ObjectProperties"); -} - - -static void sp_set_mask(GtkMenuItem *menuitem, SPItem *item) -{ - SPDesktop *desktop; - - g_assert(SP_IS_ITEM(item)); - - desktop = (SPDesktop*)g_object_get_data(G_OBJECT(menuitem), "desktop"); - g_return_if_fail(desktop != NULL); - - sp_selection_set_mask(desktop, false, false); -} - - -static void sp_release_mask(GtkMenuItem *menuitem, SPItem *item) -{ - SPDesktop *desktop; - - g_assert(SP_IS_ITEM(item)); - - desktop = (SPDesktop*)g_object_get_data(G_OBJECT(menuitem), "desktop"); - g_return_if_fail(desktop != NULL); - - sp_selection_unset_mask(desktop, false); -} - - -static void sp_set_clip(GtkMenuItem *menuitem, SPItem *item) -{ - SPDesktop *desktop; - - g_assert(SP_IS_ITEM(item)); - - desktop = (SPDesktop*)g_object_get_data(G_OBJECT(menuitem), "desktop"); - g_return_if_fail(desktop != NULL); - - sp_selection_set_mask(desktop, true, false); -} - - -static void sp_release_clip(GtkMenuItem *menuitem, SPItem *item) -{ - SPDesktop *desktop; - - g_assert(SP_IS_ITEM(item)); - - desktop = (SPDesktop*)g_object_get_data(G_OBJECT(menuitem), "desktop"); - g_return_if_fail(desktop != NULL); - - sp_selection_unset_mask(desktop, true); -} - - -static void sp_item_select_this(GtkMenuItem *menuitem, SPItem *item) -{ - SPDesktop *desktop; - - g_assert(SP_IS_ITEM(item)); - - desktop = (SPDesktop*)g_object_get_data(G_OBJECT(menuitem), "desktop"); - g_return_if_fail(desktop != NULL); - - sp_desktop_selection(desktop)->set(item); -} - -static void sp_item_create_link(GtkMenuItem *menuitem, SPItem *item) -{ - g_assert(SP_IS_ITEM(item)); - g_assert(!SP_IS_ANCHOR(item)); - - SPDesktop *desktop = (SPDesktop*)g_object_get_data(G_OBJECT(menuitem), "desktop"); - g_return_if_fail(desktop != NULL); - - Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc(); - Inkscape::XML::Node *repr = xml_doc->createElement("svg:a"); - item->parent->getRepr()->addChild(repr, item->getRepr()); - SPObject *object = item->document->getObjectByRepr(repr); - g_return_if_fail(SP_IS_ANCHOR(object)); - - 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(object->document, SP_VERB_NONE, - _("Create link")); - - sp_desktop_selection(desktop)->set(SP_ITEM(object)); - desktop->_dlg_mgr->showDialog("ObjectAttributes"); -} - -/* SPGroup */ - -static void sp_item_group_ungroup_activate(GtkMenuItem *menuitem, SPGroup *group); - -static void sp_group_menu(SPObject *object, SPDesktop *desktop, GtkMenu *menu) -{ - SPItem *item=SP_ITEM(object); - GtkWidget *w; - - /* "Ungroup" */ - w = gtk_menu_item_new_with_mnemonic(_("_Ungroup")); - g_object_set_data(G_OBJECT(w), "desktop", desktop); - g_signal_connect(G_OBJECT(w), "activate", G_CALLBACK(sp_item_group_ungroup_activate), item); - gtk_widget_show(w); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), w); -} - -static void sp_item_group_ungroup_activate(GtkMenuItem *menuitem, SPGroup *group) -{ - SPDesktop *desktop; - GSList *children; - - g_assert(SP_IS_GROUP(group)); - - desktop = (SPDesktop*)g_object_get_data(G_OBJECT(menuitem), "desktop"); - g_return_if_fail(desktop != NULL); - - children = NULL; - sp_item_group_ungroup(group, &children); - - sp_desktop_selection(desktop)->setList(children); - g_slist_free(children); -} - -/* SPAnchor */ - -static void sp_anchor_link_properties(GtkMenuItem *menuitem, SPAnchor *anchor); -static void sp_anchor_link_follow(GtkMenuItem *menuitem, SPAnchor *anchor); -static void sp_anchor_link_remove(GtkMenuItem *menuitem, SPAnchor *anchor); - -static void sp_anchor_menu(SPObject *object, SPDesktop *desktop, GtkMenu *m) -{ - SPItem *item; - GtkWidget *w; - - item = (SPItem *) object; - - /* Link dialog */ - w = gtk_menu_item_new_with_mnemonic(_("Link _Properties...")); - g_object_set_data(G_OBJECT(w), "desktop", desktop); - g_signal_connect(G_OBJECT(w), "activate", G_CALLBACK(sp_anchor_link_properties), item); - gtk_widget_show(w); - gtk_menu_shell_append(GTK_MENU_SHELL(m), w); - /* Select item */ - w = gtk_menu_item_new_with_mnemonic(_("_Follow Link")); - g_signal_connect(G_OBJECT(w), "activate", G_CALLBACK(sp_anchor_link_follow), item); - gtk_widget_show(w); - gtk_menu_shell_append(GTK_MENU_SHELL(m), w); - /* Reset transformations */ - w = gtk_menu_item_new_with_mnemonic(_("_Remove Link")); - g_object_set_data(G_OBJECT(w), "desktop", desktop); - g_signal_connect(G_OBJECT(w), "activate", G_CALLBACK(sp_anchor_link_remove), item); - gtk_widget_show(w); - gtk_menu_shell_append(GTK_MENU_SHELL(m), w); -} - -static void sp_anchor_link_properties(GtkMenuItem *menuitem, SPAnchor */*anchor*/) -{ - SPDesktop *desktop = (SPDesktop*)g_object_get_data(G_OBJECT(menuitem), "desktop"); - g_return_if_fail(desktop != NULL); - desktop->_dlg_mgr->showDialog("ObjectAttributes"); -} - -static void sp_anchor_link_follow(GtkMenuItem */*menuitem*/, SPAnchor *anchor) -{ - g_return_if_fail(anchor != NULL); - g_return_if_fail(SP_IS_ANCHOR(anchor)); - - /* shell out to an external browser here */ -} - -static void sp_anchor_link_remove(GtkMenuItem */*menuitem*/, SPAnchor *anchor) -{ - GSList *children; - - g_return_if_fail(anchor != NULL); - g_return_if_fail(SP_IS_ANCHOR(anchor)); - - children = NULL; - sp_item_group_ungroup(SP_GROUP(anchor), &children); - - g_slist_free(children); -} - -/* Image */ - -static void sp_image_image_properties(GtkMenuItem *menuitem, SPAnchor *anchor); -static void sp_image_image_edit(GtkMenuItem *menuitem, SPAnchor *anchor); -static void sp_image_image_embed(GtkMenuItem *menuitem, SPItem *item); -static void sp_image_image_extract(GtkMenuItem *menuitem, SPItem *item); - -static void sp_image_menu(SPObject *object, SPDesktop *desktop, GtkMenu *m) -{ - SPItem *item = SP_ITEM(object); - GtkWidget *w; - Inkscape::XML::Node *ir = object->getRepr(); - const gchar *href = ir->attribute("xlink:href"); - - /* Image properties */ - w = gtk_menu_item_new_with_mnemonic(_("Image _Properties...")); - g_object_set_data(G_OBJECT(w), "desktop", desktop); - g_signal_connect(G_OBJECT(w), "activate", G_CALLBACK(sp_image_image_properties), item); - gtk_widget_show(w); - gtk_menu_shell_append(GTK_MENU_SHELL(m), w); - - /* Edit externally */ - w = gtk_menu_item_new_with_mnemonic(_("Edit Externally...")); - g_object_set_data(G_OBJECT(w), "desktop", desktop); - g_signal_connect(G_OBJECT(w), "activate", G_CALLBACK(sp_image_image_edit), item); - gtk_widget_show(w); - gtk_menu_shell_append(GTK_MENU_SHELL(m), w); - if ( (!href) || ((strncmp(href, "data:", 5) == 0)) ) { - gtk_widget_set_sensitive( w, FALSE ); - } - - /* Embed image */ - if (Inkscape::Verb::getbyid( "org.ekips.filter.embedselectedimages" )) { - w = gtk_menu_item_new_with_mnemonic(C_("Context menu", "Embed Image")); - g_object_set_data(G_OBJECT(w), "desktop", desktop); - g_signal_connect(G_OBJECT(w), "activate", G_CALLBACK(sp_image_image_embed), item); - gtk_widget_show(w); - gtk_menu_shell_append(GTK_MENU_SHELL(m), w); - if ( (!href) || ((strncmp(href, "data:", 5) == 0)) ) { - gtk_widget_set_sensitive( w, FALSE ); - } - } - - /* Extract image */ - if (Inkscape::Verb::getbyid( "org.ekips.filter.extractimage" )) { - w = gtk_menu_item_new_with_mnemonic(C_("Context menu", "Extract Image")); - g_object_set_data(G_OBJECT(w), "desktop", desktop); - g_signal_connect(G_OBJECT(w), "activate", G_CALLBACK(sp_image_image_extract), item); - gtk_widget_show(w); - gtk_menu_shell_append(GTK_MENU_SHELL(m), w); - if ( (!href) || ((strncmp(href, "data:", 5) != 0)) ) { - gtk_widget_set_sensitive( w, FALSE ); - } - } -} - -/* Image Properties entry */ -static void sp_image_image_properties(GtkMenuItem *menuitem, SPAnchor */*anchor*/) -{ - SPDesktop *desktop = (SPDesktop*)g_object_get_data(G_OBJECT(menuitem), "desktop"); - g_return_if_fail(desktop != NULL); - desktop->_dlg_mgr->showDialog("ObjectAttributes"); -} - -static gchar* getImageEditorName() { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - gchar* value = 0; - Glib::ustring choices = prefs->getString("/options/bitmapeditor/value"); - if (!choices.empty()) { - value = g_strdup(choices.c_str()); - } - if (!value) { - value = g_strdup("gimp"); - } - return value; -} - -/* Edit Externally entry */ -static void sp_image_image_edit(GtkMenuItem *menuitem, SPAnchor *anchor) -{ - SPObject* obj = anchor; - Inkscape::XML::Node *ir = obj->getRepr(); - const gchar *href = ir->attribute("xlink:href"); - - GError* errThing = 0; - Glib::ustring cmdline = getImageEditorName(); - Glib::ustring name; - 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 - name = g_filename_from_uri(href, NULL, NULL); - } else { - name.append(href); - } - - if (Glib::path_is_absolute(name)) { - fullname = name; - } else if (SP_ACTIVE_DOCUMENT->getBase()) { - fullname = Glib::build_filename(SP_ACTIVE_DOCUMENT->getBase(), name); - } else { - fullname = Glib::build_filename(Glib::get_current_dir(), name); - } - - cmdline.append(" '"); - cmdline.append(fullname.c_str()); - cmdline.append("'"); - - //g_warning("##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*)g_object_get_data(G_OBJECT(menuitem), "desktop"); - desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, errThing->message); - g_error_free(errThing); - errThing = 0; - } -} - -/* Embed Image entry */ -static void sp_image_image_embed(GtkMenuItem *menuitem, SPItem *item) -{ - SPDesktop *desktop; - - g_assert(SP_IS_ITEM(item)); - - desktop = (SPDesktop*)g_object_get_data(G_OBJECT(menuitem), "desktop"); - g_return_if_fail(desktop != NULL); - - if (sp_desktop_selection(desktop)->isEmpty()) { - sp_desktop_selection(desktop)->set(item); - } - - Inkscape::Verb *verb = Inkscape::Verb::getbyid( "org.ekips.filter.embedselectedimages" ); - if (verb) { - SPAction *action = verb->get_action(desktop); - if (action) { - sp_action_perform(action, NULL); - } - } -} - -/* Extract Image entry */ -static void sp_image_image_extract(GtkMenuItem *menuitem, SPItem *item) -{ - SPDesktop *desktop; - - g_assert(SP_IS_ITEM(item)); - - desktop = (SPDesktop*)g_object_get_data(G_OBJECT(menuitem), "desktop"); - g_return_if_fail(desktop != NULL); - - if (sp_desktop_selection(desktop)->isEmpty()) { - sp_desktop_selection(desktop)->set(item); - } - - Inkscape::Verb *verb = Inkscape::Verb::getbyid( "org.ekips.filter.extractimage" ); - if (verb) { - SPAction *action = verb->get_action(desktop); - if (action) { - sp_action_perform(action, NULL); - } - } -} - -/* Fill and Stroke entry */ -static void sp_fill_settings(GtkMenuItem *menuitem, SPItem *item) -{ - SPDesktop *desktop; - - g_assert(SP_IS_ITEM(item)); - - desktop = (SPDesktop*)g_object_get_data(G_OBJECT(menuitem), "desktop"); - g_return_if_fail(desktop != NULL); - - if (sp_desktop_selection(desktop)->isEmpty()) { - sp_desktop_selection(desktop)->set(item); - } - - desktop->_dlg_mgr->showDialog("FillAndStroke"); -} - -/* SPShape */ -static void sp_shape_menu(SPObject *object, SPDesktop *desktop, GtkMenu *m) -{ - SPItem *item; - GtkWidget *w; - - item = (SPItem *) object; - - /* Item dialog */ - w = gtk_menu_item_new_with_mnemonic(_("_Fill and Stroke...")); - g_object_set_data(G_OBJECT(w), "desktop", desktop); - g_signal_connect(G_OBJECT(w), "activate", G_CALLBACK(sp_fill_settings), item); - gtk_widget_show(w); - gtk_menu_shell_append(GTK_MENU_SHELL(m), w); -} - -/* Edit Text entry */ -static void sp_text_settings(GtkMenuItem *menuitem, SPItem *item) -{ - SPDesktop *desktop; - - g_assert(SP_IS_ITEM(item)); - - desktop = (SPDesktop*)g_object_get_data(G_OBJECT(menuitem), "desktop"); - g_return_if_fail(desktop != NULL); - - if (sp_desktop_selection(desktop)->isEmpty()) { - sp_desktop_selection(desktop)->set(item); - } - - desktop->_dlg_mgr->showDialog("TextFont"); -} - -/* Spellcheck entry */ -static void sp_spellcheck_settings(GtkMenuItem *menuitem, SPItem *item) -{ - SPDesktop *desktop; - - g_assert(SP_IS_ITEM(item)); - - desktop = (SPDesktop*)g_object_get_data(G_OBJECT(menuitem), "desktop"); - g_return_if_fail(desktop != NULL); - - if (sp_desktop_selection(desktop)->isEmpty()) { - sp_desktop_selection(desktop)->set(item); - } - - desktop->_dlg_mgr->showDialog("SpellCheck"); -} - -/* SPText */ -static void sp_text_menu(SPObject *object, SPDesktop *desktop, GtkMenu *m) -{ - SPItem *item; - GtkWidget *w; - - item = (SPItem *) object; - - /* Fill and Stroke dialog */ - w = gtk_menu_item_new_with_mnemonic(_("_Fill and Stroke...")); - g_object_set_data(G_OBJECT(w), "desktop", desktop); - g_signal_connect(G_OBJECT(w), "activate", G_CALLBACK(sp_fill_settings), item); - gtk_widget_show(w); - gtk_menu_shell_append(GTK_MENU_SHELL(m), w); - - /* Edit Text dialog */ - w = gtk_menu_item_new_with_mnemonic(_("_Text and Font...")); - g_object_set_data(G_OBJECT(w), "desktop", desktop); - g_signal_connect(G_OBJECT(w), "activate", G_CALLBACK(sp_text_settings), item); - gtk_widget_show(w); - gtk_menu_shell_append(GTK_MENU_SHELL(m), w); - - /* Spellcheck dialog */ - w = gtk_menu_item_new_with_mnemonic(_("Check Spellin_g...")); - g_object_set_data(G_OBJECT(w), "desktop", desktop); - g_signal_connect(G_OBJECT(w), "activate", G_CALLBACK(sp_spellcheck_settings), item); - gtk_widget_show(w); - gtk_menu_shell_append(GTK_MENU_SHELL(m), w); -} -/* - 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 : +/* + * Unser-interface related object extension + * + * Authors: + * Lauris Kaplinski + * Jon A. Cruz + * Abhishek Sharma + * + * This code is in public domain + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "ui/dialog/dialog-manager.h" +#include "context-menu.h" +#include "../xml/repr.h" +#include "desktop.h" +#include "document.h" +#include "document-undo.h" +#include "helper/action.h" //sp_action_perform +#include "inkscape.h" +#include "message-stack.h" +#include "preferences.h" +#include "verbs.h" + +using Inkscape::DocumentUndo; + +static void sp_object_type_menu(GType type, SPObject *object, SPDesktop *desktop, GtkMenu *menu); + +/* Append object-specific part to context menu */ + +void sp_object_menu(SPObject *object, SPDesktop *desktop, GtkMenu *menu) +{ + GObjectClass *klass; + klass = G_OBJECT_GET_CLASS(object); + while (G_TYPE_CHECK_CLASS_TYPE((klass), SP_TYPE_OBJECT)) { + GType type; + type = G_TYPE_FROM_CLASS(klass); + sp_object_type_menu(type, object, desktop, menu); + klass = (GObjectClass*)g_type_class_peek_parent(klass); + } +} + +/* Implementation */ + +#include +#include + +#include "selection.h" +#include "selection-chemistry.h" +#include "sp-anchor.h" +#include "sp-clippath.h" +#include "sp-image.h" +#include "sp-mask.h" +#include "sp-path.h" +#include "sp-text.h" +#include "desktop-handles.h" +#include "ui/dialog/object-attributes.h" +#include "ui/dialog/object-properties.h" +#include "ui/dialog/spellcheck.h" + + +static void sp_item_menu(SPObject *object, SPDesktop *desktop, GtkMenu *menu); +static void sp_group_menu(SPObject *object, SPDesktop *desktop, GtkMenu *menu); +static void sp_anchor_menu(SPObject *object, SPDesktop *desktop, GtkMenu *menu); +static void sp_image_menu(SPObject *object, SPDesktop *desktop, GtkMenu *menu); +static void sp_shape_menu(SPObject *object, SPDesktop *desktop, GtkMenu *menu); +static void sp_text_menu(SPObject *object, SPDesktop *desktop, GtkMenu *menu); + +static void sp_object_type_menu(GType type, SPObject *object, SPDesktop *desktop, GtkMenu *menu) +{ + static GHashTable *t2m = NULL; + void (* handler)(SPObject *object, SPDesktop *desktop, GtkMenu *menu); + if (!t2m) { + t2m = g_hash_table_new(NULL, NULL); + g_hash_table_insert(t2m, GUINT_TO_POINTER(SP_TYPE_ITEM), (void*)sp_item_menu); + g_hash_table_insert(t2m, GUINT_TO_POINTER(SP_TYPE_GROUP), (void*)sp_group_menu); + g_hash_table_insert(t2m, GUINT_TO_POINTER(SP_TYPE_ANCHOR), (void*)sp_anchor_menu); + g_hash_table_insert(t2m, GUINT_TO_POINTER(SP_TYPE_IMAGE), (void*)sp_image_menu); + g_hash_table_insert(t2m, GUINT_TO_POINTER(SP_TYPE_SHAPE), (void*)sp_shape_menu); + g_hash_table_insert(t2m, GUINT_TO_POINTER(SP_TYPE_TEXT), (void*)sp_text_menu); + } + handler = (void (*)(SPObject*, SPDesktop*, GtkMenu*))g_hash_table_lookup(t2m, GUINT_TO_POINTER(type)); + if (handler) handler(object, desktop, menu); +} + +/* SPItem */ + +static void sp_item_properties(GtkMenuItem *menuitem, SPItem *item); +static void sp_item_select_this(GtkMenuItem *menuitem, SPItem *item); +static void sp_item_create_link(GtkMenuItem *menuitem, SPItem *item); +static void sp_set_mask(GtkMenuItem *menuitem, SPItem *item); +static void sp_release_mask(GtkMenuItem *menuitem, SPItem *item); +static void sp_set_clip(GtkMenuItem *menuitem, SPItem *item); +static void sp_release_clip(GtkMenuItem *menuitem, SPItem *item); + +/* Generate context menu item section */ +static void sp_item_menu(SPObject *object, SPDesktop *desktop, GtkMenu *m) +{ + SPItem *item; + GtkWidget *w; + + item = (SPItem *) object; + + /* Item dialog */ + w = gtk_menu_item_new_with_mnemonic(_("_Object Properties...")); + g_object_set_data(G_OBJECT(w), "desktop", desktop); + g_signal_connect(G_OBJECT(w), "activate", G_CALLBACK(sp_item_properties), item); + gtk_widget_show(w); + gtk_menu_shell_append(GTK_MENU_SHELL(m), w); + /* Separator */ + w = gtk_menu_item_new(); + gtk_widget_show(w); + gtk_menu_shell_append(GTK_MENU_SHELL(m), w); + /* Select item */ + w = gtk_menu_item_new_with_mnemonic(_("_Select This")); + if (sp_desktop_selection(desktop)->includes(item)) { + gtk_widget_set_sensitive(w, FALSE); + } else { + g_object_set_data(G_OBJECT(w), "desktop", desktop); + g_signal_connect(G_OBJECT(w), "activate", G_CALLBACK(sp_item_select_this), item); + } + gtk_widget_show(w); + gtk_menu_shell_append(GTK_MENU_SHELL(m), w); + /* Create link */ + w = gtk_menu_item_new_with_mnemonic(_("_Create Link")); + g_object_set_data(G_OBJECT(w), "desktop", desktop); + g_signal_connect(G_OBJECT(w), "activate", G_CALLBACK(sp_item_create_link), item); + gtk_widget_set_sensitive(w, !SP_IS_ANCHOR(item)); + gtk_widget_show(w); + gtk_menu_shell_append(GTK_MENU_SHELL(m), w); + /* Set mask */ + w = gtk_menu_item_new_with_mnemonic(_("Set Mask")); + g_object_set_data(G_OBJECT(w), "desktop", desktop); + g_signal_connect(G_OBJECT(w), "activate", G_CALLBACK(sp_set_mask), item); + if ((item && item->mask_ref && item->mask_ref->getObject()) || (item->clip_ref && item->clip_ref->getObject())) { + gtk_widget_set_sensitive(w, FALSE); + } else { + gtk_widget_set_sensitive(w, TRUE); + } + gtk_widget_show(w); + gtk_menu_shell_append(GTK_MENU_SHELL(m), w); + /* Release mask */ + w = gtk_menu_item_new_with_mnemonic(_("Release Mask")); + g_object_set_data(G_OBJECT(w), "desktop", desktop); + g_signal_connect(G_OBJECT(w), "activate", G_CALLBACK(sp_release_mask), item); + if (item && item->mask_ref && item->mask_ref->getObject()) { + gtk_widget_set_sensitive(w, TRUE); + } else { + gtk_widget_set_sensitive(w, FALSE); + } + gtk_widget_show(w); + gtk_menu_shell_append(GTK_MENU_SHELL(m), w); + /* Set Clip */ + w = gtk_menu_item_new_with_mnemonic(_("Set _Clip")); + g_object_set_data(G_OBJECT(w), "desktop", desktop); + g_signal_connect(G_OBJECT(w), "activate", G_CALLBACK(sp_set_clip), item); + if ((item && item->mask_ref && item->mask_ref->getObject()) || (item->clip_ref && item->clip_ref->getObject())) { + gtk_widget_set_sensitive(w, FALSE); + } else { + gtk_widget_set_sensitive(w, TRUE); + } + gtk_widget_show(w); + gtk_menu_shell_append(GTK_MENU_SHELL(m), w); + /* Release Clip */ + w = gtk_menu_item_new_with_mnemonic(_("Release C_lip")); + g_object_set_data(G_OBJECT(w), "desktop", desktop); + g_signal_connect(G_OBJECT(w), "activate", G_CALLBACK(sp_release_clip), item); + if (item && item->clip_ref && item->clip_ref->getObject()) { + gtk_widget_set_sensitive(w, TRUE); + } else { + gtk_widget_set_sensitive(w, FALSE); + } + gtk_widget_show(w); + gtk_menu_shell_append(GTK_MENU_SHELL(m), w); + +} + +static void sp_item_properties(GtkMenuItem *menuitem, SPItem *item) +{ + SPDesktop *desktop; + + g_assert(SP_IS_ITEM(item)); + + desktop = (SPDesktop*)g_object_get_data(G_OBJECT(menuitem), "desktop"); + g_return_if_fail(desktop != NULL); + + sp_desktop_selection(desktop)->set(item); + + // sp_item_dialog(); + desktop->_dlg_mgr->showDialog("ObjectProperties"); +} + + +static void sp_set_mask(GtkMenuItem *menuitem, SPItem *item) +{ + SPDesktop *desktop; + + g_assert(SP_IS_ITEM(item)); + + desktop = (SPDesktop*)g_object_get_data(G_OBJECT(menuitem), "desktop"); + g_return_if_fail(desktop != NULL); + + sp_selection_set_mask(desktop, false, false); +} + + +static void sp_release_mask(GtkMenuItem *menuitem, SPItem *item) +{ + SPDesktop *desktop; + + g_assert(SP_IS_ITEM(item)); + + desktop = (SPDesktop*)g_object_get_data(G_OBJECT(menuitem), "desktop"); + g_return_if_fail(desktop != NULL); + + sp_selection_unset_mask(desktop, false); +} + + +static void sp_set_clip(GtkMenuItem *menuitem, SPItem *item) +{ + SPDesktop *desktop; + + g_assert(SP_IS_ITEM(item)); + + desktop = (SPDesktop*)g_object_get_data(G_OBJECT(menuitem), "desktop"); + g_return_if_fail(desktop != NULL); + + sp_selection_set_mask(desktop, true, false); +} + + +static void sp_release_clip(GtkMenuItem *menuitem, SPItem *item) +{ + SPDesktop *desktop; + + g_assert(SP_IS_ITEM(item)); + + desktop = (SPDesktop*)g_object_get_data(G_OBJECT(menuitem), "desktop"); + g_return_if_fail(desktop != NULL); + + sp_selection_unset_mask(desktop, true); +} + + +static void sp_item_select_this(GtkMenuItem *menuitem, SPItem *item) +{ + SPDesktop *desktop; + + g_assert(SP_IS_ITEM(item)); + + desktop = (SPDesktop*)g_object_get_data(G_OBJECT(menuitem), "desktop"); + g_return_if_fail(desktop != NULL); + + sp_desktop_selection(desktop)->set(item); +} + +static void sp_item_create_link(GtkMenuItem *menuitem, SPItem *item) +{ + g_assert(SP_IS_ITEM(item)); + g_assert(!SP_IS_ANCHOR(item)); + + SPDesktop *desktop = (SPDesktop*)g_object_get_data(G_OBJECT(menuitem), "desktop"); + g_return_if_fail(desktop != NULL); + + Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc(); + Inkscape::XML::Node *repr = xml_doc->createElement("svg:a"); + item->parent->getRepr()->addChild(repr, item->getRepr()); + SPObject *object = item->document->getObjectByRepr(repr); + g_return_if_fail(SP_IS_ANCHOR(object)); + + 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(object->document, SP_VERB_NONE, + _("Create link")); + + sp_desktop_selection(desktop)->set(SP_ITEM(object)); + desktop->_dlg_mgr->showDialog("ObjectAttributes"); +} + +/* SPGroup */ + +static void sp_item_group_ungroup_activate(GtkMenuItem *menuitem, SPGroup *group); + +static void sp_group_menu(SPObject *object, SPDesktop *desktop, GtkMenu *menu) +{ + SPItem *item=SP_ITEM(object); + GtkWidget *w; + + /* "Ungroup" */ + w = gtk_menu_item_new_with_mnemonic(_("_Ungroup")); + g_object_set_data(G_OBJECT(w), "desktop", desktop); + g_signal_connect(G_OBJECT(w), "activate", G_CALLBACK(sp_item_group_ungroup_activate), item); + gtk_widget_show(w); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), w); +} + +static void sp_item_group_ungroup_activate(GtkMenuItem *menuitem, SPGroup *group) +{ + SPDesktop *desktop; + GSList *children; + + g_assert(SP_IS_GROUP(group)); + + desktop = (SPDesktop*)g_object_get_data(G_OBJECT(menuitem), "desktop"); + g_return_if_fail(desktop != NULL); + + children = NULL; + sp_item_group_ungroup(group, &children); + + sp_desktop_selection(desktop)->setList(children); + g_slist_free(children); +} + +/* SPAnchor */ + +static void sp_anchor_link_properties(GtkMenuItem *menuitem, SPAnchor *anchor); +static void sp_anchor_link_follow(GtkMenuItem *menuitem, SPAnchor *anchor); +static void sp_anchor_link_remove(GtkMenuItem *menuitem, SPAnchor *anchor); + +static void sp_anchor_menu(SPObject *object, SPDesktop *desktop, GtkMenu *m) +{ + SPItem *item; + GtkWidget *w; + + item = (SPItem *) object; + + /* Link dialog */ + w = gtk_menu_item_new_with_mnemonic(_("Link _Properties...")); + g_object_set_data(G_OBJECT(w), "desktop", desktop); + g_signal_connect(G_OBJECT(w), "activate", G_CALLBACK(sp_anchor_link_properties), item); + gtk_widget_show(w); + gtk_menu_shell_append(GTK_MENU_SHELL(m), w); + /* Select item */ + w = gtk_menu_item_new_with_mnemonic(_("_Follow Link")); + g_signal_connect(G_OBJECT(w), "activate", G_CALLBACK(sp_anchor_link_follow), item); + gtk_widget_show(w); + gtk_menu_shell_append(GTK_MENU_SHELL(m), w); + /* Reset transformations */ + w = gtk_menu_item_new_with_mnemonic(_("_Remove Link")); + g_object_set_data(G_OBJECT(w), "desktop", desktop); + g_signal_connect(G_OBJECT(w), "activate", G_CALLBACK(sp_anchor_link_remove), item); + gtk_widget_show(w); + gtk_menu_shell_append(GTK_MENU_SHELL(m), w); +} + +static void sp_anchor_link_properties(GtkMenuItem *menuitem, SPAnchor */*anchor*/) +{ + SPDesktop *desktop = (SPDesktop*)g_object_get_data(G_OBJECT(menuitem), "desktop"); + g_return_if_fail(desktop != NULL); + desktop->_dlg_mgr->showDialog("ObjectAttributes"); +} + +static void sp_anchor_link_follow(GtkMenuItem */*menuitem*/, SPAnchor *anchor) +{ + g_return_if_fail(anchor != NULL); + g_return_if_fail(SP_IS_ANCHOR(anchor)); + + /* shell out to an external browser here */ +} + +static void sp_anchor_link_remove(GtkMenuItem */*menuitem*/, SPAnchor *anchor) +{ + GSList *children; + + g_return_if_fail(anchor != NULL); + g_return_if_fail(SP_IS_ANCHOR(anchor)); + + children = NULL; + sp_item_group_ungroup(SP_GROUP(anchor), &children); + + g_slist_free(children); +} + +/* Image */ + +static void sp_image_image_properties(GtkMenuItem *menuitem, SPAnchor *anchor); +static void sp_image_image_edit(GtkMenuItem *menuitem, SPAnchor *anchor); +static void sp_image_image_embed(GtkMenuItem *menuitem, SPItem *item); +static void sp_image_image_extract(GtkMenuItem *menuitem, SPItem *item); + +static void sp_image_menu(SPObject *object, SPDesktop *desktop, GtkMenu *m) +{ + SPItem *item = SP_ITEM(object); + GtkWidget *w; + Inkscape::XML::Node *ir = object->getRepr(); + const gchar *href = ir->attribute("xlink:href"); + + /* Image properties */ + w = gtk_menu_item_new_with_mnemonic(_("Image _Properties...")); + g_object_set_data(G_OBJECT(w), "desktop", desktop); + g_signal_connect(G_OBJECT(w), "activate", G_CALLBACK(sp_image_image_properties), item); + gtk_widget_show(w); + gtk_menu_shell_append(GTK_MENU_SHELL(m), w); + + /* Edit externally */ + w = gtk_menu_item_new_with_mnemonic(_("Edit Externally...")); + g_object_set_data(G_OBJECT(w), "desktop", desktop); + g_signal_connect(G_OBJECT(w), "activate", G_CALLBACK(sp_image_image_edit), item); + gtk_widget_show(w); + gtk_menu_shell_append(GTK_MENU_SHELL(m), w); + if ( (!href) || ((strncmp(href, "data:", 5) == 0)) ) { + gtk_widget_set_sensitive( w, FALSE ); + } + + /* Embed image */ + if (Inkscape::Verb::getbyid( "org.ekips.filter.embedselectedimages" )) { + w = gtk_menu_item_new_with_mnemonic(C_("Context menu", "Embed Image")); + g_object_set_data(G_OBJECT(w), "desktop", desktop); + g_signal_connect(G_OBJECT(w), "activate", G_CALLBACK(sp_image_image_embed), item); + gtk_widget_show(w); + gtk_menu_shell_append(GTK_MENU_SHELL(m), w); + if ( (!href) || ((strncmp(href, "data:", 5) == 0)) ) { + gtk_widget_set_sensitive( w, FALSE ); + } + } + + /* Extract image */ + if (Inkscape::Verb::getbyid( "org.ekips.filter.extractimage" )) { + w = gtk_menu_item_new_with_mnemonic(C_("Context menu", "Extract Image")); + g_object_set_data(G_OBJECT(w), "desktop", desktop); + g_signal_connect(G_OBJECT(w), "activate", G_CALLBACK(sp_image_image_extract), item); + gtk_widget_show(w); + gtk_menu_shell_append(GTK_MENU_SHELL(m), w); + if ( (!href) || ((strncmp(href, "data:", 5) != 0)) ) { + gtk_widget_set_sensitive( w, FALSE ); + } + } +} + +/* Image Properties entry */ +static void sp_image_image_properties(GtkMenuItem *menuitem, SPAnchor */*anchor*/) +{ + SPDesktop *desktop = (SPDesktop*)g_object_get_data(G_OBJECT(menuitem), "desktop"); + g_return_if_fail(desktop != NULL); + desktop->_dlg_mgr->showDialog("ObjectAttributes"); +} + +static gchar* getImageEditorName() { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + gchar* value = 0; + Glib::ustring choices = prefs->getString("/options/bitmapeditor/value"); + if (!choices.empty()) { + value = g_strdup(choices.c_str()); + } + if (!value) { + value = g_strdup("gimp"); + } + return value; +} + +/* Edit Externally entry */ +static void sp_image_image_edit(GtkMenuItem *menuitem, SPAnchor *anchor) +{ + SPObject* obj = anchor; + Inkscape::XML::Node *ir = obj->getRepr(); + const gchar *href = ir->attribute("xlink:href"); + + GError* errThing = 0; + Glib::ustring cmdline = getImageEditorName(); + Glib::ustring name; + 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 + name = g_filename_from_uri(href, NULL, NULL); + } else { + name.append(href); + } + + if (Glib::path_is_absolute(name)) { + fullname = name; + } else if (SP_ACTIVE_DOCUMENT->getBase()) { + fullname = Glib::build_filename(SP_ACTIVE_DOCUMENT->getBase(), name); + } else { + fullname = Glib::build_filename(Glib::get_current_dir(), name); + } + + cmdline.append(" '"); + cmdline.append(fullname.c_str()); + cmdline.append("'"); + + //g_warning("##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*)g_object_get_data(G_OBJECT(menuitem), "desktop"); + desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, errThing->message); + g_error_free(errThing); + errThing = 0; + } +} + +/* Embed Image entry */ +static void sp_image_image_embed(GtkMenuItem *menuitem, SPItem *item) +{ + SPDesktop *desktop; + + g_assert(SP_IS_ITEM(item)); + + desktop = (SPDesktop*)g_object_get_data(G_OBJECT(menuitem), "desktop"); + g_return_if_fail(desktop != NULL); + + if (sp_desktop_selection(desktop)->isEmpty()) { + sp_desktop_selection(desktop)->set(item); + } + + Inkscape::Verb *verb = Inkscape::Verb::getbyid( "org.ekips.filter.embedselectedimages" ); + if (verb) { + SPAction *action = verb->get_action(desktop); + if (action) { + sp_action_perform(action, NULL); + } + } +} + +/* Extract Image entry */ +static void sp_image_image_extract(GtkMenuItem *menuitem, SPItem *item) +{ + SPDesktop *desktop; + + g_assert(SP_IS_ITEM(item)); + + desktop = (SPDesktop*)g_object_get_data(G_OBJECT(menuitem), "desktop"); + g_return_if_fail(desktop != NULL); + + if (sp_desktop_selection(desktop)->isEmpty()) { + sp_desktop_selection(desktop)->set(item); + } + + Inkscape::Verb *verb = Inkscape::Verb::getbyid( "org.ekips.filter.extractimage" ); + if (verb) { + SPAction *action = verb->get_action(desktop); + if (action) { + sp_action_perform(action, NULL); + } + } +} + +/* Fill and Stroke entry */ +static void sp_fill_settings(GtkMenuItem *menuitem, SPItem *item) +{ + SPDesktop *desktop; + + g_assert(SP_IS_ITEM(item)); + + desktop = (SPDesktop*)g_object_get_data(G_OBJECT(menuitem), "desktop"); + g_return_if_fail(desktop != NULL); + + if (sp_desktop_selection(desktop)->isEmpty()) { + sp_desktop_selection(desktop)->set(item); + } + + desktop->_dlg_mgr->showDialog("FillAndStroke"); +} + +/* SPShape */ +static void sp_shape_menu(SPObject *object, SPDesktop *desktop, GtkMenu *m) +{ + SPItem *item; + GtkWidget *w; + + item = (SPItem *) object; + + /* Item dialog */ + w = gtk_menu_item_new_with_mnemonic(_("_Fill and Stroke...")); + g_object_set_data(G_OBJECT(w), "desktop", desktop); + g_signal_connect(G_OBJECT(w), "activate", G_CALLBACK(sp_fill_settings), item); + gtk_widget_show(w); + gtk_menu_shell_append(GTK_MENU_SHELL(m), w); +} + +/* Edit Text entry */ +static void sp_text_settings(GtkMenuItem *menuitem, SPItem *item) +{ + SPDesktop *desktop; + + g_assert(SP_IS_ITEM(item)); + + desktop = (SPDesktop*)g_object_get_data(G_OBJECT(menuitem), "desktop"); + g_return_if_fail(desktop != NULL); + + if (sp_desktop_selection(desktop)->isEmpty()) { + sp_desktop_selection(desktop)->set(item); + } + + desktop->_dlg_mgr->showDialog("TextFont"); +} + +/* Spellcheck entry */ +static void sp_spellcheck_settings(GtkMenuItem *menuitem, SPItem *item) +{ + SPDesktop *desktop; + + g_assert(SP_IS_ITEM(item)); + + desktop = (SPDesktop*)g_object_get_data(G_OBJECT(menuitem), "desktop"); + g_return_if_fail(desktop != NULL); + + if (sp_desktop_selection(desktop)->isEmpty()) { + sp_desktop_selection(desktop)->set(item); + } + + desktop->_dlg_mgr->showDialog("SpellCheck"); +} + +/* SPText */ +static void sp_text_menu(SPObject *object, SPDesktop *desktop, GtkMenu *m) +{ + SPItem *item; + GtkWidget *w; + + item = (SPItem *) object; + + /* Fill and Stroke dialog */ + w = gtk_menu_item_new_with_mnemonic(_("_Fill and Stroke...")); + g_object_set_data(G_OBJECT(w), "desktop", desktop); + g_signal_connect(G_OBJECT(w), "activate", G_CALLBACK(sp_fill_settings), item); + gtk_widget_show(w); + gtk_menu_shell_append(GTK_MENU_SHELL(m), w); + + /* Edit Text dialog */ + w = gtk_menu_item_new_with_mnemonic(_("_Text and Font...")); + g_object_set_data(G_OBJECT(w), "desktop", desktop); + g_signal_connect(G_OBJECT(w), "activate", G_CALLBACK(sp_text_settings), item); + gtk_widget_show(w); + gtk_menu_shell_append(GTK_MENU_SHELL(m), w); + + /* Spellcheck dialog */ + w = gtk_menu_item_new_with_mnemonic(_("Check Spellin_g...")); + g_object_set_data(G_OBJECT(w), "desktop", desktop); + g_signal_connect(G_OBJECT(w), "activate", G_CALLBACK(sp_spellcheck_settings), item); + gtk_widget_show(w); + gtk_menu_shell_append(GTK_MENU_SHELL(m), w); +} +/* + 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 : -- cgit v1.2.3 From b4e6bb0a426ba62b98fc0e10ea26ec8554457543 Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Thu, 22 Mar 2012 18:08:31 +0100 Subject: =?UTF-8?q?UI.=20Fix=20for=20bug=20#962002=20(=20context=20?= =?UTF-8?q?menu=20item=20Edit=20externally=E2=80=A6=20ignores=20current=20?= =?UTF-8?q?selection).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixed bugs: - https://launchpad.net/bugs/962002 (bzr r11115) --- src/ui/context-menu.cpp | 58 ++++++++++++++++++++++++++++++------------------- 1 file changed, 36 insertions(+), 22 deletions(-) diff --git a/src/ui/context-menu.cpp b/src/ui/context-menu.cpp index 6688185a1..9e5c65af9 100644 --- a/src/ui/context-menu.cpp +++ b/src/ui/context-menu.cpp @@ -385,7 +385,7 @@ static void sp_anchor_link_remove(GtkMenuItem */*menuitem*/, SPAnchor *anchor) /* Image */ static void sp_image_image_properties(GtkMenuItem *menuitem, SPAnchor *anchor); -static void sp_image_image_edit(GtkMenuItem *menuitem, SPAnchor *anchor); +static void sp_image_image_edit(GtkMenuItem *menuitem, SPItem *item); static void sp_image_image_embed(GtkMenuItem *menuitem, SPItem *item); static void sp_image_image_extract(GtkMenuItem *menuitem, SPItem *item); @@ -427,7 +427,7 @@ static void sp_image_menu(SPObject *object, SPDesktop *desktop, GtkMenu *m) /* Extract image */ if (Inkscape::Verb::getbyid( "org.ekips.filter.extractimage" )) { - w = gtk_menu_item_new_with_mnemonic(C_("Context menu", "Extract Image")); + w = gtk_menu_item_new_with_mnemonic(C_("Context menu", "Extract Image...")); g_object_set_data(G_OBJECT(w), "desktop", desktop); g_signal_connect(G_OBJECT(w), "activate", G_CALLBACK(sp_image_image_extract), item); gtk_widget_show(w); @@ -460,11 +460,20 @@ static gchar* getImageEditorName() { } /* Edit Externally entry */ -static void sp_image_image_edit(GtkMenuItem *menuitem, SPAnchor *anchor) +static void sp_image_image_edit(GtkMenuItem *menuitem, SPItem *item) { - SPObject* obj = anchor; - Inkscape::XML::Node *ir = obj->getRepr(); - const gchar *href = ir->attribute("xlink:href"); + SPDesktop *desktop = NULL; + + g_assert(SP_IS_ITEM(item)); + + desktop = (SPDesktop*)g_object_get_data(G_OBJECT(menuitem), "desktop"); + g_return_if_fail(desktop != NULL); + + if (sp_desktop_selection(desktop)->isEmpty()) { + sp_desktop_selection(desktop)->set(item); + } + + GSList const *selected = sp_desktop_selection(desktop)->itemList(); GError* errThing = 0; Glib::ustring cmdline = getImageEditorName(); @@ -492,24 +501,29 @@ static void sp_image_image_edit(GtkMenuItem *menuitem, SPAnchor *anchor) } #endif - if (strncmp (href,"file:",5) == 0) { - // URI to filename conversion - name = g_filename_from_uri(href, NULL, NULL); - } else { - name.append(href); - } + for (GSList const *iter = selected; iter != NULL; iter = iter->next) { + Inkscape::XML::Node *ir = SP_ITEM(iter->data)->getRepr(); + const gchar *href = ir->attribute("xlink:href"); + + if (strncmp (href,"file:",5) == 0) { + // URI to filename conversion + name = g_filename_from_uri(href, NULL, NULL); + } else { + name.append(href); + } - if (Glib::path_is_absolute(name)) { - fullname = name; - } else if (SP_ACTIVE_DOCUMENT->getBase()) { - fullname = Glib::build_filename(SP_ACTIVE_DOCUMENT->getBase(), name); - } else { - fullname = Glib::build_filename(Glib::get_current_dir(), name); - } + if (Glib::path_is_absolute(name)) { + fullname = name; + } else if (SP_ACTIVE_DOCUMENT->getBase()) { + fullname = Glib::build_filename(SP_ACTIVE_DOCUMENT->getBase(), name); + } else { + fullname = Glib::build_filename(Glib::get_current_dir(), name); + } - cmdline.append(" '"); - cmdline.append(fullname.c_str()); - cmdline.append("'"); + cmdline.append(" '"); + cmdline.append(fullname.c_str()); + cmdline.append("'"); + } //g_warning("##Command line: %s\n", cmdline.c_str()); -- cgit v1.2.3 From d622704efbe803d7e271bc41655dc4432a1d556e Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Thu, 22 Mar 2012 20:19:09 +0100 Subject: UI. Patch for Bug #666370 (Not all units in the Object Transform dialog are translatable) by Fernando Lucchesi. Fixed bugs: - https://launchpad.net/bugs/666370 (bzr r11116) --- share/ui/units.txt | 2 +- share/ui/units.xml | 2 +- src/ui/dialog/guides.cpp | 6 +++--- src/ui/dialog/transformation.cpp | 2 +- src/util/units.h | 2 ++ 5 files changed, 8 insertions(+), 6 deletions(-) diff --git a/share/ui/units.txt b/share/ui/units.txt index a82cec529..55fd68577 100644 --- a/share/ui/units.txt +++ b/share/ui/units.txt @@ -13,7 +13,7 @@ centimeter centimeters cm LINEAR 35.43307 N Centimeters (10 mm/cm) meter meters m LINEAR 3543.307 N Meters (100 cm/m) foot feet ft LINEAR 1080 N Feet (12 in/ft) - degree degrees deg RADIAL 1.00 Y Degrees + degree degrees ° RADIAL 1.00 Y Degrees radian radians rad RADIAL 57.296 N Radians (57.296 deg/rad) font-height font-heights em FONT_HEIGHT 1.00 Y Font height x-height x-heights ex FONT_HEIGHT 0.50 N Height of letter 'x' diff --git a/share/ui/units.xml b/share/ui/units.xml index e4a07fe06..69d78565d 100644 --- a/share/ui/units.xml +++ b/share/ui/units.xml @@ -66,7 +66,7 @@ degree degrees - deg + ° 1.00 Degrees diff --git a/src/ui/dialog/guides.cpp b/src/ui/dialog/guides.cpp index 61b4fe389..088290b6f 100644 --- a/src/ui/dialog/guides.cpp +++ b/src/ui/dialog/guides.cpp @@ -54,7 +54,7 @@ GuidelinePropertiesDialog::GuidelinePropertiesDialog(SPGuide *guide, SPDesktop * } bool GuidelinePropertiesDialog::_relative_toggle_status = false; // initialize relative checkbox status for when this dialog is opened for first time -Glib::ustring GuidelinePropertiesDialog::_angle_unit_status = "deg"; // initialize angle unit status +Glib::ustring GuidelinePropertiesDialog::_angle_unit_status = DEG; // initialize angle unit status GuidelinePropertiesDialog::~GuidelinePropertiesDialog() { // save current status @@ -87,7 +87,7 @@ void GuidelinePropertiesDialog::_modeChanged() _spin_button_x.setValue(0); } else { // absolute - _spin_angle.setValueKeepUnit(_oldangle, "deg"); + _spin_angle.setValueKeepUnit(_oldangle, DEG); _spin_button_x.setValueKeepUnit(_oldpos[Geom::X], "px"); _spin_button_y.setValueKeepUnit(_oldpos[Geom::Y], "px"); @@ -96,7 +96,7 @@ void GuidelinePropertiesDialog::_modeChanged() void GuidelinePropertiesDialog::_onApply() { - double deg_angle = _spin_angle.getValue("deg"); + double deg_angle = _spin_angle.getValue(DEG); if (!_mode) deg_angle += _oldangle; Geom::Point normal; diff --git a/src/ui/dialog/transformation.cpp b/src/ui/dialog/transformation.cpp index 9b65c1f68..1951dc92a 100644 --- a/src/ui/dialog/transformation.cpp +++ b/src/ui/dialog/transformation.cpp @@ -724,7 +724,7 @@ void Transformation::applyPageScale(Inkscape::Selection *selection) void Transformation::applyPageRotate(Inkscape::Selection *selection) { - double angle = _scalar_rotate.getValue("deg"); + double angle = _scalar_rotate.getValue(DEG); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); if (prefs->getBool("/dialogs/transformation/applyseparately")) { diff --git a/src/util/units.h b/src/util/units.h index d45109a8f..b22bdb1f2 100644 --- a/src/util/units.h +++ b/src/util/units.h @@ -32,6 +32,8 @@ enum UnitType { UNIT_TYPE_NONE = -1 }; +const char DEG[] = "°"; + class Unit { public: Glib::ustring name; -- cgit v1.2.3 From 924e671a1e5d76c1d25d4fcad9d0e9f015dc394e Mon Sep 17 00:00:00 2001 From: John Smith Date: Fri, 23 Mar 2012 11:53:58 +0900 Subject: Fix for 909328 : Dockable Find & Replace dialog (bzr r11117) --- src/ui/dialog/find.cpp | 898 ++++++++++++++++++++++++++++++++++------------- src/ui/dialog/find.h | 282 +++++++++++++-- src/ui/widget/button.cpp | 16 + src/ui/widget/button.h | 14 + src/ui/widget/entry.cpp | 9 +- src/ui/widget/entry.h | 46 +++ src/verbs.cpp | 4 +- 7 files changed, 990 insertions(+), 279 deletions(-) diff --git a/src/ui/dialog/find.cpp b/src/ui/dialog/find.cpp index 9d3508c53..1652fbb16 100644 --- a/src/ui/dialog/find.cpp +++ b/src/ui/dialog/find.cpp @@ -24,12 +24,14 @@ #include "inkscape.h" #include "desktop.h" #include "document.h" +#include "document-undo.h" #include "selection.h" #include "desktop-handles.h" #include "dialogs/dialog-events.h" #include "verbs.h" #include "interface.h" +#include "preferences.h" #include "sp-text.h" #include "sp-flowtext.h" #include "text-editing.h" @@ -50,6 +52,8 @@ #include "sp-offset.h" #include "sp-root.h" #include "xml/repr.h" +#include "xml/node-iterators.h" +#include "xml/attribute-record.h" #include @@ -59,112 +63,278 @@ namespace Dialog { Find::Find() : UI::Widget::Panel("", "/dialogs/find", SP_VERB_DIALOG_FIND), - _entry_text(_("_Text:"), _("Find objects by their text content (exact or partial match)")), - _entry_id(_("_ID:"), _("Find objects by the value of the id attribute (exact or partial match)")), - _entry_style(_("_Style:"), _("Find objects by the value of the style attribute (exact or partial match)")), - _entry_attribute(_("_Attribute:"), _("Find objects by the name of an attribute (exact or partial match)")), - _check_search_selection(_("Search in s_election"), _("Limit search to the current selection")), - _check_search_layer(_("Search in current _layer"), _("Limit search to the current layer")), - _check_include_hidden(_("Include _hidden"), _("Include hidden objects in search")), - _check_include_locked(_("Include l_ocked"), _("Include locked objects in search")), - - _check_all(_("All types"), _("Search in all object types")), - _check_all_shapes(_("All shapes"), _("Search all shapes")), - _check_rects(_("Rectangles"), _("Search rectangles")), - _check_ellipses(_("Ellipses"), _("Search ellipses, arcs, circles")), - _check_stars(_("Stars"), _("Search stars and polygons")), - _check_spirals(_("Spirals"), _("Search spirals")), - _check_paths(_("Paths"), _("Search paths, lines, polylines")), - _check_texts(_("Texts"), _("Search text objects")), - _check_groups(_("Groups"), _("Search groups")), - _check_clones( + + entry_find(_("F_ind:"), _("Find objects by their content (exact or partial match)")), + entry_replace(_("Re_place:"), _("Replace found objects with this value ")), + + check_scope_all(_("_All"), _("Search in all layers")), + check_scope_layer(_("Current _layer"), _("Limit search to the current layer")), + check_scope_selection(_("S_election"), _("Limit search to the current selection")), + check_searchin_text(_("Te_xt"), _("Search in text objects")), + check_searchin_property(_("_Properties"), _("Search in object properties, styles, attributes and IDs")), + frame_searchin(_("Search in")), + frame_scope(_("Scope")), + + + check_case_sensitive(_("Case sensiti_ve"), _("Match upper/lower case"), false), + check_exact_match(_("E_xact match"), _("Match whole objects only"), false), + check_include_hidden(_("Include _hidden"), _("Include hidden objects in search"), false), + check_include_locked(_("Include loc_ked"), _("Include locked objects in search"), false), + expander_options(_("Options")), + frame_options(_("General")), + + check_ids(_("_ID"), _("Search id name"), true), + check_attributename(_("Attribute _Name"), _("Search attribute name"), false), + check_attributevalue(_("Attribute _Value"), _("Search attribute value"), true), + check_style(_("_Style"), _("Search style"), true), + check_font(_("_Font"), _("Search fonts"), false), + frame_properties(_("Properties")), + + check_alltypes(_("All types"), _("Search all object types"), true), + check_rects(_("Rectangles"), _("Search rectangles"), false), + check_ellipses(_("Ellipses"), _("Search ellipses, arcs, circles"), false), + check_stars(_("Stars"), _("Search stars and polygons"), false), + check_spirals(_("Spirals"), _("Search spirals"), false), + check_paths(_("Paths"), _("Search paths, lines, polylines"), false), + check_texts(_("Texts"), _("Search text objects"), false), + check_groups(_("Groups"), _("Search groups"), false), + check_clones( //TRANSLATORS: "Clones" is a noun indicating type of object to find - C_("Find dialog", "Clones"), _("Search clones")), - _check_images(_("Images"), _("Search images")), - _check_offsets(_("Offsets"), _("Search offset objects")), - - _button_clear(_("_Clear"), _("Clear values")), - _button_find(_("_Find"), _("Select objects matching all of the fields you filled in")) + C_("Find dialog", "Clones"), _("Search clones"), false), + + check_images(_("Images"), _("Search images"), false), + check_offsets(_("Offsets"), _("Search offset objects"), false), + frame_types(_("Object Types")), + + status(""), + button_find(_("_Find"), _("Select all objects matching the selected fields ")), + button_replace(_("_Replace All"), _("Replace all the matching objects")), + _action_replace(false), + blocked(false), + desktop(NULL), + deskTrack() + { + entry_find.getEntry()->set_width_chars(25); + entry_replace.getEntry()->set_width_chars(25); + + Gtk::RadioButtonGroup grp_searchin = check_searchin_text.get_group(); + check_searchin_property.set_group(grp_searchin); + vbox_searchin.pack_start(check_searchin_text, true, true); + vbox_searchin.pack_start(check_searchin_property, true, true); + frame_searchin.add(vbox_searchin); + + Gtk::RadioButtonGroup grp_scope = check_scope_all.get_group(); + check_scope_layer.set_group(grp_scope); + check_scope_selection.set_group(grp_scope); + vbox_scope.pack_start(check_scope_all, true, true); + vbox_scope.pack_start(check_scope_layer, true, true); + vbox_scope.pack_start(check_scope_selection, true, true); + frame_scope.add(vbox_scope); + + hbox_searchin.set_spacing(4); + hbox_searchin.pack_start(frame_searchin, true, true); + hbox_searchin.pack_start(frame_scope, true, true); + + vbox_options1.pack_start(check_case_sensitive, true, true); + vbox_options1.pack_start(check_include_hidden, true, true); + vbox_options2.pack_start(check_exact_match, true, true); + vbox_options2.pack_start(check_include_locked, true, true); + hbox_options.pack_start(vbox_options1, true, true, 4); + hbox_options.pack_start(vbox_options2, true, true, 4); + frame_options.add(hbox_options); + + hbox_properties1.set_homogeneous(false); + hbox_properties1.pack_start(check_ids, false, false, 4 ); + hbox_properties1.pack_start(check_style, false, false, 8); + hbox_properties1.pack_start(check_font, false, false, 8); + hbox_properties2.set_homogeneous(false); + hbox_properties2.pack_start(check_attributevalue, false, false, 4); + hbox_properties2.pack_start(check_attributename, false, false, 4); + vbox_properties.pack_start(hbox_properties1, true, true, 0); + vbox_properties.pack_start(hbox_properties2, true, true, 2); + frame_properties.add(vbox_properties); + + vbox_types1.pack_start(check_alltypes, true, true); + vbox_types1.pack_start(check_paths, true, true); + vbox_types1.pack_start(check_texts, true, true); + vbox_types1.pack_start(check_groups, true, true); + vbox_types1.pack_start(check_clones, true, true); + vbox_types1.pack_start(check_images, true, true); + vbox_types2.pack_start(check_offsets, true, true); + vbox_types2.pack_start(check_rects, true, true); + vbox_types2.pack_start(check_ellipses, true, true); + vbox_types2.pack_start(check_stars, true, true); + vbox_types2.pack_start(check_spirals, true, true); + hbox_types.pack_start(vbox_types1, true, true, 4); + hbox_types.pack_start(vbox_types2, true, true, 4); + frame_types.add(hbox_types); + + vbox_expander.pack_start(frame_options, true, true, 4); + vbox_expander.pack_start(frame_properties, true, true, 4); + vbox_expander.pack_start(frame_types, true, true, 4); + + expander_options.set_use_underline(); + expander_options.add(vbox_expander); + + box_buttons.set_layout(Gtk::BUTTONBOX_END); + box_buttons.set_spacing(4); + box_buttons.pack_start(button_find, true, true, 6); + box_buttons.pack_start(button_replace, true, true, 6); + hboxbutton_row.pack_start(status, true, true, 6); + hboxbutton_row.pack_end(box_buttons, true, true); + Gtk::Box *contents = _getContents(); - contents->set_spacing(4); - - contents->pack_start(_entry_text, true, true); - contents->pack_start(_entry_id, true, true); - contents->pack_start(_entry_style, true, true); - contents->pack_start(_entry_attribute, true, true); - - contents->pack_start(_check_all, true, true); - contents->pack_start(_check_all_shapes, true, true); - contents->pack_start(_check_rects, true, true); - contents->pack_start(_check_ellipses, true, true); - contents->pack_start(_check_stars, true, true); - contents->pack_start(_check_spirals, true, true); - contents->pack_start(_check_paths, true, true); - contents->pack_start(_check_texts, true, true); - contents->pack_start(_check_groups, true, true); - contents->pack_start(_check_clones, true, true); - contents->pack_start(_check_images, true, true); - contents->pack_start(_check_offsets, true, true); - - contents->pack_start(_check_search_selection, true, true); - contents->pack_start(_check_search_layer, true, true); - contents->pack_start(_check_include_hidden, true, true); - contents->pack_start(_check_include_locked, true, true); - - contents->pack_start(_button_clear, true, true); - contents->pack_start(_button_find, true, true); + contents->set_spacing(6); + contents->pack_start(entry_find, false, false); + contents->pack_start(entry_replace, false, false); + contents->pack_start(hbox_searchin, false, false); + contents->pack_start(expander_options, false, false); + contents->pack_end(hboxbutton_row, false, false); + + checkProperties.push_back(&check_ids); + checkProperties.push_back(&check_style); + checkProperties.push_back(&check_font); + checkProperties.push_back(&check_attributevalue); + checkProperties.push_back(&check_attributename); + + checkTypes.push_back(&check_paths); + checkTypes.push_back(&check_texts); + checkTypes.push_back(&check_groups); + checkTypes.push_back(&check_clones); + checkTypes.push_back(&check_images); + checkTypes.push_back(&check_offsets); + checkTypes.push_back(&check_rects); + checkTypes.push_back(&check_ellipses); + checkTypes.push_back(&check_stars); + checkTypes.push_back(&check_spirals); + checkTypes.push_back(&check_offsets); // set signals to handle clicks - _check_all.signal_clicked().connect(sigc::mem_fun(*this, &Find::onToggleAlltypes)); - _check_all_shapes.signal_clicked().connect(sigc::mem_fun(*this, &Find::onToggleShapes)); - _button_clear.signal_clicked().connect(sigc::mem_fun(*this, &Find::onClear)); - _button_find.signal_clicked().connect(sigc::mem_fun(*this, &Find::onFind)); + expander_options.property_expanded().signal_changed().connect(sigc::mem_fun(*this, &Find::onExpander)); + button_find.signal_clicked().connect(sigc::mem_fun(*this, &Find::onFind)); + button_replace.signal_clicked().connect(sigc::mem_fun(*this, &Find::onReplace)); + check_searchin_text.signal_clicked().connect(sigc::mem_fun(*this, &Find::onSearchinText)); + check_searchin_property.signal_clicked().connect(sigc::mem_fun(*this, &Find::onSearchinProperty)); + check_alltypes.signal_clicked().connect(sigc::mem_fun(*this, &Find::onToggleAlltypes)); + + for(size_t i = 0; i < checkProperties.size(); i++) { + checkProperties[i]->signal_clicked().connect(sigc::mem_fun(*this, &Find::onToggleCheck)); + } + + for(size_t i = 0; i < checkTypes.size(); i++) { + checkTypes[i]->signal_clicked().connect(sigc::mem_fun(*this, &Find::onToggleCheck)); + } + + onSearchinText(); + onToggleAlltypes(); - _button_find.set_can_default(); - // set_default (_button_find); // activatable by Enter - _entry_text.getEntry()->grab_focus(); + desktopChangeConn = deskTrack.connectDesktopChanged( sigc::mem_fun(*this, &Find::setTargetDesktop) ); + deskTrack.connect(GTK_WIDGET(gobj())); show_all_children(); - onClear(); + + Inkscape::Selection *selection = sp_desktop_selection (SP_ACTIVE_DESKTOP); + SPItem *item = selection->singleItem(); + if (item) { + if (SP_IS_TEXT(item) || SP_IS_FLOWTEXT(item)) { + gchar *str; + str = sp_te_get_string_multiline (item); + entry_find.getEntry()->set_text(str); + } + } + + button_find.set_can_default(); + //button_find.grab_default(); // activatable by Enter + entry_find.getEntry()->grab_focus(); +} + +Find::~Find() +{ + desktopChangeConn.disconnect(); + selectChangedConn.disconnect(); + deskTrack.disconnect(); } -Find::~Find() +void Find::setDesktop(SPDesktop *desktop) { + Panel::setDesktop(desktop); + deskTrack.setBase(desktop); +} + +void Find::setTargetDesktop(SPDesktop *desktop) +{ + if (this->desktop != desktop) { + if (this->desktop) { + selectChangedConn.disconnect(); + } + this->desktop = desktop; + if (desktop && desktop->selection) { + selectChangedConn = desktop->selection->connectChanged(sigc::hide(sigc::mem_fun(*this, &Find::onSelectionChange))); + } + } } +void Find::onSelectionChange(void) +{ + if (!blocked) { + status.set_text(""); + } +} /*######################################################################## # FIND helper functions ########################################################################*/ - -bool -Find::item_id_match (SPItem *item, const gchar *id, bool exact) +Glib::ustring Find::find_replace(const gchar *str, const gchar *find, const gchar *replace, bool exact, bool casematch, bool replaceall) { - if (item->getRepr() == NULL) { - return false; + Glib::ustring ustr = str; + Glib::ustring ufind = find; + if (!casematch) { + ufind = ufind.lowercase(); } - - if (SP_IS_STRING(item)) { // SPStrings have "on demand" ids which are useless for searching - return false; + gsize n = find_strcmp_pos(ustr.c_str(), ufind.c_str(), exact, casematch); + while (n != std::string::npos) { + ustr.replace(n, ufind.length(), replace); + if (!replaceall) { + return ustr; + } + // Start the next search after the last replace character to avoid infinite loops (replace "a" with "aaa" etc) + n = find_strcmp_pos(ustr.c_str(), ufind.c_str(), exact, casematch, n + strlen(replace) + 1); } + return ustr; +} - const gchar *item_id = item->getRepr()->attribute("id"); - if (item_id == NULL) { - return false; +gsize Find::find_strcmp_pos(const gchar *str, const gchar *find, bool exact, bool casematch, gsize start/*=0*/) +{ + Glib::ustring ustr = str; + Glib::ustring ufind = find; + + if (!casematch) { + ustr = ustr.lowercase(); + ufind = ufind.lowercase(); } + gsize pos = std::string::npos; if (exact) { - return ((bool) !strcmp(item_id, id)); + if (ustr == ufind) { + pos = 0; + } } else { -// g_print ("strstr: %s %s: %s\n", item_id, id, strstr(item_id, id) != NULL? "yes":"no"); - return ((bool) (strstr(item_id, id) != NULL)); + pos = ustr.find(ufind, start); } + + return pos; +} + + +bool Find::find_strcmp(const gchar *str, const gchar *find, bool exact, bool casematch) +{ + return (std::string::npos != find_strcmp_pos(str, find, exact, casematch)); } bool -Find::item_text_match (SPItem *item, const gchar *text, bool exact) +Find::item_text_match (SPItem *item, const gchar *find, bool exact, bool casematch, bool replace/*=false*/) { if (item->getRepr() == NULL) { return false; @@ -172,111 +342,317 @@ Find::item_text_match (SPItem *item, const gchar *text, bool exact) if (SP_IS_TEXT(item) || SP_IS_FLOWTEXT(item)) { const gchar *item_text = sp_te_get_string_multiline (item); - if (item_text == NULL) + if (item_text == NULL) { return false; - bool ret; - if (exact) { - ret = ((bool) !strcasecmp(item_text, text)); - } else { - //FIXME: strcasestr - ret = ((bool) (strstr(item_text, text) != NULL)); } - g_free ((void*) item_text); - return ret; + bool found = find_strcmp(item_text, find, exact, casematch); + + if (found && replace) { + Glib::ustring ufind = find; + if (!casematch) { + ufind = ufind.lowercase(); + } + + Inkscape::Text::Layout const *layout = te_get_layout (item); + if (!layout) { + return found; + } + + gchar* replace_text = g_strdup(entry_replace.get_text().c_str()); + gsize n = find_strcmp_pos(item_text, ufind.c_str(), exact, casematch); + static Inkscape::Text::Layout::iterator _begin_w; + static Inkscape::Text::Layout::iterator _end_w; + while (n != std::string::npos) { + _begin_w = layout->charIndexToIterator(n); + _end_w = layout->charIndexToIterator(n + strlen(find)); + sp_te_replace(item, _begin_w, _end_w, replace_text); + item_text = sp_te_get_string_multiline (item); + n = find_strcmp_pos(item_text, ufind.c_str(), exact, casematch, n + strlen(replace_text) + 1); + } + + g_free(replace_text); + } + + return found; } return false; } + +bool +Find::item_id_match (SPItem *item, const gchar *id, bool exact, bool casematch, bool replace/*=false*/) +{ + if (item->getRepr() == NULL) { + return false; + } + + if (SP_IS_STRING(item)) { // SPStrings have "on demand" ids which are useless for searching + return false; + } + + const gchar *item_id = item->getRepr()->attribute("id"); + if (item_id == NULL) { + return false; + } + + bool found = find_strcmp(item_id, id, exact, casematch); + + if (found && replace) { + gchar * replace_text = g_strdup(entry_replace.get_text().c_str()); + Glib::ustring new_item_style = find_replace(item_id, id, replace_text , exact, casematch, true); + if (new_item_style != item_id) { + item->getRepr()->setAttribute("id", new_item_style.data()); + } + g_free(replace_text); + } + + return found; +} + bool -Find::item_style_match (SPItem *item, const gchar *text, bool exact) +Find::item_style_match (SPItem *item, const gchar *text, bool exact, bool casematch, bool replace/*=false*/) { if (item->getRepr() == NULL) { return false; } - const gchar *item_text = item->getRepr()->attribute("style"); - if (item_text == NULL) { + gchar *item_style = g_strdup(item->getRepr()->attribute("style")); + if (item_style == NULL) { return false; } + bool found = find_strcmp(item_style, text, exact, casematch); + + if (found && replace) { + gchar * replace_text = g_strdup(entry_replace.get_text().c_str()); + Glib::ustring new_item_style = find_replace(item_style, text, replace_text , exact, casematch, true); + if (new_item_style != item_style) { + item->getRepr()->setAttribute("style", new_item_style.data()); + } + g_free(replace_text); + } + + g_free(item_style); + return found; +} + +bool Find::item_attr_match(SPItem *item, const gchar *text, bool exact, bool casematch, bool replace/*=false*/) +{ + bool found = false; + + if (item->getRepr() == NULL) { + return false; + } + + gchar *attr_value = g_strdup(item->getRepr()->attribute(text)); if (exact) { - return ((bool) !strcmp(item_text, text)); + found = (attr_value != NULL); } else { - return ((bool) (strstr(item_text, text) != NULL)); + found = item->getRepr()->matchAttributeName(text); + } + g_free(attr_value); + + // TODO - Rename attribute name ? + if (found && replace) { + found = false; } + + return found; } -bool Find::item_attr_match(SPItem *item, const gchar *name, bool exact) +bool Find::item_attrvalue_match(SPItem *item, const gchar *text, bool exact, bool casematch, bool replace/*=false*/) { - 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); + bool ret = false; + + if (item->getRepr() == NULL) { + return false; + } + + Inkscape::Util::List iter = item->getRepr()->attributeList(); + for (; iter; ++iter) { + const gchar* key = g_quark_to_string(iter->key); + gchar *attr_value = g_strdup(item->getRepr()->attribute(key)); + bool found = find_strcmp(attr_value, text, exact, casematch); + if (found) { + ret = true; + } + + if (found && replace) { + gchar * replace_text = g_strdup(entry_replace.get_text().c_str()); + Glib::ustring new_item_style = find_replace(attr_value, text, replace_text , exact, casematch, true); + if (new_item_style != attr_value) { + item->getRepr()->setAttribute(key, new_item_style.data()); + } + } + + g_free(attr_value); + } + + return ret; +} + + +bool Find::item_font_match(SPItem *item, const gchar *text, bool exact, bool casematch, bool replace/*=false*/) +{ + bool ret = false; + + if (item->getRepr() == NULL) { + return false; + } + + const gchar *item_style = item->getRepr()->attribute("style"); + if (item_style == NULL) { + return false; + } + + std::vector vFontTokenNames; + vFontTokenNames.push_back("font-family:"); + vFontTokenNames.push_back("-inkscape-font-specification:"); + + std::vector vStyleTokens = Glib::Regex::split_simple(";", item_style); + for(size_t i=0; igetRepr()->setAttribute("style", new_item_style.data()); } - return result; + + return ret; } GSList * -Find::filter_fields (GSList *l, bool exact) +Find::filter_fields (GSList *l, bool exact, bool casematch) { - const gchar* text = _entry_text.getEntry()->get_text().c_str(); - const gchar* id = _entry_id.getEntry()->get_text().c_str(); - const gchar* style = _entry_style.getEntry()->get_text().c_str(); - const gchar* attr = _entry_attribute.getEntry()->get_text().c_str(); - + Glib::ustring tmp = entry_find.get_text(); + if (tmp.empty()) { + return l; + } + gchar* text = g_strdup(tmp.c_str()); + GSList *in = l; GSList *out = NULL; - if (strlen (text) != 0) { + + if (check_searchin_text.get_active()) { for (GSList *i = in; i != NULL; i = i->next) { - if (item_text_match (SP_ITEM(i->data), text, exact)) { - out = g_slist_prepend (out, i->data); + if (item_text_match (SP_ITEM(i->data), text, exact, casematch)) { + if (!g_slist_find(out, i->data)) { + out = g_slist_prepend (out, i->data); + if (_action_replace) { + item_text_match (SP_ITEM(i->data), text, exact, casematch, _action_replace); + } + } } } - } else { - out = in; } - - in = out; - out = NULL; - if (strlen (id) != 0) { - for (GSList *i = in; i != NULL; i = i->next) { - if (item_id_match (SP_ITEM(i->data), id, exact)) { - out = g_slist_prepend (out, i->data); + else if (check_searchin_property.get_active()) { + + bool ids = check_ids.get_active(); + bool style = check_style.get_active(); + bool font = check_font.get_active(); + bool attrname = check_attributename.get_active(); + bool attrvalue = check_attributevalue.get_active(); + + if (ids) { + for (GSList *i = in; i != NULL; i = i->next) { + if (item_id_match (SP_ITEM(i->data), text, exact, casematch)) { + if (!g_slist_find(out, i->data)) { + out = g_slist_prepend (out, i->data); + if (_action_replace) { + item_id_match (SP_ITEM(i->data), text, exact, casematch, _action_replace); + } + } + } } } - } else { - out = in; - } - in = out; - out = NULL; - if (strlen (style) != 0) { - for (GSList *i = in; i != NULL; i = i->next) { - if (item_style_match (SP_ITEM(i->data), style, exact)) { - out = g_slist_prepend (out, i->data); + + if (style) { + for (GSList *i = in; i != NULL; i = i->next) { + if (item_style_match (SP_ITEM(i->data), text, exact, casematch)) { + if (!g_slist_find(out, i->data)) + if (!g_slist_find(out, i->data)) { + out = g_slist_prepend (out, i->data); + if (_action_replace) { + item_style_match (SP_ITEM(i->data), text, exact, casematch, _action_replace); + } + } + } } } - } else { - out = in; - } - in = out; - out = NULL; - if (strlen (attr) != 0) { - for (GSList *i = in; i != NULL; i = i->next) { - if (item_attr_match (SP_ITEM(i->data), attr, exact)) { - out = g_slist_prepend (out, i->data); + + if (attrname) { + for (GSList *i = in; i != NULL; i = i->next) { + if (item_attr_match (SP_ITEM(i->data), text, exact, casematch)) { + if (!g_slist_find(out, i->data)) { + out = g_slist_prepend (out, i->data); + if (_action_replace) { + item_attr_match (SP_ITEM(i->data), text, exact, casematch, _action_replace); + } + } + } } } - } else { - out = in; + + + if (attrvalue) { + for (GSList *i = in; i != NULL; i = i->next) { + if (item_attrvalue_match (SP_ITEM(i->data), text, exact, casematch)) { + if (!g_slist_find(out, i->data)) { + out = g_slist_prepend (out, i->data); + if (_action_replace) { + item_attrvalue_match (SP_ITEM(i->data), text, exact, casematch, _action_replace); + } + } + } + } + } + + + if (font) { + for (GSList *i = in; i != NULL; i = i->next) { + if (item_font_match (SP_ITEM(i->data), text, exact, casematch)) { + if (!g_slist_find(out, i->data)) { + out = g_slist_prepend (out, i->data); + if (_action_replace) { + item_font_match (SP_ITEM(i->data), text, exact, casematch, _action_replace); + } + } + } + } + } + } + g_free(text); + return out; } @@ -284,37 +660,37 @@ Find::filter_fields (GSList *l, bool exact) bool Find::item_type_match (SPItem *item) { - SPDesktop *desktop = getDesktop(); + bool all =check_alltypes.get_active(); - if (SP_IS_RECT(item)) { - return (_check_all_shapes.get_active() || _check_rects.get_active()); + if ( SP_IS_RECT(item)) { + return ( all ||check_rects.get_active()); } else if (SP_IS_GENERICELLIPSE(item) || SP_IS_ELLIPSE(item) || SP_IS_ARC(item) || SP_IS_CIRCLE(item)) { - return (_check_all_shapes.get_active() || _check_ellipses.get_active()); + return ( all || check_ellipses.get_active()); } else if (SP_IS_STAR(item) || SP_IS_POLYGON(item)) { - return (_check_all_shapes.get_active() || _check_stars.get_active()); + return ( all || check_stars.get_active()); } else if (SP_IS_SPIRAL(item)) { - return (_check_all_shapes.get_active() || _check_spirals.get_active()); + return ( all || check_spirals.get_active()); } else if (SP_IS_PATH(item) || SP_IS_LINE(item) || SP_IS_POLYLINE(item)) { - return (_check_paths.get_active()); + return (all || check_paths.get_active()); } else if (SP_IS_TEXT(item) || SP_IS_TSPAN(item) || SP_IS_TREF(item) || SP_IS_STRING(item)) { - return (_check_texts.get_active()); + return (all || check_texts.get_active()); } else if (SP_IS_GROUP(item) && !desktop->isLayer(item) ) { // never select layers! - return (_check_groups.get_active()); + return (all || check_groups.get_active()); } else if (SP_IS_USE(item)) { - return (_check_clones.get_active()); + return (all || check_clones.get_active()); } else if (SP_IS_IMAGE(item)) { - return (_check_images.get_active()); + return (all || check_images.get_active()); } else if (SP_IS_OFFSET(item)) { - return (_check_offsets.get_active()); + return (all || check_offsets.get_active()); } return false; @@ -323,8 +699,6 @@ Find::item_type_match (SPItem *item) GSList * Find::filter_types (GSList *l) { - if (_check_all.get_active()) return l; - GSList *n = NULL; for (GSList *i = l; i != NULL; i = i->next) { if (item_type_match (SP_ITEM(i->data))) { @@ -336,18 +710,16 @@ Find::filter_types (GSList *l) GSList * -Find::filter_list (GSList *l, bool exact) +Find::filter_list (GSList *l, bool exact, bool casematch) { - l = filter_fields (l, exact); l = filter_types (l); + l = filter_fields (l, exact, casematch); return l; } GSList * Find::all_items (SPObject *r, GSList *l, bool hidden, bool locked) { - SPDesktop *desktop = getDesktop(); - if (SP_IS_DEFS(r)) { return l; // we're not interested in items in defs } @@ -371,8 +743,6 @@ Find::all_items (SPObject *r, GSList *l, bool hidden, bool locked) GSList * Find::all_selection_items (Inkscape::Selection *s, GSList *l, SPObject *ancestor, bool hidden, bool locked) { - SPDesktop *desktop = getDesktop(); - for (GSList *i = (GSList *) s->itemList(); i != NULL; i = i->next) { if (SP_IS_ITEM (i->data) && !reinterpret_cast(i->data)->cloned && !desktop->isLayer(SP_ITEM(i->data))) { SPItem *item = reinterpret_cast(i->data); @@ -388,43 +758,67 @@ Find::all_selection_items (Inkscape::Selection *s, GSList *l, SPObject *ancestor } return l; } - - + + /*######################################################################## # BUTTON CLICK HANDLERS (callbacks) ########################################################################*/ void -Find::onClear() -{ - _entry_text.getEntry()->set_text(Glib::ustring("")); - _entry_id.getEntry()->set_text(Glib::ustring("")); - _entry_style.getEntry()->set_text(Glib::ustring("")); - _entry_attribute.getEntry()->set_text(Glib::ustring("")); - - _check_all.set_active(); +Find::onFind() +{ + _action_replace = false; + onAction(); + + // Return focus to the find entry + entry_find.getEntry()->grab_focus(); } - - void -Find::onFind() -{ - SPDesktop *desktop = getDesktop(); +Find::onReplace() +{ + if (entry_find.get_text().length() < 1) { + status.set_text(_("Nothing to replace")); + return; + } + _action_replace = true; + onAction(); + + // Return focus to the find entry + entry_find.getEntry()->grab_focus(); +} - bool hidden = _check_include_hidden.get_active(); - bool locked = _check_include_locked.get_active(); +void +Find::onAction() +{ + + bool hidden = check_include_hidden.get_active(); + bool locked = check_include_locked.get_active(); + bool exact = check_exact_match.get_active(); + bool casematch = check_case_sensitive.get_active(); + blocked = true; + + // Add find/replace text to combobox list + if (entry_find.get_text().length() > 0) { + entry_find.remove_text(entry_find.get_text()); + entry_find.prepend_text(entry_find.get_text()); + } + + if (_action_replace && entry_replace.get_text().length() > 0) { + entry_replace.remove_text(entry_replace.get_text()); + entry_replace.prepend_text(entry_replace.get_text()); + } GSList *l = NULL; - if (_check_search_selection.get_active()) { - if (_check_search_layer.get_active()) { + if (check_scope_selection.get_active()) { + if (check_scope_layer.get_active()) { l = all_selection_items (desktop->selection, l, desktop->currentLayer(), hidden, locked); } else { l = all_selection_items (desktop->selection, l, NULL, hidden, locked); } } else { - if (_check_search_layer.get_active()) { + if (check_scope_layer.get_active()) { l = all_items (desktop->currentLayer(), l, hidden, locked); } else { l = all_items(sp_desktop_document(desktop)->getRoot(), l, hidden, locked); @@ -432,13 +826,7 @@ Find::onFind() } guint all = g_slist_length (l); - bool exact = true; - GSList *n = NULL; - n = filter_list (l, exact); - if (n == NULL) { - exact = false; - n = filter_list (l, exact); - } + GSList *n = filter_list (l, exact, casematch); if (n != NULL) { int count = g_slist_length (n); @@ -448,88 +836,124 @@ Find::onFind() "%d objects found (out of %d), %s match.", count), count, all, exact? _("exact") : _("partial")); + status.set_text(Glib::ustring::compose("%1 %2 %3", count, _("objects"), _action_replace? _("replaced") : _("found") )); Inkscape::Selection *selection = sp_desktop_selection (desktop); selection->clear(); selection->setList(n); scroll_to_show_item (desktop, SP_ITEM(n->data)); + + if (_action_replace) { + DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT, _("Text Replace")); + } + } else { + status.set_text(_("Not found")); + if (!check_scope_selection.get_active()) { + Inkscape::Selection *selection = sp_desktop_selection (desktop); + selection->clear(); + } desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("No objects found")); } + blocked = false; + +} +void +Find::onToggleCheck () +{ + bool objectok = false; + status.set_text(""); + + if (check_alltypes.get_active()) { + objectok = true; + } + for(int i = 0; i < 11; i++) { + if (checkTypes[i]->get_active()) { + objectok = true; + } + } + + if (!objectok) { + status.set_text(_("Select an object")); + } + + + bool propertyok = false; + + if (!check_searchin_property.get_active()) { + propertyok = true; + } else { + + for(size_t i = 0; i < checkProperties.size(); i++) { + if (checkProperties[i]->get_active()) { + propertyok = true; + } + } + } + + if (!propertyok) { + status.set_text(_("Select a property")); + } + + // Can't replace attribute names + bool attributenameyok = !check_attributename.get_active(); + + button_find.set_sensitive(objectok && propertyok); + button_replace.set_sensitive(objectok && propertyok && attributenameyok); + } void Find::onToggleAlltypes () { - if (_check_all.get_active()) { - // explicit toggle to make sure its handler gets called, no matter what was the original state - _check_all_shapes.toggled(); - _check_all_shapes.set_active(); - _check_all_shapes.hide(); - _check_paths.hide(); - _check_texts.hide(); - _check_groups.hide(); - _check_clones.hide(); - _check_images.hide(); - _check_offsets.hide(); - } else { - // explicit toggle to make sure its handler gets called, no matter what was the original state - _check_all_shapes.toggled(); - _check_all_shapes.set_active(); - _check_all_shapes.show(); - - _check_paths.set_active(); - _check_paths.show(); - _check_texts.set_active(); - _check_texts.show(); - _check_groups.set_active(); - _check_groups.show(); - _check_clones.set_active(); - _check_clones.show(); - _check_images.set_active(); - _check_images.show(); - _check_offsets.set_active(); - _check_offsets.show(); - } - squeeze_window(); + bool all =check_alltypes.get_active(); + for(size_t i = 0; i < checkTypes.size(); i++) { + checkTypes[i]->set_sensitive(!all); + } + + onToggleCheck(); } void -Find::onToggleShapes () +Find::onSearchinText () { - if (_check_all_shapes.get_active()) { - _check_rects.hide(); - _check_ellipses.hide(); - _check_stars.hide(); - _check_spirals.hide(); - } else { - _check_rects.set_active(); - _check_rects.show(); - _check_ellipses.set_active(); - _check_ellipses.show(); - _check_stars.set_active(); - _check_stars.show(); - _check_spirals.set_active(); - _check_spirals.show(); - } - squeeze_window(); + searchinToggle(false); + onToggleCheck(); } +void +Find::onSearchinProperty () +{ + searchinToggle(true); + onToggleCheck(); +} + +void +Find::searchinToggle(bool on) +{ + for(size_t i = 0; i < checkProperties.size(); i++) { + checkProperties[i]->set_sensitive(on); + } +} + +void +Find::onExpander () +{ + if (!expander_options.get_expanded()) + squeeze_window(); +} /*######################################################################## # UTILITY ########################################################################*/ - - void Find::squeeze_window() { - // TO DO: make window as small as possible + // TODO: resize dialog window when the expander is closed + // set_size_request(-1, -1); } - - } // namespace Dialog } // namespace UI } // namespace Inkscape diff --git a/src/ui/dialog/find.h b/src/ui/dialog/find.h index 15263caac..26ac37d7f 100644 --- a/src/ui/dialog/find.h +++ b/src/ui/dialog/find.h @@ -16,6 +16,10 @@ #include "ui/widget/button.h" #include "ui/widget/entry.h" #include +#include + +#include "desktop.h" +#include "ui/dialog/desktop-tracker.h" class SPItem; class SPObject; @@ -26,66 +30,268 @@ class Selection; namespace UI { namespace Dialog { +/** + * The Find class defines the Find and replace dialog. + * + * The Find and replace dialog allows you to search within the + * current document for specific text or properties of items. + * Matches items are highlighted and can be replaced as well. + * Scope can be limited to the entire document, current layer or selected items. + * Other options allow searching on specific object types and properties. + */ + class Find : public UI::Widget::Panel { public: Find(); virtual ~Find(); + /** + * Helper function which returns a new instance of the dialog. + * getInstance is needed by the dialog manager (Inkscape::UI::Dialog::DialogManager). + */ static Find &getInstance() { return *new Find(); } protected: - // Widgets: - Inkscape::UI::Widget::Entry _entry_text; - Inkscape::UI::Widget::Entry _entry_id; - Inkscape::UI::Widget::Entry _entry_style; - Inkscape::UI::Widget::Entry _entry_attribute; - - Inkscape::UI::Widget::CheckButton _check_search_selection; - Inkscape::UI::Widget::CheckButton _check_search_layer; - Inkscape::UI::Widget::CheckButton _check_include_hidden; - Inkscape::UI::Widget::CheckButton _check_include_locked; - - // Type checkbutton widgets... - Inkscape::UI::Widget::CheckButton _check_all; - Inkscape::UI::Widget::CheckButton _check_all_shapes; - Inkscape::UI::Widget::CheckButton _check_rects; - Inkscape::UI::Widget::CheckButton _check_ellipses; - Inkscape::UI::Widget::CheckButton _check_stars; - Inkscape::UI::Widget::CheckButton _check_spirals; - Inkscape::UI::Widget::CheckButton _check_paths; - Inkscape::UI::Widget::CheckButton _check_texts; - Inkscape::UI::Widget::CheckButton _check_groups; - Inkscape::UI::Widget::CheckButton _check_clones; - Inkscape::UI::Widget::CheckButton _check_images; - Inkscape::UI::Widget::CheckButton _check_offsets; - - // Button-click handlers - void onClear(); + + + /** + * Callbacks for pressing the dialog buttons. + */ void onFind(); + void onReplace(); + void onExpander(); + void onAction(); void onToggleAlltypes(); - void onToggleShapes(); + void onToggleCheck(); + void onSearchinText(); + void onSearchinProperty(); + /** + * Toggle all the properties checkboxes + */ + void searchinToggle(bool on); - // onFind helper functions - bool item_id_match (SPItem *item, const gchar *id, bool exact); - bool item_text_match (SPItem *item, const gchar *text, bool exact); - bool item_style_match (SPItem *item, const gchar *text, bool exact); - bool item_attr_match (SPItem *item, const gchar *name, bool exact); - GSList * filter_fields (GSList *l, bool exact); + /** + * Returns true if the SPItem 'item' has the same id + * + * @param item the SPItem to check + * @param id the value to compare with + * @param exact do an exacty match + * @param casematch match the text case exactly + * @param replace replace the value if found + * + */ + bool item_id_match (SPItem *item, const gchar *id, bool exact, bool casematch, bool replace=false); + /** + * Returns true if the SPItem 'item' has the same text content + * + * @param item the SPItem to check + * @param name the value to compare with + * @param exact do an exacty match + * @param casematch match the text case exactly + * @param replace replace the value if found + * + * + */ + bool item_text_match (SPItem *item, const gchar *text, bool exact, bool casematch, bool replace=false); + /** + * Returns true if the SPItem 'item' has the same text in the style attribute + * + * @param item the SPItem to check + * @param name the value to compare with + * @param exact do an exacty match + * @param casematch match the text case exactly + * @param replace replace the value if found + * + */ + bool item_style_match (SPItem *item, const gchar *text, bool exact, bool casematch, bool replace=false); + /** + * Returns true if found the SPItem 'item' has the same attribute name + * + * @param item the SPItem to check + * @param name the value to compare with + * @param exact do an exacty match + * @param casematch match the text case exactly + * @param replace replace the value if found + * + */ + bool item_attr_match (SPItem *item, const gchar *name, bool exact, bool casematch, bool replace=false); + /** + * Returns true if the SPItem 'item' has the same attribute value + * + * @param item the SPItem to check + * @param name the value to compare with + * @param exact do an exacty match + * @param casematch match the text case exactly + * @param replace replace the value if found + * + */ + bool item_attrvalue_match (SPItem *item, const gchar *name, bool exact, bool casematch, bool replace=false); + /** + * Returns true if the SPItem 'item' has the same font values + * + * @param item the SPItem to check + * @param name the value to compare with + * @param exact do an exacty match + * @param casematch match the text case exactly + * @param replace replace the value if found + * + */ + bool item_font_match (SPItem *item, const gchar *name, bool exact, bool casematch, bool replace=false); + /** + * Function to filter a list of items based on the item type by calling each item_XXX_match function + */ + GSList * filter_fields (GSList *l, bool exact, bool casematch); bool item_type_match (SPItem *item); GSList * filter_types (GSList *l); - GSList * filter_list (GSList *l, bool exact); + GSList * filter_list (GSList *l, bool exact, bool casematch); + + /** + * Find a string within a string and returns true if found with options for exact and casematching + */ + bool find_strcmp(const gchar *str, const gchar *find, bool exact, bool casematch); + + /** + * Find a string within a string and return the position with options for exact, casematching and search start location + */ + gsize find_strcmp_pos(const gchar *str, const gchar *find, bool exact, bool casematch, gsize start=0); + + /** + * Replace a string with another string with options for exact and casematching and replace once/all + */ + Glib::ustring find_replace(const gchar *str, const gchar *find, const gchar *replace, bool exact, bool casematch, bool replaceall); + + /** + * recursive function to return a list of all the items in the SPObject tree + * + */ GSList * all_items (SPObject *r, GSList *l, bool hidden, bool locked); + /** + * to return a list of all the selected items + * + */ GSList * all_selection_items (Inkscape::Selection *s, GSList *l, SPObject *ancestor, bool hidden, bool locked); + /** + * Shrink the dialog size when the expander widget is closed + * Currently not working, no known way to do this + */ void squeeze_window(); + /** + * Can be invoked for setting the desktop. Currently not used. + */ + void setDesktop(SPDesktop *desktop); + /** + * Is invoked by the desktop tracker when the desktop changes. + */ + void setTargetDesktop(SPDesktop *desktop); + /** + * Called when desktop selection changes + */ + void onSelectionChange(void); + private: Find(Find const &d); Find& operator=(Find const &d); - - Inkscape::UI::Widget::Button _button_clear; - Inkscape::UI::Widget::Button _button_find; + + /* + * Find and replace combo box widgets + */ + Inkscape::UI::Widget::ComboBoxText entry_find; + Inkscape::UI::Widget::ComboBoxText entry_replace; + + /** + * Scope and search in widgets + */ + Inkscape::UI::Widget::RadioButton check_scope_all; + Inkscape::UI::Widget::RadioButton check_scope_layer; + Inkscape::UI::Widget::RadioButton check_scope_selection; + Inkscape::UI::Widget::RadioButton check_searchin_text; + Inkscape::UI::Widget::RadioButton check_searchin_property; + Gtk::HBox hbox_searchin; + Gtk::VBox vbox_scope; + Gtk::VBox vbox_searchin; + Gtk::Frame frame_searchin; + Gtk::Frame frame_scope; + + /** + * General option widgets + */ + Inkscape::UI::Widget::CheckButton check_case_sensitive; + Inkscape::UI::Widget::CheckButton check_exact_match; + Inkscape::UI::Widget::CheckButton check_include_hidden; + Inkscape::UI::Widget::CheckButton check_include_locked; + Gtk::VBox vbox_options1; + Gtk::VBox vbox_options2; + Gtk::HBox hbox_options; + Gtk::VBox vbox_expander; + Gtk::Expander expander_options; + Gtk::Frame frame_options; + + /** + * Property type widgets + */ + Inkscape::UI::Widget::CheckButton check_ids; + Inkscape::UI::Widget::CheckButton check_attributename; + Inkscape::UI::Widget::CheckButton check_attributevalue; + Inkscape::UI::Widget::CheckButton check_style; + Inkscape::UI::Widget::CheckButton check_font; + Gtk::VBox vbox_properties; + Gtk::HBox hbox_properties1; + Gtk::HBox hbox_properties2; + Gtk::Frame frame_properties; + + /** + * A vector of all the properties widgets for easy processing + */ + std::vector checkProperties; + + /** + * Object type widgets + */ + Inkscape::UI::Widget::CheckButton check_alltypes; + Inkscape::UI::Widget::CheckButton check_rects; + Inkscape::UI::Widget::CheckButton check_ellipses; + Inkscape::UI::Widget::CheckButton check_stars; + Inkscape::UI::Widget::CheckButton check_spirals; + Inkscape::UI::Widget::CheckButton check_paths; + Inkscape::UI::Widget::CheckButton check_texts; + Inkscape::UI::Widget::CheckButton check_groups; + Inkscape::UI::Widget::CheckButton check_clones; + Inkscape::UI::Widget::CheckButton check_images; + Inkscape::UI::Widget::CheckButton check_offsets; + Gtk::VBox vbox_types1; + Gtk::VBox vbox_types2; + Gtk::HBox hbox_types; + Gtk::Frame frame_types; + + /** + * A vector of all the check option widgets for easy processing + */ + std::vector checkTypes; + + //Gtk::HBox hbox_text; + + /** + * Action Buttons and status + */ + Gtk::Label status; + Inkscape::UI::Widget::Button button_find; + Inkscape::UI::Widget::Button button_replace; + Gtk::HButtonBox box_buttons; + Gtk::HBox hboxbutton_row; + + /** + * Finding or replacing + */ + bool _action_replace; + bool blocked; + + SPDesktop *desktop; + DesktopTracker deskTrack; + sigc::connection desktopChangeConn; + sigc::connection selectChangedConn; }; } // namespace Dialog diff --git a/src/ui/widget/button.cpp b/src/ui/widget/button.cpp index 1ba531ddf..bac866920 100644 --- a/src/ui/widget/button.cpp +++ b/src/ui/widget/button.cpp @@ -31,6 +31,22 @@ CheckButton::CheckButton(Glib::ustring const &label, Glib::ustring const &toolti set_tooltip_text(tooltip); } +CheckButton::CheckButton(Glib::ustring const &label, Glib::ustring const &tooltip, bool active) +{ + set_use_underline (true); + set_label (label); + set_tooltip_text(tooltip); + set_active(active); +} + +RadioButton::RadioButton(Glib::ustring const &label, Glib::ustring const &tooltip) +{ + set_use_underline (true); + set_label (label); + set_tooltip_text(tooltip); +} + + } // namespace Widget } // namespace UI } // namespace Inkscape diff --git a/src/ui/widget/button.h b/src/ui/widget/button.h index 362cdf8ff..b219fc3db 100644 --- a/src/ui/widget/button.h +++ b/src/ui/widget/button.h @@ -11,6 +11,7 @@ #define INKSCAPE_UI_WIDGET_BUTTON_H #include +#include namespace Inkscape { namespace UI { @@ -34,6 +35,19 @@ class CheckButton : public Gtk::CheckButton public: CheckButton(); CheckButton(Glib::ustring const &label, Glib::ustring const &tooltip); + CheckButton(Glib::ustring const &label, Glib::ustring const &tooltip, bool active); + +}; + +/** + * RadioButton widget. + */ +class RadioButton : public Gtk::RadioButton +{ +public: + RadioButton(); + RadioButton(Glib::ustring const &label, Glib::ustring const &tooltip); + }; } // namespace Widget diff --git a/src/ui/widget/entry.cpp b/src/ui/widget/entry.cpp index 7ac8532fb..08617433c 100644 --- a/src/ui/widget/entry.cpp +++ b/src/ui/widget/entry.cpp @@ -24,7 +24,14 @@ Entry::Entry( Glib::ustring const &label, Glib::ustring const &tooltip, : Labelled(label, tooltip, new Gtk::Entry(), suffix, icon, mnemonic) { } - + +ComboBoxText::ComboBoxText( Glib::ustring const &label, Glib::ustring const &tooltip, + Glib::ustring const &suffix, + Glib::ustring const &icon, + bool mnemonic) + : Labelled(label, tooltip, new Gtk::ComboBoxText(true), suffix, icon, mnemonic) +{ +} } // namespace Widget } // namespace UI diff --git a/src/ui/widget/entry.h b/src/ui/widget/entry.h index d332dde1b..be7c8b450 100644 --- a/src/ui/widget/entry.h +++ b/src/ui/widget/entry.h @@ -11,8 +11,10 @@ #define INKSCAPE_UI_WIDGET_ENTRY__H #include "labelled.h" +#include #include +#include namespace Inkscape { namespace UI { @@ -35,6 +37,50 @@ public: Gtk::Entry* getEntry() {return (Gtk::Entry*)(_widget);}; }; +class ComboBoxText : public Labelled +{ +public: + ComboBoxText( Glib::ustring const &label, + Glib::ustring const &tooltip, + Glib::ustring const &suffix = "", + Glib::ustring const &icon = "", + bool mnemonic = true); + + Gtk::ComboBoxText* getWidget() { return (Gtk::ComboBoxText *)_widget; }; + Gtk::Entry* getEntry() { return (Gtk::Entry *)getWidget()->get_child(); }; + Glib::ustring get_text() { return getEntry()->get_text(); }; + void prepend_text(const Glib::ustring& text) { +#if WITH_GTKMM_2_24 + getWidget()->prepend(text); +#else + getWidget()->prepend_text(text); +#endif + }; + void append_text(const Glib::ustring& text) { +#if WITH_GTKMM_2_24 + getWidget()->append(text); +#else + getWidget()->append_text(text); +#endif + }; + void insert_text(gint position, const Glib::ustring& text) { +#if WITH_GTKMM_2_24 + getWidget()->insert(position, text); +#else + getWidget()->insert_text(position, text); +#endif + }; + void remove_text(const Glib::ustring& text) { getWidget()->remove_text(text); }; + void remove_all() { +#if WITH_GTKMM_2_24 + getWidget()->remove_all(); +#else + getWidget()->clear_items(); +#endif + }; + +}; + } // namespace Widget } // namespace UI } // namespace Inkscape diff --git a/src/verbs.cpp b/src/verbs.cpp index b00315248..b890e64a5 100644 --- a/src/verbs.cpp +++ b/src/verbs.cpp @@ -1822,9 +1822,7 @@ void DialogVerb::perform(SPAction *action, void *data) dt->_dlg_mgr->showDialog("XmlTree"); break; case SP_VERB_DIALOG_FIND: - sp_find_dialog(); -// Please test the new find dialog if you have time: -// dt->_dlg_mgr->showDialog("Find"); + dt->_dlg_mgr->showDialog("Find"); break; case SP_VERB_DIALOG_FINDREPLACE: // not implemented yet -- cgit v1.2.3 From cb40f324c39c3b18f0349e61ace70bf650088c5c Mon Sep 17 00:00:00 2001 From: John Smith Date: Fri, 23 Mar 2012 19:22:33 +0900 Subject: Fix for 903676 : Replace GtkCList with GtkTreeView in XML Tree, selection bug fixes (bzr r11118) --- src/ui/dialog/xml-tree.cpp | 23 ++++++++++++++++++++--- src/ui/dialog/xml-tree.h | 7 ++++++- src/widgets/sp-xmlview-attr-list.cpp | 2 +- 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/src/ui/dialog/xml-tree.cpp b/src/ui/dialog/xml-tree.cpp index cdbb2257c..ae1ebf5ca 100644 --- a/src/ui/dialog/xml-tree.cpp +++ b/src/ui/dialog/xml-tree.cpp @@ -233,7 +233,7 @@ XmlTree::XmlTree (void) : GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(attributes)); g_signal_connect (G_OBJECT(selection), "changed", G_CALLBACK (on_attr_select_row), this); - + g_signal_connect( G_OBJECT(attributes), "row-value-changed", G_CALLBACK(on_attr_row_changed), this); xml_element_new_button.signal_clicked().connect(sigc::mem_fun(*this, &XmlTree::cmd_new_element_node)); xml_text_new_button.signal_clicked().connect(sigc::mem_fun(*this, &XmlTree::cmd_new_text_node)); @@ -738,11 +738,12 @@ void XmlTree::on_attr_select_row(GtkTreeSelection *selection, gpointer data) GtkTreeModel *model; if (!gtk_tree_selection_get_selected (selection, &model, &iter)) { -/* self->selected_attr = 0; + // Nothing selected + self->selected_attr = 0; self->attr_reset_context(self->selected_attr); self->xml_attribute_delete_button.set_sensitive(false); - self->on_attr_unselect_row_clear_text();*/ + self->on_attr_unselect_row_clear_text(); return; } @@ -763,6 +764,22 @@ void XmlTree::on_attr_select_row(GtkTreeSelection *selection, gpointer data) } +void XmlTree::on_attr_row_changed(SPXMLViewAttrList *attributes, const gchar * name, gpointer data) +{ + // Reselect the selected row if the data changes to refresh the attribute and value edit boxes. + GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(attributes)); + GtkTreeIter iter; + GtkTreeModel *model; + const gchar *attr_name; + if (gtk_tree_selection_get_selected (selection, &model, &iter)) { + gtk_tree_model_get (model, &iter, 0, &attr_name, -1); + if (!strcmp(name, attr_name)) { + gtk_tree_selection_unselect_all(selection); + gtk_tree_selection_select_iter(selection, &iter); + } + } +} + void XmlTree::on_attr_unselect_row_clear_text() { attr_name.set_text(""); diff --git a/src/ui/dialog/xml-tree.h b/src/ui/dialog/xml-tree.h index eeb828771..bf43f5ae8 100644 --- a/src/ui/dialog/xml-tree.h +++ b/src/ui/dialog/xml-tree.h @@ -126,10 +126,15 @@ private: static void after_tree_move(GtkCTree *tree, GtkCTreeNode *node, GtkCTreeNode *new_parent, GtkCTreeNode *new_sibling, gpointer data); /** - * Callback functions for when attribute selection changes + * Callback for when attribute selection changes */ static void on_attr_select_row(GtkTreeSelection *selection, gpointer data); + /** + * Callback for when attribute list values change + */ + static void on_attr_row_changed(SPXMLViewAttrList *attributes, const gchar * name, gpointer data); + /** * Enable widgets based on current selections */ diff --git a/src/widgets/sp-xmlview-attr-list.cpp b/src/widgets/sp-xmlview-attr-list.cpp index b2d22754d..1c92476fa 100644 --- a/src/widgets/sp-xmlview-attr-list.cpp +++ b/src/widgets/sp-xmlview-attr-list.cpp @@ -207,6 +207,6 @@ event_attr_changed (Inkscape::XML::Node * /*repr*/, } // send a "changed" signal so widget owners will know I've updated - g_signal_emit_by_name(G_OBJECT (list), "row-value-changed", row ); + g_signal_emit_by_name(G_OBJECT (list), "row-value-changed", name ); } -- cgit v1.2.3 From 64d4659e32867f30f2dfa71c21778a834894ffca Mon Sep 17 00:00:00 2001 From: John Smith Date: Fri, 23 Mar 2012 22:30:43 +0900 Subject: Fix for 909328 : Dockable Find & Replace dialog, replace ComboBoxText with Entry to fix build error with gtkmm2.4 (bzr r11119) --- src/ui/dialog/find.cpp | 25 +++++++------------------ src/ui/dialog/find.h | 4 ++-- src/ui/widget/entry.cpp | 8 -------- src/ui/widget/entry.h | 44 -------------------------------------------- 4 files changed, 9 insertions(+), 72 deletions(-) diff --git a/src/ui/dialog/find.cpp b/src/ui/dialog/find.cpp index 1652fbb16..f5745e02b 100644 --- a/src/ui/dialog/find.cpp +++ b/src/ui/dialog/find.cpp @@ -358,7 +358,7 @@ Find::item_text_match (SPItem *item, const gchar *find, bool exact, bool casemat return found; } - gchar* replace_text = g_strdup(entry_replace.get_text().c_str()); + gchar* replace_text = g_strdup(entry_replace.getEntry()->get_text().c_str()); gsize n = find_strcmp_pos(item_text, ufind.c_str(), exact, casematch); static Inkscape::Text::Layout::iterator _begin_w; static Inkscape::Text::Layout::iterator _end_w; @@ -398,7 +398,7 @@ Find::item_id_match (SPItem *item, const gchar *id, bool exact, bool casematch, bool found = find_strcmp(item_id, id, exact, casematch); if (found && replace) { - gchar * replace_text = g_strdup(entry_replace.get_text().c_str()); + gchar * replace_text = g_strdup(entry_replace.getEntry()->get_text().c_str()); Glib::ustring new_item_style = find_replace(item_id, id, replace_text , exact, casematch, true); if (new_item_style != item_id) { item->getRepr()->setAttribute("id", new_item_style.data()); @@ -424,7 +424,7 @@ Find::item_style_match (SPItem *item, const gchar *text, bool exact, bool casema bool found = find_strcmp(item_style, text, exact, casematch); if (found && replace) { - gchar * replace_text = g_strdup(entry_replace.get_text().c_str()); + gchar * replace_text = g_strdup(entry_replace.getEntry()->get_text().c_str()); Glib::ustring new_item_style = find_replace(item_style, text, replace_text , exact, casematch, true); if (new_item_style != item_style) { item->getRepr()->setAttribute("style", new_item_style.data()); @@ -478,7 +478,7 @@ bool Find::item_attrvalue_match(SPItem *item, const gchar *text, bool exact, boo } if (found && replace) { - gchar * replace_text = g_strdup(entry_replace.get_text().c_str()); + gchar * replace_text = g_strdup(entry_replace.getEntry()->get_text().c_str()); Glib::ustring new_item_style = find_replace(attr_value, text, replace_text , exact, casematch, true); if (new_item_style != attr_value) { item->getRepr()->setAttribute(key, new_item_style.data()); @@ -519,7 +519,7 @@ bool Find::item_font_match(SPItem *item, const gchar *text, bool exact, bool cas if (found) { ret = true; if (_action_replace) { - gchar *replace_text = g_strdup(entry_replace.get_text().c_str()); + gchar *replace_text = g_strdup(entry_replace.getEntry()->get_text().c_str()); gchar *orig_str = g_strdup(token.c_str()); // Exact match fails since the "font-family:" is in the token, since the find was exact it still works with false below Glib::ustring new_item_style = find_replace(orig_str, text, replace_text , false /*exact*/, casematch, true); @@ -550,7 +550,7 @@ bool Find::item_font_match(SPItem *item, const gchar *text, bool exact, bool cas GSList * Find::filter_fields (GSList *l, bool exact, bool casematch) { - Glib::ustring tmp = entry_find.get_text(); + Glib::ustring tmp = entry_find.getEntry()->get_text(); if (tmp.empty()) { return l; } @@ -778,7 +778,7 @@ Find::onFind() void Find::onReplace() { - if (entry_find.get_text().length() < 1) { + if (entry_find.getEntry()->get_text().length() < 1) { status.set_text(_("Nothing to replace")); return; } @@ -799,17 +799,6 @@ Find::onAction() bool casematch = check_case_sensitive.get_active(); blocked = true; - // Add find/replace text to combobox list - if (entry_find.get_text().length() > 0) { - entry_find.remove_text(entry_find.get_text()); - entry_find.prepend_text(entry_find.get_text()); - } - - if (_action_replace && entry_replace.get_text().length() > 0) { - entry_replace.remove_text(entry_replace.get_text()); - entry_replace.prepend_text(entry_replace.get_text()); - } - GSList *l = NULL; if (check_scope_selection.get_active()) { if (check_scope_layer.get_active()) { diff --git a/src/ui/dialog/find.h b/src/ui/dialog/find.h index 26ac37d7f..62ecd1763 100644 --- a/src/ui/dialog/find.h +++ b/src/ui/dialog/find.h @@ -198,8 +198,8 @@ private: /* * Find and replace combo box widgets */ - Inkscape::UI::Widget::ComboBoxText entry_find; - Inkscape::UI::Widget::ComboBoxText entry_replace; + Inkscape::UI::Widget::Entry entry_find; + Inkscape::UI::Widget::Entry entry_replace; /** * Scope and search in widgets diff --git a/src/ui/widget/entry.cpp b/src/ui/widget/entry.cpp index 08617433c..173e014d9 100644 --- a/src/ui/widget/entry.cpp +++ b/src/ui/widget/entry.cpp @@ -25,14 +25,6 @@ Entry::Entry( Glib::ustring const &label, Glib::ustring const &tooltip, { } -ComboBoxText::ComboBoxText( Glib::ustring const &label, Glib::ustring const &tooltip, - Glib::ustring const &suffix, - Glib::ustring const &icon, - bool mnemonic) - : Labelled(label, tooltip, new Gtk::ComboBoxText(true), suffix, icon, mnemonic) -{ -} - } // namespace Widget } // namespace UI } // namespace Inkscape diff --git a/src/ui/widget/entry.h b/src/ui/widget/entry.h index be7c8b450..53b848fc9 100644 --- a/src/ui/widget/entry.h +++ b/src/ui/widget/entry.h @@ -37,50 +37,6 @@ public: Gtk::Entry* getEntry() {return (Gtk::Entry*)(_widget);}; }; -class ComboBoxText : public Labelled -{ -public: - ComboBoxText( Glib::ustring const &label, - Glib::ustring const &tooltip, - Glib::ustring const &suffix = "", - Glib::ustring const &icon = "", - bool mnemonic = true); - - Gtk::ComboBoxText* getWidget() { return (Gtk::ComboBoxText *)_widget; }; - Gtk::Entry* getEntry() { return (Gtk::Entry *)getWidget()->get_child(); }; - Glib::ustring get_text() { return getEntry()->get_text(); }; - void prepend_text(const Glib::ustring& text) { -#if WITH_GTKMM_2_24 - getWidget()->prepend(text); -#else - getWidget()->prepend_text(text); -#endif - }; - void append_text(const Glib::ustring& text) { -#if WITH_GTKMM_2_24 - getWidget()->append(text); -#else - getWidget()->append_text(text); -#endif - }; - void insert_text(gint position, const Glib::ustring& text) { -#if WITH_GTKMM_2_24 - getWidget()->insert(position, text); -#else - getWidget()->insert_text(position, text); -#endif - }; - void remove_text(const Glib::ustring& text) { getWidget()->remove_text(text); }; - void remove_all() { -#if WITH_GTKMM_2_24 - getWidget()->remove_all(); -#else - getWidget()->clear_items(); -#endif - }; - -}; - } // namespace Widget } // namespace UI } // namespace Inkscape -- cgit v1.2.3 From 41833cc6958c81ba111a1b429d0d503834bb58c2 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Fri, 23 Mar 2012 20:06:18 +0100 Subject: powerstroke: correct naming of join parameter. breaks earlier created powerstroke paths, sorry. hope it does not hurt too many testers... (bzr r11120) --- src/live_effects/lpe-powerstroke.cpp | 54 ++++++++++++++++++------------------ src/live_effects/lpe-powerstroke.h | 2 +- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/src/live_effects/lpe-powerstroke.cpp b/src/live_effects/lpe-powerstroke.cpp index 6cc2d2368..1f521da5d 100644 --- a/src/live_effects/lpe-powerstroke.cpp +++ b/src/live_effects/lpe-powerstroke.cpp @@ -125,19 +125,19 @@ static const Util::EnumData LineCapTypeData[] = { }; static const Util::EnumDataConverter LineCapTypeConverter(LineCapTypeData, sizeof(LineCapTypeData)/sizeof(*LineCapTypeData)); -enum LineCuspType { - LINECUSP_BEVEL, - LINECUSP_ROUND, - LINECUSP_EXTRP_MITER, - LINECUSP_MITER +enum LineJoinType { + LINEJOIN_BEVEL, + LINEJOIN_ROUND, + LINEJOIN_EXTRP_MITER, + LINEJOIN_MITER }; -static const Util::EnumData LineCuspTypeData[] = { - {LINECUSP_BEVEL, N_("Beveled"), "bevel"}, - {LINECUSP_ROUND, N_("Rounded"), "round"}, - {LINECUSP_EXTRP_MITER, N_("Extrapolated"), "extrapolated"}, - {LINECUSP_MITER, N_("Miter"), "miter"}, +static const Util::EnumData LineJoinTypeData[] = { + {LINEJOIN_BEVEL, N_("Beveled"), "bevel"}, + {LINEJOIN_ROUND, N_("Rounded"), "round"}, + {LINEJOIN_EXTRP_MITER, N_("Extrapolated"), "extrapolated"}, + {LINEJOIN_MITER, N_("Miter"), "miter"}, }; -static const Util::EnumDataConverter LineCuspTypeConverter(LineCuspTypeData, sizeof(LineCuspTypeData)/sizeof(*LineCuspTypeData)); +static const Util::EnumDataConverter LineJoinTypeConverter(LineJoinTypeData, sizeof(LineJoinTypeData)/sizeof(*LineJoinTypeData)); LPEPowerStroke::LPEPowerStroke(LivePathEffectObject *lpeobject) : Effect(lpeobject), @@ -146,7 +146,7 @@ LPEPowerStroke::LPEPowerStroke(LivePathEffectObject *lpeobject) : interpolator_type(_("Interpolator type"), _("Determines which kind of interpolator will be used to interpolate between stroke width along the path."), "interpolator_type", InterpolatorTypeConverter, &wr, this, Geom::Interpolate::INTERP_CUBICBEZIER_JOHAN), interpolator_beta(_("Smoothness"), _("Sets the smoothness for the CubicBezierJohan interpolator. 0 = linear interpolation, 1 = smooth"), "interpolator_beta", &wr, this, 0.2), start_linecap_type(_("Start cap"), _("Determines the shape of the path's start."), "start_linecap_type", LineCapTypeConverter, &wr, this, LINECAP_ROUND), - cusp_linecap_type(_("Join"), _("Specifies the shape of the path's corners."), "cusp_linecap_type", LineCuspTypeConverter, &wr, this, LINECUSP_ROUND), + linejoin_type(_("Join"), _("Specifies the shape of the path's corners."), "linejoin_type", LineJoinTypeConverter, &wr, this, LINEJOIN_ROUND), miter_limit(_("Miter limit"), _("Maximum length of the miter (in units of stroke width)"), "miter_limit", &wr, this, 4.), end_linecap_type(_("End cap"), _("Determines the shape of the path's end."), "end_linecap_type", LineCapTypeConverter, &wr, this, LINECAP_ROUND) { @@ -162,7 +162,7 @@ LPEPowerStroke::LPEPowerStroke(LivePathEffectObject *lpeobject) : registerParameter( dynamic_cast(&interpolator_type) ); registerParameter( dynamic_cast(&interpolator_beta) ); registerParameter( dynamic_cast(&start_linecap_type) ); - registerParameter( dynamic_cast(&cusp_linecap_type) ); + registerParameter( dynamic_cast(&linejoin_type) ); registerParameter( dynamic_cast(&miter_limit) ); registerParameter( dynamic_cast(&end_linecap_type) ); } @@ -204,9 +204,9 @@ static bool compare_offsets (Geom::Point first, Geom::Point second) // find discontinuities in input path struct discontinuity_data { - Geom::Point der0; // unit derivative of 'left' side of cusp - Geom::Point der1; // unit derivative of 'right' side of cusp - double width; // intended stroke width at cusp + Geom::Point der0; // unit derivative of 'left' side of join + Geom::Point der1; // unit derivative of 'right' side of join + double width; // intended stroke width at join }; std::vector find_discontinuities( Geom::Piecewise > const & der, Geom::Piecewise const & x, @@ -243,12 +243,12 @@ std::vector find_discontinuities( Geom::Piecewise > const & B, std::vector const & cusps, - LineCuspType cusp_linecap, + LineJoinType jointype, double miter_limit, bool forward_direction, double tol=Geom::EPSILON) { -/* per definition, each discontinuity should be fixed with a cusp-ending, as defined by cusp_linecap_type +/* per definition, each discontinuity should be fixed with a join-ending, as defined by linejoin_type */ Geom::PathBuilder pb; if (B.size() == 0) { @@ -272,8 +272,8 @@ Geom::Path path_from_piecewise_fix_cusps( Geom::Piecewise { // discontinuity found, so fix it :-) discontinuity_data cusp = cusps[cusp_i]; - switch (cusp_linecap) { - case LINECUSP_ROUND: { + switch (jointype) { + case LINEJOIN_ROUND: { if ( sign*cusp.width*angle_between(cusp.der0, cusp.der1) < 0.) { // we are on the outside: round corner /* for constant width paths, the rounding is a circular arc (rx == ry), @@ -303,7 +303,7 @@ Geom::Path path_from_piecewise_fix_cusps( Geom::Piecewise } break; } -/* case LINECUSP_NONE: { +/* case LINEJOIN_NONE: { if ( sign*cusp.width*angle_between(cusp.der0, cusp.der1) < 0.) { // we are on the outside Geom::Point der1 = unitTangentAt(B[prev_i],1); @@ -315,7 +315,7 @@ Geom::Path path_from_piecewise_fix_cusps( Geom::Piecewise pb.lineTo(B[i].at0()); // default to bevel for too shallow cusp angles } } */ - case LINECUSP_EXTRP_MITER: { + case LINEJOIN_EXTRP_MITER: { // first figure out whether we are on the outside or inside of the corner in the path if ( sign*cusp.width*angle_between(cusp.der0, cusp.der1) < 0.) { // we are on the outside, do something complicated to make it look good ;) @@ -354,7 +354,7 @@ Geom::Path path_from_piecewise_fix_cusps( Geom::Piecewise } break; } - case LINECUSP_MITER: { + case LINEJOIN_MITER: { // first figure out whether we are on the outside or inside of the corner in the path if ( sign*cusp.width*angle_between(cusp.der0, cusp.der1) < 0.) { // we are on the outside, do something complicated to make it look good ;) @@ -379,7 +379,7 @@ Geom::Path path_from_piecewise_fix_cusps( Geom::Piecewise } break; } - case LINECUSP_BEVEL: + case LINEJOIN_BEVEL: default: pb.lineTo(B[i].at0()); break; @@ -457,13 +457,13 @@ LPEPowerStroke::doEffect_path (std::vector const & path_in) } std::vector cusps = find_discontinuities(der, x, y); - LineCuspType cusp_linecap = static_cast(cusp_linecap_type.get_value()); + LineJoinType jointype = static_cast(linejoin_type.get_value()); Piecewise > pwd2_out = compose(pwd2_in,x) + y*compose(n,x); Piecewise > mirrorpath = reverse(compose(pwd2_in,x) - y*compose(n,x)); - Geom::Path fixed_path = path_from_piecewise_fix_cusps( pwd2_out, cusps, cusp_linecap, miter_limit, true, LPE_CONVERSION_TOLERANCE); - Geom::Path fixed_mirrorpath = path_from_piecewise_fix_cusps( mirrorpath, cusps, cusp_linecap, miter_limit, false, LPE_CONVERSION_TOLERANCE); + Geom::Path fixed_path = path_from_piecewise_fix_cusps( pwd2_out, cusps, jointype, miter_limit, true, LPE_CONVERSION_TOLERANCE); + Geom::Path fixed_mirrorpath = path_from_piecewise_fix_cusps( mirrorpath, cusps, jointype, miter_limit, false, LPE_CONVERSION_TOLERANCE); if (path_in[0].closed()) { fixed_path.close(true); diff --git a/src/live_effects/lpe-powerstroke.h b/src/live_effects/lpe-powerstroke.h index a5bb8c836..e6c915234 100644 --- a/src/live_effects/lpe-powerstroke.h +++ b/src/live_effects/lpe-powerstroke.h @@ -39,7 +39,7 @@ private: EnumParam interpolator_type; ScalarParam interpolator_beta; EnumParam start_linecap_type; - EnumParam cusp_linecap_type; + EnumParam linejoin_type; ScalarParam miter_limit; EnumParam end_linecap_type; -- cgit v1.2.3 From 5d21c3b51c6a2e202b05847b69218189f9247059 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Fri, 23 Mar 2012 20:30:38 +0100 Subject: clean up spiro code (bzr r11121) --- src/live_effects/bezctx.h | 5 +++ src/live_effects/bezctx_intf.h | 5 +++ src/live_effects/lpe-spiro.cpp | 78 ---------------------------------- src/live_effects/spiro.cpp | 95 ++++++++++++++++++++++++++++++++++++++++-- src/live_effects/spiro.h | 51 +++++++++++++++++++---- 5 files changed, 146 insertions(+), 88 deletions(-) diff --git a/src/live_effects/bezctx.h b/src/live_effects/bezctx.h index 057312e5a..df074676e 100644 --- a/src/live_effects/bezctx.h +++ b/src/live_effects/bezctx.h @@ -1,3 +1,6 @@ +#ifndef INKSCAPE_SPIRO_bezctx_H +#define INKSCAPE_SPIRO_bezctx_H + #include "bezctx_intf.h" struct _bezctx { @@ -8,3 +11,5 @@ struct _bezctx { double x3, double y3); void (*mark_knot)(bezctx *bc, int knot_idx); }; + +#endif diff --git a/src/live_effects/bezctx_intf.h b/src/live_effects/bezctx_intf.h index a47b8ef5a..05ea79a63 100644 --- a/src/live_effects/bezctx_intf.h +++ b/src/live_effects/bezctx_intf.h @@ -1,3 +1,6 @@ +#ifndef INKSCAPE_SPIRO_bezctx_intf_H +#define INKSCAPE_SPIRO_bezctx_intf_H + typedef struct _bezctx bezctx; bezctx * @@ -18,3 +21,5 @@ bezctx_curveto(bezctx *bc, double x1, double y1, double x2, double y2, void bezctx_mark_knot(bezctx *bc, int knot_idx); + +#endif diff --git a/src/live_effects/lpe-spiro.cpp b/src/live_effects/lpe-spiro.cpp index 22974fe13..7f700bddd 100644 --- a/src/live_effects/lpe-spiro.cpp +++ b/src/live_effects/lpe-spiro.cpp @@ -15,8 +15,6 @@ #include "helper/geom-nodetype.h" #include "helper/geom-curves.h" -#include "live_effects/bezctx.h" -#include "live_effects/bezctx_intf.h" #include "live_effects/spiro.h" // For handling un-continuous paths: @@ -24,82 +22,6 @@ #include "inkscape.h" #include "desktop.h" -#define SPIRO_SHOW_INFINITE_COORDINATE_CALLS - -typedef struct { - bezctx base; - SPCurve *curve; - int is_open; -} bezctx_ink; - -void bezctx_ink_moveto(bezctx *bc, double x, double y, int /*is_open*/) -{ - bezctx_ink *bi = (bezctx_ink *) bc; - if ( IS_FINITE(x) && IS_FINITE(y) ) { - bi->curve->moveto(x, y); - } -#ifdef SPIRO_SHOW_INFINITE_COORDINATE_CALLS - else { - g_message("lpe moveto not finite"); - } -#endif -} - -void bezctx_ink_lineto(bezctx *bc, double x, double y) -{ - bezctx_ink *bi = (bezctx_ink *) bc; - if ( IS_FINITE(x) && IS_FINITE(y) ) { - bi->curve->lineto(x, y); - } -#ifdef SPIRO_SHOW_INFINITE_COORDINATE_CALLS - else { - g_message("lpe lineto not finite"); - } -#endif -} - -void bezctx_ink_quadto(bezctx *bc, double xm, double ym, double x3, double y3) -{ - bezctx_ink *bi = (bezctx_ink *) bc; - - if ( IS_FINITE(xm) && IS_FINITE(ym) && IS_FINITE(x3) && IS_FINITE(y3) ) { - bi->curve->quadto(xm, ym, x3, y3); - } -#ifdef SPIRO_SHOW_INFINITE_COORDINATE_CALLS - else { - g_message("lpe quadto not finite"); - } -#endif -} - -void bezctx_ink_curveto(bezctx *bc, double x1, double y1, double x2, double y2, - double x3, double y3) -{ - bezctx_ink *bi = (bezctx_ink *) bc; - if ( IS_FINITE(x1) && IS_FINITE(y1) && IS_FINITE(x2) && IS_FINITE(y2) ) { - bi->curve->curveto(x1, y1, x2, y2, x3, y3); - } -#ifdef SPIRO_SHOW_INFINITE_COORDINATE_CALLS - else { - g_message("lpe curveto not finite"); - } -#endif -} - -bezctx * -new_bezctx_ink(SPCurve *curve) { - bezctx_ink *result = g_new(bezctx_ink, 1); - result->base.moveto = bezctx_ink_moveto; - result->base.lineto = bezctx_ink_lineto; - result->base.quadto = bezctx_ink_quadto; - result->base.curveto = bezctx_ink_curveto; - result->base.mark_knot = NULL; - result->curve = curve; - return &result->base; -} - - - namespace Inkscape { namespace LivePathEffect { diff --git a/src/live_effects/spiro.cpp b/src/live_effects/spiro.cpp index b98e12213..b916a2cf7 100644 --- a/src/live_effects/spiro.cpp +++ b/src/live_effects/spiro.cpp @@ -1,6 +1,8 @@ /* -ppedit - A pattern plate editor for Spiro splines. -Copyright (C) 2007 Raph Levien +Copyright (C) 2007-2012 Authors + +Authors: Raph Levien + Johan Engelen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -20,12 +22,22 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA */ /* C implementation of third-order polynomial spirals. */ +#include "spiro.h" + #include #include #include #include "bezctx_intf.h" -#include "spiro.h" +#include "display/curve.h" +#include <2geom/math-utils.h> + +#define SPIRO_SHOW_INFINITE_COORDINATE_CALLS + + +/************************************ + * Spiro math + */ struct spiro_seg_s { double x; @@ -922,6 +934,83 @@ get_knot_th(const spiro_seg *s, int i) } } + +/************************************ + * Conversion to Inkscape's curve + */ + +void bezctx_ink_moveto(bezctx *bc, double x, double y, int /*is_open*/) +{ + bezctx_ink *bi = (bezctx_ink *) bc; + if ( IS_FINITE(x) && IS_FINITE(y) ) { + bi->curve->moveto(x, y); + } +#ifdef SPIRO_SHOW_INFINITE_COORDINATE_CALLS + else { + g_message("Spiro: moveto not finite"); + } +#endif +} + +void bezctx_ink_lineto(bezctx *bc, double x, double y) +{ + bezctx_ink *bi = (bezctx_ink *) bc; + if ( IS_FINITE(x) && IS_FINITE(y) ) { + bi->curve->lineto(x, y); + } +#ifdef SPIRO_SHOW_INFINITE_COORDINATE_CALLS + else { + g_message("Spiro: lineto not finite"); + } +#endif +} + +void bezctx_ink_quadto(bezctx *bc, double xm, double ym, double x3, double y3) +{ + bezctx_ink *bi = (bezctx_ink *) bc; + + if ( IS_FINITE(xm) && IS_FINITE(ym) && IS_FINITE(x3) && IS_FINITE(y3) ) { + bi->curve->quadto(xm, ym, x3, y3); + } +#ifdef SPIRO_SHOW_INFINITE_COORDINATE_CALLS + else { + g_message("Spiro: quadto not finite"); + } +#endif +} + +void bezctx_ink_curveto(bezctx *bc, double x1, double y1, double x2, double y2, + double x3, double y3) +{ + bezctx_ink *bi = (bezctx_ink *) bc; + if ( IS_FINITE(x1) && IS_FINITE(y1) && IS_FINITE(x2) && IS_FINITE(y2) ) { + bi->curve->curveto(x1, y1, x2, y2, x3, y3); + } +#ifdef SPIRO_SHOW_INFINITE_COORDINATE_CALLS + else { + g_message("Spiro: curveto not finite"); + } +#endif +} + +bezctx * new_bezctx_ink(SPCurve *curve) +{ + bezctx_ink *result = g_new(bezctx_ink, 1); + result->base.moveto = bezctx_ink_moveto; + result->base.lineto = bezctx_ink_lineto; + result->base.quadto = bezctx_ink_quadto; + result->base.curveto = bezctx_ink_curveto; + result->base.mark_knot = NULL; + result->curve = curve; + return &result->base; +} + + +/************************************ + * Unit_test code + */ + + #ifdef UNIT_TEST #include #include /* for gettimeofday */ diff --git a/src/live_effects/spiro.h b/src/live_effects/spiro.h index 54de40465..f39fbded6 100644 --- a/src/live_effects/spiro.h +++ b/src/live_effects/spiro.h @@ -1,3 +1,34 @@ +/* +Copyright (C) 2007-2012 Authors + +Authors: Raph Levien + Johan Engelen + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301, USA. + +*/ + +#ifndef INKSCAPE_SPIRO_H +#define INKSCAPE_SPIRO_H + +#include "live_effects/bezctx.h" +#include "live_effects/bezctx_intf.h" + +class SPCurve; + typedef struct { double x; double y; @@ -6,13 +37,19 @@ typedef struct { typedef struct spiro_seg_s spiro_seg; -spiro_seg * -run_spiro(const spiro_cp *src, int n); +spiro_seg * run_spiro(const spiro_cp *src, int n); +void free_spiro(spiro_seg *s); +void spiro_to_bpath(const spiro_seg *s, int n, bezctx *bc); +double get_knot_th(const spiro_seg *s, int i); -void -free_spiro(spiro_seg *s); -void -spiro_to_bpath(const spiro_seg *s, int n, bezctx *bc); +typedef struct { + bezctx base; + SPCurve *curve; + int is_open; +} bezctx_ink; -double get_knot_th(const spiro_seg *s, int i); +bezctx * new_bezctx_ink(SPCurve *curve); + + +#endif // INKSCAPE_SPIRO_H \ No newline at end of file -- cgit v1.2.3 From be2093259f84b6ae9095b99e020c6fc5f2aec45d Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Fri, 23 Mar 2012 20:44:33 +0100 Subject: more spiro cleanup (bzr r11122) --- src/live_effects/CMakeLists.txt | 2 - src/live_effects/Makefile_insert | 2 - src/live_effects/bezctx.cpp | 48 ------------------------ src/live_effects/bezctx.h | 6 +-- src/live_effects/bezctx_intf.h | 25 ------------ src/live_effects/lpe-powerstroke-interpolators.h | 1 - src/live_effects/spiro.cpp | 9 ++--- 7 files changed, 6 insertions(+), 87 deletions(-) delete mode 100644 src/live_effects/bezctx.cpp delete mode 100644 src/live_effects/bezctx_intf.h diff --git a/src/live_effects/CMakeLists.txt b/src/live_effects/CMakeLists.txt index e066e7f43..f2e10c771 100644 --- a/src/live_effects/CMakeLists.txt +++ b/src/live_effects/CMakeLists.txt @@ -1,6 +1,5 @@ set(live_effects_SRC - bezctx.cpp effect.cpp lpe-angle_bisector.cpp lpe-bendpath.cpp @@ -59,7 +58,6 @@ set(live_effects_SRC # ------- # Headers bezctx.h - bezctx_intf.h effect-enum.h effect.h lpe-angle_bisector.h diff --git a/src/live_effects/Makefile_insert b/src/live_effects/Makefile_insert index 74356f563..65a934c9c 100644 --- a/src/live_effects/Makefile_insert +++ b/src/live_effects/Makefile_insert @@ -51,8 +51,6 @@ ink_common_sources += \ live_effects/spiro.h \ live_effects/spiro.cpp \ live_effects/bezctx.h \ - live_effects/bezctx_intf.h \ - live_effects/bezctx.cpp \ live_effects/lpe-circle_with_radius.cpp \ live_effects/lpe-circle_with_radius.h \ live_effects/lpe-perspective_path.cpp \ diff --git a/src/live_effects/bezctx.cpp b/src/live_effects/bezctx.cpp deleted file mode 100644 index 722f5dbaf..000000000 --- a/src/live_effects/bezctx.cpp +++ /dev/null @@ -1,48 +0,0 @@ -/* -ppedit - A pattern plate editor for Spiro splines. -Copyright (C) 2007 Raph Levien - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301, USA. - -*/ -#include "bezctx.h" - -void bezctx_moveto(bezctx *bc, double x, double y, int is_open) -{ - bc->moveto(bc, x, y, is_open); -} - -void bezctx_lineto(bezctx *bc, double x, double y) -{ - bc->lineto(bc, x, y); -} - -void bezctx_quadto(bezctx *bc, double x1, double y1, double x2, double y2) -{ - bc->quadto(bc, x1, y1, x2, y2); -} - -void bezctx_curveto(bezctx *bc, double x1, double y1, double x2, double y2, - double x3, double y3) -{ - bc->curveto(bc, x1, y1, x2, y2, x3, y3); -} - -void bezctx_mark_knot(bezctx *bc, int knot_idx) -{ - if (bc->mark_knot) - bc->mark_knot(bc, knot_idx); -} diff --git a/src/live_effects/bezctx.h b/src/live_effects/bezctx.h index df074676e..d8eb38e8c 100644 --- a/src/live_effects/bezctx.h +++ b/src/live_effects/bezctx.h @@ -3,13 +3,13 @@ #include "bezctx_intf.h" -struct _bezctx { +class _bezctx { +public: void (*moveto)(bezctx *bc, double x, double y, int is_open); void (*lineto)(bezctx *bc, double x, double y); void (*quadto)(bezctx *bc, double x1, double y1, double x2, double y2); void (*curveto)(bezctx *bc, double x1, double y1, double x2, double y2, - double x3, double y3); - void (*mark_knot)(bezctx *bc, int knot_idx); + double x3, double y3); }; #endif diff --git a/src/live_effects/bezctx_intf.h b/src/live_effects/bezctx_intf.h deleted file mode 100644 index 05ea79a63..000000000 --- a/src/live_effects/bezctx_intf.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef INKSCAPE_SPIRO_bezctx_intf_H -#define INKSCAPE_SPIRO_bezctx_intf_H - -typedef struct _bezctx bezctx; - -bezctx * -new_bezctx(void); - -void -bezctx_moveto(bezctx *bc, double x, double y, int is_open); - -void -bezctx_lineto(bezctx *bc, double x, double y); - -void -bezctx_quadto(bezctx *bc, double x1, double y1, double x2, double y2); - -void -bezctx_curveto(bezctx *bc, double x1, double y1, double x2, double y2, - double x3, double y3); - -void -bezctx_mark_knot(bezctx *bc, int knot_idx); - -#endif diff --git a/src/live_effects/lpe-powerstroke-interpolators.h b/src/live_effects/lpe-powerstroke-interpolators.h index 7f9cb3ddb..224c56e89 100644 --- a/src/live_effects/lpe-powerstroke-interpolators.h +++ b/src/live_effects/lpe-powerstroke-interpolators.h @@ -237,7 +237,6 @@ private: result->base.lineto = bezctx_ink_lineto; result->base.quadto = bezctx_ink_quadto; result->base.curveto = bezctx_ink_curveto; - result->base.mark_knot = NULL; result->path = path; return &result->base; } diff --git a/src/live_effects/spiro.cpp b/src/live_effects/spiro.cpp index b916a2cf7..e7824c297 100644 --- a/src/live_effects/spiro.cpp +++ b/src/live_effects/spiro.cpp @@ -28,7 +28,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA #include #include -#include "bezctx_intf.h" #include "display/curve.h" #include <2geom/math-utils.h> @@ -834,7 +833,7 @@ spiro_seg_to_bpath(const double ks[4], fabs((1./48) * ks[3]); if (!bend > 1e-8) { - bezctx_lineto(bc, x1, y1); + bc->lineto(bc, x1, y1); } else { double seg_ch = hypot(x1 - x0, y1 - y0); double seg_th = atan2(y1 - y0, x1 - x0); @@ -857,7 +856,7 @@ spiro_seg_to_bpath(const double ks[4], vl = (scale * (1./3)) * sin(th_even - th_odd); ur = (scale * (1./3)) * cos(th_even + th_odd); vr = (scale * (1./3)) * sin(th_even + th_odd); - bezctx_curveto(bc, x0 + ul, y0 + vl, x1 - ur, y1 - vr, x1, y1); + bc->curveto(bc, x0 + ul, y0 + vl, x1 - ur, y1 - vr, x1, y1); } else { /* subdivide */ double ksub[4]; @@ -914,8 +913,7 @@ spiro_to_bpath(const spiro_seg *s, int n, bezctx *bc) double y1 = s[i + 1].y; if (i == 0) - bezctx_moveto(bc, x0, y0, s[0].ty == '{'); - bezctx_mark_knot(bc, i); + bc->moveto(bc, x0, y0, s[0].ty == '{'); spiro_seg_to_bpath(s[i].ks, x0, y0, x1, y1, bc, 0); } } @@ -1000,7 +998,6 @@ bezctx * new_bezctx_ink(SPCurve *curve) result->base.lineto = bezctx_ink_lineto; result->base.quadto = bezctx_ink_quadto; result->base.curveto = bezctx_ink_curveto; - result->base.mark_knot = NULL; result->curve = curve; return &result->base; } -- cgit v1.2.3 From 2ad4d90803d4c83b28f146130db83c5e569b8ec7 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Fri, 23 Mar 2012 22:02:03 +0100 Subject: cleanup spiro code (bzr r11123) --- src/live_effects/CMakeLists.txt | 6 +- src/live_effects/Makefile_insert | 3 +- src/live_effects/bezctx.h | 15 --- src/live_effects/lpe-powerstroke-interpolators.h | 82 +---------------- src/live_effects/lpe-spiro.cpp | 7 +- src/live_effects/spiro-converters.h | 69 ++++++++++++++ src/live_effects/spiro.cpp | 111 +++++++---------------- src/live_effects/spiro.h | 25 ++--- 8 files changed, 124 insertions(+), 194 deletions(-) delete mode 100644 src/live_effects/bezctx.h create mode 100644 src/live_effects/spiro-converters.h diff --git a/src/live_effects/CMakeLists.txt b/src/live_effects/CMakeLists.txt index f2e10c771..a5f50a69d 100644 --- a/src/live_effects/CMakeLists.txt +++ b/src/live_effects/CMakeLists.txt @@ -40,6 +40,7 @@ set(live_effects_SRC lpeobject-reference.cpp lpeobject.cpp spiro.cpp + spiro-converters.cpp parameter/array.cpp parameter/bool.cpp @@ -57,7 +58,6 @@ set(live_effects_SRC # ------- # Headers - bezctx.h effect-enum.h effect.h lpe-angle_bisector.h @@ -99,6 +99,8 @@ set(live_effects_SRC lpegroupbbox.h lpeobject-reference.h lpeobject.h + spiro.h + spiro-converters.h parameter/array.h parameter/bool.h @@ -113,7 +115,7 @@ set(live_effects_SRC parameter/text.h parameter/unit.h parameter/vector.h - spiro.h + ) # add_inkscape_lib(live_effects_LIB "${live_effects_SRC}") diff --git a/src/live_effects/Makefile_insert b/src/live_effects/Makefile_insert index 65a934c9c..9c3c171f2 100644 --- a/src/live_effects/Makefile_insert +++ b/src/live_effects/Makefile_insert @@ -50,7 +50,8 @@ ink_common_sources += \ live_effects/lpe-perp_bisector.h \ live_effects/spiro.h \ live_effects/spiro.cpp \ - live_effects/bezctx.h \ + live_effects/spiro-converters.h \ + live_effects/spiro-converters.cpp \ live_effects/lpe-circle_with_radius.cpp \ live_effects/lpe-circle_with_radius.h \ live_effects/lpe-perspective_path.cpp \ diff --git a/src/live_effects/bezctx.h b/src/live_effects/bezctx.h deleted file mode 100644 index d8eb38e8c..000000000 --- a/src/live_effects/bezctx.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef INKSCAPE_SPIRO_bezctx_H -#define INKSCAPE_SPIRO_bezctx_H - -#include "bezctx_intf.h" - -class _bezctx { -public: - void (*moveto)(bezctx *bc, double x, double y, int is_open); - void (*lineto)(bezctx *bc, double x, double y); - void (*quadto)(bezctx *bc, double x1, double y1, double x2, double y2); - void (*curveto)(bezctx *bc, double x1, double y1, double x2, double y2, - double x3, double y3); -}; - -#endif diff --git a/src/live_effects/lpe-powerstroke-interpolators.h b/src/live_effects/lpe-powerstroke-interpolators.h index 224c56e89..6f5b75af8 100644 --- a/src/live_effects/lpe-powerstroke-interpolators.h +++ b/src/live_effects/lpe-powerstroke-interpolators.h @@ -16,8 +16,6 @@ #include <2geom/bezier-utils.h> #include <2geom/sbasis-to-bezier.h> -#include "live_effects/bezctx.h" -#include "live_effects/bezctx_intf.h" #include "live_effects/spiro.h" @@ -136,7 +134,6 @@ private: }; -#define SPIRO_SHOW_INFINITE_COORDINATE_CALLS class SpiroInterpolator : public Interpolator { public: SpiroInterpolator() {}; @@ -148,8 +145,7 @@ public: Coord scale_y = 100.; guint len = points.size(); - bezctx *bc = new_bezctx_ink(&fit); - spiro_cp *controlpoints = g_new (spiro_cp, len); + Spiro::spiro_cp *controlpoints = g_new (Spiro::spiro_cp, len); for (unsigned int i = 0; i < len; ++i) { controlpoints[i].x = points[i][X]; controlpoints[i].y = points[i][Y] / scale_y; @@ -160,87 +156,13 @@ public: controlpoints[len-2].ty = 'v'; controlpoints[len-1].ty = '}'; - spiro_seg *s = run_spiro(controlpoints, len); - spiro_to_bpath(s, len, bc); - free(s); - free(bc); + Spiro::spiro_run(controlpoints, len, fit); fit *= Scale(1,scale_y); return fit; }; private: - typedef struct { - bezctx base; - Path *path; - int is_open; - } bezctx_ink; - - static void bezctx_ink_moveto(bezctx *bc, double x, double y, int /*is_open*/) - { - bezctx_ink *bi = (bezctx_ink *) bc; - if ( IS_FINITE(x) && IS_FINITE(y) ) { - bi->path->start(Point(x, y)); - } - #ifdef SPIRO_SHOW_INFINITE_COORDINATE_CALLS - else { - g_message("spiro moveto not finite"); - } - #endif - } - - static void bezctx_ink_lineto(bezctx *bc, double x, double y) - { - bezctx_ink *bi = (bezctx_ink *) bc; - if ( IS_FINITE(x) && IS_FINITE(y) ) { - bi->path->appendNew( Point(x, y) ); - } - #ifdef SPIRO_SHOW_INFINITE_COORDINATE_CALLS - else { - g_message("spiro lineto not finite"); - } - #endif - } - - static void bezctx_ink_quadto(bezctx *bc, double xm, double ym, double x3, double y3) - { - bezctx_ink *bi = (bezctx_ink *) bc; - - if ( IS_FINITE(xm) && IS_FINITE(ym) && IS_FINITE(x3) && IS_FINITE(y3) ) { - bi->path->appendNew(Point(xm, ym), Point(x3, y3)); - } - #ifdef SPIRO_SHOW_INFINITE_COORDINATE_CALLS - else { - g_message("spiro quadto not finite"); - } - #endif - } - - static void bezctx_ink_curveto(bezctx *bc, double x1, double y1, double x2, double y2, - double x3, double y3) - { - bezctx_ink *bi = (bezctx_ink *) bc; - if ( IS_FINITE(x1) && IS_FINITE(y1) && IS_FINITE(x2) && IS_FINITE(y2) ) { - bi->path->appendNew(Point(x1, y1), Point(x2, y2), Point(x3, y3)); - } - #ifdef SPIRO_SHOW_INFINITE_COORDINATE_CALLS - else { - g_message("spiro curveto not finite"); - } - #endif - } - - bezctx * - new_bezctx_ink(Geom::Path *path) const { - bezctx_ink *result = g_new(bezctx_ink, 1); - result->base.moveto = bezctx_ink_moveto; - result->base.lineto = bezctx_ink_lineto; - result->base.quadto = bezctx_ink_quadto; - result->base.curveto = bezctx_ink_curveto; - result->path = path; - return &result->base; - } - SpiroInterpolator(const SpiroInterpolator&); SpiroInterpolator& operator=(const SpiroInterpolator&); }; diff --git a/src/live_effects/lpe-spiro.cpp b/src/live_effects/lpe-spiro.cpp index 7f700bddd..8b4274ab2 100644 --- a/src/live_effects/lpe-spiro.cpp +++ b/src/live_effects/lpe-spiro.cpp @@ -46,8 +46,7 @@ LPESpiro::doEffect(SPCurve * curve) guint len = curve->get_segment_count() + 2; curve->reset(); - bezctx *bc = new_bezctx_ink(curve); - spiro_cp *path = g_new (spiro_cp, len); + Spiro::spiro_cp *path = g_new (Spiro::spiro_cp, len); int ip = 0; for(Geom::PathVector::const_iterator path_it = original_pathv.begin(); path_it != original_pathv.end(); ++path_it) { @@ -140,9 +139,7 @@ LPESpiro::doEffect(SPCurve * curve) // run subpath through spiro int sp_len = ip; - spiro_seg *s = run_spiro(path, sp_len); - spiro_to_bpath(s, sp_len, bc); - free(s); + Spiro::spiro_run(path, sp_len, *curve); ip = 0; } diff --git a/src/live_effects/spiro-converters.h b/src/live_effects/spiro-converters.h new file mode 100644 index 000000000..dbc10efda --- /dev/null +++ b/src/live_effects/spiro-converters.h @@ -0,0 +1,69 @@ +#ifndef INKSCAPE_SPIRO_CONVERTERS_H +#define INKSCAPE_SPIRO_CONVERTERS_H + +#include <2geom/forward.h> +class SPCurve; + +namespace Spiro { + +class ConverterBase { +public: + ConverterBase() {}; + virtual ~ConverterBase() {}; + + virtual void moveto(double x, double y, bool is_open) = 0; + virtual void lineto(double x, double y) = 0; + virtual void quadto(double x1, double y1, double x2, double y2) = 0; + virtual void curveto(double x1, double y1, double x2, double y2, double x3, double y3) = 0; +}; + + +/** + * Converts Spiro to Inkscape's SPCurve + */ +class ConverterSPCurve : public ConverterBase { +public: + ConverterSPCurve(SPCurve &curve) + : _curve(curve), _is_open(false) + {} ; + + virtual void moveto(double x, double y, bool is_open); + virtual void lineto(double x, double y); + virtual void quadto(double x1, double y1, double x2, double y2); + virtual void curveto(double x1, double y1, double x2, double y2, double x3, double y3); + + SPCurve &_curve; + bool _is_open; + +private: + ConverterSPCurve(const ConverterSPCurve&); + ConverterSPCurve& operator=(const ConverterSPCurve&); +}; + + +/** + * Converts Spiro to 2Geom's Path + */ +class ConverterPath : public ConverterBase { +public: + ConverterPath(Geom::Path &path) + : _path(path), _is_open(false) + {} ; + + virtual void moveto(double x, double y, bool is_open); + virtual void lineto(double x, double y); + virtual void quadto(double x1, double y1, double x2, double y2); + virtual void curveto(double x1, double y1, double x2, double y2, double x3, double y3); + + Geom::Path &_path; + bool _is_open; + +private: + ConverterPath(const ConverterPath&); + ConverterPath& operator=(const ConverterPath&); +}; + + +} // namespace Spiro + +#endif diff --git a/src/live_effects/spiro.cpp b/src/live_effects/spiro.cpp index e7824c297..e4b72793c 100644 --- a/src/live_effects/spiro.cpp +++ b/src/live_effects/spiro.cpp @@ -33,6 +33,24 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA #define SPIRO_SHOW_INFINITE_COORDINATE_CALLS +namespace Spiro { + +void spiro_run(const spiro_cp *src, int src_len, SPCurve &curve) +{ + spiro_seg *s = Spiro::run_spiro(src, src_len); + Spiro::ConverterSPCurve bc(curve); + Spiro::spiro_to_otherpath(s, src_len, bc); + free(s); +} + +void spiro_run(const spiro_cp *src, int src_len, Geom::Path &path) +{ + spiro_seg *s = Spiro::run_spiro(src, src_len); + Spiro::ConverterPath bc(path); + Spiro::spiro_to_otherpath(s, src_len, bc); + free(s); +} + /************************************ * Spiro math @@ -825,15 +843,15 @@ solve_spiro(spiro_seg *s, int nseg) } static void -spiro_seg_to_bpath(const double ks[4], +spiro_seg_to_otherpath(const double ks[4], double x0, double y0, double x1, double y1, - bezctx *bc, int depth) + ConverterBase &bc, int depth) { double bend = fabs(ks[0]) + fabs(.5 * ks[1]) + fabs(.125 * ks[2]) + fabs((1./48) * ks[3]); if (!bend > 1e-8) { - bc->lineto(bc, x1, y1); + bc.lineto(x1, y1); } else { double seg_ch = hypot(x1 - x0, y1 - y0); double seg_th = atan2(y1 - y0, x1 - x0); @@ -856,7 +874,7 @@ spiro_seg_to_bpath(const double ks[4], vl = (scale * (1./3)) * sin(th_even - th_odd); ur = (scale * (1./3)) * cos(th_even + th_odd); vr = (scale * (1./3)) * sin(th_even + th_odd); - bc->curveto(bc, x0 + ul, y0 + vl, x1 - ur, y1 - vr, x1, y1); + bc.curveto(x0 + ul, y0 + vl, x1 - ur, y1 - vr, x1, y1); } else { /* subdivide */ double ksub[4]; @@ -875,11 +893,11 @@ spiro_seg_to_bpath(const double ks[4], integrate_spiro(ksub, xysub); xmid = x0 + cth * xysub[0] - sth * xysub[1]; ymid = y0 + cth * xysub[1] + sth * xysub[0]; - spiro_seg_to_bpath(ksub, x0, y0, xmid, ymid, bc, depth + 1); + spiro_seg_to_otherpath(ksub, x0, y0, xmid, ymid, bc, depth + 1); ksub[0] += .25 * ks[1] + (1./384) * ks[3]; ksub[1] += .125 * ks[2]; ksub[2] += (1./16) * ks[3]; - spiro_seg_to_bpath(ksub, xmid, ymid, x1, y1, bc, depth + 1); + spiro_seg_to_otherpath(ksub, xmid, ymid, x1, y1, bc, depth + 1); } } } @@ -901,7 +919,7 @@ free_spiro(spiro_seg *s) } void -spiro_to_bpath(const spiro_seg *s, int n, bezctx *bc) +spiro_to_otherpath(const spiro_seg *s, int n, ConverterBase &bc) { int i; int nsegs = s[n - 1].ty == '}' ? n - 1 : n; @@ -912,9 +930,10 @@ spiro_to_bpath(const spiro_seg *s, int n, bezctx *bc) double x1 = s[i + 1].x; double y1 = s[i + 1].y; - if (i == 0) - bc->moveto(bc, x0, y0, s[0].ty == '{'); - spiro_seg_to_bpath(s[i].ks, x0, y0, x1, y1, bc, 0); + if (i == 0) { + bc.moveto(x0, y0, s[0].ty == '{'); + } + spiro_seg_to_otherpath(s[i].ks, x0, y0, x1, y1, bc, 0); } } @@ -933,75 +952,7 @@ get_knot_th(const spiro_seg *s, int i) } -/************************************ - * Conversion to Inkscape's curve - */ - -void bezctx_ink_moveto(bezctx *bc, double x, double y, int /*is_open*/) -{ - bezctx_ink *bi = (bezctx_ink *) bc; - if ( IS_FINITE(x) && IS_FINITE(y) ) { - bi->curve->moveto(x, y); - } -#ifdef SPIRO_SHOW_INFINITE_COORDINATE_CALLS - else { - g_message("Spiro: moveto not finite"); - } -#endif -} - -void bezctx_ink_lineto(bezctx *bc, double x, double y) -{ - bezctx_ink *bi = (bezctx_ink *) bc; - if ( IS_FINITE(x) && IS_FINITE(y) ) { - bi->curve->lineto(x, y); - } -#ifdef SPIRO_SHOW_INFINITE_COORDINATE_CALLS - else { - g_message("Spiro: lineto not finite"); - } -#endif -} - -void bezctx_ink_quadto(bezctx *bc, double xm, double ym, double x3, double y3) -{ - bezctx_ink *bi = (bezctx_ink *) bc; - - if ( IS_FINITE(xm) && IS_FINITE(ym) && IS_FINITE(x3) && IS_FINITE(y3) ) { - bi->curve->quadto(xm, ym, x3, y3); - } -#ifdef SPIRO_SHOW_INFINITE_COORDINATE_CALLS - else { - g_message("Spiro: quadto not finite"); - } -#endif -} - -void bezctx_ink_curveto(bezctx *bc, double x1, double y1, double x2, double y2, - double x3, double y3) -{ - bezctx_ink *bi = (bezctx_ink *) bc; - if ( IS_FINITE(x1) && IS_FINITE(y1) && IS_FINITE(x2) && IS_FINITE(y2) ) { - bi->curve->curveto(x1, y1, x2, y2, x3, y3); - } -#ifdef SPIRO_SHOW_INFINITE_COORDINATE_CALLS - else { - g_message("Spiro: curveto not finite"); - } -#endif -} - -bezctx * new_bezctx_ink(SPCurve *curve) -{ - bezctx_ink *result = g_new(bezctx_ink, 1); - result->base.moveto = bezctx_ink_moveto; - result->base.lineto = bezctx_ink_lineto; - result->base.quadto = bezctx_ink_quadto; - result->base.curveto = bezctx_ink_curveto; - result->curve = curve; - return &result->base; -} - +} // namespace Spiro /************************************ * Unit_test code @@ -1012,6 +963,8 @@ bezctx * new_bezctx_ink(SPCurve *curve) #include #include /* for gettimeofday */ +using namespace Spiro; + static double get_time (void) { diff --git a/src/live_effects/spiro.h b/src/live_effects/spiro.h index f39fbded6..0d85da74b 100644 --- a/src/live_effects/spiro.h +++ b/src/live_effects/spiro.h @@ -24,10 +24,14 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA #ifndef INKSCAPE_SPIRO_H #define INKSCAPE_SPIRO_H -#include "live_effects/bezctx.h" -#include "live_effects/bezctx_intf.h" +#include "live_effects/spiro-converters.h" class SPCurve; +namespace Geom { + class Path; +} + +namespace Spiro { typedef struct { double x; @@ -35,21 +39,18 @@ typedef struct { char ty; } spiro_cp; -typedef struct spiro_seg_s spiro_seg; +void spiro_run(const spiro_cp *src, int src_len, SPCurve &curve); +void spiro_run(const spiro_cp *src, int src_len, Geom::Path &path); + +/* the following methods are only for expert use: */ +typedef struct spiro_seg_s spiro_seg; spiro_seg * run_spiro(const spiro_cp *src, int n); void free_spiro(spiro_seg *s); -void spiro_to_bpath(const spiro_seg *s, int n, bezctx *bc); +void spiro_to_otherpath(const spiro_seg *s, int n, ConverterBase &bc); double get_knot_th(const spiro_seg *s, int i); -typedef struct { - bezctx base; - SPCurve *curve; - int is_open; -} bezctx_ink; - -bezctx * new_bezctx_ink(SPCurve *curve); - +} // namespace Spiro #endif // INKSCAPE_SPIRO_H \ No newline at end of file -- cgit v1.2.3 From 4f1b7ec0d0ba21d3c81ce63e3a49f48736a67feb Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Fri, 23 Mar 2012 22:07:34 +0100 Subject: final cleanup of spiro? (bzr r11124) --- src/live_effects/spiro-converters.cpp | 123 ++++++++++++++++++++++++++++++++++ src/live_effects/spiro-converters.h | 10 ++- 2 files changed, 127 insertions(+), 6 deletions(-) create mode 100644 src/live_effects/spiro-converters.cpp diff --git a/src/live_effects/spiro-converters.cpp b/src/live_effects/spiro-converters.cpp new file mode 100644 index 000000000..3c7bdf99e --- /dev/null +++ b/src/live_effects/spiro-converters.cpp @@ -0,0 +1,123 @@ +/* Authors: + * Johan Engelen + * + * Copyright (C) 2010-2012 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "spiro-converters.h" +#include <2geom/path.h> +#include "display/curve.h" +#include + +#define SPIRO_SHOW_INFINITE_COORDINATE_CALLS +#ifdef SPIRO_SHOW_INFINITE_COORDINATE_CALLS +# define SPIRO_G_MESSAGE(x) g_message(x) +#else +# define SPIRO_G_MESSAGE(x) +#endif + +namespace Spiro { + +void +ConverterSPCurve::moveto(double x, double y, bool is_open) +{ + if ( IS_FINITE(x) && IS_FINITE(y) ) { + _curve.moveto(x, y); + if (!is_open) { + _curve.closepath(); + } + } else { + SPIRO_G_MESSAGE("Spiro: moveto not finite"); + } +} + +void +ConverterSPCurve::lineto(double x, double y) +{ + if ( IS_FINITE(x) && IS_FINITE(y) ) { + _curve.lineto(x, y); + } else { + SPIRO_G_MESSAGE("Spiro: lineto not finite"); + } +} + +void +ConverterSPCurve::quadto(double xm, double ym, double x3, double y3) +{ + if ( IS_FINITE(xm) && IS_FINITE(ym) && IS_FINITE(x3) && IS_FINITE(y3) ) { + _curve.quadto(xm, ym, x3, y3); + } else { + SPIRO_G_MESSAGE("Spiro: quadto not finite"); + } +} + +void +ConverterSPCurve::curveto(double x1, double y1, double x2, double y2, double x3, double y3) +{ + if ( IS_FINITE(x1) && IS_FINITE(y1) && IS_FINITE(x2) && IS_FINITE(y2) ) { + _curve.curveto(x1, y1, x2, y2, x3, y3); + } else { + SPIRO_G_MESSAGE("Spiro: curveto not finite"); + } +} + + + + +void +ConverterPath::moveto(double x, double y, bool is_open) +{ + if ( IS_FINITE(x) && IS_FINITE(y) ) { + _path.start(Geom::Point(x, y)); + _path.close(!is_open); + } else { + SPIRO_G_MESSAGE("spiro moveto not finite"); + } +} + +void +ConverterPath::lineto(double x, double y) +{ + if ( IS_FINITE(x) && IS_FINITE(y) ) { + _path.appendNew( Geom::Point(x, y) ); + } else { + SPIRO_G_MESSAGE("spiro lineto not finite"); + } +} + +void +ConverterPath::quadto(double xm, double ym, double x3, double y3) +{ + if ( IS_FINITE(xm) && IS_FINITE(ym) && IS_FINITE(x3) && IS_FINITE(y3) ) { + _path.appendNew(Geom::Point(xm, ym), Geom::Point(x3, y3)); + } else { + SPIRO_G_MESSAGE("spiro quadto not finite"); + } +} + +void +ConverterPath::curveto(double x1, double y1, double x2, double y2, double x3, double y3) +{ + if ( IS_FINITE(x1) && IS_FINITE(y1) && IS_FINITE(x2) && IS_FINITE(y2) ) { + _path.appendNew(Geom::Point(x1, y1), Geom::Point(x2, y2), Geom::Point(x3, y3)); + } else { + SPIRO_G_MESSAGE("spiro curveto not finite"); + } +} + +} // namespace Spiro + + + +/* + 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 : diff --git a/src/live_effects/spiro-converters.h b/src/live_effects/spiro-converters.h index dbc10efda..83f6ebbc3 100644 --- a/src/live_effects/spiro-converters.h +++ b/src/live_effects/spiro-converters.h @@ -24,7 +24,7 @@ public: class ConverterSPCurve : public ConverterBase { public: ConverterSPCurve(SPCurve &curve) - : _curve(curve), _is_open(false) + : _curve(curve) {} ; virtual void moveto(double x, double y, bool is_open); @@ -32,10 +32,9 @@ public: virtual void quadto(double x1, double y1, double x2, double y2); virtual void curveto(double x1, double y1, double x2, double y2, double x3, double y3); +private: SPCurve &_curve; - bool _is_open; -private: ConverterSPCurve(const ConverterSPCurve&); ConverterSPCurve& operator=(const ConverterSPCurve&); }; @@ -47,7 +46,7 @@ private: class ConverterPath : public ConverterBase { public: ConverterPath(Geom::Path &path) - : _path(path), _is_open(false) + : _path(path) {} ; virtual void moveto(double x, double y, bool is_open); @@ -55,10 +54,9 @@ public: virtual void quadto(double x1, double y1, double x2, double y2); virtual void curveto(double x1, double y1, double x2, double y2, double x3, double y3); +private: Geom::Path &_path; - bool _is_open; -private: ConverterPath(const ConverterPath&); ConverterPath& operator=(const ConverterPath&); }; -- cgit v1.2.3 From da7fae5bb65071a4f90505799d74ef937cb275f1 Mon Sep 17 00:00:00 2001 From: John Smith Date: Sat, 24 Mar 2012 14:24:22 +0900 Subject: Fix for 251674 and 592323 : Make CloneTiler dialog dockable (bzr r11125) --- src/dialogs/CMakeLists.txt | 2 - src/dialogs/Makefile_insert | 2 - src/dialogs/clonetiler.cpp | 2916 -------------------------------------- src/dialogs/clonetiler.h | 30 - src/ui/CMakeLists.txt | 2 + src/ui/dialog/Makefile_insert | 2 + src/ui/dialog/clonetiler.cpp | 2833 ++++++++++++++++++++++++++++++++++++ src/ui/dialog/clonetiler.h | 183 +++ src/ui/dialog/dialog-manager.cpp | 3 + src/verbs.cpp | 5 +- 10 files changed, 3026 insertions(+), 2952 deletions(-) delete mode 100644 src/dialogs/clonetiler.cpp delete mode 100644 src/dialogs/clonetiler.h create mode 100644 src/ui/dialog/clonetiler.cpp create mode 100644 src/ui/dialog/clonetiler.h diff --git a/src/dialogs/CMakeLists.txt b/src/dialogs/CMakeLists.txt index 7af6f2ede..1cd230a08 100644 --- a/src/dialogs/CMakeLists.txt +++ b/src/dialogs/CMakeLists.txt @@ -1,12 +1,10 @@ set(dialogs_SRC - clonetiler.cpp dialog-events.cpp find.cpp # ------- # Headers - clonetiler.h dialog-events.h find.h ) diff --git a/src/dialogs/Makefile_insert b/src/dialogs/Makefile_insert index ac0792a73..62641ecb9 100644 --- a/src/dialogs/Makefile_insert +++ b/src/dialogs/Makefile_insert @@ -1,8 +1,6 @@ ## Makefile.am fragment sourced by src/Makefile.am. ink_common_sources += \ - dialogs/clonetiler.cpp \ - dialogs/clonetiler.h \ dialogs/dialog-events.cpp \ dialogs/dialog-events.h \ dialogs/find.cpp \ diff --git a/src/dialogs/clonetiler.cpp b/src/dialogs/clonetiler.cpp deleted file mode 100644 index c56abc21a..000000000 --- a/src/dialogs/clonetiler.cpp +++ /dev/null @@ -1,2916 +0,0 @@ -/** @file - * Clone tiling dialog - */ -/* Authors: - * bulia byak - * Johan Engelen - * Jon A. Cruz - * Abhishek Sharma - * Romain de Bossoreille - * - * Copyright (C) 2004-2011 Authors - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include - -#include "ui/widget/color-picker.h" - -#include -#include -#include <2geom/transforms.h> -#include - -#include "desktop.h" -#include "desktop-handles.h" -#include "dialog-events.h" -#include "display/cairo-utils.h" -#include "display/drawing.h" -#include "display/drawing-context.h" -#include "display/drawing-item.h" -#include "document.h" -#include "document-undo.h" -#include "filter-chemistry.h" -#include "helper/unit-menu.h" -#include "helper/units.h" -#include "helper/window.h" -#include "inkscape.h" -#include "interface.h" -#include "macros.h" -#include "message-stack.h" -#include "preferences.h" -#include "selection.h" -#include "sp-filter.h" -#include "sp-namedview.h" -#include "sp-use.h" -#include "style.h" -#include "svg/svg-color.h" -#include "svg/svg.h" -#include "ui/icon-names.h" -#include "ui/widget/spinbutton.h" -#include "unclump.h" -#include "verbs.h" -#include "widgets/icon.h" -#include "xml/repr.h" -#include "sp-root.h" - -#include - -using Inkscape::DocumentUndo; - -#define MIN_ONSCREEN_DISTANCE 50 - -static GtkWidget *dlg = NULL; -static win_data wd; - -// impossible original values to make sure they are read from prefs -static gint x = -1000, y = -1000, w = 0, h = 0; -static Glib::ustring const prefs_path = "/dialogs/clonetiler/"; - -#define SB_MARGIN 1 -#define VB_MARGIN 4 - -enum { - PICK_COLOR, - PICK_OPACITY, - PICK_R, - PICK_G, - PICK_B, - PICK_H, - PICK_S, - PICK_L -}; - -static GtkSizeGroup* table_row_labels = NULL; - -static sigc::connection _shutdown_connection; -static sigc::connection _dialogs_hidden_connection; -static sigc::connection _dialogs_unhidden_connection; -static sigc::connection _desktop_activated_connection; -static sigc::connection _color_changed_connection; - -static Inkscape::UI::Widget::ColorPicker *color_picker; - -static void clonetiler_dialog_destroy(GtkObject */*object*/, gpointer /*data*/) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setInt(prefs_path + "visible", 0); - - sp_signal_disconnect_by_data (INKSCAPE, dlg); - _color_changed_connection.disconnect(); - - delete color_picker; - - wd.win = dlg = NULL; - wd.stop = 0; - -} - -static gboolean clonetiler_dialog_delete(GtkObject */*object*/, GdkEvent * /*event*/, gpointer /*data*/) -{ - gtk_window_get_position ((GtkWindow *) dlg, &x, &y); - gtk_window_get_size ((GtkWindow *) dlg, &w, &h); - - if (x < 0) { - x = 0; - } - if (y < 0) { - y = 0; - } - - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setInt(prefs_path + "x", x); - prefs->setInt(prefs_path + "y", y); - prefs->setInt(prefs_path + "w", w); - prefs->setInt(prefs_path + "h", h); - - return FALSE; // which means, go ahead and destroy it - -} - -static void on_picker_color_changed(guint rgba) -{ - static bool is_updating = false; - if (is_updating || !SP_ACTIVE_DESKTOP) - return; - - is_updating = true; - - gchar c[32]; - sp_svg_write_color(c, sizeof(c), rgba); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setString(prefs_path + "initial_color", c); - - is_updating = false; -} - -static guint clonetiler_number_of_clones(SPObject *obj); - -static void clonetiler_change_selection(Inkscape::Application * /*inkscape*/, Inkscape::Selection *selection, GtkWidget *dlg) -{ - GtkWidget *buttons = (GtkWidget *) g_object_get_data (G_OBJECT(dlg), "buttons_on_tiles"); - GtkWidget *status = (GtkWidget *) g_object_get_data (G_OBJECT(dlg), "status"); - - if (selection->isEmpty()) { - gtk_widget_set_sensitive (buttons, FALSE); - gtk_label_set_markup (GTK_LABEL(status), _("Nothing selected.")); - return; - } - - if (g_slist_length ((GSList *) selection->itemList()) > 1) { - gtk_widget_set_sensitive (buttons, FALSE); - gtk_label_set_markup (GTK_LABEL(status), _("More than one object selected.")); - return; - } - - guint n = clonetiler_number_of_clones(selection->singleItem()); - if (n > 0) { - gtk_widget_set_sensitive (buttons, TRUE); - gchar *sta = g_strdup_printf (_("Object has %d tiled clones."), n); - gtk_label_set_markup (GTK_LABEL(status), sta); - g_free (sta); - } else { - gtk_widget_set_sensitive (buttons, FALSE); - gtk_label_set_markup (GTK_LABEL(status), _("Object has no tiled clones.")); - } -} - -static void clonetiler_external_change(Inkscape::Application * /*inkscape*/, GtkWidget *dlg) -{ - clonetiler_change_selection (NULL, sp_desktop_selection(SP_ACTIVE_DESKTOP), dlg); -} - -static void clonetiler_disconnect_gsignal(GObject *widget, gpointer source) -{ - if (source && G_IS_OBJECT(source)) { - sp_signal_disconnect_by_data (source, widget); - } -} - - -enum { - TILE_P1, - TILE_P2, - TILE_PM, - TILE_PG, - TILE_CM, - TILE_PMM, - TILE_PMG, - TILE_PGG, - TILE_CMM, - TILE_P4, - TILE_P4M, - TILE_P4G, - TILE_P3, - TILE_P31M, - TILE_P3M1, - TILE_P6, - TILE_P6M -}; - - -static Geom::Affine clonetiler_get_transform( - // symmetry group - int type, - - // row, column - int i, int j, - - // center, width, height of the tile - double cx, double cy, - double w, double h, - - // values from the dialog: - // Shift - double shiftx_per_i, double shifty_per_i, - double shiftx_per_j, double shifty_per_j, - double shiftx_rand, double shifty_rand, - double shiftx_exp, double shifty_exp, - int shiftx_alternate, int shifty_alternate, - int shiftx_cumulate, int shifty_cumulate, - int shiftx_excludew, int shifty_excludeh, - - // Scale - double scalex_per_i, double scaley_per_i, - double scalex_per_j, double scaley_per_j, - double scalex_rand, double scaley_rand, - double scalex_exp, double scaley_exp, - double scalex_log, double scaley_log, - int scalex_alternate, int scaley_alternate, - int scalex_cumulate, int scaley_cumulate, - - // Rotation - double rotate_per_i, double rotate_per_j, - double rotate_rand, - int rotate_alternatei, int rotate_alternatej, - int rotate_cumulatei, int rotate_cumulatej - ) -{ - - // Shift (in units of tile width or height) ------------- - double delta_shifti = 0.0; - double delta_shiftj = 0.0; - - if( shiftx_alternate ) { - delta_shifti = (double)(i%2); - } else { - if( shiftx_cumulate ) { // Should the delta shifts be cumulative (i.e. 1, 1+2, 1+2+3, ...) - delta_shifti = (double)(i*i); - } else { - delta_shifti = (double)i; - } - } - - if( shifty_alternate ) { - delta_shiftj = (double)(j%2); - } else { - if( shifty_cumulate ) { - delta_shiftj = (double)(j*j); - } else { - delta_shiftj = (double)j; - } - } - - // Random shift, only calculate if non-zero. - double delta_shiftx_rand = 0.0; - double delta_shifty_rand = 0.0; - if( shiftx_rand != 0.0 ) delta_shiftx_rand = shiftx_rand * g_random_double_range (-1, 1); - if( shifty_rand != 0.0 ) delta_shifty_rand = shifty_rand * g_random_double_range (-1, 1); - - - // Delta shift (units of tile width/height) - double di = shiftx_per_i * delta_shifti + shiftx_per_j * delta_shiftj + delta_shiftx_rand; - double dj = shifty_per_i * delta_shifti + shifty_per_j * delta_shiftj + delta_shifty_rand; - - // Shift in actual x and y, used below - double dx = w * di; - double dy = h * dj; - - double shifti = di; - double shiftj = dj; - - // Include tile width and height in shift if required - if( !shiftx_excludew ) shifti += i; - if( !shifty_excludeh ) shiftj += j; - - // Add exponential shift if necessary - if ( shiftx_exp != 1.0 ) shifti = pow( shifti, shiftx_exp ); - if ( shifty_exp != 1.0 ) shiftj = pow( shiftj, shifty_exp ); - - // Final shift - Geom::Affine rect_translate (Geom::Translate (w * shifti, h * shiftj)); - - // Rotation (in degrees) ------------ - double delta_rotationi = 0.0; - double delta_rotationj = 0.0; - - if( rotate_alternatei ) { - delta_rotationi = (double)(i%2); - } else { - if( rotate_cumulatei ) { - delta_rotationi = (double)(i*i + i)/2.0; - } else { - delta_rotationi = (double)i; - } - } - - if( rotate_alternatej ) { - delta_rotationj = (double)(j%2); - } else { - if( rotate_cumulatej ) { - delta_rotationj = (double)(j*j + j)/2.0; - } else { - delta_rotationj = (double)j; - } - } - - double delta_rotate_rand = 0.0; - if( rotate_rand != 0.0 ) delta_rotate_rand = rotate_rand * 180.0 * g_random_double_range (-1, 1); - - double dr = rotate_per_i * delta_rotationi + rotate_per_j * delta_rotationj + delta_rotate_rand; - - // Scale (times the original) ----------- - double delta_scalei = 0.0; - double delta_scalej = 0.0; - - if( scalex_alternate ) { - delta_scalei = (double)(i%2); - } else { - if( scalex_cumulate ) { // Should the delta scales be cumulative (i.e. 1, 1+2, 1+2+3, ...) - delta_scalei = (double)(i*i + i)/2.0; - } else { - delta_scalei = (double)i; - } - } - - if( scaley_alternate ) { - delta_scalej = (double)(j%2); - } else { - if( scaley_cumulate ) { - delta_scalej = (double)(j*j + j)/2.0; - } else { - delta_scalej = (double)j; - } - } - - // Random scale, only calculate if non-zero. - double delta_scalex_rand = 0.0; - double delta_scaley_rand = 0.0; - if( scalex_rand != 0.0 ) delta_scalex_rand = scalex_rand * g_random_double_range (-1, 1); - if( scaley_rand != 0.0 ) delta_scaley_rand = scaley_rand * g_random_double_range (-1, 1); - // But if random factors are same, scale x and y proportionally - if( scalex_rand == scaley_rand ) delta_scalex_rand = delta_scaley_rand; - - // Total delta scale - double scalex = 1.0 + scalex_per_i * delta_scalei + scalex_per_j * delta_scalej + delta_scalex_rand; - double scaley = 1.0 + scaley_per_i * delta_scalei + scaley_per_j * delta_scalej + delta_scaley_rand; - - if( scalex < 0.0 ) scalex = 0.0; - if( scaley < 0.0 ) scaley = 0.0; - - // Add exponential scale if necessary - if ( scalex_exp != 1.0 ) scalex = pow( scalex, scalex_exp ); - if ( scaley_exp != 1.0 ) scaley = pow( scaley, scaley_exp ); - - // Add logarithmic factor if necessary - if ( scalex_log > 0.0 ) scalex = pow( scalex_log, scalex - 1.0 ); - if ( scaley_log > 0.0 ) scaley = pow( scaley_log, scaley - 1.0 ); - // Alternative using rotation angle - //if ( scalex_log != 1.0 ) scalex *= pow( scalex_log, M_PI*dr/180 ); - //if ( scaley_log != 1.0 ) scaley *= pow( scaley_log, M_PI*dr/180 ); - - - // Calculate transformation matrices, translating back to "center of tile" (rotation center) before transforming - Geom::Affine drot_c = Geom::Translate(-cx, -cy) * Geom::Rotate (M_PI*dr/180) * Geom::Translate(cx, cy); - - Geom::Affine dscale_c = Geom::Translate(-cx, -cy) * Geom::Scale (scalex, scaley) * Geom::Translate(cx, cy); - - Geom::Affine d_s_r = dscale_c * drot_c; - - Geom::Affine rotate_180_c = Geom::Translate(-cx, -cy) * Geom::Rotate (M_PI) * Geom::Translate(cx, cy); - - Geom::Affine rotate_90_c = Geom::Translate(-cx, -cy) * Geom::Rotate (-M_PI/2) * Geom::Translate(cx, cy); - Geom::Affine rotate_m90_c = Geom::Translate(-cx, -cy) * Geom::Rotate ( M_PI/2) * Geom::Translate(cx, cy); - - Geom::Affine rotate_120_c = Geom::Translate(-cx, -cy) * Geom::Rotate (-2*M_PI/3) * Geom::Translate(cx, cy); - Geom::Affine rotate_m120_c = Geom::Translate(-cx, -cy) * Geom::Rotate ( 2*M_PI/3) * Geom::Translate(cx, cy); - - Geom::Affine rotate_60_c = Geom::Translate(-cx, -cy) * Geom::Rotate (-M_PI/3) * Geom::Translate(cx, cy); - Geom::Affine rotate_m60_c = Geom::Translate(-cx, -cy) * Geom::Rotate ( M_PI/3) * Geom::Translate(cx, cy); - - Geom::Affine flip_x = Geom::Translate(-cx, -cy) * Geom::Scale (-1, 1) * Geom::Translate(cx, cy); - Geom::Affine flip_y = Geom::Translate(-cx, -cy) * Geom::Scale (1, -1) * Geom::Translate(cx, cy); - - - // Create tile with required symmetry - const double cos60 = cos(M_PI/3); - const double sin60 = sin(M_PI/3); - const double cos30 = cos(M_PI/6); - const double sin30 = sin(M_PI/6); - - switch (type) { - - case TILE_P1: - return d_s_r * rect_translate; - break; - - case TILE_P2: - if (i % 2 == 0) { - return d_s_r * rect_translate; - } else { - return d_s_r * rotate_180_c * rect_translate; - } - break; - - case TILE_PM: - if (i % 2 == 0) { - return d_s_r * rect_translate; - } else { - return d_s_r * flip_x * rect_translate; - } - break; - - case TILE_PG: - if (j % 2 == 0) { - return d_s_r * rect_translate; - } else { - return d_s_r * flip_x * rect_translate; - } - break; - - case TILE_CM: - if ((i + j) % 2 == 0) { - return d_s_r * rect_translate; - } else { - return d_s_r * flip_x * rect_translate; - } - break; - - case TILE_PMM: - if (j % 2 == 0) { - if (i % 2 == 0) { - return d_s_r * rect_translate; - } else { - return d_s_r * flip_x * rect_translate; - } - } else { - if (i % 2 == 0) { - return d_s_r * flip_y * rect_translate; - } else { - return d_s_r * flip_x * flip_y * rect_translate; - } - } - break; - - case TILE_PMG: - if (j % 2 == 0) { - if (i % 2 == 0) { - return d_s_r * rect_translate; - } else { - return d_s_r * rotate_180_c * rect_translate; - } - } else { - if (i % 2 == 0) { - return d_s_r * flip_y * rect_translate; - } else { - return d_s_r * rotate_180_c * flip_y * rect_translate; - } - } - break; - - case TILE_PGG: - if (j % 2 == 0) { - if (i % 2 == 0) { - return d_s_r * rect_translate; - } else { - return d_s_r * flip_y * rect_translate; - } - } else { - if (i % 2 == 0) { - return d_s_r * rotate_180_c * rect_translate; - } else { - return d_s_r * rotate_180_c * flip_y * rect_translate; - } - } - break; - - case TILE_CMM: - if (j % 4 == 0) { - if (i % 2 == 0) { - return d_s_r * rect_translate; - } else { - return d_s_r * flip_x * rect_translate; - } - } else if (j % 4 == 1) { - if (i % 2 == 0) { - return d_s_r * flip_y * rect_translate; - } else { - return d_s_r * flip_x * flip_y * rect_translate; - } - } else if (j % 4 == 2) { - if (i % 2 == 1) { - return d_s_r * rect_translate; - } else { - return d_s_r * flip_x * rect_translate; - } - } else { - if (i % 2 == 1) { - return d_s_r * flip_y * rect_translate; - } else { - return d_s_r * flip_x * flip_y * rect_translate; - } - } - break; - - case TILE_P4: - { - Geom::Affine ori (Geom::Translate ((w + h) * pow((i/2), shiftx_exp) + dx, (h + w) * pow((j/2), shifty_exp) + dy)); - Geom::Affine dia1 (Geom::Translate (w/2 + h/2, -h/2 + w/2)); - Geom::Affine dia2 (Geom::Translate (-w/2 + h/2, h/2 + w/2)); - if (j % 2 == 0) { - if (i % 2 == 0) { - return d_s_r * ori; - } else { - return d_s_r * rotate_m90_c * dia1 * ori; - } - } else { - if (i % 2 == 0) { - return d_s_r * rotate_90_c * dia2 * ori; - } else { - return d_s_r * rotate_180_c * dia1 * dia2 * ori; - } - } - } - break; - - case TILE_P4M: - { - double max = MAX(w, h); - Geom::Affine ori (Geom::Translate ((max + max) * pow((i/4), shiftx_exp) + dx, (max + max) * pow((j/2), shifty_exp) + dy)); - Geom::Affine dia1 (Geom::Translate ( w/2 - h/2, h/2 - w/2)); - Geom::Affine dia2 (Geom::Translate (-h/2 + w/2, w/2 - h/2)); - if (j % 2 == 0) { - if (i % 4 == 0) { - return d_s_r * ori; - } else if (i % 4 == 1) { - return d_s_r * flip_y * rotate_m90_c * dia1 * ori; - } else if (i % 4 == 2) { - return d_s_r * rotate_m90_c * dia1 * Geom::Translate (h, 0) * ori; - } else if (i % 4 == 3) { - return d_s_r * flip_x * Geom::Translate (w, 0) * ori; - } - } else { - if (i % 4 == 0) { - return d_s_r * flip_y * Geom::Translate(0, h) * ori; - } else if (i % 4 == 1) { - return d_s_r * rotate_90_c * dia2 * Geom::Translate(0, h) * ori; - } else if (i % 4 == 2) { - return d_s_r * flip_y * rotate_90_c * dia2 * Geom::Translate(h, 0) * Geom::Translate(0, h) * ori; - } else if (i % 4 == 3) { - return d_s_r * flip_y * flip_x * Geom::Translate(w, 0) * Geom::Translate(0, h) * ori; - } - } - } - break; - - case TILE_P4G: - { - double max = MAX(w, h); - Geom::Affine ori (Geom::Translate ((max + max) * pow((i/4), shiftx_exp) + dx, (max + max) * pow(j, shifty_exp) + dy)); - Geom::Affine dia1 (Geom::Translate ( w/2 + h/2, h/2 - w/2)); - Geom::Affine dia2 (Geom::Translate (-h/2 + w/2, w/2 + h/2)); - if (((i/4) + j) % 2 == 0) { - if (i % 4 == 0) { - return d_s_r * ori; - } else if (i % 4 == 1) { - return d_s_r * rotate_m90_c * dia1 * ori; - } else if (i % 4 == 2) { - return d_s_r * rotate_90_c * dia2 * ori; - } else if (i % 4 == 3) { - return d_s_r * rotate_180_c * dia1 * dia2 * ori; - } - } else { - if (i % 4 == 0) { - return d_s_r * flip_y * Geom::Translate (0, h) * ori; - } else if (i % 4 == 1) { - return d_s_r * flip_y * rotate_m90_c * dia1 * Geom::Translate (-h, 0) * ori; - } else if (i % 4 == 2) { - return d_s_r * flip_y * rotate_90_c * dia2 * Geom::Translate (h, 0) * ori; - } else if (i % 4 == 3) { - return d_s_r * flip_x * Geom::Translate (w, 0) * ori; - } - } - } - break; - - case TILE_P3: - { - double width; - double height; - Geom::Affine dia1; - Geom::Affine dia2; - if (w > h) { - width = w + w * cos60; - height = 2 * w * sin60; - dia1 = Geom::Affine (Geom::Translate (w/2 + w/2 * cos60, -(w/2 * sin60))); - dia2 = dia1 * Geom::Affine (Geom::Translate (0, 2 * (w/2 * sin60))); - } else { - width = h * cos (M_PI/6); - height = h; - dia1 = Geom::Affine (Geom::Translate (h/2 * cos30, -(h/2 * sin30))); - dia2 = dia1 * Geom::Affine (Geom::Translate (0, h/2)); - } - Geom::Affine ori (Geom::Translate (width * pow((2*(i/3) + j%2), shiftx_exp) + dx, (height/2) * pow(j, shifty_exp) + dy)); - if (i % 3 == 0) { - return d_s_r * ori; - } else if (i % 3 == 1) { - return d_s_r * rotate_m120_c * dia1 * ori; - } else if (i % 3 == 2) { - return d_s_r * rotate_120_c * dia2 * ori; - } - } - break; - - case TILE_P31M: - { - Geom::Affine ori; - Geom::Affine dia1; - Geom::Affine dia2; - Geom::Affine dia3; - Geom::Affine dia4; - if (w > h) { - ori = Geom::Affine(Geom::Translate (w * pow((i/6) + 0.5*(j%2), shiftx_exp) + dx, (w * cos30) * pow(j, shifty_exp) + dy)); - dia1 = Geom::Affine (Geom::Translate (0, h/2) * Geom::Translate (w/2, 0) * Geom::Translate (w/2 * cos60, -w/2 * sin60) * Geom::Translate (-h/2 * cos30, -h/2 * sin30) ); - dia2 = dia1 * Geom::Affine (Geom::Translate (h * cos30, h * sin30)); - dia3 = dia2 * Geom::Affine (Geom::Translate (0, 2 * (w/2 * sin60 - h/2 * sin30))); - dia4 = dia3 * Geom::Affine (Geom::Translate (-h * cos30, h * sin30)); - } else { - ori = Geom::Affine (Geom::Translate (2*h * cos30 * pow((i/6 + 0.5*(j%2)), shiftx_exp) + dx, (2*h - h * sin30) * pow(j, shifty_exp) + dy)); - dia1 = Geom::Affine (Geom::Translate (0, -h/2) * Geom::Translate (h/2 * cos30, h/2 * sin30)); - dia2 = dia1 * Geom::Affine (Geom::Translate (h * cos30, h * sin30)); - dia3 = dia2 * Geom::Affine (Geom::Translate (0, h/2)); - dia4 = dia3 * Geom::Affine (Geom::Translate (-h * cos30, h * sin30)); - } - if (i % 6 == 0) { - return d_s_r * ori; - } else if (i % 6 == 1) { - return d_s_r * flip_y * rotate_m120_c * dia1 * ori; - } else if (i % 6 == 2) { - return d_s_r * rotate_m120_c * dia2 * ori; - } else if (i % 6 == 3) { - return d_s_r * flip_y * rotate_120_c * dia3 * ori; - } else if (i % 6 == 4) { - return d_s_r * rotate_120_c * dia4 * ori; - } else if (i % 6 == 5) { - return d_s_r * flip_y * Geom::Translate(0, h) * ori; - } - } - break; - - case TILE_P3M1: - { - double width; - double height; - Geom::Affine dia1; - Geom::Affine dia2; - Geom::Affine dia3; - Geom::Affine dia4; - if (w > h) { - width = w + w * cos60; - height = 2 * w * sin60; - dia1 = Geom::Affine (Geom::Translate (0, h/2) * Geom::Translate (w/2, 0) * Geom::Translate (w/2 * cos60, -w/2 * sin60) * Geom::Translate (-h/2 * cos30, -h/2 * sin30) ); - dia2 = dia1 * Geom::Affine (Geom::Translate (h * cos30, h * sin30)); - dia3 = dia2 * Geom::Affine (Geom::Translate (0, 2 * (w/2 * sin60 - h/2 * sin30))); - dia4 = dia3 * Geom::Affine (Geom::Translate (-h * cos30, h * sin30)); - } else { - width = 2 * h * cos (M_PI/6); - height = 2 * h; - dia1 = Geom::Affine (Geom::Translate (0, -h/2) * Geom::Translate (h/2 * cos30, h/2 * sin30)); - dia2 = dia1 * Geom::Affine (Geom::Translate (h * cos30, h * sin30)); - dia3 = dia2 * Geom::Affine (Geom::Translate (0, h/2)); - dia4 = dia3 * Geom::Affine (Geom::Translate (-h * cos30, h * sin30)); - } - Geom::Affine ori (Geom::Translate (width * pow((2*(i/6) + j%2), shiftx_exp) + dx, (height/2) * pow(j, shifty_exp) + dy)); - if (i % 6 == 0) { - return d_s_r * ori; - } else if (i % 6 == 1) { - return d_s_r * flip_y * rotate_m120_c * dia1 * ori; - } else if (i % 6 == 2) { - return d_s_r * rotate_m120_c * dia2 * ori; - } else if (i % 6 == 3) { - return d_s_r * flip_y * rotate_120_c * dia3 * ori; - } else if (i % 6 == 4) { - return d_s_r * rotate_120_c * dia4 * ori; - } else if (i % 6 == 5) { - return d_s_r * flip_y * Geom::Translate(0, h) * ori; - } - } - break; - - case TILE_P6: - { - Geom::Affine ori; - Geom::Affine dia1; - Geom::Affine dia2; - Geom::Affine dia3; - Geom::Affine dia4; - Geom::Affine dia5; - if (w > h) { - ori = Geom::Affine(Geom::Translate (w * pow((2*(i/6) + (j%2)), shiftx_exp) + dx, (2*w * sin60) * pow(j, shifty_exp) + dy)); - dia1 = Geom::Affine (Geom::Translate (w/2 * cos60, -w/2 * sin60)); - dia2 = dia1 * Geom::Affine (Geom::Translate (w/2, 0)); - dia3 = dia2 * Geom::Affine (Geom::Translate (w/2 * cos60, w/2 * sin60)); - dia4 = dia3 * Geom::Affine (Geom::Translate (-w/2 * cos60, w/2 * sin60)); - dia5 = dia4 * Geom::Affine (Geom::Translate (-w/2, 0)); - } else { - ori = Geom::Affine(Geom::Translate (2*h * cos30 * pow((i/6 + 0.5*(j%2)), shiftx_exp) + dx, (h + h * sin30) * pow(j, shifty_exp) + dy)); - dia1 = Geom::Affine (Geom::Translate (-w/2, -h/2) * Geom::Translate (h/2 * cos30, -h/2 * sin30) * Geom::Translate (w/2 * cos60, w/2 * sin60)); - dia2 = dia1 * Geom::Affine (Geom::Translate (-w/2 * cos60, -w/2 * sin60) * Geom::Translate (h/2 * cos30, -h/2 * sin30) * Geom::Translate (h/2 * cos30, h/2 * sin30) * Geom::Translate (-w/2 * cos60, w/2 * sin60)); - dia3 = dia2 * Geom::Affine (Geom::Translate (w/2 * cos60, -w/2 * sin60) * Geom::Translate (h/2 * cos30, h/2 * sin30) * Geom::Translate (-w/2, h/2)); - dia4 = dia3 * dia1.inverse(); - dia5 = dia3 * dia2.inverse(); - } - if (i % 6 == 0) { - return d_s_r * ori; - } else if (i % 6 == 1) { - return d_s_r * rotate_m60_c * dia1 * ori; - } else if (i % 6 == 2) { - return d_s_r * rotate_m120_c * dia2 * ori; - } else if (i % 6 == 3) { - return d_s_r * rotate_180_c * dia3 * ori; - } else if (i % 6 == 4) { - return d_s_r * rotate_120_c * dia4 * ori; - } else if (i % 6 == 5) { - return d_s_r * rotate_60_c * dia5 * ori; - } - } - break; - - case TILE_P6M: - { - - Geom::Affine ori; - Geom::Affine dia1, dia2, dia3, dia4, dia5, dia6, dia7, dia8, dia9, dia10; - if (w > h) { - ori = Geom::Affine(Geom::Translate (w * pow((2*(i/12) + (j%2)), shiftx_exp) + dx, (2*w * sin60) * pow(j, shifty_exp) + dy)); - dia1 = Geom::Affine (Geom::Translate (w/2, h/2) * Geom::Translate (-w/2 * cos60, -w/2 * sin60) * Geom::Translate (-h/2 * cos30, h/2 * sin30)); - dia2 = dia1 * Geom::Affine (Geom::Translate (h * cos30, -h * sin30)); - dia3 = dia2 * Geom::Affine (Geom::Translate (-h/2 * cos30, h/2 * sin30) * Geom::Translate (w * cos60, 0) * Geom::Translate (-h/2 * cos30, -h/2 * sin30)); - dia4 = dia3 * Geom::Affine (Geom::Translate (h * cos30, h * sin30)); - dia5 = dia4 * Geom::Affine (Geom::Translate (-h/2 * cos30, -h/2 * sin30) * Geom::Translate (-w/2 * cos60, w/2 * sin60) * Geom::Translate (w/2, -h/2)); - dia6 = dia5 * Geom::Affine (Geom::Translate (0, h)); - dia7 = dia6 * dia1.inverse(); - dia8 = dia6 * dia2.inverse(); - dia9 = dia6 * dia3.inverse(); - dia10 = dia6 * dia4.inverse(); - } else { - ori = Geom::Affine(Geom::Translate (4*h * cos30 * pow((i/12 + 0.5*(j%2)), shiftx_exp) + dx, (2*h + 2*h * sin30) * pow(j, shifty_exp) + dy)); - dia1 = Geom::Affine (Geom::Translate (-w/2, -h/2) * Geom::Translate (h/2 * cos30, -h/2 * sin30) * Geom::Translate (w/2 * cos60, w/2 * sin60)); - dia2 = dia1 * Geom::Affine (Geom::Translate (h * cos30, -h * sin30)); - dia3 = dia2 * Geom::Affine (Geom::Translate (-w/2 * cos60, -w/2 * sin60) * Geom::Translate (h * cos30, 0) * Geom::Translate (-w/2 * cos60, w/2 * sin60)); - dia4 = dia3 * Geom::Affine (Geom::Translate (h * cos30, h * sin30)); - dia5 = dia4 * Geom::Affine (Geom::Translate (w/2 * cos60, -w/2 * sin60) * Geom::Translate (h/2 * cos30, h/2 * sin30) * Geom::Translate (-w/2, h/2)); - dia6 = dia5 * Geom::Affine (Geom::Translate (0, h)); - dia7 = dia6 * dia1.inverse(); - dia8 = dia6 * dia2.inverse(); - dia9 = dia6 * dia3.inverse(); - dia10 = dia6 * dia4.inverse(); - } - if (i % 12 == 0) { - return d_s_r * ori; - } else if (i % 12 == 1) { - return d_s_r * flip_y * rotate_m60_c * dia1 * ori; - } else if (i % 12 == 2) { - return d_s_r * rotate_m60_c * dia2 * ori; - } else if (i % 12 == 3) { - return d_s_r * flip_y * rotate_m120_c * dia3 * ori; - } else if (i % 12 == 4) { - return d_s_r * rotate_m120_c * dia4 * ori; - } else if (i % 12 == 5) { - return d_s_r * flip_x * dia5 * ori; - } else if (i % 12 == 6) { - return d_s_r * flip_x * flip_y * dia6 * ori; - } else if (i % 12 == 7) { - return d_s_r * flip_y * rotate_120_c * dia7 * ori; - } else if (i % 12 == 8) { - return d_s_r * rotate_120_c * dia8 * ori; - } else if (i % 12 == 9) { - return d_s_r * flip_y * rotate_60_c * dia9 * ori; - } else if (i % 12 == 10) { - return d_s_r * rotate_60_c * dia10 * ori; - } else if (i % 12 == 11) { - return d_s_r * flip_y * Geom::Translate (0, h) * ori; - } - } - break; - - default: - break; - } - - return Geom::identity(); -} - -static bool clonetiler_is_a_clone_of(SPObject *tile, SPObject *obj) -{ - bool result = false; - char *id_href = NULL; - - if (obj) { - Inkscape::XML::Node *obj_repr = obj->getRepr(); - id_href = g_strdup_printf("#%s", obj_repr->attribute("id")); - } - - if (SP_IS_USE(tile) && - tile->getRepr()->attribute("xlink:href") && - (!id_href || !strcmp(id_href, tile->getRepr()->attribute("xlink:href"))) && - tile->getRepr()->attribute("inkscape:tiled-clone-of") && - (!id_href || !strcmp(id_href, tile->getRepr()->attribute("inkscape:tiled-clone-of")))) - { - result = true; - } else { - result = false; - } - if (id_href) { - g_free(id_href); - id_href = 0; - } - return result; -} - -static Inkscape::Drawing *trace_drawing = NULL; -static unsigned trace_visionkey; -static gdouble trace_zoom; -static SPDocument *trace_doc = NULL; - -static void clonetiler_trace_hide_tiled_clones_recursively(SPObject *from) -{ - if (!trace_drawing) - return; - - for (SPObject *o = from->firstChild(); o != NULL; o = o->next) { - if (SP_IS_ITEM(o) && clonetiler_is_a_clone_of (o, NULL)) - SP_ITEM(o)->invoke_hide(trace_visionkey); // FIXME: hide each tiled clone's original too! - clonetiler_trace_hide_tiled_clones_recursively (o); - } -} - -static void clonetiler_trace_setup(SPDocument *doc, gdouble zoom, SPItem *original) -{ - trace_drawing = new Inkscape::Drawing(); - /* Create ArenaItem and set transform */ - trace_visionkey = SPItem::display_key_new(1); - trace_doc = doc; - trace_drawing->setRoot(trace_doc->getRoot()->invoke_show(*trace_drawing, trace_visionkey, SP_ITEM_SHOW_DISPLAY)); - - // hide the (current) original and any tiled clones, we only want to pick the background - original->invoke_hide(trace_visionkey); - clonetiler_trace_hide_tiled_clones_recursively(trace_doc->getRoot()); - - trace_doc->getRoot()->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); - trace_doc->ensureUpToDate(); - - trace_zoom = zoom; -} - -static guint32 clonetiler_trace_pick(Geom::Rect box) -{ - if (!trace_drawing) { - return 0; - } - - trace_drawing->root()->setTransform(Geom::Scale(trace_zoom)); - trace_drawing->update(); - - /* Item integer bbox in points */ - Geom::IntRect ibox = (box * Geom::Scale(trace_zoom)).roundOutwards(); - - /* Find visible area */ - cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, ibox.width(), ibox.height()); - Inkscape::DrawingContext ct(s, ibox.min()); - /* Render */ - trace_drawing->render(ct, ibox); - double R = 0, G = 0, B = 0, A = 0; - ink_cairo_surface_average_color(s, R, G, B, A); - cairo_surface_destroy(s); - - return SP_RGBA32_F_COMPOSE (R, G, B, A); -} - -static void clonetiler_trace_finish() -{ - if (trace_doc) { - trace_doc->getRoot()->invoke_hide(trace_visionkey); - delete trace_drawing; - trace_doc = NULL; - trace_drawing = NULL; - } -} - -static void clonetiler_unclump(GtkWidget */*widget*/, void *) -{ - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - if (desktop == NULL) { - return; - } - - Inkscape::Selection *selection = sp_desktop_selection(desktop); - - // check if something is selected - if (selection->isEmpty() || g_slist_length((GSList *) selection->itemList()) > 1) { - sp_desktop_message_stack(desktop)->flash(Inkscape::WARNING_MESSAGE, _("Select one object whose tiled clones to unclump.")); - return; - } - - SPObject *obj = selection->singleItem(); - SPObject *parent = obj->parent; - - GSList *to_unclump = NULL; // not including the original - - for (SPObject *child = parent->firstChild(); child != NULL; child = child->next) { - if (clonetiler_is_a_clone_of (child, obj)) { - to_unclump = g_slist_prepend (to_unclump, child); - } - } - - sp_desktop_document(desktop)->ensureUpToDate(); - - unclump (to_unclump); - - g_slist_free (to_unclump); - - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_DIALOG_CLONETILER, - _("Unclump tiled clones")); -} - -static guint clonetiler_number_of_clones(SPObject *obj) -{ - SPObject *parent = obj->parent; - - guint n = 0; - - for (SPObject *child = parent->firstChild(); child != NULL; child = child->next) { - if (clonetiler_is_a_clone_of (child, obj)) { - n ++; - } - } - - return n; -} - -static void clonetiler_remove(GtkWidget */*widget*/, void *, bool do_undo = true) -{ - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - if (desktop == NULL) { - return; - } - - Inkscape::Selection *selection = sp_desktop_selection(desktop); - - // check if something is selected - if (selection->isEmpty() || g_slist_length((GSList *) selection->itemList()) > 1) { - sp_desktop_message_stack(desktop)->flash(Inkscape::WARNING_MESSAGE, _("Select one object whose tiled clones to remove.")); - return; - } - - SPObject *obj = selection->singleItem(); - SPObject *parent = obj->parent; - -// remove old tiling - GSList *to_delete = NULL; - for (SPObject *child = parent->firstChild(); child != NULL; child = child->next) { - if (clonetiler_is_a_clone_of (child, obj)) { - to_delete = g_slist_prepend (to_delete, child); - } - } - for (GSList *i = to_delete; i; i = i->next) { - SP_OBJECT(i->data)->deleteObject(); - } - g_slist_free (to_delete); - - clonetiler_change_selection (NULL, selection, dlg); - - if (do_undo) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_DIALOG_CLONETILER, - _("Delete tiled clones")); - } -} - -static Geom::Rect transform_rect(Geom::Rect const &r, Geom::Affine const &m) -{ - using Geom::X; - using Geom::Y; - Geom::Point const p1 = r.corner(1) * m; - Geom::Point const p2 = r.corner(2) * m; - Geom::Point const p3 = r.corner(3) * m; - Geom::Point const p4 = r.corner(4) * m; - return Geom::Rect( - Geom::Point( - std::min(std::min(p1[X], p2[X]), std::min(p3[X], p4[X])), - std::min(std::min(p1[Y], p2[Y]), std::min(p3[Y], p4[Y]))), - Geom::Point( - std::max(std::max(p1[X], p2[X]), std::max(p3[X], p4[X])), - std::max(std::max(p1[Y], p2[Y]), std::max(p3[Y], p4[Y])))); -} - -/** -Randomizes \a val by \a rand, with 0 < val < 1 and all values (including 0, 1) having the same -probability of being displaced. - */ -static double randomize01(double val, double rand) -{ - double base = MIN (val - rand, 1 - 2*rand); - if (base < 0) { - base = 0; - } - val = base + g_random_double_range (0, MIN (2 * rand, 1 - base)); - return CLAMP(val, 0, 1); // this should be unnecessary with the above provisions, but just in case... -} - - -static void clonetiler_apply(GtkWidget */*widget*/, void *) -{ - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - if (desktop == NULL) { - return; - } - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - Inkscape::Selection *selection = sp_desktop_selection(desktop); - - // check if something is selected - if (selection->isEmpty()) { - sp_desktop_message_stack(desktop)->flash(Inkscape::WARNING_MESSAGE, _("Select an object to clone.")); - return; - } - - // Check if more than one object is selected. - if (g_slist_length((GSList *) selection->itemList()) > 1) { - sp_desktop_message_stack(desktop)->flash(Inkscape::ERROR_MESSAGE, _("If you want to clone several objects, group them and clone the group.")); - return; - } - - // set "busy" cursor - desktop->setWaitingCursor(); - - // set statusbar text - GtkWidget *status = (GtkWidget *) g_object_get_data (G_OBJECT(dlg), "status"); - gtk_label_set_markup (GTK_LABEL(status), _("Creating tiled clones...")); - gtk_widget_queue_draw(GTK_WIDGET(status)); - gdk_window_process_all_updates(); - - SPObject *obj = selection->singleItem(); - SPItem *item = SP_IS_ITEM(obj) ? SP_ITEM(obj) : 0; - Inkscape::XML::Node *obj_repr = obj->getRepr(); - const char *id_href = g_strdup_printf("#%s", obj_repr->attribute("id")); - SPObject *parent = obj->parent; - - clonetiler_remove (NULL, NULL, false); - - double shiftx_per_i = 0.01 * prefs->getDoubleLimited(prefs_path + "shiftx_per_i", 0, -10000, 10000); - double shifty_per_i = 0.01 * prefs->getDoubleLimited(prefs_path + "shifty_per_i", 0, -10000, 10000); - double shiftx_per_j = 0.01 * prefs->getDoubleLimited(prefs_path + "shiftx_per_j", 0, -10000, 10000); - double shifty_per_j = 0.01 * prefs->getDoubleLimited(prefs_path + "shifty_per_j", 0, -10000, 10000); - double shiftx_rand = 0.01 * prefs->getDoubleLimited(prefs_path + "shiftx_rand", 0, 0, 1000); - double shifty_rand = 0.01 * prefs->getDoubleLimited(prefs_path + "shifty_rand", 0, 0, 1000); - double shiftx_exp = prefs->getDoubleLimited(prefs_path + "shiftx_exp", 1, 0, 10); - double shifty_exp = prefs->getDoubleLimited(prefs_path + "shifty_exp", 1, 0, 10); - bool shiftx_alternate = prefs->getBool(prefs_path + "shiftx_alternate"); - bool shifty_alternate = prefs->getBool(prefs_path + "shifty_alternate"); - bool shiftx_cumulate = prefs->getBool(prefs_path + "shiftx_cumulate"); - bool shifty_cumulate = prefs->getBool(prefs_path + "shifty_cumulate"); - bool shiftx_excludew = prefs->getBool(prefs_path + "shiftx_excludew"); - bool shifty_excludeh = prefs->getBool(prefs_path + "shifty_excludeh"); - - double scalex_per_i = 0.01 * prefs->getDoubleLimited(prefs_path + "scalex_per_i", 0, -100, 1000); - double scaley_per_i = 0.01 * prefs->getDoubleLimited(prefs_path + "scaley_per_i", 0, -100, 1000); - double scalex_per_j = 0.01 * prefs->getDoubleLimited(prefs_path + "scalex_per_j", 0, -100, 1000); - double scaley_per_j = 0.01 * prefs->getDoubleLimited(prefs_path + "scaley_per_j", 0, -100, 1000); - double scalex_rand = 0.01 * prefs->getDoubleLimited(prefs_path + "scalex_rand", 0, 0, 1000); - double scaley_rand = 0.01 * prefs->getDoubleLimited(prefs_path + "scaley_rand", 0, 0, 1000); - double scalex_exp = prefs->getDoubleLimited(prefs_path + "scalex_exp", 1, 0, 10); - double scaley_exp = prefs->getDoubleLimited(prefs_path + "scaley_exp", 1, 0, 10); - double scalex_log = prefs->getDoubleLimited(prefs_path + "scalex_log", 0, 0, 10); - double scaley_log = prefs->getDoubleLimited(prefs_path + "scaley_log", 0, 0, 10); - bool scalex_alternate = prefs->getBool(prefs_path + "scalex_alternate"); - bool scaley_alternate = prefs->getBool(prefs_path + "scaley_alternate"); - bool scalex_cumulate = prefs->getBool(prefs_path + "scalex_cumulate"); - bool scaley_cumulate = prefs->getBool(prefs_path + "scaley_cumulate"); - - double rotate_per_i = prefs->getDoubleLimited(prefs_path + "rotate_per_i", 0, -180, 180); - double rotate_per_j = prefs->getDoubleLimited(prefs_path + "rotate_per_j", 0, -180, 180); - double rotate_rand = 0.01 * prefs->getDoubleLimited(prefs_path + "rotate_rand", 0, 0, 100); - bool rotate_alternatei = prefs->getBool(prefs_path + "rotate_alternatei"); - bool rotate_alternatej = prefs->getBool(prefs_path + "rotate_alternatej"); - bool rotate_cumulatei = prefs->getBool(prefs_path + "rotate_cumulatei"); - bool rotate_cumulatej = prefs->getBool(prefs_path + "rotate_cumulatej"); - - double blur_per_i = 0.01 * prefs->getDoubleLimited(prefs_path + "blur_per_i", 0, 0, 100); - double blur_per_j = 0.01 * prefs->getDoubleLimited(prefs_path + "blur_per_j", 0, 0, 100); - bool blur_alternatei = prefs->getBool(prefs_path + "blur_alternatei"); - bool blur_alternatej = prefs->getBool(prefs_path + "blur_alternatej"); - double blur_rand = 0.01 * prefs->getDoubleLimited(prefs_path + "blur_rand", 0, 0, 100); - - double opacity_per_i = 0.01 * prefs->getDoubleLimited(prefs_path + "opacity_per_i", 0, 0, 100); - double opacity_per_j = 0.01 * prefs->getDoubleLimited(prefs_path + "opacity_per_j", 0, 0, 100); - bool opacity_alternatei = prefs->getBool(prefs_path + "opacity_alternatei"); - bool opacity_alternatej = prefs->getBool(prefs_path + "opacity_alternatej"); - double opacity_rand = 0.01 * prefs->getDoubleLimited(prefs_path + "opacity_rand", 0, 0, 100); - - Glib::ustring initial_color = prefs->getString(prefs_path + "initial_color"); - double hue_per_j = 0.01 * prefs->getDoubleLimited(prefs_path + "hue_per_j", 0, -100, 100); - double hue_per_i = 0.01 * prefs->getDoubleLimited(prefs_path + "hue_per_i", 0, -100, 100); - double hue_rand = 0.01 * prefs->getDoubleLimited(prefs_path + "hue_rand", 0, 0, 100); - double saturation_per_j = 0.01 * prefs->getDoubleLimited(prefs_path + "saturation_per_j", 0, -100, 100); - double saturation_per_i = 0.01 * prefs->getDoubleLimited(prefs_path + "saturation_per_i", 0, -100, 100); - double saturation_rand = 0.01 * prefs->getDoubleLimited(prefs_path + "saturation_rand", 0, 0, 100); - double lightness_per_j = 0.01 * prefs->getDoubleLimited(prefs_path + "lightness_per_j", 0, -100, 100); - double lightness_per_i = 0.01 * prefs->getDoubleLimited(prefs_path + "lightness_per_i", 0, -100, 100); - double lightness_rand = 0.01 * prefs->getDoubleLimited(prefs_path + "lightness_rand", 0, 0, 100); - bool color_alternatej = prefs->getBool(prefs_path + "color_alternatej"); - bool color_alternatei = prefs->getBool(prefs_path + "color_alternatei"); - - int type = prefs->getInt(prefs_path + "symmetrygroup", 0); - bool keepbbox = prefs->getBool(prefs_path + "keepbbox", true); - int imax = prefs->getInt(prefs_path + "imax", 2); - int jmax = prefs->getInt(prefs_path + "jmax", 2); - - bool fillrect = prefs->getBool(prefs_path + "fillrect"); - double fillwidth = prefs->getDoubleLimited(prefs_path + "fillwidth", 50, 0, 1e6); - double fillheight = prefs->getDoubleLimited(prefs_path + "fillheight", 50, 0, 1e6); - - bool dotrace = prefs->getBool(prefs_path + "dotrace"); - int pick = prefs->getInt(prefs_path + "pick"); - bool pick_to_presence = prefs->getBool(prefs_path + "pick_to_presence"); - bool pick_to_size = prefs->getBool(prefs_path + "pick_to_size"); - bool pick_to_color = prefs->getBool(prefs_path + "pick_to_color"); - bool pick_to_opacity = prefs->getBool(prefs_path + "pick_to_opacity"); - double rand_picked = 0.01 * prefs->getDoubleLimited(prefs_path + "rand_picked", 0, 0, 100); - bool invert_picked = prefs->getBool(prefs_path + "invert_picked"); - double gamma_picked = prefs->getDoubleLimited(prefs_path + "gamma_picked", 0, -10, 10); - - if (dotrace) { - clonetiler_trace_setup (sp_desktop_document(desktop), 1.0, item); - } - - Geom::Point center; - double w = 0; - double h = 0; - double x0 = 0; - double y0 = 0; - - if (keepbbox && - obj_repr->attribute("inkscape:tile-w") && - obj_repr->attribute("inkscape:tile-h") && - obj_repr->attribute("inkscape:tile-x0") && - obj_repr->attribute("inkscape:tile-y0") && - obj_repr->attribute("inkscape:tile-cx") && - obj_repr->attribute("inkscape:tile-cy")) { - - double cx = 0; - double cy = 0; - sp_repr_get_double (obj_repr, "inkscape:tile-cx", &cx); - sp_repr_get_double (obj_repr, "inkscape:tile-cy", &cy); - center = Geom::Point (cx, cy); - - sp_repr_get_double (obj_repr, "inkscape:tile-w", &w); - sp_repr_get_double (obj_repr, "inkscape:tile-h", &h); - sp_repr_get_double (obj_repr, "inkscape:tile-x0", &x0); - sp_repr_get_double (obj_repr, "inkscape:tile-y0", &y0); - } else { - bool prefs_bbox = prefs->getBool("/tools/bounding_box", false); - SPItem::BBoxType bbox_type = ( !prefs_bbox ? - SPItem::VISUAL_BBOX : SPItem::GEOMETRIC_BBOX ); - Geom::OptRect r = item->documentBounds(bbox_type); - if (r) { - w = r->dimensions()[Geom::X]; - h = r->dimensions()[Geom::Y]; - x0 = r->min()[Geom::X]; - y0 = r->min()[Geom::Y]; - center = desktop->dt2doc(item->getCenter()); - - sp_repr_set_svg_double(obj_repr, "inkscape:tile-cx", center[Geom::X]); - sp_repr_set_svg_double(obj_repr, "inkscape:tile-cy", center[Geom::Y]); - sp_repr_set_svg_double(obj_repr, "inkscape:tile-w", w); - sp_repr_set_svg_double(obj_repr, "inkscape:tile-h", h); - sp_repr_set_svg_double(obj_repr, "inkscape:tile-x0", x0); - sp_repr_set_svg_double(obj_repr, "inkscape:tile-y0", y0); - } else { - center = Geom::Point(0, 0); - w = h = 0; - x0 = y0 = 0; - } - } - - Geom::Point cur(0, 0); - Geom::Rect bbox_original (Geom::Point (x0, y0), Geom::Point (x0 + w, y0 + h)); - double perimeter_original = (w + h)/4; - - // The integers i and j are reserved for tile column and row. - // The doubles x and y are used for coordinates - for (int i = 0; - fillrect? - (fabs(cur[Geom::X]) < fillwidth && i < 200) // prevent "freezing" with too large fillrect, arbitrarily limit rows - : (i < imax); - i ++) { - for (int j = 0; - fillrect? - (fabs(cur[Geom::Y]) < fillheight && j < 200) // prevent "freezing" with too large fillrect, arbitrarily limit cols - : (j < jmax); - j ++) { - - // Note: We create a clone at 0,0 too, right over the original, in case our clones are colored - - // Get transform from symmetry, shift, scale, rotation - Geom::Affine t = clonetiler_get_transform (type, i, j, center[Geom::X], center[Geom::Y], w, h, - shiftx_per_i, shifty_per_i, - shiftx_per_j, shifty_per_j, - shiftx_rand, shifty_rand, - shiftx_exp, shifty_exp, - shiftx_alternate, shifty_alternate, - shiftx_cumulate, shifty_cumulate, - shiftx_excludew, shifty_excludeh, - scalex_per_i, scaley_per_i, - scalex_per_j, scaley_per_j, - scalex_rand, scaley_rand, - scalex_exp, scaley_exp, - scalex_log, scaley_log, - scalex_alternate, scaley_alternate, - scalex_cumulate, scaley_cumulate, - rotate_per_i, rotate_per_j, - rotate_rand, - rotate_alternatei, rotate_alternatej, - rotate_cumulatei, rotate_cumulatej ); - - cur = center * t - center; - if (fillrect) { - if ((cur[Geom::X] > fillwidth) || (cur[Geom::Y] > fillheight)) { // off limits - continue; - } - } - - gchar color_string[32]; *color_string = 0; - - // Color tab - if (!initial_color.empty()) { - guint32 rgba = sp_svg_read_color (initial_color.data(), 0x000000ff); - float hsl[3]; - sp_color_rgb_to_hsl_floatv (hsl, SP_RGBA32_R_F(rgba), SP_RGBA32_G_F(rgba), SP_RGBA32_B_F(rgba)); - - double eff_i = (color_alternatei? (i%2) : (i)); - double eff_j = (color_alternatej? (j%2) : (j)); - - hsl[0] += hue_per_i * eff_i + hue_per_j * eff_j + hue_rand * g_random_double_range (-1, 1); - double notused; - hsl[0] = modf( hsl[0], ¬used ); // Restrict to 0-1 - hsl[1] += saturation_per_i * eff_i + saturation_per_j * eff_j + saturation_rand * g_random_double_range (-1, 1); - hsl[1] = CLAMP (hsl[1], 0, 1); - hsl[2] += lightness_per_i * eff_i + lightness_per_j * eff_j + lightness_rand * g_random_double_range (-1, 1); - hsl[2] = CLAMP (hsl[2], 0, 1); - - float rgb[3]; - sp_color_hsl_to_rgb_floatv (rgb, hsl[0], hsl[1], hsl[2]); - sp_svg_write_color(color_string, sizeof(color_string), SP_RGBA32_F_COMPOSE(rgb[0], rgb[1], rgb[2], 1.0)); - } - - // Blur - double blur = 0.0; - { - int eff_i = (blur_alternatei? (i%2) : (i)); - int eff_j = (blur_alternatej? (j%2) : (j)); - blur = (blur_per_i * eff_i + blur_per_j * eff_j + blur_rand * g_random_double_range (-1, 1)); - blur = CLAMP (blur, 0, 1); - } - - // Opacity - double opacity = 1.0; - { - int eff_i = (opacity_alternatei? (i%2) : (i)); - int eff_j = (opacity_alternatej? (j%2) : (j)); - opacity = 1 - (opacity_per_i * eff_i + opacity_per_j * eff_j + opacity_rand * g_random_double_range (-1, 1)); - opacity = CLAMP (opacity, 0, 1); - } - - // Trace tab - if (dotrace) { - Geom::Rect bbox_t = transform_rect (bbox_original, t); - - guint32 rgba = clonetiler_trace_pick (bbox_t); - float r = SP_RGBA32_R_F(rgba); - float g = SP_RGBA32_G_F(rgba); - float b = SP_RGBA32_B_F(rgba); - float a = SP_RGBA32_A_F(rgba); - - float hsl[3]; - sp_color_rgb_to_hsl_floatv (hsl, r, g, b); - - gdouble val = 0; - switch (pick) { - case PICK_COLOR: - val = 1 - hsl[2]; // inverse lightness; to match other picks where black = max - break; - case PICK_OPACITY: - val = a; - break; - case PICK_R: - val = r; - break; - case PICK_G: - val = g; - break; - case PICK_B: - val = b; - break; - case PICK_H: - val = hsl[0]; - break; - case PICK_S: - val = hsl[1]; - break; - case PICK_L: - val = 1 - hsl[2]; - break; - default: - break; - } - - if (rand_picked > 0) { - val = randomize01 (val, rand_picked); - r = randomize01 (r, rand_picked); - g = randomize01 (g, rand_picked); - b = randomize01 (b, rand_picked); - } - - if (gamma_picked != 0) { - double power; - if (gamma_picked > 0) - power = 1/(1 + fabs(gamma_picked)); - else - power = 1 + fabs(gamma_picked); - - val = pow (val, power); - r = pow (r, power); - g = pow (g, power); - b = pow (b, power); - } - - if (invert_picked) { - val = 1 - val; - r = 1 - r; - g = 1 - g; - b = 1 - b; - } - - val = CLAMP (val, 0, 1); - r = CLAMP (r, 0, 1); - g = CLAMP (g, 0, 1); - b = CLAMP (b, 0, 1); - - // recompose tweaked color - rgba = SP_RGBA32_F_COMPOSE(r, g, b, a); - - if (pick_to_presence) { - if (g_random_double_range (0, 1) > val) { - continue; // skip! - } - } - if (pick_to_size) { - t = Geom::Translate(-center[Geom::X], -center[Geom::Y]) * Geom::Scale (val, val) * Geom::Translate(center[Geom::X], center[Geom::Y]) * t; - } - if (pick_to_opacity) { - opacity *= val; - } - if (pick_to_color) { - sp_svg_write_color(color_string, sizeof(color_string), rgba); - } - } - - if (opacity < 1e-6) { // invisibly transparent, skip - continue; - } - - if (fabs(t[0]) + fabs (t[1]) + fabs(t[2]) + fabs(t[3]) < 1e-6) { // too small, skip - continue; - } - - // Create the clone - Inkscape::XML::Node *clone = obj_repr->document()->createElement("svg:use"); - clone->setAttribute("x", "0"); - clone->setAttribute("y", "0"); - clone->setAttribute("inkscape:tiled-clone-of", id_href); - clone->setAttribute("xlink:href", id_href); - - Geom::Point new_center; - bool center_set = false; - if (obj_repr->attribute("inkscape:transform-center-x") || obj_repr->attribute("inkscape:transform-center-y")) { - new_center = desktop->dt2doc(item->getCenter()) * t; - center_set = true; - } - - gchar *affinestr=sp_svg_transform_write(t); - clone->setAttribute("transform", affinestr); - g_free(affinestr); - - if (opacity < 1.0) { - sp_repr_set_css_double(clone, "opacity", opacity); - } - - if (*color_string) { - clone->setAttribute("fill", color_string); - clone->setAttribute("stroke", color_string); - } - - // add the new clone to the top of the original's parent - parent->getRepr()->appendChild(clone); - - if (blur > 0.0) { - SPObject *clone_object = sp_desktop_document(desktop)->getObjectByRepr(clone); - double perimeter = perimeter_original * t.descrim(); - double radius = blur * perimeter; - // this is necessary for all newly added clones to have correct bboxes, - // otherwise filters won't work: - sp_desktop_document(desktop)->ensureUpToDate(); - // it's hard to figure out exact width/height of the tile without having an object - // that we can take bbox of; however here we only need a lower bound so that blur - // margins are not too small, and the perimeter should work - SPFilter *constructed = new_filter_gaussian_blur(sp_desktop_document(desktop), radius, t.descrim(), t.expansionX(), t.expansionY(), perimeter, perimeter); - sp_style_set_property_url (clone_object, "filter", constructed, false); - } - - if (center_set) { - SPObject *clone_object = sp_desktop_document(desktop)->getObjectByRepr(clone); - if (clone_object && SP_IS_ITEM(clone_object)) { - clone_object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); - SP_ITEM(clone_object)->setCenter(desktop->doc2dt(new_center)); - clone_object->updateRepr(); - } - } - - Inkscape::GC::release(clone); - } - cur[Geom::Y] = 0; - } - - if (dotrace) { - clonetiler_trace_finish (); - } - - clonetiler_change_selection (NULL, selection, dlg); - - desktop->clearWaitingCursor(); - - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_DIALOG_CLONETILER, - _("Create tiled clones")); -} - -static GtkWidget * clonetiler_new_tab(GtkWidget *nb, const gchar *label) -{ - GtkWidget *l = gtk_label_new_with_mnemonic (label); - GtkWidget *vb = gtk_vbox_new (FALSE, VB_MARGIN); - gtk_container_set_border_width (GTK_CONTAINER (vb), VB_MARGIN); - gtk_notebook_append_page (GTK_NOTEBOOK (nb), vb, l); - return vb; -} - -static void clonetiler_checkbox_toggled(GtkToggleButton *tb, gpointer *data) -{ - const gchar *attr = (const gchar *) data; - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setBool(prefs_path + attr, gtk_toggle_button_get_active(tb)); -} - -static GtkWidget * clonetiler_checkbox(const char *tip, const char *attr) -{ - GtkWidget *hb = gtk_hbox_new(FALSE, VB_MARGIN); - - GtkWidget *b = gtk_check_button_new (); - gtk_widget_set_tooltip_text (b, tip); - - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - bool value = prefs->getBool(prefs_path + attr); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(b), value); - - gtk_box_pack_end (GTK_BOX (hb), b, FALSE, TRUE, 0); - g_signal_connect ( G_OBJECT (b), "clicked", - G_CALLBACK (clonetiler_checkbox_toggled), (gpointer) attr); - - g_object_set_data (G_OBJECT(b), "uncheckable", GINT_TO_POINTER(TRUE)); - - return hb; -} - -static void clonetiler_value_changed(GtkAdjustment *adj, gpointer data) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - const gchar *pref = (const gchar *) data; - prefs->setDouble(prefs_path + pref, gtk_adjustment_get_value (adj)); -} - -static GtkWidget * clonetiler_spinbox(const char *tip, const char *attr, double lower, double upper, const gchar *suffix, bool exponent = false) -{ - GtkWidget *hb = gtk_hbox_new(FALSE, 0); - - { - Gtk::Adjustment *a; - if (exponent) { - a = new Gtk::Adjustment (1.0, lower, upper, 0.01, 0.05, 0); - } else { - a = new Gtk::Adjustment (0.0, lower, upper, 0.1, 0.5, 0); - } - - Inkscape::UI::Widget::SpinButton *sb; - if (exponent) { - sb = new Inkscape::UI::Widget::SpinButton (*a, 0.01, 2); - } else { - sb = new Inkscape::UI::Widget::SpinButton (*a, 0.1, 1); - } - - sb->set_tooltip_text (tip); - sb->set_width_chars (5); - sb->set_digits(3); - gtk_box_pack_start (GTK_BOX (hb), GTK_WIDGET(sb->gobj()), FALSE, FALSE, SB_MARGIN); - - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - double value = prefs->getDoubleLimited(prefs_path + attr, exponent? 1.0 : 0.0, lower, upper); - a->set_value (value); - // TODO: C++ification - g_signal_connect(G_OBJECT(a->gobj()), "value_changed", - G_CALLBACK(clonetiler_value_changed), (gpointer) attr); - - if (exponent) { - sb->set_data ("oneable", GINT_TO_POINTER(TRUE)); - } else { - sb->set_data ("zeroable", GINT_TO_POINTER(TRUE)); - } - } - - { - GtkWidget *l = gtk_label_new (""); - gtk_label_set_markup (GTK_LABEL(l), suffix); - gtk_misc_set_alignment (GTK_MISC (l), 1.0, 0); - gtk_box_pack_start (GTK_BOX (hb), l, FALSE, FALSE, 0); - } - - return hb; -} - -static void clonetiler_symgroup_changed(GtkComboBox *cb, gpointer /*data*/) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - gint group_new = gtk_combo_box_get_active (cb); - prefs->setInt(prefs_path + "symmetrygroup", group_new); -} - -static void clonetiler_xy_changed(GtkAdjustment *adj, gpointer data) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - const gchar *pref = (const gchar *) data; - prefs->setInt(prefs_path + pref, (int) floor(gtk_adjustment_get_value (adj) + 0.5)); -} - -static void clonetiler_keep_bbox_toggled(GtkToggleButton *tb, gpointer /*data*/) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setBool(prefs_path + "keepbbox", gtk_toggle_button_get_active(tb)); -} - -static void clonetiler_pick_to(GtkToggleButton *tb, gpointer data) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - const gchar *pref = (const gchar *) data; - prefs->setBool(prefs_path + pref, gtk_toggle_button_get_active(tb)); -} - - -static void clonetiler_reset_recursive(GtkWidget *w) -{ - if (w && GTK_IS_OBJECT(w)) { - { - int r = GPOINTER_TO_INT (g_object_get_data(G_OBJECT(w), "zeroable")); - if (r && GTK_IS_SPIN_BUTTON(w)) { // spinbutton - GtkAdjustment *a = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON(w)); - gtk_adjustment_set_value (a, 0); - } - } - { - int r = GPOINTER_TO_INT (g_object_get_data(G_OBJECT(w), "oneable")); - if (r && GTK_IS_SPIN_BUTTON(w)) { // spinbutton - GtkAdjustment *a = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON(w)); - gtk_adjustment_set_value (a, 1); - } - } - { - int r = GPOINTER_TO_INT (g_object_get_data(G_OBJECT(w), "uncheckable")); - if (r && GTK_IS_TOGGLE_BUTTON(w)) { // checkbox - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(w), FALSE); - } - } - } - - if (GTK_IS_CONTAINER(w)) { - GList *ch = gtk_container_get_children (GTK_CONTAINER(w)); - for (GList *i = ch; i != NULL; i = i->next) { - clonetiler_reset_recursive (GTK_WIDGET(i->data)); - } - g_list_free (ch); - } -} - -static void clonetiler_reset(GtkWidget */*widget*/, void *) -{ - clonetiler_reset_recursive (dlg); -} - -static void clonetiler_table_attach(GtkWidget *table, GtkWidget *widget, float align, int row, int col) -{ - GtkWidget *a = gtk_alignment_new (align, 0, 0, 0); - gtk_container_add(GTK_CONTAINER(a), widget); - gtk_table_attach ( GTK_TABLE (table), a, col, col + 1, row, row + 1, (GtkAttachOptions)4, (GtkAttachOptions)0, 0, 0 ); -} - -static GtkWidget * clonetiler_table_x_y_rand(int values) -{ - GtkWidget *table = gtk_table_new (values + 2, 5, FALSE); - gtk_container_set_border_width (GTK_CONTAINER (table), VB_MARGIN); - gtk_table_set_row_spacings (GTK_TABLE (table), 6); - gtk_table_set_col_spacings (GTK_TABLE (table), 8); - - { - GtkWidget *hb = gtk_hbox_new (FALSE, 0); - - GtkWidget *i = sp_icon_new (Inkscape::ICON_SIZE_DECORATION, INKSCAPE_ICON("object-rows")); - gtk_box_pack_start (GTK_BOX (hb), i, FALSE, FALSE, 2); - - GtkWidget *l = gtk_label_new (""); - gtk_label_set_markup (GTK_LABEL(l), _("Per row:")); - gtk_box_pack_start (GTK_BOX (hb), l, FALSE, FALSE, 2); - - clonetiler_table_attach (table, hb, 0, 1, 2); - } - - { - GtkWidget *hb = gtk_hbox_new (FALSE, 0); - - GtkWidget *i = sp_icon_new (Inkscape::ICON_SIZE_DECORATION, INKSCAPE_ICON("object-columns")); - gtk_box_pack_start (GTK_BOX (hb), i, FALSE, FALSE, 2); - - GtkWidget *l = gtk_label_new (""); - gtk_label_set_markup (GTK_LABEL(l), _("Per column:")); - gtk_box_pack_start (GTK_BOX (hb), l, FALSE, FALSE, 2); - - clonetiler_table_attach (table, hb, 0, 1, 3); - } - - { - GtkWidget *l = gtk_label_new (""); - gtk_label_set_markup (GTK_LABEL(l), _("Randomize:")); - clonetiler_table_attach (table, l, 0, 1, 4); - } - - return table; -} - -static void clonetiler_pick_switched(GtkToggleButton */*tb*/, gpointer data) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - guint v = GPOINTER_TO_INT (data); - prefs->setInt(prefs_path + "pick", v); -} - - -static void clonetiler_switch_to_create(GtkToggleButton */*tb*/, GtkWidget *dlg) -{ - GtkWidget *rowscols = (GtkWidget *) g_object_get_data (G_OBJECT(dlg), "rowscols"); - GtkWidget *widthheight = (GtkWidget *) g_object_get_data (G_OBJECT(dlg), "widthheight"); - - if (rowscols) { - gtk_widget_set_sensitive (rowscols, TRUE); - } - if (widthheight) { - gtk_widget_set_sensitive (widthheight, FALSE); - } - - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setBool(prefs_path + "fillrect", false); -} - - -static void clonetiler_switch_to_fill(GtkToggleButton */*tb*/, GtkWidget *dlg) -{ - GtkWidget *rowscols = (GtkWidget *) g_object_get_data (G_OBJECT(dlg), "rowscols"); - GtkWidget *widthheight = (GtkWidget *) g_object_get_data (G_OBJECT(dlg), "widthheight"); - - if (rowscols) { - gtk_widget_set_sensitive (rowscols, FALSE); - } - if (widthheight) { - gtk_widget_set_sensitive (widthheight, TRUE); - } - - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setBool(prefs_path + "fillrect", true); -} - - - - -static void clonetiler_fill_width_changed(GtkAdjustment *adj, GtkWidget *u) -{ - gdouble const raw_dist = gtk_adjustment_get_value (adj); - SPUnit const &unit = *sp_unit_selector_get_unit(SP_UNIT_SELECTOR(u)); - gdouble const pixels = sp_units_get_pixels (raw_dist, unit); - - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble(prefs_path + "fillwidth", pixels); -} - -static void clonetiler_fill_height_changed(GtkAdjustment *adj, GtkWidget *u) -{ - gdouble const raw_dist = gtk_adjustment_get_value (adj); - SPUnit const &unit = *sp_unit_selector_get_unit(SP_UNIT_SELECTOR(u)); - gdouble const pixels = sp_units_get_pixels (raw_dist, unit); - - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble(prefs_path + "fillheight", pixels); -} - - -static void clonetiler_do_pick_toggled(GtkToggleButton *tb, gpointer /*data*/) -{ - GtkWidget *vvb = (GtkWidget *) g_object_get_data (G_OBJECT(dlg), "dotrace"); - - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setBool(prefs_path + "dotrace", gtk_toggle_button_get_active (tb)); - - if (vvb) { - gtk_widget_set_sensitive (vvb, gtk_toggle_button_get_active (tb)); - } -} - - - - -void clonetiler_dialog(void) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - if (!dlg) - { - gchar title[500]; - sp_ui_dialog_title_string (Inkscape::Verb::get(SP_VERB_DIALOG_CLONETILER), title); - - dlg = sp_window_new (title, TRUE); - if (x == -1000 || y == -1000) { - x = prefs->getInt(prefs_path + "x", -1000); - y = prefs->getInt(prefs_path + "y", -1000); - } - - if (w ==0 || h == 0) { - w = prefs->getInt(prefs_path + "w", 0); - h = prefs->getInt(prefs_path + "h", 0); - } - - prefs->setInt(prefs_path + "visible", 1); - -// if (x<0) x=0; -// if (y<0) y=0; - - if (w && h) { - gtk_window_resize ((GtkWindow *) dlg, w, h); - } - if (x >= 0 && y >= 0 && (x < (gdk_screen_width()-MIN_ONSCREEN_DISTANCE)) && (y < (gdk_screen_height()-MIN_ONSCREEN_DISTANCE))) { - gtk_window_move ((GtkWindow *) dlg, x, y); - - } else { - gtk_window_set_position(GTK_WINDOW(dlg), GTK_WIN_POS_CENTER); - } - - - sp_transientize (dlg); - wd.win = dlg; - wd.stop = 0; - - - g_signal_connect ( G_OBJECT (dlg), "event", G_CALLBACK (sp_dialog_event_handler), dlg); - - g_signal_connect ( G_OBJECT (dlg), "destroy", G_CALLBACK (clonetiler_dialog_destroy), dlg); - g_signal_connect ( G_OBJECT (dlg), "delete_event", G_CALLBACK (clonetiler_dialog_delete), dlg); - - g_signal_connect ( G_OBJECT (INKSCAPE), "shut_down", G_CALLBACK (clonetiler_dialog_delete), dlg); - g_signal_connect ( G_OBJECT (INKSCAPE), "dialogs_hide", G_CALLBACK (sp_dialog_hide), dlg); - g_signal_connect ( G_OBJECT (INKSCAPE), "dialogs_unhide", G_CALLBACK (sp_dialog_unhide), dlg); - g_signal_connect ( G_OBJECT (INKSCAPE), "activate_desktop", G_CALLBACK (sp_transientize_callback), &wd); - - GtkWidget *mainbox = gtk_vbox_new(FALSE, 4); - gtk_container_set_border_width (GTK_CONTAINER (mainbox), 6); - gtk_container_add (GTK_CONTAINER (dlg), mainbox); - - GtkWidget *nb = gtk_notebook_new (); - gtk_box_pack_start (GTK_BOX (mainbox), nb, FALSE, FALSE, 0); - - -// Symmetry - { - GtkWidget *vb = clonetiler_new_tab (nb, _("_Symmetry")); - - /* TRANSLATORS: For the following 17 symmetry groups, see - * http://www.bib.ulb.ac.be/coursmath/doc/17.htm (visual examples); - * http://www.clarku.edu/~djoyce/wallpaper/seventeen.html (English vocabulary); or - * http://membres.lycos.fr/villemingerard/Geometri/Sym1D.htm (French vocabulary). - */ - struct SymGroups { - gint group; - gchar const *label; - } const sym_groups[] = { - // TRANSLATORS: "translation" means "shift" / "displacement" here. - {TILE_P1, _("P1: simple translation")}, - {TILE_P2, _("P2: 180° rotation")}, - {TILE_PM, _("PM: reflection")}, - // TRANSLATORS: "glide reflection" is a reflection and a translation combined. - // For more info, see http://mathforum.org/sum95/suzanne/symsusan.html - {TILE_PG, _("PG: glide reflection")}, - {TILE_CM, _("CM: reflection + glide reflection")}, - {TILE_PMM, _("PMM: reflection + reflection")}, - {TILE_PMG, _("PMG: reflection + 180° rotation")}, - {TILE_PGG, _("PGG: glide reflection + 180° rotation")}, - {TILE_CMM, _("CMM: reflection + reflection + 180° rotation")}, - {TILE_P4, _("P4: 90° rotation")}, - {TILE_P4M, _("P4M: 90° rotation + 45° reflection")}, - {TILE_P4G, _("P4G: 90° rotation + 90° reflection")}, - {TILE_P3, _("P3: 120° rotation")}, - {TILE_P31M, _("P31M: reflection + 120° rotation, dense")}, - {TILE_P3M1, _("P3M1: reflection + 120° rotation, sparse")}, - {TILE_P6, _("P6: 60° rotation")}, - {TILE_P6M, _("P6M: reflection + 60° rotation")}, - }; - - gint current = prefs->getInt(prefs_path + "symmetrygroup", 0); - - // Create a list structure containing all the data to be displayed in - // the symmetry group combo box. - GtkListStore *store = gtk_list_store_new (1, G_TYPE_STRING); - GtkTreeIter iter; - - for (unsigned j = 0; j < G_N_ELEMENTS(sym_groups); ++j) { - SymGroups const &sg = sym_groups[j]; - - // Add the description of the symgroup to a new row - gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, - 0, sg.label, - -1); - } - - // Add a new combo box widget with the list of symmetry groups to the vbox - GtkWidget *combo = gtk_combo_box_new_with_model (GTK_TREE_MODEL (store)); - gtk_widget_set_tooltip_text (combo, _("Select one of the 17 symmetry groups for the tiling")); - gtk_box_pack_start (GTK_BOX (vb), combo, FALSE, FALSE, SB_MARGIN); - - // Specify the rendering of data from the list in a combo box cell - GtkCellRenderer *renderer = gtk_cell_renderer_text_new (); - gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, FALSE); - gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), renderer, - "markup", 0, - NULL); - - gtk_combo_box_set_active (GTK_COMBO_BOX (combo), current); - - g_signal_connect (G_OBJECT (combo), "changed", - G_CALLBACK (clonetiler_symgroup_changed), - NULL); - } - - table_row_labels = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); - -// Shift - { - GtkWidget *vb = clonetiler_new_tab (nb, _("S_hift")); - - GtkWidget *table = clonetiler_table_x_y_rand (3); - gtk_box_pack_start (GTK_BOX (vb), table, FALSE, FALSE, 0); - - // X - { - GtkWidget *l = gtk_label_new (""); - // TRANSLATORS: "shift" means: the tiles will be shifted (offset) horizontally by this amount - // xgettext:no-c-format - gtk_label_set_markup (GTK_LABEL(l), _("Shift X:")); - gtk_size_group_add_widget(table_row_labels, l); - clonetiler_table_attach (table, l, 1, 2, 1); - } - - { - GtkWidget *l = clonetiler_spinbox ( - // xgettext:no-c-format - _("Horizontal shift per row (in % of tile width)"), "shiftx_per_j", - -10000, 10000, "%"); - clonetiler_table_attach (table, l, 0, 2, 2); - } - - { - GtkWidget *l = clonetiler_spinbox ( - // xgettext:no-c-format - _("Horizontal shift per column (in % of tile width)"), "shiftx_per_i", - -10000, 10000, "%"); - clonetiler_table_attach (table, l, 0, 2, 3); - } - - { - GtkWidget *l = clonetiler_spinbox (_("Randomize the horizontal shift by this percentage"), "shiftx_rand", - 0, 1000, "%"); - clonetiler_table_attach (table, l, 0, 2, 4); - } - - // Y - { - GtkWidget *l = gtk_label_new (""); - // TRANSLATORS: "shift" means: the tiles will be shifted (offset) vertically by this amount - // xgettext:no-c-format - gtk_label_set_markup (GTK_LABEL(l), _("Shift Y:")); - gtk_size_group_add_widget(table_row_labels, l); - clonetiler_table_attach (table, l, 1, 3, 1); - } - - { - GtkWidget *l = clonetiler_spinbox ( - // xgettext:no-c-format - _("Vertical shift per row (in % of tile height)"), "shifty_per_j", - -10000, 10000, "%"); - clonetiler_table_attach (table, l, 0, 3, 2); - } - - { - GtkWidget *l = clonetiler_spinbox ( - // xgettext:no-c-format - _("Vertical shift per column (in % of tile height)"), "shifty_per_i", - -10000, 10000, "%"); - clonetiler_table_attach (table, l, 0, 3, 3); - } - - { - GtkWidget *l = clonetiler_spinbox ( - _("Randomize the vertical shift by this percentage"), "shifty_rand", - 0, 1000, "%"); - clonetiler_table_attach (table, l, 0, 3, 4); - } - - // Exponent - { - GtkWidget *l = gtk_label_new (""); - gtk_label_set_markup (GTK_LABEL(l), _("Exponent:")); - gtk_size_group_add_widget(table_row_labels, l); - clonetiler_table_attach (table, l, 1, 4, 1); - } - - { - GtkWidget *l = clonetiler_spinbox ( - _("Whether rows are spaced evenly (1), converge (<1) or diverge (>1)"), "shifty_exp", - 0, 10, "", true); - clonetiler_table_attach (table, l, 0, 4, 2); - } - - { - GtkWidget *l = clonetiler_spinbox ( - _("Whether columns are spaced evenly (1), converge (<1) or diverge (>1)"), "shiftx_exp", - 0, 10, "", true); - clonetiler_table_attach (table, l, 0, 4, 3); - } - - { // alternates - GtkWidget *l = gtk_label_new (""); - // TRANSLATORS: "Alternate" is a verb here - gtk_label_set_markup (GTK_LABEL(l), _("Alternate:")); - gtk_size_group_add_widget(table_row_labels, l); - clonetiler_table_attach (table, l, 1, 5, 1); - } - - { - GtkWidget *l = clonetiler_checkbox (_("Alternate the sign of shifts for each row"), "shifty_alternate"); - clonetiler_table_attach (table, l, 0, 5, 2); - } - - { - GtkWidget *l = clonetiler_checkbox (_("Alternate the sign of shifts for each column"), "shiftx_alternate"); - clonetiler_table_attach (table, l, 0, 5, 3); - } - - { // Cumulate - GtkWidget *l = gtk_label_new (""); - // TRANSLATORS: "Cumulate" is a verb here - gtk_label_set_markup (GTK_LABEL(l), _("Cumulate:")); - gtk_size_group_add_widget(table_row_labels, l); - clonetiler_table_attach (table, l, 1, 6, 1); - } - - { - GtkWidget *l = clonetiler_checkbox (_("Cumulate the shifts for each row"), "shifty_cumulate"); - clonetiler_table_attach (table, l, 0, 6, 2); - } - - { - GtkWidget *l = clonetiler_checkbox (_("Cumulate the shifts for each column"), "shiftx_cumulate"); - clonetiler_table_attach (table, l, 0, 6, 3); - } - - { // Exclude tile width and height in shift - GtkWidget *l = gtk_label_new (""); - // TRANSLATORS: "Cumulate" is a verb here - gtk_label_set_markup (GTK_LABEL(l), _("Exclude tile:")); - gtk_size_group_add_widget(table_row_labels, l); - clonetiler_table_attach (table, l, 1, 7, 1); - } - - { - GtkWidget *l = clonetiler_checkbox (_("Exclude tile height in shift"), "shifty_excludeh"); - clonetiler_table_attach (table, l, 0, 7, 2); - } - - { - GtkWidget *l = clonetiler_checkbox (_("Exclude tile width in shift"), "shiftx_excludew"); - clonetiler_table_attach (table, l, 0, 7, 3); - } - - } - - -// Scale - { - GtkWidget *vb = clonetiler_new_tab (nb, _("Sc_ale")); - - GtkWidget *table = clonetiler_table_x_y_rand (2); - gtk_box_pack_start (GTK_BOX (vb), table, FALSE, FALSE, 0); - - // X - { - GtkWidget *l = gtk_label_new (""); - gtk_label_set_markup (GTK_LABEL(l), _("Scale X:")); - gtk_size_group_add_widget(table_row_labels, l); - clonetiler_table_attach (table, l, 1, 2, 1); - } - - { - GtkWidget *l = clonetiler_spinbox ( - // xgettext:no-c-format - _("Horizontal scale per row (in % of tile width)"), "scalex_per_j", - -100, 1000, "%"); - clonetiler_table_attach (table, l, 0, 2, 2); - } - - { - GtkWidget *l = clonetiler_spinbox ( - // xgettext:no-c-format - _("Horizontal scale per column (in % of tile width)"), "scalex_per_i", - -100, 1000, "%"); - clonetiler_table_attach (table, l, 0, 2, 3); - } - - { - GtkWidget *l = clonetiler_spinbox (_("Randomize the horizontal scale by this percentage"), "scalex_rand", - 0, 1000, "%"); - clonetiler_table_attach (table, l, 0, 2, 4); - } - - // Y - { - GtkWidget *l = gtk_label_new (""); - gtk_label_set_markup (GTK_LABEL(l), _("Scale Y:")); - gtk_size_group_add_widget(table_row_labels, l); - clonetiler_table_attach (table, l, 1, 3, 1); - } - - { - GtkWidget *l = clonetiler_spinbox ( - // xgettext:no-c-format - _("Vertical scale per row (in % of tile height)"), "scaley_per_j", - -100, 1000, "%"); - clonetiler_table_attach (table, l, 0, 3, 2); - } - - { - GtkWidget *l = clonetiler_spinbox ( - // xgettext:no-c-format - _("Vertical scale per column (in % of tile height)"), "scaley_per_i", - -100, 1000, "%"); - clonetiler_table_attach (table, l, 0, 3, 3); - } - - { - GtkWidget *l = clonetiler_spinbox (_("Randomize the vertical scale by this percentage"), "scaley_rand", - 0, 1000, "%"); - clonetiler_table_attach (table, l, 0, 3, 4); - } - - // Exponent - { - GtkWidget *l = gtk_label_new (""); - gtk_label_set_markup (GTK_LABEL(l), _("Exponent:")); - gtk_size_group_add_widget(table_row_labels, l); - clonetiler_table_attach (table, l, 1, 4, 1); - } - - { - GtkWidget *l = clonetiler_spinbox (_("Whether row scaling is uniform (1), converge (<1) or diverge (>1)"), "scaley_exp", - 0, 10, "", true); - clonetiler_table_attach (table, l, 0, 4, 2); - } - - { - GtkWidget *l = clonetiler_spinbox (_("Whether column scaling is uniform (1), converge (<1) or diverge (>1)"), "scalex_exp", - 0, 10, "", true); - clonetiler_table_attach (table, l, 0, 4, 3); - } - - // Logarithmic (as in logarithmic spiral) - { - GtkWidget *l = gtk_label_new (""); - gtk_label_set_markup (GTK_LABEL(l), _("Base:")); - gtk_size_group_add_widget(table_row_labels, l); - clonetiler_table_attach (table, l, 1, 5, 1); - } - - { - GtkWidget *l = clonetiler_spinbox (_("Base for a logarithmic spiral: not used (0), converge (<1), or diverge (>1)"), "scaley_log", - 0, 10, "", false); - clonetiler_table_attach (table, l, 0, 5, 2); - } - - { - GtkWidget *l = clonetiler_spinbox (_("Base for a logarithmic spiral: not used (0), converge (<1), or diverge (>1)"), "scalex_log", - 0, 10, "", false); - clonetiler_table_attach (table, l, 0, 5, 3); - } - - { // alternates - GtkWidget *l = gtk_label_new (""); - // TRANSLATORS: "Alternate" is a verb here - gtk_label_set_markup (GTK_LABEL(l), _("Alternate:")); - gtk_size_group_add_widget(table_row_labels, l); - clonetiler_table_attach (table, l, 1, 6, 1); - } - - { - GtkWidget *l = clonetiler_checkbox (_("Alternate the sign of scales for each row"), "scaley_alternate"); - clonetiler_table_attach (table, l, 0, 6, 2); - } - - { - GtkWidget *l = clonetiler_checkbox (_("Alternate the sign of scales for each column"), "scalex_alternate"); - clonetiler_table_attach (table, l, 0, 6, 3); - } - - { // Cumulate - GtkWidget *l = gtk_label_new (""); - // TRANSLATORS: "Cumulate" is a verb here - gtk_label_set_markup (GTK_LABEL(l), _("Cumulate:")); - gtk_size_group_add_widget(table_row_labels, l); - clonetiler_table_attach (table, l, 1, 7, 1); - } - - { - GtkWidget *l = clonetiler_checkbox (_("Cumulate the scales for each row"), "scaley_cumulate"); - clonetiler_table_attach (table, l, 0, 7, 2); - } - - { - GtkWidget *l = clonetiler_checkbox (_("Cumulate the scales for each column"), "scalex_cumulate"); - clonetiler_table_attach (table, l, 0, 7, 3); - } - - } - - -// Rotation - { - GtkWidget *vb = clonetiler_new_tab (nb, _("_Rotation")); - - GtkWidget *table = clonetiler_table_x_y_rand (1); - gtk_box_pack_start (GTK_BOX (vb), table, FALSE, FALSE, 0); - - // Angle - { - GtkWidget *l = gtk_label_new (""); - gtk_label_set_markup (GTK_LABEL(l), _("Angle:")); - gtk_size_group_add_widget(table_row_labels, l); - clonetiler_table_attach (table, l, 1, 2, 1); - } - - { - GtkWidget *l = clonetiler_spinbox ( - // xgettext:no-c-format - _("Rotate tiles by this angle for each row"), "rotate_per_j", - -180, 180, "°"); - clonetiler_table_attach (table, l, 0, 2, 2); - } - - { - GtkWidget *l = clonetiler_spinbox ( - // xgettext:no-c-format - _("Rotate tiles by this angle for each column"), "rotate_per_i", - -180, 180, "°"); - clonetiler_table_attach (table, l, 0, 2, 3); - } - - { - GtkWidget *l = clonetiler_spinbox (_("Randomize the rotation angle by this percentage"), "rotate_rand", - 0, 100, "%"); - clonetiler_table_attach (table, l, 0, 2, 4); - } - - { // alternates - GtkWidget *l = gtk_label_new (""); - // TRANSLATORS: "Alternate" is a verb here - gtk_label_set_markup (GTK_LABEL(l), _("Alternate:")); - gtk_size_group_add_widget(table_row_labels, l); - clonetiler_table_attach (table, l, 1, 3, 1); - } - - { - GtkWidget *l = clonetiler_checkbox (_("Alternate the rotation direction for each row"), "rotate_alternatej"); - clonetiler_table_attach (table, l, 0, 3, 2); - } - - { - GtkWidget *l = clonetiler_checkbox (_("Alternate the rotation direction for each column"), "rotate_alternatei"); - clonetiler_table_attach (table, l, 0, 3, 3); - } - - { // Cumulate - GtkWidget *l = gtk_label_new (""); - // TRANSLATORS: "Cumulate" is a verb here - gtk_label_set_markup (GTK_LABEL(l), _("Cumulate:")); - gtk_size_group_add_widget(table_row_labels, l); - clonetiler_table_attach (table, l, 1, 4, 1); - } - - { - GtkWidget *l = clonetiler_checkbox (_("Cumulate the rotation for each row"), "rotate_cumulatej"); - clonetiler_table_attach (table, l, 0, 4, 2); - } - - { - GtkWidget *l = clonetiler_checkbox (_("Cumulate the rotation for each column"), "rotate_cumulatei"); - clonetiler_table_attach (table, l, 0, 4, 3); - } - - } - - -// Blur and opacity - { - GtkWidget *vb = clonetiler_new_tab (nb, _("_Blur & opacity")); - - GtkWidget *table = clonetiler_table_x_y_rand (1); - gtk_box_pack_start (GTK_BOX (vb), table, FALSE, FALSE, 0); - - - // Blur - { - GtkWidget *l = gtk_label_new (""); - gtk_label_set_markup (GTK_LABEL(l), _("Blur:")); - gtk_size_group_add_widget(table_row_labels, l); - clonetiler_table_attach (table, l, 1, 2, 1); - } - - { - GtkWidget *l = clonetiler_spinbox (_("Blur tiles by this percentage for each row"), "blur_per_j", - 0, 100, "%"); - clonetiler_table_attach (table, l, 0, 2, 2); - } - - { - GtkWidget *l = clonetiler_spinbox (_("Blur tiles by this percentage for each column"), "blur_per_i", - 0, 100, "%"); - clonetiler_table_attach (table, l, 0, 2, 3); - } - - { - GtkWidget *l = clonetiler_spinbox (_("Randomize the tile blur by this percentage"), "blur_rand", - 0, 100, "%"); - clonetiler_table_attach (table, l, 0, 2, 4); - } - - { // alternates - GtkWidget *l = gtk_label_new (""); - // TRANSLATORS: "Alternate" is a verb here - gtk_label_set_markup (GTK_LABEL(l), _("Alternate:")); - gtk_size_group_add_widget(table_row_labels, l); - clonetiler_table_attach (table, l, 1, 3, 1); - } - - { - GtkWidget *l = clonetiler_checkbox (_("Alternate the sign of blur change for each row"), "blur_alternatej"); - clonetiler_table_attach (table, l, 0, 3, 2); - } - - { - GtkWidget *l = clonetiler_checkbox (_("Alternate the sign of blur change for each column"), "blur_alternatei"); - clonetiler_table_attach (table, l, 0, 3, 3); - } - - - - // Dissolve - { - GtkWidget *l = gtk_label_new (""); - gtk_label_set_markup (GTK_LABEL(l), _("Opacity:")); - gtk_size_group_add_widget(table_row_labels, l); - clonetiler_table_attach (table, l, 1, 4, 1); - } - - { - GtkWidget *l = clonetiler_spinbox (_("Decrease tile opacity by this percentage for each row"), "opacity_per_j", - 0, 100, "%"); - clonetiler_table_attach (table, l, 0, 4, 2); - } - - { - GtkWidget *l = clonetiler_spinbox (_("Decrease tile opacity by this percentage for each column"), "opacity_per_i", - 0, 100, "%"); - clonetiler_table_attach (table, l, 0, 4, 3); - } - - { - GtkWidget *l = clonetiler_spinbox (_("Randomize the tile opacity by this percentage"), "opacity_rand", - 0, 100, "%"); - clonetiler_table_attach (table, l, 0, 4, 4); - } - - { // alternates - GtkWidget *l = gtk_label_new (""); - // TRANSLATORS: "Alternate" is a verb here - gtk_label_set_markup (GTK_LABEL(l), _("Alternate:")); - gtk_size_group_add_widget(table_row_labels, l); - clonetiler_table_attach (table, l, 1, 5, 1); - } - - { - GtkWidget *l = clonetiler_checkbox (_("Alternate the sign of opacity change for each row"), "opacity_alternatej"); - clonetiler_table_attach (table, l, 0, 5, 2); - } - - { - GtkWidget *l = clonetiler_checkbox (_("Alternate the sign of opacity change for each column"), "opacity_alternatei"); - clonetiler_table_attach (table, l, 0, 5, 3); - } - } - - -// Color - { - GtkWidget *vb = clonetiler_new_tab (nb, _("Co_lor")); - - { - GtkWidget *hb = gtk_hbox_new (FALSE, 0); - - GtkWidget *l = gtk_label_new (_("Initial color: ")); - gtk_box_pack_start (GTK_BOX (hb), l, FALSE, FALSE, 0); - - guint32 rgba = 0x000000ff | sp_svg_read_color (prefs->getString(prefs_path + "initial_color").data(), 0x000000ff); - color_picker = new Inkscape::UI::Widget::ColorPicker (*new Glib::ustring(_("Initial color of tiled clones")), *new Glib::ustring(_("Initial color for clones (works only if the original has unset fill or stroke)")), rgba, false); - _color_changed_connection = color_picker->connectChanged (sigc::ptr_fun(on_picker_color_changed)); - - gtk_box_pack_start (GTK_BOX (hb), reinterpret_cast(color_picker->gobj()), FALSE, FALSE, 0); - - gtk_box_pack_start (GTK_BOX (vb), hb, FALSE, FALSE, 0); - } - - - GtkWidget *table = clonetiler_table_x_y_rand (3); - gtk_box_pack_start (GTK_BOX (vb), table, FALSE, FALSE, 0); - - // Hue - { - GtkWidget *l = gtk_label_new (""); - gtk_label_set_markup (GTK_LABEL(l), _("H:")); - gtk_size_group_add_widget(table_row_labels, l); - clonetiler_table_attach (table, l, 1, 2, 1); - } - - { - GtkWidget *l = clonetiler_spinbox (_("Change the tile hue by this percentage for each row"), "hue_per_j", - -100, 100, "%"); - clonetiler_table_attach (table, l, 0, 2, 2); - } - - { - GtkWidget *l = clonetiler_spinbox (_("Change the tile hue by this percentage for each column"), "hue_per_i", - -100, 100, "%"); - clonetiler_table_attach (table, l, 0, 2, 3); - } - - { - GtkWidget *l = clonetiler_spinbox (_("Randomize the tile hue by this percentage"), "hue_rand", - 0, 100, "%"); - clonetiler_table_attach (table, l, 0, 2, 4); - } - - - // Saturation - { - GtkWidget *l = gtk_label_new (""); - gtk_label_set_markup (GTK_LABEL(l), _("S:")); - gtk_size_group_add_widget(table_row_labels, l); - clonetiler_table_attach (table, l, 1, 3, 1); - } - - { - GtkWidget *l = clonetiler_spinbox (_("Change the color saturation by this percentage for each row"), "saturation_per_j", - -100, 100, "%"); - clonetiler_table_attach (table, l, 0, 3, 2); - } - - { - GtkWidget *l = clonetiler_spinbox (_("Change the color saturation by this percentage for each column"), "saturation_per_i", - -100, 100, "%"); - clonetiler_table_attach (table, l, 0, 3, 3); - } - - { - GtkWidget *l = clonetiler_spinbox (_("Randomize the color saturation by this percentage"), "saturation_rand", - 0, 100, "%"); - clonetiler_table_attach (table, l, 0, 3, 4); - } - - // Lightness - { - GtkWidget *l = gtk_label_new (""); - gtk_label_set_markup (GTK_LABEL(l), _("L:")); - gtk_size_group_add_widget(table_row_labels, l); - clonetiler_table_attach (table, l, 1, 4, 1); - } - - { - GtkWidget *l = clonetiler_spinbox (_("Change the color lightness by this percentage for each row"), "lightness_per_j", - -100, 100, "%"); - clonetiler_table_attach (table, l, 0, 4, 2); - } - - { - GtkWidget *l = clonetiler_spinbox (_("Change the color lightness by this percentage for each column"), "lightness_per_i", - -100, 100, "%"); - clonetiler_table_attach (table, l, 0, 4, 3); - } - - { - GtkWidget *l = clonetiler_spinbox (_("Randomize the color lightness by this percentage"), "lightness_rand", - 0, 100, "%"); - clonetiler_table_attach (table, l, 0, 4, 4); - } - - - { // alternates - GtkWidget *l = gtk_label_new (""); - gtk_label_set_markup (GTK_LABEL(l), _("Alternate:")); - gtk_size_group_add_widget(table_row_labels, l); - clonetiler_table_attach (table, l, 1, 5, 1); - } - - { - GtkWidget *l = clonetiler_checkbox (_("Alternate the sign of color changes for each row"), "color_alternatej"); - clonetiler_table_attach (table, l, 0, 5, 2); - } - - { - GtkWidget *l = clonetiler_checkbox (_("Alternate the sign of color changes for each column"), "color_alternatei"); - clonetiler_table_attach (table, l, 0, 5, 3); - } - - } - -// Trace - { - GtkWidget *vb = clonetiler_new_tab (nb, _("_Trace")); - - - { - GtkWidget *hb = gtk_hbox_new(FALSE, VB_MARGIN); - gtk_box_pack_start (GTK_BOX (vb), hb, FALSE, FALSE, 0); - - GtkWidget *b = gtk_check_button_new_with_label (_("Trace the drawing under the tiles")); - g_object_set_data (G_OBJECT(b), "uncheckable", GINT_TO_POINTER(TRUE)); - bool old = prefs->getBool(prefs_path + "dotrace"); - gtk_toggle_button_set_active ((GtkToggleButton *) b, old); - gtk_widget_set_tooltip_text (b, _("For each clone, pick a value from the drawing in that clone's location and apply it to the clone")); - gtk_box_pack_start (GTK_BOX (hb), b, FALSE, FALSE, 0); - - g_signal_connect(G_OBJECT(b), "toggled", - G_CALLBACK(clonetiler_do_pick_toggled), dlg); - } - - { - GtkWidget *vvb = gtk_vbox_new (FALSE, 0); - gtk_box_pack_start (GTK_BOX (vb), vvb, FALSE, FALSE, 0); - g_object_set_data (G_OBJECT(dlg), "dotrace", (gpointer) vvb); - - - { - GtkWidget *frame = gtk_frame_new (_("1. Pick from the drawing:")); - gtk_box_pack_start (GTK_BOX (vvb), frame, FALSE, FALSE, 0); - - GtkWidget *table = gtk_table_new (3, 3, FALSE); - gtk_table_set_row_spacings (GTK_TABLE (table), 4); - gtk_table_set_col_spacings (GTK_TABLE (table), 6); - gtk_container_add(GTK_CONTAINER(frame), table); - - - GtkWidget* radio; - { - radio = gtk_radio_button_new_with_label (NULL, _("Color")); - gtk_widget_set_tooltip_text (radio, _("Pick the visible color and opacity")); - clonetiler_table_attach (table, radio, 0.0, 1, 1); - g_signal_connect (G_OBJECT (radio), "toggled", - G_CALLBACK (clonetiler_pick_switched), GINT_TO_POINTER(PICK_COLOR)); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio), prefs->getInt(prefs_path + "pick", 0) == PICK_COLOR); - } - { - radio = gtk_radio_button_new_with_label (gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio)), _("Opacity")); - gtk_widget_set_tooltip_text (radio, _("Pick the total accumulated opacity")); - clonetiler_table_attach (table, radio, 0.0, 2, 1); - g_signal_connect (G_OBJECT (radio), "toggled", - G_CALLBACK (clonetiler_pick_switched), GINT_TO_POINTER(PICK_OPACITY)); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio), prefs->getInt(prefs_path + "pick", 0) == PICK_OPACITY); - } - { - radio = gtk_radio_button_new_with_label (gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio)), _("R")); - gtk_widget_set_tooltip_text (radio, _("Pick the Red component of the color")); - clonetiler_table_attach (table, radio, 0.0, 1, 2); - g_signal_connect (G_OBJECT (radio), "toggled", - G_CALLBACK (clonetiler_pick_switched), GINT_TO_POINTER(PICK_R)); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio), prefs->getInt(prefs_path + "pick", 0) == PICK_R); - } - { - radio = gtk_radio_button_new_with_label (gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio)), _("G")); - gtk_widget_set_tooltip_text (radio, _("Pick the Green component of the color")); - clonetiler_table_attach (table, radio, 0.0, 2, 2); - g_signal_connect (G_OBJECT (radio), "toggled", - G_CALLBACK (clonetiler_pick_switched), GINT_TO_POINTER(PICK_G)); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio), prefs->getInt(prefs_path + "pick", 0) == PICK_G); - } - { - radio = gtk_radio_button_new_with_label (gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio)), _("B")); - gtk_widget_set_tooltip_text (radio, _("Pick the Blue component of the color")); - clonetiler_table_attach (table, radio, 0.0, 3, 2); - g_signal_connect (G_OBJECT (radio), "toggled", - G_CALLBACK (clonetiler_pick_switched), GINT_TO_POINTER(PICK_B)); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio), prefs->getInt(prefs_path + "pick", 0) == PICK_B); - } - { - radio = gtk_radio_button_new_with_label (gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio)), C_("Clonetiler color hue", "H")); - gtk_widget_set_tooltip_text (radio, _("Pick the hue of the color")); - clonetiler_table_attach (table, radio, 0.0, 1, 3); - g_signal_connect (G_OBJECT (radio), "toggled", - G_CALLBACK (clonetiler_pick_switched), GINT_TO_POINTER(PICK_H)); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio), prefs->getInt(prefs_path + "pick", 0) == PICK_H); - } - { - radio = gtk_radio_button_new_with_label (gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio)), C_("Clonetiler color saturation", "S")); - gtk_widget_set_tooltip_text (radio, _("Pick the saturation of the color")); - clonetiler_table_attach (table, radio, 0.0, 2, 3); - g_signal_connect (G_OBJECT (radio), "toggled", - G_CALLBACK (clonetiler_pick_switched), GINT_TO_POINTER(PICK_S)); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio), prefs->getInt(prefs_path + "pick", 0) == PICK_S); - } - { - radio = gtk_radio_button_new_with_label (gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio)), C_("Clonetiler color lightness", "L")); - gtk_widget_set_tooltip_text (radio, _("Pick the lightness of the color")); - clonetiler_table_attach (table, radio, 0.0, 3, 3); - g_signal_connect (G_OBJECT (radio), "toggled", - G_CALLBACK (clonetiler_pick_switched), GINT_TO_POINTER(PICK_L)); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio), prefs->getInt(prefs_path + "pick", 0) == PICK_L); - } - - } - - { - GtkWidget *frame = gtk_frame_new (_("2. Tweak the picked value:")); - gtk_box_pack_start (GTK_BOX (vvb), frame, FALSE, FALSE, VB_MARGIN); - - GtkWidget *table = gtk_table_new (4, 2, FALSE); - gtk_table_set_row_spacings (GTK_TABLE (table), 4); - gtk_table_set_col_spacings (GTK_TABLE (table), 6); - gtk_container_add(GTK_CONTAINER(frame), table); - - { - GtkWidget *l = gtk_label_new (""); - gtk_label_set_markup (GTK_LABEL(l), _("Gamma-correct:")); - clonetiler_table_attach (table, l, 1.0, 1, 1); - } - { - GtkWidget *l = clonetiler_spinbox (_("Shift the mid-range of the picked value upwards (>0) or downwards (<0)"), "gamma_picked", - -10, 10, ""); - clonetiler_table_attach (table, l, 0.0, 1, 2); - } - - { - GtkWidget *l = gtk_label_new (""); - gtk_label_set_markup (GTK_LABEL(l), _("Randomize:")); - clonetiler_table_attach (table, l, 1.0, 1, 3); - } - { - GtkWidget *l = clonetiler_spinbox (_("Randomize the picked value by this percentage"), "rand_picked", - 0, 100, "%"); - clonetiler_table_attach (table, l, 0.0, 1, 4); - } - - { - GtkWidget *l = gtk_label_new (""); - gtk_label_set_markup (GTK_LABEL(l), _("Invert:")); - clonetiler_table_attach (table, l, 1.0, 2, 1); - } - { - GtkWidget *l = clonetiler_checkbox (_("Invert the picked value"), "invert_picked"); - clonetiler_table_attach (table, l, 0.0, 2, 2); - } - } - - { - GtkWidget *frame = gtk_frame_new (_("3. Apply the value to the clones':")); - gtk_box_pack_start (GTK_BOX (vvb), frame, FALSE, FALSE, 0); - - - GtkWidget *table = gtk_table_new (2, 2, FALSE); - gtk_table_set_row_spacings (GTK_TABLE (table), 4); - gtk_table_set_col_spacings (GTK_TABLE (table), 6); - gtk_container_add(GTK_CONTAINER(frame), table); - - { - GtkWidget *b = gtk_check_button_new_with_label (_("Presence")); - bool old = prefs->getBool(prefs_path + "pick_to_presence", true); - gtk_toggle_button_set_active ((GtkToggleButton *) b, old); - gtk_widget_set_tooltip_text (b, _("Each clone is created with the probability determined by the picked value in that point")); - clonetiler_table_attach (table, b, 0.0, 1, 1); - g_signal_connect(G_OBJECT(b), "toggled", - G_CALLBACK(clonetiler_pick_to), (gpointer) "pick_to_presence"); - } - - { - GtkWidget *b = gtk_check_button_new_with_label (_("Size")); - bool old = prefs->getBool(prefs_path + "pick_to_size"); - gtk_toggle_button_set_active ((GtkToggleButton *) b, old); - gtk_widget_set_tooltip_text (b, _("Each clone's size is determined by the picked value in that point")); - clonetiler_table_attach (table, b, 0.0, 2, 1); - g_signal_connect(G_OBJECT(b), "toggled", - G_CALLBACK(clonetiler_pick_to), (gpointer) "pick_to_size"); - } - - { - GtkWidget *b = gtk_check_button_new_with_label (_("Color")); - bool old = prefs->getBool(prefs_path + "pick_to_color", 0); - gtk_toggle_button_set_active ((GtkToggleButton *) b, old); - gtk_widget_set_tooltip_text (b, _("Each clone is painted by the picked color (the original must have unset fill or stroke)")); - clonetiler_table_attach (table, b, 0.0, 1, 2); - g_signal_connect(G_OBJECT(b), "toggled", - G_CALLBACK(clonetiler_pick_to), (gpointer) "pick_to_color"); - } - - { - GtkWidget *b = gtk_check_button_new_with_label (_("Opacity")); - bool old = prefs->getBool(prefs_path + "pick_to_opacity", 0); - gtk_toggle_button_set_active ((GtkToggleButton *) b, old); - gtk_widget_set_tooltip_text (b, _("Each clone's opacity is determined by the picked value in that point")); - clonetiler_table_attach (table, b, 0.0, 2, 2); - g_signal_connect(G_OBJECT(b), "toggled", - G_CALLBACK(clonetiler_pick_to), (gpointer) "pick_to_opacity"); - } - } - gtk_widget_set_sensitive (vvb, prefs->getBool(prefs_path + "dotrace")); - } - } - -// Rows/columns, width/height - { - GtkWidget *table = gtk_table_new (2, 2, FALSE); - gtk_container_set_border_width (GTK_CONTAINER (table), VB_MARGIN); - gtk_table_set_row_spacings (GTK_TABLE (table), 4); - gtk_table_set_col_spacings (GTK_TABLE (table), 6); - gtk_box_pack_start (GTK_BOX (mainbox), table, FALSE, FALSE, 0); - - { - GtkWidget *hb = gtk_hbox_new(FALSE, VB_MARGIN); - g_object_set_data (G_OBJECT(dlg), "rowscols", (gpointer) hb); - - { - Gtk::Adjustment *a = new Gtk::Adjustment (0.0, 1, 500, 1, 10, 0); - int value = prefs->getInt(prefs_path + "jmax", 2); - a->set_value (value); - - Inkscape::UI::Widget::SpinButton *sb = new Inkscape::UI::Widget::SpinButton (*a, 1.0, 0); - sb->set_tooltip_text (_("How many rows in the tiling")); - sb->set_width_chars (7); - gtk_box_pack_start (GTK_BOX (hb), GTK_WIDGET(sb->gobj()), TRUE, TRUE, 0); - - // TODO: C++ification - g_signal_connect(G_OBJECT(a->gobj()), "value_changed", - G_CALLBACK(clonetiler_xy_changed), (gpointer) "jmax"); - } - - { - GtkWidget *l = gtk_label_new (""); - gtk_label_set_markup (GTK_LABEL(l), "×"); - gtk_misc_set_alignment (GTK_MISC (l), 1.0, 0.5); - gtk_box_pack_start (GTK_BOX (hb), l, TRUE, TRUE, 0); - } - - { - Gtk::Adjustment *a = new Gtk::Adjustment (0.0, 1, 500, 1, 10, 0); - int value = prefs->getInt(prefs_path + "imax", 2); - a->set_value (value); - - Inkscape::UI::Widget::SpinButton *sb = new Inkscape::UI::Widget::SpinButton (*a, 1.0, 0); - sb->set_tooltip_text (_("How many columns in the tiling")); - sb->set_width_chars (7); - gtk_box_pack_start (GTK_BOX (hb), GTK_WIDGET(sb->gobj()), TRUE, TRUE, 0); - - // TODO: C++ification - g_signal_connect(G_OBJECT(a->gobj()), "value_changed", - G_CALLBACK(clonetiler_xy_changed), (gpointer) "imax"); - } - - clonetiler_table_attach (table, hb, 0.0, 1, 2); - } - - { - GtkWidget *hb = gtk_hbox_new(FALSE, VB_MARGIN); - g_object_set_data (G_OBJECT(dlg), "widthheight", (gpointer) hb); - - // unitmenu - GtkWidget *u = sp_unit_selector_new (SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE); - sp_unit_selector_set_unit (SP_UNIT_SELECTOR(u), sp_desktop_namedview(SP_ACTIVE_DESKTOP)->doc_units); - - { - // Width spinbutton - Gtk::Adjustment *a = new Gtk::Adjustment (0.0, -1e6, 1e6, 1.0, 10.0, 0); - sp_unit_selector_add_adjustment (SP_UNIT_SELECTOR (u), GTK_ADJUSTMENT (a->gobj())); - - double value = prefs->getDouble(prefs_path + "fillwidth", 50.0); - SPUnit const &unit = *sp_unit_selector_get_unit(SP_UNIT_SELECTOR(u)); - gdouble const units = sp_pixels_get_units (value, unit); - a->set_value (units); - - Inkscape::UI::Widget::SpinButton *e = new Inkscape::UI::Widget::SpinButton (*a, 1.0, 2); - e->set_tooltip_text (_("Width of the rectangle to be filled")); - e->set_width_chars (7); - e->set_digits (4); - gtk_box_pack_start (GTK_BOX (hb), GTK_WIDGET(e->gobj()), TRUE, TRUE, 0); - // TODO: C++ification - g_signal_connect(G_OBJECT(a->gobj()), "value_changed", - G_CALLBACK(clonetiler_fill_width_changed), u); - } - { - GtkWidget *l = gtk_label_new (""); - gtk_label_set_markup (GTK_LABEL(l), "×"); - gtk_misc_set_alignment (GTK_MISC (l), 1.0, 0.5); - gtk_box_pack_start (GTK_BOX (hb), l, TRUE, TRUE, 0); - } - - { - // Height spinbutton - Gtk::Adjustment *a = new Gtk::Adjustment (0.0, -1e6, 1e6, 1.0, 10.0, 0); - sp_unit_selector_add_adjustment (SP_UNIT_SELECTOR (u), GTK_ADJUSTMENT (a->gobj())); - - double value = prefs->getDouble(prefs_path + "fillheight", 50.0); - SPUnit const &unit = *sp_unit_selector_get_unit(SP_UNIT_SELECTOR(u)); - gdouble const units = sp_pixels_get_units (value, unit); - a->set_value (units); - - Inkscape::UI::Widget::SpinButton *e = new Inkscape::UI::Widget::SpinButton (*a, 1.0, 2); - e->set_tooltip_text (_("Height of the rectangle to be filled")); - e->set_width_chars (7); - e->set_digits (4); - gtk_box_pack_start (GTK_BOX (hb), GTK_WIDGET(e->gobj()), TRUE, TRUE, 0); - // TODO: C++ification - g_signal_connect(G_OBJECT(a->gobj()), "value_changed", - G_CALLBACK(clonetiler_fill_height_changed), u); - } - - gtk_box_pack_start (GTK_BOX (hb), u, TRUE, TRUE, 0); - clonetiler_table_attach (table, hb, 0.0, 2, 2); - - } - - // Switch - GtkWidget* radio; - { - radio = gtk_radio_button_new_with_label (NULL, _("Rows, columns: ")); - gtk_widget_set_tooltip_text (radio, _("Create the specified number of rows and columns")); - clonetiler_table_attach (table, radio, 0.0, 1, 1); - g_signal_connect (G_OBJECT (radio), "toggled", G_CALLBACK (clonetiler_switch_to_create), (gpointer) dlg); - } - if (!prefs->getBool(prefs_path + "fillrect")) { - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio), TRUE); - gtk_toggle_button_toggled (GTK_TOGGLE_BUTTON (radio)); - } - { - radio = gtk_radio_button_new_with_label (gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio)), _("Width, height: ")); - gtk_widget_set_tooltip_text (radio, _("Fill the specified width and height with the tiling")); - clonetiler_table_attach (table, radio, 0.0, 2, 1); - g_signal_connect (G_OBJECT (radio), "toggled", G_CALLBACK (clonetiler_switch_to_fill), (gpointer) dlg); - } - if (prefs->getBool(prefs_path + "fillrect")) { - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio), TRUE); - gtk_toggle_button_toggled (GTK_TOGGLE_BUTTON (radio)); - } - } - - -// Use saved pos - { - GtkWidget *hb = gtk_hbox_new(FALSE, VB_MARGIN); - gtk_box_pack_start (GTK_BOX (mainbox), hb, FALSE, FALSE, 0); - - GtkWidget *b = gtk_check_button_new_with_label (_("Use saved size and position of the tile")); - bool keepbbox = prefs->getBool(prefs_path + "keepbbox", true); - gtk_toggle_button_set_active ((GtkToggleButton *) b, keepbbox); - gtk_widget_set_tooltip_text (b, _("Pretend that the size and position of the tile are the same as the last time you tiled it (if any), instead of using the current size")); - gtk_box_pack_start (GTK_BOX (hb), b, FALSE, FALSE, 0); - - g_signal_connect(G_OBJECT(b), "toggled", - G_CALLBACK(clonetiler_keep_bbox_toggled), NULL); - } - -// Statusbar - { - GtkWidget *hb = gtk_hbox_new(FALSE, VB_MARGIN); - gtk_box_pack_end (GTK_BOX (mainbox), hb, FALSE, FALSE, 0); - GtkWidget *l = gtk_label_new(""); - g_object_set_data (G_OBJECT(dlg), "status", (gpointer) l); - gtk_box_pack_start (GTK_BOX (hb), l, FALSE, FALSE, 0); - } - -// Buttons - { - GtkWidget *hb = gtk_hbox_new(FALSE, VB_MARGIN); - gtk_box_pack_start (GTK_BOX (mainbox), hb, FALSE, FALSE, 0); - - { - GtkWidget *b = gtk_button_new (); - GtkWidget *l = gtk_label_new (""); - gtk_label_set_markup_with_mnemonic (GTK_LABEL(l), _(" _Create ")); - gtk_container_add (GTK_CONTAINER(b), l); - gtk_widget_set_tooltip_text (b, _("Create and tile the clones of the selection")); - g_signal_connect (G_OBJECT (b), "clicked", G_CALLBACK (clonetiler_apply), NULL); - gtk_box_pack_end (GTK_BOX (hb), b, FALSE, FALSE, 0); - } - - { // buttons which are enabled only when there are tiled clones - GtkWidget *sb = gtk_hbox_new(FALSE, 0); - gtk_box_pack_end (GTK_BOX (hb), sb, FALSE, FALSE, 0); - g_object_set_data (G_OBJECT(dlg), "buttons_on_tiles", (gpointer) sb); - { - // TRANSLATORS: if a group of objects are "clumped" together, then they - // are unevenly spread in the given amount of space - as shown in the - // diagrams on the left in the following screenshot: - // http://www.inkscape.org/screenshots/gallery/inkscape-0.42-CVS-tiles-unclump.png - // So unclumping is the process of spreading a number of objects out more evenly. - GtkWidget *b = gtk_button_new_with_mnemonic (_(" _Unclump ")); - gtk_widget_set_tooltip_text (b, _("Spread out clones to reduce clumping; can be applied repeatedly")); - g_signal_connect (G_OBJECT (b), "clicked", G_CALLBACK (clonetiler_unclump), NULL); - gtk_box_pack_end (GTK_BOX (sb), b, FALSE, FALSE, 0); - } - - { - GtkWidget *b = gtk_button_new_with_mnemonic (_(" Re_move ")); - gtk_widget_set_tooltip_text (b, _("Remove existing tiled clones of the selected object (siblings only)")); - g_signal_connect (G_OBJECT (b), "clicked", G_CALLBACK (clonetiler_remove), NULL); - gtk_box_pack_end (GTK_BOX (sb), b, FALSE, FALSE, 0); - } - - // connect to global selection changed signal (so we can change desktops) and - // external_change (so we're not fooled by undo) - g_signal_connect (G_OBJECT (INKSCAPE), "change_selection", G_CALLBACK (clonetiler_change_selection), dlg); - g_signal_connect (G_OBJECT (INKSCAPE), "external_change", G_CALLBACK (clonetiler_external_change), dlg); - g_signal_connect(G_OBJECT(dlg), "destroy", G_CALLBACK(clonetiler_disconnect_gsignal), G_OBJECT (INKSCAPE)); - - // update now - clonetiler_change_selection (NULL, sp_desktop_selection(SP_ACTIVE_DESKTOP), dlg); - } - - { - GtkWidget *b = gtk_button_new_with_mnemonic (_(" R_eset ")); - // TRANSLATORS: "change" is a noun here - gtk_widget_set_tooltip_text (b, _("Reset all shifts, scales, rotates, opacity and color changes in the dialog to zero")); - g_signal_connect (G_OBJECT (b), "clicked", G_CALLBACK (clonetiler_reset), NULL); - gtk_box_pack_start (GTK_BOX (hb), b, FALSE, FALSE, 0); - } - } - - gtk_widget_show_all (mainbox); - - } // end of if (!dlg) - - gtk_window_present ((GtkWindow *) dlg); -} - - -/* - 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/dialogs/clonetiler.h b/src/dialogs/clonetiler.h deleted file mode 100644 index 899181346..000000000 --- a/src/dialogs/clonetiler.h +++ /dev/null @@ -1,30 +0,0 @@ -/** @file - * @brief Clone tiling dialog - */ -/* Authors: - * bulia byak - * - * Copyright (C) 2004 Authors - * Released under the GNU GPL, read the file 'COPYING' for more information - */ -#ifndef __SP_CLONE_TILER_H__ -#define __SP_CLONE_TILER_H__ - -#include - -#include - -void clonetiler_dialog ( void ); - -#endif - -/* - 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/CMakeLists.txt b/src/ui/CMakeLists.txt index 484edc6e2..35840e0c4 100644 --- a/src/ui/CMakeLists.txt +++ b/src/ui/CMakeLists.txt @@ -25,6 +25,7 @@ set(ui_SRC dialog/align-and-distribute.cpp dialog/calligraphic-profile-rename.cpp dialog/color-item.cpp + dialog/clonetiler.cpp dialog/debug.cpp dialog/desktop-tracker.cpp dialog/dialog-manager.cpp @@ -134,6 +135,7 @@ set(ui_SRC dialog/behavior.h dialog/calligraphic-profile-rename.h dialog/color-item.h + dialog/clonetiler.h dialog/debug.h dialog/desktop-tracker.h dialog/dialog-manager.h diff --git a/src/ui/dialog/Makefile_insert b/src/ui/dialog/Makefile_insert index 91b1ccaf6..f8b95247a 100644 --- a/src/ui/dialog/Makefile_insert +++ b/src/ui/dialog/Makefile_insert @@ -8,6 +8,8 @@ ink_common_sources += \ ui/dialog/behavior.h \ ui/dialog/calligraphic-profile-rename.h \ ui/dialog/calligraphic-profile-rename.cpp \ + ui/dialog/clonetiler.cpp \ + ui/dialog/clonetiler.h \ ui/dialog/color-item.cpp \ ui/dialog/color-item.h \ ui/dialog/debug.cpp \ diff --git a/src/ui/dialog/clonetiler.cpp b/src/ui/dialog/clonetiler.cpp new file mode 100644 index 000000000..36e79a682 --- /dev/null +++ b/src/ui/dialog/clonetiler.cpp @@ -0,0 +1,2833 @@ + +/** @file + * Clone tiling dialog + */ +/* Authors: + * bulia byak + * Johan Engelen + * Jon A. Cruz + * Abhishek Sharma + * Romain de Bossoreille + * + * Copyright (C) 2004-2011 Authors + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "clonetiler.h" + +#include + +#include +#include +#include <2geom/transforms.h> +#include + +#include "desktop.h" +#include "desktop-handles.h" +#include "display/cairo-utils.h" +#include "display/drawing.h" +#include "display/drawing-context.h" +#include "display/drawing-item.h" +#include "document.h" +#include "document-undo.h" +#include "filter-chemistry.h" +#include "helper/unit-menu.h" +#include "helper/units.h" +#include "helper/window.h" +#include "inkscape.h" +#include "interface.h" +#include "macros.h" +#include "message-stack.h" +#include "preferences.h" +#include "selection.h" +#include "sp-filter.h" +#include "sp-namedview.h" +#include "sp-use.h" +#include "style.h" +#include "svg/svg-color.h" +#include "svg/svg.h" +#include "ui/icon-names.h" +#include "ui/widget/spinbutton.h" +#include "unclump.h" +#include "verbs.h" +#include "widgets/icon.h" +#include "xml/repr.h" +#include "sp-root.h" + +using Inkscape::DocumentUndo; + +namespace Inkscape { +namespace UI { +namespace Dialog { + +#define SB_MARGIN 1 +#define VB_MARGIN 4 + +static Glib::ustring const prefs_path = "/dialogs/clonetiler/"; + +static Inkscape::Drawing *trace_drawing = NULL; +static unsigned trace_visionkey; +static gdouble trace_zoom; +static SPDocument *trace_doc = NULL; + + +CloneTiler::CloneTiler (void) : + UI::Widget::Panel ("", "/dialogs/clonetiler/", SP_VERB_DIALOG_CLONETILER), + dlg(NULL), + desktop(NULL), + deskTrack(), + table_row_labels(NULL), + selectChangedConn(), + subselChangedConn(), + selectModifiedConn() +{ + Gtk::Box *contents = _getContents(); + contents->set_spacing(0); + + { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + + dlg = GTK_WIDGET(gobj()); + + GtkWidget *mainbox = gtk_vbox_new(FALSE, 4); + gtk_container_set_border_width (GTK_CONTAINER (mainbox), 6); + + contents->pack_start (*Gtk::manage(Glib::wrap(mainbox)), true, true, 0); + + GtkWidget *nb = gtk_notebook_new (); + gtk_box_pack_start (GTK_BOX (mainbox), nb, FALSE, FALSE, 0); + + + // Symmetry + { + GtkWidget *vb = clonetiler_new_tab (nb, _("_Symmetry")); + + /* TRANSLATORS: For the following 17 symmetry groups, see + * http://www.bib.ulb.ac.be/coursmath/doc/17.htm (visual examples); + * http://www.clarku.edu/~djoyce/wallpaper/seventeen.html (English vocabulary); or + * http://membres.lycos.fr/villemingerard/Geometri/Sym1D.htm (French vocabulary). + */ + struct SymGroups { + gint group; + gchar const *label; + } const sym_groups[] = { + // TRANSLATORS: "translation" means "shift" / "displacement" here. + {TILE_P1, _("P1: simple translation")}, + {TILE_P2, _("P2: 180° rotation")}, + {TILE_PM, _("PM: reflection")}, + // TRANSLATORS: "glide reflection" is a reflection and a translation combined. + // For more info, see http://mathforum.org/sum95/suzanne/symsusan.html + {TILE_PG, _("PG: glide reflection")}, + {TILE_CM, _("CM: reflection + glide reflection")}, + {TILE_PMM, _("PMM: reflection + reflection")}, + {TILE_PMG, _("PMG: reflection + 180° rotation")}, + {TILE_PGG, _("PGG: glide reflection + 180° rotation")}, + {TILE_CMM, _("CMM: reflection + reflection + 180° rotation")}, + {TILE_P4, _("P4: 90° rotation")}, + {TILE_P4M, _("P4M: 90° rotation + 45° reflection")}, + {TILE_P4G, _("P4G: 90° rotation + 90° reflection")}, + {TILE_P3, _("P3: 120° rotation")}, + {TILE_P31M, _("P31M: reflection + 120° rotation, dense")}, + {TILE_P3M1, _("P3M1: reflection + 120° rotation, sparse")}, + {TILE_P6, _("P6: 60° rotation")}, + {TILE_P6M, _("P6M: reflection + 60° rotation")}, + }; + + gint current = prefs->getInt(prefs_path + "symmetrygroup", 0); + + // Create a list structure containing all the data to be displayed in + // the symmetry group combo box. + GtkListStore *store = gtk_list_store_new (1, G_TYPE_STRING); + GtkTreeIter iter; + + for (unsigned j = 0; j < G_N_ELEMENTS(sym_groups); ++j) { + SymGroups const &sg = sym_groups[j]; + + // Add the description of the symgroup to a new row + gtk_list_store_append(store, &iter); + gtk_list_store_set(store, &iter, 0, sg.label, -1); + } + + // Add a new combo box widget with the list of symmetry groups to the vbox + GtkWidget *combo = gtk_combo_box_new_with_model (GTK_TREE_MODEL (store)); + gtk_widget_set_tooltip_text (combo, _("Select one of the 17 symmetry groups for the tiling")); + gtk_box_pack_start (GTK_BOX (vb), combo, FALSE, FALSE, SB_MARGIN); + + // Specify the rendering of data from the list in a combo box cell + GtkCellRenderer *renderer = gtk_cell_renderer_text_new (); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, FALSE); + gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo), renderer, "markup", 0, NULL); + + gtk_combo_box_set_active (GTK_COMBO_BOX (combo), current); + + g_signal_connect(G_OBJECT(combo), "changed", + G_CALLBACK(clonetiler_symgroup_changed), NULL); + } + + table_row_labels = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); + + // Shift + { + GtkWidget *vb = clonetiler_new_tab (nb, _("S_hift")); + + GtkWidget *table = clonetiler_table_x_y_rand (3); + gtk_box_pack_start (GTK_BOX (vb), table, FALSE, FALSE, 0); + + // X + { + GtkWidget *l = gtk_label_new (""); + // TRANSLATORS: "shift" means: the tiles will be shifted (offset) horizontally by this amount + // xgettext:no-c-format + gtk_label_set_markup (GTK_LABEL(l), _("Shift X:")); + gtk_size_group_add_widget(table_row_labels, l); + clonetiler_table_attach (table, l, 1, 2, 1); + } + + { + GtkWidget *l = clonetiler_spinbox ( + // xgettext:no-c-format + _("Horizontal shift per row (in % of tile width)"), "shiftx_per_j", + -10000, 10000, "%"); + clonetiler_table_attach (table, l, 0, 2, 2); + } + + { + GtkWidget *l = clonetiler_spinbox ( + // xgettext:no-c-format + _("Horizontal shift per column (in % of tile width)"), "shiftx_per_i", + -10000, 10000, "%"); + clonetiler_table_attach (table, l, 0, 2, 3); + } + + { + GtkWidget *l = clonetiler_spinbox (_("Randomize the horizontal shift by this percentage"), "shiftx_rand", + 0, 1000, "%"); + clonetiler_table_attach (table, l, 0, 2, 4); + } + + // Y + { + GtkWidget *l = gtk_label_new (""); + // TRANSLATORS: "shift" means: the tiles will be shifted (offset) vertically by this amount + // xgettext:no-c-format + gtk_label_set_markup (GTK_LABEL(l), _("Shift Y:")); + gtk_size_group_add_widget(table_row_labels, l); + clonetiler_table_attach (table, l, 1, 3, 1); + } + + { + GtkWidget *l = clonetiler_spinbox ( + // xgettext:no-c-format + _("Vertical shift per row (in % of tile height)"), "shifty_per_j", + -10000, 10000, "%"); + clonetiler_table_attach (table, l, 0, 3, 2); + } + + { + GtkWidget *l = clonetiler_spinbox ( + // xgettext:no-c-format + _("Vertical shift per column (in % of tile height)"), "shifty_per_i", + -10000, 10000, "%"); + clonetiler_table_attach (table, l, 0, 3, 3); + } + + { + GtkWidget *l = clonetiler_spinbox ( + _("Randomize the vertical shift by this percentage"), "shifty_rand", + 0, 1000, "%"); + clonetiler_table_attach (table, l, 0, 3, 4); + } + + // Exponent + { + GtkWidget *l = gtk_label_new (""); + gtk_label_set_markup (GTK_LABEL(l), _("Exponent:")); + gtk_size_group_add_widget(table_row_labels, l); + clonetiler_table_attach (table, l, 1, 4, 1); + } + + { + GtkWidget *l = clonetiler_spinbox ( + _("Whether rows are spaced evenly (1), converge (<1) or diverge (>1)"), "shifty_exp", + 0, 10, "", true); + clonetiler_table_attach (table, l, 0, 4, 2); + } + + { + GtkWidget *l = clonetiler_spinbox ( + _("Whether columns are spaced evenly (1), converge (<1) or diverge (>1)"), "shiftx_exp", + 0, 10, "", true); + clonetiler_table_attach (table, l, 0, 4, 3); + } + + { // alternates + GtkWidget *l = gtk_label_new (""); + // TRANSLATORS: "Alternate" is a verb here + gtk_label_set_markup (GTK_LABEL(l), _("Alternate:")); + gtk_size_group_add_widget(table_row_labels, l); + clonetiler_table_attach (table, l, 1, 5, 1); + } + + { + GtkWidget *l = clonetiler_checkbox (_("Alternate the sign of shifts for each row"), "shifty_alternate"); + clonetiler_table_attach (table, l, 0, 5, 2); + } + + { + GtkWidget *l = clonetiler_checkbox (_("Alternate the sign of shifts for each column"), "shiftx_alternate"); + clonetiler_table_attach (table, l, 0, 5, 3); + } + + { // Cumulate + GtkWidget *l = gtk_label_new (""); + // TRANSLATORS: "Cumulate" is a verb here + gtk_label_set_markup (GTK_LABEL(l), _("Cumulate:")); + gtk_size_group_add_widget(table_row_labels, l); + clonetiler_table_attach (table, l, 1, 6, 1); + } + + { + GtkWidget *l = clonetiler_checkbox (_("Cumulate the shifts for each row"), "shifty_cumulate"); + clonetiler_table_attach (table, l, 0, 6, 2); + } + + { + GtkWidget *l = clonetiler_checkbox (_("Cumulate the shifts for each column"), "shiftx_cumulate"); + clonetiler_table_attach (table, l, 0, 6, 3); + } + + { // Exclude tile width and height in shift + GtkWidget *l = gtk_label_new (""); + // TRANSLATORS: "Cumulate" is a verb here + gtk_label_set_markup (GTK_LABEL(l), _("Exclude tile:")); + gtk_size_group_add_widget(table_row_labels, l); + clonetiler_table_attach (table, l, 1, 7, 1); + } + + { + GtkWidget *l = clonetiler_checkbox (_("Exclude tile height in shift"), "shifty_excludeh"); + clonetiler_table_attach (table, l, 0, 7, 2); + } + + { + GtkWidget *l = clonetiler_checkbox (_("Exclude tile width in shift"), "shiftx_excludew"); + clonetiler_table_attach (table, l, 0, 7, 3); + } + + } + + + // Scale + { + GtkWidget *vb = clonetiler_new_tab (nb, _("Sc_ale")); + + GtkWidget *table = clonetiler_table_x_y_rand (2); + gtk_box_pack_start (GTK_BOX (vb), table, FALSE, FALSE, 0); + + // X + { + GtkWidget *l = gtk_label_new (""); + gtk_label_set_markup (GTK_LABEL(l), _("Scale X:")); + gtk_size_group_add_widget(table_row_labels, l); + clonetiler_table_attach (table, l, 1, 2, 1); + } + + { + GtkWidget *l = clonetiler_spinbox ( + // xgettext:no-c-format + _("Horizontal scale per row (in % of tile width)"), "scalex_per_j", + -100, 1000, "%"); + clonetiler_table_attach (table, l, 0, 2, 2); + } + + { + GtkWidget *l = clonetiler_spinbox ( + // xgettext:no-c-format + _("Horizontal scale per column (in % of tile width)"), "scalex_per_i", + -100, 1000, "%"); + clonetiler_table_attach (table, l, 0, 2, 3); + } + + { + GtkWidget *l = clonetiler_spinbox (_("Randomize the horizontal scale by this percentage"), "scalex_rand", + 0, 1000, "%"); + clonetiler_table_attach (table, l, 0, 2, 4); + } + + // Y + { + GtkWidget *l = gtk_label_new (""); + gtk_label_set_markup (GTK_LABEL(l), _("Scale Y:")); + gtk_size_group_add_widget(table_row_labels, l); + clonetiler_table_attach (table, l, 1, 3, 1); + } + + { + GtkWidget *l = clonetiler_spinbox ( + // xgettext:no-c-format + _("Vertical scale per row (in % of tile height)"), "scaley_per_j", + -100, 1000, "%"); + clonetiler_table_attach (table, l, 0, 3, 2); + } + + { + GtkWidget *l = clonetiler_spinbox ( + // xgettext:no-c-format + _("Vertical scale per column (in % of tile height)"), "scaley_per_i", + -100, 1000, "%"); + clonetiler_table_attach (table, l, 0, 3, 3); + } + + { + GtkWidget *l = clonetiler_spinbox (_("Randomize the vertical scale by this percentage"), "scaley_rand", + 0, 1000, "%"); + clonetiler_table_attach (table, l, 0, 3, 4); + } + + // Exponent + { + GtkWidget *l = gtk_label_new (""); + gtk_label_set_markup (GTK_LABEL(l), _("Exponent:")); + gtk_size_group_add_widget(table_row_labels, l); + clonetiler_table_attach (table, l, 1, 4, 1); + } + + { + GtkWidget *l = clonetiler_spinbox (_("Whether row scaling is uniform (1), converge (<1) or diverge (>1)"), "scaley_exp", + 0, 10, "", true); + clonetiler_table_attach (table, l, 0, 4, 2); + } + + { + GtkWidget *l = clonetiler_spinbox (_("Whether column scaling is uniform (1), converge (<1) or diverge (>1)"), "scalex_exp", + 0, 10, "", true); + clonetiler_table_attach (table, l, 0, 4, 3); + } + + // Logarithmic (as in logarithmic spiral) + { + GtkWidget *l = gtk_label_new (""); + gtk_label_set_markup (GTK_LABEL(l), _("Base:")); + gtk_size_group_add_widget(table_row_labels, l); + clonetiler_table_attach (table, l, 1, 5, 1); + } + + { + GtkWidget *l = clonetiler_spinbox (_("Base for a logarithmic spiral: not used (0), converge (<1), or diverge (>1)"), "scaley_log", + 0, 10, "", false); + clonetiler_table_attach (table, l, 0, 5, 2); + } + + { + GtkWidget *l = clonetiler_spinbox (_("Base for a logarithmic spiral: not used (0), converge (<1), or diverge (>1)"), "scalex_log", + 0, 10, "", false); + clonetiler_table_attach (table, l, 0, 5, 3); + } + + { // alternates + GtkWidget *l = gtk_label_new (""); + // TRANSLATORS: "Alternate" is a verb here + gtk_label_set_markup (GTK_LABEL(l), _("Alternate:")); + gtk_size_group_add_widget(table_row_labels, l); + clonetiler_table_attach (table, l, 1, 6, 1); + } + + { + GtkWidget *l = clonetiler_checkbox (_("Alternate the sign of scales for each row"), "scaley_alternate"); + clonetiler_table_attach (table, l, 0, 6, 2); + } + + { + GtkWidget *l = clonetiler_checkbox (_("Alternate the sign of scales for each column"), "scalex_alternate"); + clonetiler_table_attach (table, l, 0, 6, 3); + } + + { // Cumulate + GtkWidget *l = gtk_label_new (""); + // TRANSLATORS: "Cumulate" is a verb here + gtk_label_set_markup (GTK_LABEL(l), _("Cumulate:")); + gtk_size_group_add_widget(table_row_labels, l); + clonetiler_table_attach (table, l, 1, 7, 1); + } + + { + GtkWidget *l = clonetiler_checkbox (_("Cumulate the scales for each row"), "scaley_cumulate"); + clonetiler_table_attach (table, l, 0, 7, 2); + } + + { + GtkWidget *l = clonetiler_checkbox (_("Cumulate the scales for each column"), "scalex_cumulate"); + clonetiler_table_attach (table, l, 0, 7, 3); + } + + } + + + // Rotation + { + GtkWidget *vb = clonetiler_new_tab (nb, _("_Rotation")); + + GtkWidget *table = clonetiler_table_x_y_rand (1); + gtk_box_pack_start (GTK_BOX (vb), table, FALSE, FALSE, 0); + + // Angle + { + GtkWidget *l = gtk_label_new (""); + gtk_label_set_markup (GTK_LABEL(l), _("Angle:")); + gtk_size_group_add_widget(table_row_labels, l); + clonetiler_table_attach (table, l, 1, 2, 1); + } + + { + GtkWidget *l = clonetiler_spinbox ( + // xgettext:no-c-format + _("Rotate tiles by this angle for each row"), "rotate_per_j", + -180, 180, "°"); + clonetiler_table_attach (table, l, 0, 2, 2); + } + + { + GtkWidget *l = clonetiler_spinbox ( + // xgettext:no-c-format + _("Rotate tiles by this angle for each column"), "rotate_per_i", + -180, 180, "°"); + clonetiler_table_attach (table, l, 0, 2, 3); + } + + { + GtkWidget *l = clonetiler_spinbox (_("Randomize the rotation angle by this percentage"), "rotate_rand", + 0, 100, "%"); + clonetiler_table_attach (table, l, 0, 2, 4); + } + + { // alternates + GtkWidget *l = gtk_label_new (""); + // TRANSLATORS: "Alternate" is a verb here + gtk_label_set_markup (GTK_LABEL(l), _("Alternate:")); + gtk_size_group_add_widget(table_row_labels, l); + clonetiler_table_attach (table, l, 1, 3, 1); + } + + { + GtkWidget *l = clonetiler_checkbox (_("Alternate the rotation direction for each row"), "rotate_alternatej"); + clonetiler_table_attach (table, l, 0, 3, 2); + } + + { + GtkWidget *l = clonetiler_checkbox (_("Alternate the rotation direction for each column"), "rotate_alternatei"); + clonetiler_table_attach (table, l, 0, 3, 3); + } + + { // Cumulate + GtkWidget *l = gtk_label_new (""); + // TRANSLATORS: "Cumulate" is a verb here + gtk_label_set_markup (GTK_LABEL(l), _("Cumulate:")); + gtk_size_group_add_widget(table_row_labels, l); + clonetiler_table_attach (table, l, 1, 4, 1); + } + + { + GtkWidget *l = clonetiler_checkbox (_("Cumulate the rotation for each row"), "rotate_cumulatej"); + clonetiler_table_attach (table, l, 0, 4, 2); + } + + { + GtkWidget *l = clonetiler_checkbox (_("Cumulate the rotation for each column"), "rotate_cumulatei"); + clonetiler_table_attach (table, l, 0, 4, 3); + } + + } + + + // Blur and opacity + { + GtkWidget *vb = clonetiler_new_tab (nb, _("_Blur & opacity")); + + GtkWidget *table = clonetiler_table_x_y_rand (1); + gtk_box_pack_start (GTK_BOX (vb), table, FALSE, FALSE, 0); + + + // Blur + { + GtkWidget *l = gtk_label_new (""); + gtk_label_set_markup (GTK_LABEL(l), _("Blur:")); + gtk_size_group_add_widget(table_row_labels, l); + clonetiler_table_attach (table, l, 1, 2, 1); + } + + { + GtkWidget *l = clonetiler_spinbox (_("Blur tiles by this percentage for each row"), "blur_per_j", + 0, 100, "%"); + clonetiler_table_attach (table, l, 0, 2, 2); + } + + { + GtkWidget *l = clonetiler_spinbox (_("Blur tiles by this percentage for each column"), "blur_per_i", + 0, 100, "%"); + clonetiler_table_attach (table, l, 0, 2, 3); + } + + { + GtkWidget *l = clonetiler_spinbox (_("Randomize the tile blur by this percentage"), "blur_rand", + 0, 100, "%"); + clonetiler_table_attach (table, l, 0, 2, 4); + } + + { // alternates + GtkWidget *l = gtk_label_new (""); + // TRANSLATORS: "Alternate" is a verb here + gtk_label_set_markup (GTK_LABEL(l), _("Alternate:")); + gtk_size_group_add_widget(table_row_labels, l); + clonetiler_table_attach (table, l, 1, 3, 1); + } + + { + GtkWidget *l = clonetiler_checkbox (_("Alternate the sign of blur change for each row"), "blur_alternatej"); + clonetiler_table_attach (table, l, 0, 3, 2); + } + + { + GtkWidget *l = clonetiler_checkbox (_("Alternate the sign of blur change for each column"), "blur_alternatei"); + clonetiler_table_attach (table, l, 0, 3, 3); + } + + + + // Dissolve + { + GtkWidget *l = gtk_label_new (""); + gtk_label_set_markup (GTK_LABEL(l), _("Opacity:")); + gtk_size_group_add_widget(table_row_labels, l); + clonetiler_table_attach (table, l, 1, 4, 1); + } + + { + GtkWidget *l = clonetiler_spinbox (_("Decrease tile opacity by this percentage for each row"), "opacity_per_j", + 0, 100, "%"); + clonetiler_table_attach (table, l, 0, 4, 2); + } + + { + GtkWidget *l = clonetiler_spinbox (_("Decrease tile opacity by this percentage for each column"), "opacity_per_i", + 0, 100, "%"); + clonetiler_table_attach (table, l, 0, 4, 3); + } + + { + GtkWidget *l = clonetiler_spinbox (_("Randomize the tile opacity by this percentage"), "opacity_rand", + 0, 100, "%"); + clonetiler_table_attach (table, l, 0, 4, 4); + } + + { // alternates + GtkWidget *l = gtk_label_new (""); + // TRANSLATORS: "Alternate" is a verb here + gtk_label_set_markup (GTK_LABEL(l), _("Alternate:")); + gtk_size_group_add_widget(table_row_labels, l); + clonetiler_table_attach (table, l, 1, 5, 1); + } + + { + GtkWidget *l = clonetiler_checkbox (_("Alternate the sign of opacity change for each row"), "opacity_alternatej"); + clonetiler_table_attach (table, l, 0, 5, 2); + } + + { + GtkWidget *l = clonetiler_checkbox (_("Alternate the sign of opacity change for each column"), "opacity_alternatei"); + clonetiler_table_attach (table, l, 0, 5, 3); + } + } + + + // Color + { + GtkWidget *vb = clonetiler_new_tab (nb, _("Co_lor")); + + { + GtkWidget *hb = gtk_hbox_new (FALSE, 0); + + GtkWidget *l = gtk_label_new (_("Initial color: ")); + gtk_box_pack_start (GTK_BOX (hb), l, FALSE, FALSE, 0); + + guint32 rgba = 0x000000ff | sp_svg_read_color (prefs->getString(prefs_path + "initial_color").data(), 0x000000ff); + color_picker = new Inkscape::UI::Widget::ColorPicker (*new Glib::ustring(_("Initial color of tiled clones")), *new Glib::ustring(_("Initial color for clones (works only if the original has unset fill or stroke)")), rgba, false); + color_changed_connection = color_picker->connectChanged (sigc::ptr_fun(on_picker_color_changed)); + + gtk_box_pack_start (GTK_BOX (hb), reinterpret_cast(color_picker->gobj()), FALSE, FALSE, 0); + + gtk_box_pack_start (GTK_BOX (vb), hb, FALSE, FALSE, 0); + } + + + GtkWidget *table = clonetiler_table_x_y_rand (3); + gtk_box_pack_start (GTK_BOX (vb), table, FALSE, FALSE, 0); + + // Hue + { + GtkWidget *l = gtk_label_new (""); + gtk_label_set_markup (GTK_LABEL(l), _("H:")); + gtk_size_group_add_widget(table_row_labels, l); + clonetiler_table_attach (table, l, 1, 2, 1); + } + + { + GtkWidget *l = clonetiler_spinbox (_("Change the tile hue by this percentage for each row"), "hue_per_j", + -100, 100, "%"); + clonetiler_table_attach (table, l, 0, 2, 2); + } + + { + GtkWidget *l = clonetiler_spinbox (_("Change the tile hue by this percentage for each column"), "hue_per_i", + -100, 100, "%"); + clonetiler_table_attach (table, l, 0, 2, 3); + } + + { + GtkWidget *l = clonetiler_spinbox (_("Randomize the tile hue by this percentage"), "hue_rand", + 0, 100, "%"); + clonetiler_table_attach (table, l, 0, 2, 4); + } + + + // Saturation + { + GtkWidget *l = gtk_label_new (""); + gtk_label_set_markup (GTK_LABEL(l), _("S:")); + gtk_size_group_add_widget(table_row_labels, l); + clonetiler_table_attach (table, l, 1, 3, 1); + } + + { + GtkWidget *l = clonetiler_spinbox (_("Change the color saturation by this percentage for each row"), "saturation_per_j", + -100, 100, "%"); + clonetiler_table_attach (table, l, 0, 3, 2); + } + + { + GtkWidget *l = clonetiler_spinbox (_("Change the color saturation by this percentage for each column"), "saturation_per_i", + -100, 100, "%"); + clonetiler_table_attach (table, l, 0, 3, 3); + } + + { + GtkWidget *l = clonetiler_spinbox (_("Randomize the color saturation by this percentage"), "saturation_rand", + 0, 100, "%"); + clonetiler_table_attach (table, l, 0, 3, 4); + } + + // Lightness + { + GtkWidget *l = gtk_label_new (""); + gtk_label_set_markup (GTK_LABEL(l), _("L:")); + gtk_size_group_add_widget(table_row_labels, l); + clonetiler_table_attach (table, l, 1, 4, 1); + } + + { + GtkWidget *l = clonetiler_spinbox (_("Change the color lightness by this percentage for each row"), "lightness_per_j", + -100, 100, "%"); + clonetiler_table_attach (table, l, 0, 4, 2); + } + + { + GtkWidget *l = clonetiler_spinbox (_("Change the color lightness by this percentage for each column"), "lightness_per_i", + -100, 100, "%"); + clonetiler_table_attach (table, l, 0, 4, 3); + } + + { + GtkWidget *l = clonetiler_spinbox (_("Randomize the color lightness by this percentage"), "lightness_rand", + 0, 100, "%"); + clonetiler_table_attach (table, l, 0, 4, 4); + } + + + { // alternates + GtkWidget *l = gtk_label_new (""); + gtk_label_set_markup (GTK_LABEL(l), _("Alternate:")); + gtk_size_group_add_widget(table_row_labels, l); + clonetiler_table_attach (table, l, 1, 5, 1); + } + + { + GtkWidget *l = clonetiler_checkbox (_("Alternate the sign of color changes for each row"), "color_alternatej"); + clonetiler_table_attach (table, l, 0, 5, 2); + } + + { + GtkWidget *l = clonetiler_checkbox (_("Alternate the sign of color changes for each column"), "color_alternatei"); + clonetiler_table_attach (table, l, 0, 5, 3); + } + + } + + // Trace + { + GtkWidget *vb = clonetiler_new_tab (nb, _("_Trace")); + + + { + GtkWidget *hb = gtk_hbox_new(FALSE, VB_MARGIN); + gtk_box_pack_start (GTK_BOX (vb), hb, FALSE, FALSE, 0); + + GtkWidget *b = gtk_check_button_new_with_label (_("Trace the drawing under the tiles")); + g_object_set_data (G_OBJECT(b), "uncheckable", GINT_TO_POINTER(TRUE)); + bool old = prefs->getBool(prefs_path + "dotrace"); + gtk_toggle_button_set_active ((GtkToggleButton *) b, old); + gtk_widget_set_tooltip_text (b, _("For each clone, pick a value from the drawing in that clone's location and apply it to the clone")); + gtk_box_pack_start (GTK_BOX (hb), b, FALSE, FALSE, 0); + + g_signal_connect(G_OBJECT(b), "toggled", + G_CALLBACK(clonetiler_do_pick_toggled), (gpointer)dlg); + } + + { + GtkWidget *vvb = gtk_vbox_new (FALSE, 0); + gtk_box_pack_start (GTK_BOX (vb), vvb, FALSE, FALSE, 0); + g_object_set_data (G_OBJECT(dlg), "dotrace", (gpointer) vvb); + + + { + GtkWidget *frame = gtk_frame_new (_("1. Pick from the drawing:")); + gtk_box_pack_start (GTK_BOX (vvb), frame, FALSE, FALSE, 0); + + GtkWidget *table = gtk_table_new (3, 3, FALSE); + gtk_table_set_row_spacings (GTK_TABLE (table), 4); + gtk_table_set_col_spacings (GTK_TABLE (table), 6); + gtk_container_add(GTK_CONTAINER(frame), table); + + + GtkWidget* radio; + { + radio = gtk_radio_button_new_with_label (NULL, _("Color")); + gtk_widget_set_tooltip_text (radio, _("Pick the visible color and opacity")); + clonetiler_table_attach (table, radio, 0.0, 1, 1); + g_signal_connect (G_OBJECT (radio), "toggled", + G_CALLBACK (clonetiler_pick_switched), GINT_TO_POINTER(PICK_COLOR)); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio), prefs->getInt(prefs_path + "pick", 0) == PICK_COLOR); + } + { + radio = gtk_radio_button_new_with_label (gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio)), _("Opacity")); + gtk_widget_set_tooltip_text (radio, _("Pick the total accumulated opacity")); + clonetiler_table_attach (table, radio, 0.0, 2, 1); + g_signal_connect (G_OBJECT (radio), "toggled", + G_CALLBACK (clonetiler_pick_switched), GINT_TO_POINTER(PICK_OPACITY)); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio), prefs->getInt(prefs_path + "pick", 0) == PICK_OPACITY); + } + { + radio = gtk_radio_button_new_with_label (gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio)), _("R")); + gtk_widget_set_tooltip_text (radio, _("Pick the Red component of the color")); + clonetiler_table_attach (table, radio, 0.0, 1, 2); + g_signal_connect (G_OBJECT (radio), "toggled", + G_CALLBACK (clonetiler_pick_switched), GINT_TO_POINTER(PICK_R)); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio), prefs->getInt(prefs_path + "pick", 0) == PICK_R); + } + { + radio = gtk_radio_button_new_with_label (gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio)), _("G")); + gtk_widget_set_tooltip_text (radio, _("Pick the Green component of the color")); + clonetiler_table_attach (table, radio, 0.0, 2, 2); + g_signal_connect (G_OBJECT (radio), "toggled", + G_CALLBACK (clonetiler_pick_switched), GINT_TO_POINTER(PICK_G)); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio), prefs->getInt(prefs_path + "pick", 0) == PICK_G); + } + { + radio = gtk_radio_button_new_with_label (gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio)), _("B")); + gtk_widget_set_tooltip_text (radio, _("Pick the Blue component of the color")); + clonetiler_table_attach (table, radio, 0.0, 3, 2); + g_signal_connect (G_OBJECT (radio), "toggled", + G_CALLBACK (clonetiler_pick_switched), GINT_TO_POINTER(PICK_B)); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio), prefs->getInt(prefs_path + "pick", 0) == PICK_B); + } + { + radio = gtk_radio_button_new_with_label (gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio)), C_("Clonetiler color hue", "H")); + gtk_widget_set_tooltip_text (radio, _("Pick the hue of the color")); + clonetiler_table_attach (table, radio, 0.0, 1, 3); + g_signal_connect (G_OBJECT (radio), "toggled", + G_CALLBACK (clonetiler_pick_switched), GINT_TO_POINTER(PICK_H)); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio), prefs->getInt(prefs_path + "pick", 0) == PICK_H); + } + { + radio = gtk_radio_button_new_with_label (gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio)), C_("Clonetiler color saturation", "S")); + gtk_widget_set_tooltip_text (radio, _("Pick the saturation of the color")); + clonetiler_table_attach (table, radio, 0.0, 2, 3); + g_signal_connect (G_OBJECT (radio), "toggled", + G_CALLBACK (clonetiler_pick_switched), GINT_TO_POINTER(PICK_S)); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio), prefs->getInt(prefs_path + "pick", 0) == PICK_S); + } + { + radio = gtk_radio_button_new_with_label (gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio)), C_("Clonetiler color lightness", "L")); + gtk_widget_set_tooltip_text (radio, _("Pick the lightness of the color")); + clonetiler_table_attach (table, radio, 0.0, 3, 3); + g_signal_connect (G_OBJECT (radio), "toggled", + G_CALLBACK (clonetiler_pick_switched), GINT_TO_POINTER(PICK_L)); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio), prefs->getInt(prefs_path + "pick", 0) == PICK_L); + } + + } + + { + GtkWidget *frame = gtk_frame_new (_("2. Tweak the picked value:")); + gtk_box_pack_start (GTK_BOX (vvb), frame, FALSE, FALSE, VB_MARGIN); + + GtkWidget *table = gtk_table_new (4, 2, FALSE); + gtk_table_set_row_spacings (GTK_TABLE (table), 4); + gtk_table_set_col_spacings (GTK_TABLE (table), 6); + gtk_container_add(GTK_CONTAINER(frame), table); + + { + GtkWidget *l = gtk_label_new (""); + gtk_label_set_markup (GTK_LABEL(l), _("Gamma-correct:")); + clonetiler_table_attach (table, l, 1.0, 1, 1); + } + { + GtkWidget *l = clonetiler_spinbox (_("Shift the mid-range of the picked value upwards (>0) or downwards (<0)"), "gamma_picked", + -10, 10, ""); + clonetiler_table_attach (table, l, 0.0, 1, 2); + } + + { + GtkWidget *l = gtk_label_new (""); + gtk_label_set_markup (GTK_LABEL(l), _("Randomize:")); + clonetiler_table_attach (table, l, 1.0, 1, 3); + } + { + GtkWidget *l = clonetiler_spinbox (_("Randomize the picked value by this percentage"), "rand_picked", + 0, 100, "%"); + clonetiler_table_attach (table, l, 0.0, 1, 4); + } + + { + GtkWidget *l = gtk_label_new (""); + gtk_label_set_markup (GTK_LABEL(l), _("Invert:")); + clonetiler_table_attach (table, l, 1.0, 2, 1); + } + { + GtkWidget *l = clonetiler_checkbox (_("Invert the picked value"), "invert_picked"); + clonetiler_table_attach (table, l, 0.0, 2, 2); + } + } + + { + GtkWidget *frame = gtk_frame_new (_("3. Apply the value to the clones':")); + gtk_box_pack_start (GTK_BOX (vvb), frame, FALSE, FALSE, 0); + + + GtkWidget *table = gtk_table_new (2, 2, FALSE); + gtk_table_set_row_spacings (GTK_TABLE (table), 4); + gtk_table_set_col_spacings (GTK_TABLE (table), 6); + gtk_container_add(GTK_CONTAINER(frame), table); + + { + GtkWidget *b = gtk_check_button_new_with_label (_("Presence")); + bool old = prefs->getBool(prefs_path + "pick_to_presence", true); + gtk_toggle_button_set_active ((GtkToggleButton *) b, old); + gtk_widget_set_tooltip_text (b, _("Each clone is created with the probability determined by the picked value in that point")); + clonetiler_table_attach (table, b, 0.0, 1, 1); + g_signal_connect(G_OBJECT(b), "toggled", + G_CALLBACK(clonetiler_pick_to), (gpointer) "pick_to_presence"); + } + + { + GtkWidget *b = gtk_check_button_new_with_label (_("Size")); + bool old = prefs->getBool(prefs_path + "pick_to_size"); + gtk_toggle_button_set_active ((GtkToggleButton *) b, old); + gtk_widget_set_tooltip_text (b, _("Each clone's size is determined by the picked value in that point")); + clonetiler_table_attach (table, b, 0.0, 2, 1); + g_signal_connect(G_OBJECT(b), "toggled", + G_CALLBACK(clonetiler_pick_to), (gpointer) "pick_to_size"); + } + + { + GtkWidget *b = gtk_check_button_new_with_label (_("Color")); + bool old = prefs->getBool(prefs_path + "pick_to_color", 0); + gtk_toggle_button_set_active ((GtkToggleButton *) b, old); + gtk_widget_set_tooltip_text (b, _("Each clone is painted by the picked color (the original must have unset fill or stroke)")); + clonetiler_table_attach (table, b, 0.0, 1, 2); + g_signal_connect(G_OBJECT(b), "toggled", + G_CALLBACK(clonetiler_pick_to), (gpointer) "pick_to_color"); + } + + { + GtkWidget *b = gtk_check_button_new_with_label (_("Opacity")); + bool old = prefs->getBool(prefs_path + "pick_to_opacity", 0); + gtk_toggle_button_set_active ((GtkToggleButton *) b, old); + gtk_widget_set_tooltip_text (b, _("Each clone's opacity is determined by the picked value in that point")); + clonetiler_table_attach (table, b, 0.0, 2, 2); + g_signal_connect(G_OBJECT(b), "toggled", + G_CALLBACK(clonetiler_pick_to), (gpointer) "pick_to_opacity"); + } + } + gtk_widget_set_sensitive (vvb, prefs->getBool(prefs_path + "dotrace")); + } + } + + // Rows/columns, width/height + { + GtkWidget *table = gtk_table_new (2, 2, FALSE); + gtk_container_set_border_width (GTK_CONTAINER (table), VB_MARGIN); + gtk_table_set_row_spacings (GTK_TABLE (table), 4); + gtk_table_set_col_spacings (GTK_TABLE (table), 6); + gtk_box_pack_start (GTK_BOX (mainbox), table, FALSE, FALSE, 0); + + { + GtkWidget *hb = gtk_hbox_new(FALSE, VB_MARGIN); + g_object_set_data (G_OBJECT(dlg), "rowscols", (gpointer) hb); + + { + Gtk::Adjustment *a = new Gtk::Adjustment (0.0, 1, 500, 1, 10, 0); + int value = prefs->getInt(prefs_path + "jmax", 2); + a->set_value (value); + + Inkscape::UI::Widget::SpinButton *sb = new Inkscape::UI::Widget::SpinButton (*a, 1.0, 0); + sb->set_tooltip_text (_("How many rows in the tiling")); + sb->set_width_chars (7); + gtk_box_pack_start (GTK_BOX (hb), GTK_WIDGET(sb->gobj()), TRUE, TRUE, 0); + + // TODO: C++ification + g_signal_connect(G_OBJECT(a->gobj()), "value_changed", + G_CALLBACK(clonetiler_xy_changed), (gpointer) "jmax"); + } + + { + GtkWidget *l = gtk_label_new (""); + gtk_label_set_markup (GTK_LABEL(l), "×"); + gtk_misc_set_alignment (GTK_MISC (l), 1.0, 0.5); + gtk_box_pack_start (GTK_BOX (hb), l, TRUE, TRUE, 0); + } + + { + Gtk::Adjustment *a = new Gtk::Adjustment (0.0, 1, 500, 1, 10, 0); + int value = prefs->getInt(prefs_path + "imax", 2); + a->set_value (value); + + Inkscape::UI::Widget::SpinButton *sb = new Inkscape::UI::Widget::SpinButton (*a, 1.0, 0); + sb->set_tooltip_text (_("How many columns in the tiling")); + sb->set_width_chars (7); + gtk_box_pack_start (GTK_BOX (hb), GTK_WIDGET(sb->gobj()), TRUE, TRUE, 0); + + // TODO: C++ification + g_signal_connect(G_OBJECT(a->gobj()), "value_changed", + G_CALLBACK(clonetiler_xy_changed), (gpointer) "imax"); + } + + clonetiler_table_attach (table, hb, 0.0, 1, 2); + } + + { + GtkWidget *hb = gtk_hbox_new(FALSE, VB_MARGIN); + g_object_set_data (G_OBJECT(dlg), "widthheight", (gpointer) hb); + + // unitmenu + GtkWidget *u = sp_unit_selector_new (SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE); + sp_unit_selector_set_unit (SP_UNIT_SELECTOR(u), sp_desktop_namedview(SP_ACTIVE_DESKTOP)->doc_units); + + { + // Width spinbutton + Gtk::Adjustment *a = new Gtk::Adjustment (0.0, -1e6, 1e6, 1.0, 10.0, 0); + sp_unit_selector_add_adjustment (SP_UNIT_SELECTOR (u), GTK_ADJUSTMENT (a->gobj())); + + double value = prefs->getDouble(prefs_path + "fillwidth", 50.0); + SPUnit const &unit = *sp_unit_selector_get_unit(SP_UNIT_SELECTOR(u)); + gdouble const units = sp_pixels_get_units (value, unit); + a->set_value (units); + + Inkscape::UI::Widget::SpinButton *e = new Inkscape::UI::Widget::SpinButton (*a, 1.0, 2); + e->set_tooltip_text (_("Width of the rectangle to be filled")); + e->set_width_chars (7); + e->set_digits (4); + gtk_box_pack_start (GTK_BOX (hb), GTK_WIDGET(e->gobj()), TRUE, TRUE, 0); + // TODO: C++ification + g_signal_connect(G_OBJECT(a->gobj()), "value_changed", + G_CALLBACK(clonetiler_fill_width_changed), u); + } + { + GtkWidget *l = gtk_label_new (""); + gtk_label_set_markup (GTK_LABEL(l), "×"); + gtk_misc_set_alignment (GTK_MISC (l), 1.0, 0.5); + gtk_box_pack_start (GTK_BOX (hb), l, TRUE, TRUE, 0); + } + + { + // Height spinbutton + Gtk::Adjustment *a = new Gtk::Adjustment (0.0, -1e6, 1e6, 1.0, 10.0, 0); + sp_unit_selector_add_adjustment (SP_UNIT_SELECTOR (u), GTK_ADJUSTMENT (a->gobj())); + + double value = prefs->getDouble(prefs_path + "fillheight", 50.0); + SPUnit const &unit = *sp_unit_selector_get_unit(SP_UNIT_SELECTOR(u)); + gdouble const units = sp_pixels_get_units (value, unit); + a->set_value (units); + + Inkscape::UI::Widget::SpinButton *e = new Inkscape::UI::Widget::SpinButton (*a, 1.0, 2); + e->set_tooltip_text (_("Height of the rectangle to be filled")); + e->set_width_chars (7); + e->set_digits (4); + gtk_box_pack_start (GTK_BOX (hb), GTK_WIDGET(e->gobj()), TRUE, TRUE, 0); + // TODO: C++ification + g_signal_connect(G_OBJECT(a->gobj()), "value_changed", + G_CALLBACK(clonetiler_fill_height_changed), u); + } + + gtk_box_pack_start (GTK_BOX (hb), u, TRUE, TRUE, 0); + clonetiler_table_attach (table, hb, 0.0, 2, 2); + + } + + // Switch + GtkWidget* radio; + { + radio = gtk_radio_button_new_with_label (NULL, _("Rows, columns: ")); + gtk_widget_set_tooltip_text (radio, _("Create the specified number of rows and columns")); + clonetiler_table_attach (table, radio, 0.0, 1, 1); + g_signal_connect (G_OBJECT (radio), "toggled", G_CALLBACK (clonetiler_switch_to_create), (gpointer) dlg); + } + if (!prefs->getBool(prefs_path + "fillrect")) { + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio), TRUE); + gtk_toggle_button_toggled (GTK_TOGGLE_BUTTON (radio)); + } + { + radio = gtk_radio_button_new_with_label (gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio)), _("Width, height: ")); + gtk_widget_set_tooltip_text (radio, _("Fill the specified width and height with the tiling")); + clonetiler_table_attach (table, radio, 0.0, 2, 1); + g_signal_connect (G_OBJECT (radio), "toggled", G_CALLBACK (clonetiler_switch_to_fill), (gpointer) dlg); + } + if (prefs->getBool(prefs_path + "fillrect")) { + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio), TRUE); + gtk_toggle_button_toggled (GTK_TOGGLE_BUTTON (radio)); + } + } + + + // Use saved pos + { + GtkWidget *hb = gtk_hbox_new(FALSE, VB_MARGIN); + gtk_box_pack_start (GTK_BOX (mainbox), hb, FALSE, FALSE, 0); + + GtkWidget *b = gtk_check_button_new_with_label (_("Use saved size and position of the tile")); + bool keepbbox = prefs->getBool(prefs_path + "keepbbox", true); + gtk_toggle_button_set_active ((GtkToggleButton *) b, keepbbox); + gtk_widget_set_tooltip_text (b, _("Pretend that the size and position of the tile are the same as the last time you tiled it (if any), instead of using the current size")); + gtk_box_pack_start (GTK_BOX (hb), b, FALSE, FALSE, 0); + + g_signal_connect(G_OBJECT(b), "toggled", + G_CALLBACK(clonetiler_keep_bbox_toggled), NULL); + } + + // Statusbar + { + GtkWidget *hb = gtk_hbox_new(FALSE, VB_MARGIN); + gtk_box_pack_end (GTK_BOX (mainbox), hb, FALSE, FALSE, 0); + GtkWidget *l = gtk_label_new(""); + g_object_set_data (G_OBJECT(dlg), "status", (gpointer) l); + gtk_box_pack_start (GTK_BOX (hb), l, FALSE, FALSE, 0); + } + + // Buttons + { + GtkWidget *hb = gtk_hbox_new(FALSE, VB_MARGIN); + gtk_box_pack_start (GTK_BOX (mainbox), hb, FALSE, FALSE, 0); + + { + GtkWidget *b = gtk_button_new (); + GtkWidget *l = gtk_label_new (""); + gtk_label_set_markup_with_mnemonic (GTK_LABEL(l), _(" _Create ")); + gtk_container_add (GTK_CONTAINER(b), l); + gtk_widget_set_tooltip_text (b, _("Create and tile the clones of the selection")); + g_signal_connect (G_OBJECT (b), "clicked", G_CALLBACK (clonetiler_apply), dlg); + gtk_box_pack_end (GTK_BOX (hb), b, FALSE, FALSE, 0); + } + + { // buttons which are enabled only when there are tiled clones + GtkWidget *sb = gtk_hbox_new(FALSE, 0); + gtk_box_pack_end (GTK_BOX (hb), sb, FALSE, FALSE, 0); + g_object_set_data (G_OBJECT(dlg), "buttons_on_tiles", (gpointer) sb); + { + // TRANSLATORS: if a group of objects are "clumped" together, then they + // are unevenly spread in the given amount of space - as shown in the + // diagrams on the left in the following screenshot: + // http://www.inkscape.org/screenshots/gallery/inkscape-0.42-CVS-tiles-unclump.png + // So unclumping is the process of spreading a number of objects out more evenly. + GtkWidget *b = gtk_button_new_with_mnemonic (_(" _Unclump ")); + gtk_widget_set_tooltip_text (b, _("Spread out clones to reduce clumping; can be applied repeatedly")); + g_signal_connect (G_OBJECT (b), "clicked", G_CALLBACK (clonetiler_unclump), NULL); + gtk_box_pack_end (GTK_BOX (sb), b, FALSE, FALSE, 0); + } + + { + GtkWidget *b = gtk_button_new_with_mnemonic (_(" Re_move ")); + gtk_widget_set_tooltip_text (b, _("Remove existing tiled clones of the selected object (siblings only)")); + g_signal_connect (G_OBJECT (b), "clicked", G_CALLBACK (clonetiler_remove), gpointer(dlg)); + gtk_box_pack_end (GTK_BOX (sb), b, FALSE, FALSE, 0); + } + + // connect to global selection changed signal (so we can change desktops) and + // external_change (so we're not fooled by undo) + g_signal_connect (G_OBJECT (INKSCAPE), "change_selection", G_CALLBACK (clonetiler_change_selection), dlg); + g_signal_connect (G_OBJECT (INKSCAPE), "external_change", G_CALLBACK (clonetiler_external_change), dlg); + g_signal_connect(G_OBJECT(dlg), "destroy", G_CALLBACK(clonetiler_disconnect_gsignal), G_OBJECT (INKSCAPE)); + + // update now + clonetiler_change_selection (NULL, sp_desktop_selection(SP_ACTIVE_DESKTOP), dlg); + } + + { + GtkWidget *b = gtk_button_new_with_mnemonic (_(" R_eset ")); + // TRANSLATORS: "change" is a noun here + gtk_widget_set_tooltip_text (b, _("Reset all shifts, scales, rotates, opacity and color changes in the dialog to zero")); + g_signal_connect (G_OBJECT (b), "clicked", G_CALLBACK (clonetiler_reset), dlg); + gtk_box_pack_start (GTK_BOX (hb), b, FALSE, FALSE, 0); + } + } + + gtk_widget_show_all (mainbox); + + } + + show_all(); + + desktopChangeConn = deskTrack.connectDesktopChanged( sigc::mem_fun(*this, &CloneTiler::setTargetDesktop) ); + deskTrack.connect(GTK_WIDGET(gobj())); + +} + +CloneTiler::~CloneTiler (void) +{ + //subselChangedConn.disconnect(); + //selectChangedConn.disconnect(); + //selectModifiedConn.disconnect(); + desktopChangeConn.disconnect(); + deskTrack.disconnect(); + color_changed_connection.disconnect(); +} + +void CloneTiler::setDesktop(SPDesktop *desktop) +{ + Panel::setDesktop(desktop); + deskTrack.setBase(desktop); +} + +void CloneTiler::setTargetDesktop(SPDesktop *desktop) +{ + if (this->desktop != desktop) { + if (this->desktop) { + //selectModifiedConn.disconnect(); + //subselChangedConn.disconnect(); + //selectChangedConn.disconnect(); + } + this->desktop = desktop; + if (desktop && desktop->selection) { + //selectChangedConn = desktop->selection->connectChanged(sigc::hide(sigc::mem_fun(*this, &CloneTiler::clonetiler_change_selection))); + //subselChangedConn = desktop->connectToolSubselectionChanged(sigc::hide(sigc::mem_fun(*this, &CloneTiler::clonetiler_change_selection))); + //selectModifiedConn = desktop->selection->connectModified(sigc::hide<0>(sigc::mem_fun(*this, &CloneTiler::clonetiler_change_selection))); + } + } +} + +void CloneTiler::on_picker_color_changed(guint rgba) +{ + static bool is_updating = false; + if (is_updating || !SP_ACTIVE_DESKTOP) + return; + + is_updating = true; + + gchar c[32]; + sp_svg_write_color(c, sizeof(c), rgba); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setString(prefs_path + "initial_color", c); + + is_updating = false; +} + +void CloneTiler::clonetiler_change_selection(Inkscape::Application * /*inkscape*/, Inkscape::Selection *selection, GtkWidget *dlg) +{ + GtkWidget *buttons = (GtkWidget *) g_object_get_data (G_OBJECT(dlg), "buttons_on_tiles"); + GtkWidget *status = (GtkWidget *) g_object_get_data (G_OBJECT(dlg), "status"); + + if (selection->isEmpty()) { + gtk_widget_set_sensitive (buttons, FALSE); + gtk_label_set_markup (GTK_LABEL(status), _("Nothing selected.")); + return; + } + + if (g_slist_length ((GSList *) selection->itemList()) > 1) { + gtk_widget_set_sensitive (buttons, FALSE); + gtk_label_set_markup (GTK_LABEL(status), _("More than one object selected.")); + return; + } + + guint n = clonetiler_number_of_clones(selection->singleItem()); + if (n > 0) { + gtk_widget_set_sensitive (buttons, TRUE); + gchar *sta = g_strdup_printf (_("Object has %d tiled clones."), n); + gtk_label_set_markup (GTK_LABEL(status), sta); + g_free (sta); + } else { + gtk_widget_set_sensitive (buttons, FALSE); + gtk_label_set_markup (GTK_LABEL(status), _("Object has no tiled clones.")); + } +} + +void CloneTiler::clonetiler_external_change(Inkscape::Application * /*inkscape*/, GtkWidget *dlg) +{ + clonetiler_change_selection (NULL, sp_desktop_selection(SP_ACTIVE_DESKTOP), dlg); +} + +void CloneTiler::clonetiler_disconnect_gsignal(GObject *widget, gpointer source) +{ + if (source && G_IS_OBJECT(source)) { + sp_signal_disconnect_by_data (source, widget); + } +} + +Geom::Affine CloneTiler::clonetiler_get_transform( + // symmetry group + int type, + + // row, column + int i, int j, + + // center, width, height of the tile + double cx, double cy, + double w, double h, + + // values from the dialog: + // Shift + double shiftx_per_i, double shifty_per_i, + double shiftx_per_j, double shifty_per_j, + double shiftx_rand, double shifty_rand, + double shiftx_exp, double shifty_exp, + int shiftx_alternate, int shifty_alternate, + int shiftx_cumulate, int shifty_cumulate, + int shiftx_excludew, int shifty_excludeh, + + // Scale + double scalex_per_i, double scaley_per_i, + double scalex_per_j, double scaley_per_j, + double scalex_rand, double scaley_rand, + double scalex_exp, double scaley_exp, + double scalex_log, double scaley_log, + int scalex_alternate, int scaley_alternate, + int scalex_cumulate, int scaley_cumulate, + + // Rotation + double rotate_per_i, double rotate_per_j, + double rotate_rand, + int rotate_alternatei, int rotate_alternatej, + int rotate_cumulatei, int rotate_cumulatej + ) +{ + + // Shift (in units of tile width or height) ------------- + double delta_shifti = 0.0; + double delta_shiftj = 0.0; + + if( shiftx_alternate ) { + delta_shifti = (double)(i%2); + } else { + if( shiftx_cumulate ) { // Should the delta shifts be cumulative (i.e. 1, 1+2, 1+2+3, ...) + delta_shifti = (double)(i*i); + } else { + delta_shifti = (double)i; + } + } + + if( shifty_alternate ) { + delta_shiftj = (double)(j%2); + } else { + if( shifty_cumulate ) { + delta_shiftj = (double)(j*j); + } else { + delta_shiftj = (double)j; + } + } + + // Random shift, only calculate if non-zero. + double delta_shiftx_rand = 0.0; + double delta_shifty_rand = 0.0; + if( shiftx_rand != 0.0 ) delta_shiftx_rand = shiftx_rand * g_random_double_range (-1, 1); + if( shifty_rand != 0.0 ) delta_shifty_rand = shifty_rand * g_random_double_range (-1, 1); + + + // Delta shift (units of tile width/height) + double di = shiftx_per_i * delta_shifti + shiftx_per_j * delta_shiftj + delta_shiftx_rand; + double dj = shifty_per_i * delta_shifti + shifty_per_j * delta_shiftj + delta_shifty_rand; + + // Shift in actual x and y, used below + double dx = w * di; + double dy = h * dj; + + double shifti = di; + double shiftj = dj; + + // Include tile width and height in shift if required + if( !shiftx_excludew ) shifti += i; + if( !shifty_excludeh ) shiftj += j; + + // Add exponential shift if necessary + if ( shiftx_exp != 1.0 ) shifti = pow( shifti, shiftx_exp ); + if ( shifty_exp != 1.0 ) shiftj = pow( shiftj, shifty_exp ); + + // Final shift + Geom::Affine rect_translate (Geom::Translate (w * shifti, h * shiftj)); + + // Rotation (in degrees) ------------ + double delta_rotationi = 0.0; + double delta_rotationj = 0.0; + + if( rotate_alternatei ) { + delta_rotationi = (double)(i%2); + } else { + if( rotate_cumulatei ) { + delta_rotationi = (double)(i*i + i)/2.0; + } else { + delta_rotationi = (double)i; + } + } + + if( rotate_alternatej ) { + delta_rotationj = (double)(j%2); + } else { + if( rotate_cumulatej ) { + delta_rotationj = (double)(j*j + j)/2.0; + } else { + delta_rotationj = (double)j; + } + } + + double delta_rotate_rand = 0.0; + if( rotate_rand != 0.0 ) delta_rotate_rand = rotate_rand * 180.0 * g_random_double_range (-1, 1); + + double dr = rotate_per_i * delta_rotationi + rotate_per_j * delta_rotationj + delta_rotate_rand; + + // Scale (times the original) ----------- + double delta_scalei = 0.0; + double delta_scalej = 0.0; + + if( scalex_alternate ) { + delta_scalei = (double)(i%2); + } else { + if( scalex_cumulate ) { // Should the delta scales be cumulative (i.e. 1, 1+2, 1+2+3, ...) + delta_scalei = (double)(i*i + i)/2.0; + } else { + delta_scalei = (double)i; + } + } + + if( scaley_alternate ) { + delta_scalej = (double)(j%2); + } else { + if( scaley_cumulate ) { + delta_scalej = (double)(j*j + j)/2.0; + } else { + delta_scalej = (double)j; + } + } + + // Random scale, only calculate if non-zero. + double delta_scalex_rand = 0.0; + double delta_scaley_rand = 0.0; + if( scalex_rand != 0.0 ) delta_scalex_rand = scalex_rand * g_random_double_range (-1, 1); + if( scaley_rand != 0.0 ) delta_scaley_rand = scaley_rand * g_random_double_range (-1, 1); + // But if random factors are same, scale x and y proportionally + if( scalex_rand == scaley_rand ) delta_scalex_rand = delta_scaley_rand; + + // Total delta scale + double scalex = 1.0 + scalex_per_i * delta_scalei + scalex_per_j * delta_scalej + delta_scalex_rand; + double scaley = 1.0 + scaley_per_i * delta_scalei + scaley_per_j * delta_scalej + delta_scaley_rand; + + if( scalex < 0.0 ) scalex = 0.0; + if( scaley < 0.0 ) scaley = 0.0; + + // Add exponential scale if necessary + if ( scalex_exp != 1.0 ) scalex = pow( scalex, scalex_exp ); + if ( scaley_exp != 1.0 ) scaley = pow( scaley, scaley_exp ); + + // Add logarithmic factor if necessary + if ( scalex_log > 0.0 ) scalex = pow( scalex_log, scalex - 1.0 ); + if ( scaley_log > 0.0 ) scaley = pow( scaley_log, scaley - 1.0 ); + // Alternative using rotation angle + //if ( scalex_log != 1.0 ) scalex *= pow( scalex_log, M_PI*dr/180 ); + //if ( scaley_log != 1.0 ) scaley *= pow( scaley_log, M_PI*dr/180 ); + + + // Calculate transformation matrices, translating back to "center of tile" (rotation center) before transforming + Geom::Affine drot_c = Geom::Translate(-cx, -cy) * Geom::Rotate (M_PI*dr/180) * Geom::Translate(cx, cy); + + Geom::Affine dscale_c = Geom::Translate(-cx, -cy) * Geom::Scale (scalex, scaley) * Geom::Translate(cx, cy); + + Geom::Affine d_s_r = dscale_c * drot_c; + + Geom::Affine rotate_180_c = Geom::Translate(-cx, -cy) * Geom::Rotate (M_PI) * Geom::Translate(cx, cy); + + Geom::Affine rotate_90_c = Geom::Translate(-cx, -cy) * Geom::Rotate (-M_PI/2) * Geom::Translate(cx, cy); + Geom::Affine rotate_m90_c = Geom::Translate(-cx, -cy) * Geom::Rotate ( M_PI/2) * Geom::Translate(cx, cy); + + Geom::Affine rotate_120_c = Geom::Translate(-cx, -cy) * Geom::Rotate (-2*M_PI/3) * Geom::Translate(cx, cy); + Geom::Affine rotate_m120_c = Geom::Translate(-cx, -cy) * Geom::Rotate ( 2*M_PI/3) * Geom::Translate(cx, cy); + + Geom::Affine rotate_60_c = Geom::Translate(-cx, -cy) * Geom::Rotate (-M_PI/3) * Geom::Translate(cx, cy); + Geom::Affine rotate_m60_c = Geom::Translate(-cx, -cy) * Geom::Rotate ( M_PI/3) * Geom::Translate(cx, cy); + + Geom::Affine flip_x = Geom::Translate(-cx, -cy) * Geom::Scale (-1, 1) * Geom::Translate(cx, cy); + Geom::Affine flip_y = Geom::Translate(-cx, -cy) * Geom::Scale (1, -1) * Geom::Translate(cx, cy); + + + // Create tile with required symmetry + const double cos60 = cos(M_PI/3); + const double sin60 = sin(M_PI/3); + const double cos30 = cos(M_PI/6); + const double sin30 = sin(M_PI/6); + + switch (type) { + + case TILE_P1: + return d_s_r * rect_translate; + break; + + case TILE_P2: + if (i % 2 == 0) { + return d_s_r * rect_translate; + } else { + return d_s_r * rotate_180_c * rect_translate; + } + break; + + case TILE_PM: + if (i % 2 == 0) { + return d_s_r * rect_translate; + } else { + return d_s_r * flip_x * rect_translate; + } + break; + + case TILE_PG: + if (j % 2 == 0) { + return d_s_r * rect_translate; + } else { + return d_s_r * flip_x * rect_translate; + } + break; + + case TILE_CM: + if ((i + j) % 2 == 0) { + return d_s_r * rect_translate; + } else { + return d_s_r * flip_x * rect_translate; + } + break; + + case TILE_PMM: + if (j % 2 == 0) { + if (i % 2 == 0) { + return d_s_r * rect_translate; + } else { + return d_s_r * flip_x * rect_translate; + } + } else { + if (i % 2 == 0) { + return d_s_r * flip_y * rect_translate; + } else { + return d_s_r * flip_x * flip_y * rect_translate; + } + } + break; + + case TILE_PMG: + if (j % 2 == 0) { + if (i % 2 == 0) { + return d_s_r * rect_translate; + } else { + return d_s_r * rotate_180_c * rect_translate; + } + } else { + if (i % 2 == 0) { + return d_s_r * flip_y * rect_translate; + } else { + return d_s_r * rotate_180_c * flip_y * rect_translate; + } + } + break; + + case TILE_PGG: + if (j % 2 == 0) { + if (i % 2 == 0) { + return d_s_r * rect_translate; + } else { + return d_s_r * flip_y * rect_translate; + } + } else { + if (i % 2 == 0) { + return d_s_r * rotate_180_c * rect_translate; + } else { + return d_s_r * rotate_180_c * flip_y * rect_translate; + } + } + break; + + case TILE_CMM: + if (j % 4 == 0) { + if (i % 2 == 0) { + return d_s_r * rect_translate; + } else { + return d_s_r * flip_x * rect_translate; + } + } else if (j % 4 == 1) { + if (i % 2 == 0) { + return d_s_r * flip_y * rect_translate; + } else { + return d_s_r * flip_x * flip_y * rect_translate; + } + } else if (j % 4 == 2) { + if (i % 2 == 1) { + return d_s_r * rect_translate; + } else { + return d_s_r * flip_x * rect_translate; + } + } else { + if (i % 2 == 1) { + return d_s_r * flip_y * rect_translate; + } else { + return d_s_r * flip_x * flip_y * rect_translate; + } + } + break; + + case TILE_P4: + { + Geom::Affine ori (Geom::Translate ((w + h) * pow((i/2), shiftx_exp) + dx, (h + w) * pow((j/2), shifty_exp) + dy)); + Geom::Affine dia1 (Geom::Translate (w/2 + h/2, -h/2 + w/2)); + Geom::Affine dia2 (Geom::Translate (-w/2 + h/2, h/2 + w/2)); + if (j % 2 == 0) { + if (i % 2 == 0) { + return d_s_r * ori; + } else { + return d_s_r * rotate_m90_c * dia1 * ori; + } + } else { + if (i % 2 == 0) { + return d_s_r * rotate_90_c * dia2 * ori; + } else { + return d_s_r * rotate_180_c * dia1 * dia2 * ori; + } + } + } + break; + + case TILE_P4M: + { + double max = MAX(w, h); + Geom::Affine ori (Geom::Translate ((max + max) * pow((i/4), shiftx_exp) + dx, (max + max) * pow((j/2), shifty_exp) + dy)); + Geom::Affine dia1 (Geom::Translate ( w/2 - h/2, h/2 - w/2)); + Geom::Affine dia2 (Geom::Translate (-h/2 + w/2, w/2 - h/2)); + if (j % 2 == 0) { + if (i % 4 == 0) { + return d_s_r * ori; + } else if (i % 4 == 1) { + return d_s_r * flip_y * rotate_m90_c * dia1 * ori; + } else if (i % 4 == 2) { + return d_s_r * rotate_m90_c * dia1 * Geom::Translate (h, 0) * ori; + } else if (i % 4 == 3) { + return d_s_r * flip_x * Geom::Translate (w, 0) * ori; + } + } else { + if (i % 4 == 0) { + return d_s_r * flip_y * Geom::Translate(0, h) * ori; + } else if (i % 4 == 1) { + return d_s_r * rotate_90_c * dia2 * Geom::Translate(0, h) * ori; + } else if (i % 4 == 2) { + return d_s_r * flip_y * rotate_90_c * dia2 * Geom::Translate(h, 0) * Geom::Translate(0, h) * ori; + } else if (i % 4 == 3) { + return d_s_r * flip_y * flip_x * Geom::Translate(w, 0) * Geom::Translate(0, h) * ori; + } + } + } + break; + + case TILE_P4G: + { + double max = MAX(w, h); + Geom::Affine ori (Geom::Translate ((max + max) * pow((i/4), shiftx_exp) + dx, (max + max) * pow(j, shifty_exp) + dy)); + Geom::Affine dia1 (Geom::Translate ( w/2 + h/2, h/2 - w/2)); + Geom::Affine dia2 (Geom::Translate (-h/2 + w/2, w/2 + h/2)); + if (((i/4) + j) % 2 == 0) { + if (i % 4 == 0) { + return d_s_r * ori; + } else if (i % 4 == 1) { + return d_s_r * rotate_m90_c * dia1 * ori; + } else if (i % 4 == 2) { + return d_s_r * rotate_90_c * dia2 * ori; + } else if (i % 4 == 3) { + return d_s_r * rotate_180_c * dia1 * dia2 * ori; + } + } else { + if (i % 4 == 0) { + return d_s_r * flip_y * Geom::Translate (0, h) * ori; + } else if (i % 4 == 1) { + return d_s_r * flip_y * rotate_m90_c * dia1 * Geom::Translate (-h, 0) * ori; + } else if (i % 4 == 2) { + return d_s_r * flip_y * rotate_90_c * dia2 * Geom::Translate (h, 0) * ori; + } else if (i % 4 == 3) { + return d_s_r * flip_x * Geom::Translate (w, 0) * ori; + } + } + } + break; + + case TILE_P3: + { + double width; + double height; + Geom::Affine dia1; + Geom::Affine dia2; + if (w > h) { + width = w + w * cos60; + height = 2 * w * sin60; + dia1 = Geom::Affine (Geom::Translate (w/2 + w/2 * cos60, -(w/2 * sin60))); + dia2 = dia1 * Geom::Affine (Geom::Translate (0, 2 * (w/2 * sin60))); + } else { + width = h * cos (M_PI/6); + height = h; + dia1 = Geom::Affine (Geom::Translate (h/2 * cos30, -(h/2 * sin30))); + dia2 = dia1 * Geom::Affine (Geom::Translate (0, h/2)); + } + Geom::Affine ori (Geom::Translate (width * pow((2*(i/3) + j%2), shiftx_exp) + dx, (height/2) * pow(j, shifty_exp) + dy)); + if (i % 3 == 0) { + return d_s_r * ori; + } else if (i % 3 == 1) { + return d_s_r * rotate_m120_c * dia1 * ori; + } else if (i % 3 == 2) { + return d_s_r * rotate_120_c * dia2 * ori; + } + } + break; + + case TILE_P31M: + { + Geom::Affine ori; + Geom::Affine dia1; + Geom::Affine dia2; + Geom::Affine dia3; + Geom::Affine dia4; + if (w > h) { + ori = Geom::Affine(Geom::Translate (w * pow((i/6) + 0.5*(j%2), shiftx_exp) + dx, (w * cos30) * pow(j, shifty_exp) + dy)); + dia1 = Geom::Affine (Geom::Translate (0, h/2) * Geom::Translate (w/2, 0) * Geom::Translate (w/2 * cos60, -w/2 * sin60) * Geom::Translate (-h/2 * cos30, -h/2 * sin30) ); + dia2 = dia1 * Geom::Affine (Geom::Translate (h * cos30, h * sin30)); + dia3 = dia2 * Geom::Affine (Geom::Translate (0, 2 * (w/2 * sin60 - h/2 * sin30))); + dia4 = dia3 * Geom::Affine (Geom::Translate (-h * cos30, h * sin30)); + } else { + ori = Geom::Affine (Geom::Translate (2*h * cos30 * pow((i/6 + 0.5*(j%2)), shiftx_exp) + dx, (2*h - h * sin30) * pow(j, shifty_exp) + dy)); + dia1 = Geom::Affine (Geom::Translate (0, -h/2) * Geom::Translate (h/2 * cos30, h/2 * sin30)); + dia2 = dia1 * Geom::Affine (Geom::Translate (h * cos30, h * sin30)); + dia3 = dia2 * Geom::Affine (Geom::Translate (0, h/2)); + dia4 = dia3 * Geom::Affine (Geom::Translate (-h * cos30, h * sin30)); + } + if (i % 6 == 0) { + return d_s_r * ori; + } else if (i % 6 == 1) { + return d_s_r * flip_y * rotate_m120_c * dia1 * ori; + } else if (i % 6 == 2) { + return d_s_r * rotate_m120_c * dia2 * ori; + } else if (i % 6 == 3) { + return d_s_r * flip_y * rotate_120_c * dia3 * ori; + } else if (i % 6 == 4) { + return d_s_r * rotate_120_c * dia4 * ori; + } else if (i % 6 == 5) { + return d_s_r * flip_y * Geom::Translate(0, h) * ori; + } + } + break; + + case TILE_P3M1: + { + double width; + double height; + Geom::Affine dia1; + Geom::Affine dia2; + Geom::Affine dia3; + Geom::Affine dia4; + if (w > h) { + width = w + w * cos60; + height = 2 * w * sin60; + dia1 = Geom::Affine (Geom::Translate (0, h/2) * Geom::Translate (w/2, 0) * Geom::Translate (w/2 * cos60, -w/2 * sin60) * Geom::Translate (-h/2 * cos30, -h/2 * sin30) ); + dia2 = dia1 * Geom::Affine (Geom::Translate (h * cos30, h * sin30)); + dia3 = dia2 * Geom::Affine (Geom::Translate (0, 2 * (w/2 * sin60 - h/2 * sin30))); + dia4 = dia3 * Geom::Affine (Geom::Translate (-h * cos30, h * sin30)); + } else { + width = 2 * h * cos (M_PI/6); + height = 2 * h; + dia1 = Geom::Affine (Geom::Translate (0, -h/2) * Geom::Translate (h/2 * cos30, h/2 * sin30)); + dia2 = dia1 * Geom::Affine (Geom::Translate (h * cos30, h * sin30)); + dia3 = dia2 * Geom::Affine (Geom::Translate (0, h/2)); + dia4 = dia3 * Geom::Affine (Geom::Translate (-h * cos30, h * sin30)); + } + Geom::Affine ori (Geom::Translate (width * pow((2*(i/6) + j%2), shiftx_exp) + dx, (height/2) * pow(j, shifty_exp) + dy)); + if (i % 6 == 0) { + return d_s_r * ori; + } else if (i % 6 == 1) { + return d_s_r * flip_y * rotate_m120_c * dia1 * ori; + } else if (i % 6 == 2) { + return d_s_r * rotate_m120_c * dia2 * ori; + } else if (i % 6 == 3) { + return d_s_r * flip_y * rotate_120_c * dia3 * ori; + } else if (i % 6 == 4) { + return d_s_r * rotate_120_c * dia4 * ori; + } else if (i % 6 == 5) { + return d_s_r * flip_y * Geom::Translate(0, h) * ori; + } + } + break; + + case TILE_P6: + { + Geom::Affine ori; + Geom::Affine dia1; + Geom::Affine dia2; + Geom::Affine dia3; + Geom::Affine dia4; + Geom::Affine dia5; + if (w > h) { + ori = Geom::Affine(Geom::Translate (w * pow((2*(i/6) + (j%2)), shiftx_exp) + dx, (2*w * sin60) * pow(j, shifty_exp) + dy)); + dia1 = Geom::Affine (Geom::Translate (w/2 * cos60, -w/2 * sin60)); + dia2 = dia1 * Geom::Affine (Geom::Translate (w/2, 0)); + dia3 = dia2 * Geom::Affine (Geom::Translate (w/2 * cos60, w/2 * sin60)); + dia4 = dia3 * Geom::Affine (Geom::Translate (-w/2 * cos60, w/2 * sin60)); + dia5 = dia4 * Geom::Affine (Geom::Translate (-w/2, 0)); + } else { + ori = Geom::Affine(Geom::Translate (2*h * cos30 * pow((i/6 + 0.5*(j%2)), shiftx_exp) + dx, (h + h * sin30) * pow(j, shifty_exp) + dy)); + dia1 = Geom::Affine (Geom::Translate (-w/2, -h/2) * Geom::Translate (h/2 * cos30, -h/2 * sin30) * Geom::Translate (w/2 * cos60, w/2 * sin60)); + dia2 = dia1 * Geom::Affine (Geom::Translate (-w/2 * cos60, -w/2 * sin60) * Geom::Translate (h/2 * cos30, -h/2 * sin30) * Geom::Translate (h/2 * cos30, h/2 * sin30) * Geom::Translate (-w/2 * cos60, w/2 * sin60)); + dia3 = dia2 * Geom::Affine (Geom::Translate (w/2 * cos60, -w/2 * sin60) * Geom::Translate (h/2 * cos30, h/2 * sin30) * Geom::Translate (-w/2, h/2)); + dia4 = dia3 * dia1.inverse(); + dia5 = dia3 * dia2.inverse(); + } + if (i % 6 == 0) { + return d_s_r * ori; + } else if (i % 6 == 1) { + return d_s_r * rotate_m60_c * dia1 * ori; + } else if (i % 6 == 2) { + return d_s_r * rotate_m120_c * dia2 * ori; + } else if (i % 6 == 3) { + return d_s_r * rotate_180_c * dia3 * ori; + } else if (i % 6 == 4) { + return d_s_r * rotate_120_c * dia4 * ori; + } else if (i % 6 == 5) { + return d_s_r * rotate_60_c * dia5 * ori; + } + } + break; + + case TILE_P6M: + { + + Geom::Affine ori; + Geom::Affine dia1, dia2, dia3, dia4, dia5, dia6, dia7, dia8, dia9, dia10; + if (w > h) { + ori = Geom::Affine(Geom::Translate (w * pow((2*(i/12) + (j%2)), shiftx_exp) + dx, (2*w * sin60) * pow(j, shifty_exp) + dy)); + dia1 = Geom::Affine (Geom::Translate (w/2, h/2) * Geom::Translate (-w/2 * cos60, -w/2 * sin60) * Geom::Translate (-h/2 * cos30, h/2 * sin30)); + dia2 = dia1 * Geom::Affine (Geom::Translate (h * cos30, -h * sin30)); + dia3 = dia2 * Geom::Affine (Geom::Translate (-h/2 * cos30, h/2 * sin30) * Geom::Translate (w * cos60, 0) * Geom::Translate (-h/2 * cos30, -h/2 * sin30)); + dia4 = dia3 * Geom::Affine (Geom::Translate (h * cos30, h * sin30)); + dia5 = dia4 * Geom::Affine (Geom::Translate (-h/2 * cos30, -h/2 * sin30) * Geom::Translate (-w/2 * cos60, w/2 * sin60) * Geom::Translate (w/2, -h/2)); + dia6 = dia5 * Geom::Affine (Geom::Translate (0, h)); + dia7 = dia6 * dia1.inverse(); + dia8 = dia6 * dia2.inverse(); + dia9 = dia6 * dia3.inverse(); + dia10 = dia6 * dia4.inverse(); + } else { + ori = Geom::Affine(Geom::Translate (4*h * cos30 * pow((i/12 + 0.5*(j%2)), shiftx_exp) + dx, (2*h + 2*h * sin30) * pow(j, shifty_exp) + dy)); + dia1 = Geom::Affine (Geom::Translate (-w/2, -h/2) * Geom::Translate (h/2 * cos30, -h/2 * sin30) * Geom::Translate (w/2 * cos60, w/2 * sin60)); + dia2 = dia1 * Geom::Affine (Geom::Translate (h * cos30, -h * sin30)); + dia3 = dia2 * Geom::Affine (Geom::Translate (-w/2 * cos60, -w/2 * sin60) * Geom::Translate (h * cos30, 0) * Geom::Translate (-w/2 * cos60, w/2 * sin60)); + dia4 = dia3 * Geom::Affine (Geom::Translate (h * cos30, h * sin30)); + dia5 = dia4 * Geom::Affine (Geom::Translate (w/2 * cos60, -w/2 * sin60) * Geom::Translate (h/2 * cos30, h/2 * sin30) * Geom::Translate (-w/2, h/2)); + dia6 = dia5 * Geom::Affine (Geom::Translate (0, h)); + dia7 = dia6 * dia1.inverse(); + dia8 = dia6 * dia2.inverse(); + dia9 = dia6 * dia3.inverse(); + dia10 = dia6 * dia4.inverse(); + } + if (i % 12 == 0) { + return d_s_r * ori; + } else if (i % 12 == 1) { + return d_s_r * flip_y * rotate_m60_c * dia1 * ori; + } else if (i % 12 == 2) { + return d_s_r * rotate_m60_c * dia2 * ori; + } else if (i % 12 == 3) { + return d_s_r * flip_y * rotate_m120_c * dia3 * ori; + } else if (i % 12 == 4) { + return d_s_r * rotate_m120_c * dia4 * ori; + } else if (i % 12 == 5) { + return d_s_r * flip_x * dia5 * ori; + } else if (i % 12 == 6) { + return d_s_r * flip_x * flip_y * dia6 * ori; + } else if (i % 12 == 7) { + return d_s_r * flip_y * rotate_120_c * dia7 * ori; + } else if (i % 12 == 8) { + return d_s_r * rotate_120_c * dia8 * ori; + } else if (i % 12 == 9) { + return d_s_r * flip_y * rotate_60_c * dia9 * ori; + } else if (i % 12 == 10) { + return d_s_r * rotate_60_c * dia10 * ori; + } else if (i % 12 == 11) { + return d_s_r * flip_y * Geom::Translate (0, h) * ori; + } + } + break; + + default: + break; + } + + return Geom::identity(); +} + +bool CloneTiler::clonetiler_is_a_clone_of(SPObject *tile, SPObject *obj) +{ + bool result = false; + char *id_href = NULL; + + if (obj) { + Inkscape::XML::Node *obj_repr = obj->getRepr(); + id_href = g_strdup_printf("#%s", obj_repr->attribute("id")); + } + + if (SP_IS_USE(tile) && + tile->getRepr()->attribute("xlink:href") && + (!id_href || !strcmp(id_href, tile->getRepr()->attribute("xlink:href"))) && + tile->getRepr()->attribute("inkscape:tiled-clone-of") && + (!id_href || !strcmp(id_href, tile->getRepr()->attribute("inkscape:tiled-clone-of")))) + { + result = true; + } else { + result = false; + } + if (id_href) { + g_free(id_href); + id_href = 0; + } + return result; +} + +void CloneTiler::clonetiler_trace_hide_tiled_clones_recursively(SPObject *from) +{ + if (!trace_drawing) + return; + + for (SPObject *o = from->firstChild(); o != NULL; o = o->next) { + if (SP_IS_ITEM(o) && clonetiler_is_a_clone_of (o, NULL)) + SP_ITEM(o)->invoke_hide(trace_visionkey); // FIXME: hide each tiled clone's original too! + clonetiler_trace_hide_tiled_clones_recursively (o); + } +} + +void CloneTiler::clonetiler_trace_setup(SPDocument *doc, gdouble zoom, SPItem *original) +{ + trace_drawing = new Inkscape::Drawing(); + /* Create ArenaItem and set transform */ + trace_visionkey = SPItem::display_key_new(1); + trace_doc = doc; + trace_drawing->setRoot(trace_doc->getRoot()->invoke_show(*trace_drawing, trace_visionkey, SP_ITEM_SHOW_DISPLAY)); + + // hide the (current) original and any tiled clones, we only want to pick the background + original->invoke_hide(trace_visionkey); + clonetiler_trace_hide_tiled_clones_recursively(trace_doc->getRoot()); + + trace_doc->getRoot()->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + trace_doc->ensureUpToDate(); + + trace_zoom = zoom; +} + +guint32 CloneTiler::clonetiler_trace_pick(Geom::Rect box) +{ + if (!trace_drawing) { + return 0; + } + + trace_drawing->root()->setTransform(Geom::Scale(trace_zoom)); + trace_drawing->update(); + + /* Item integer bbox in points */ + Geom::IntRect ibox = (box * Geom::Scale(trace_zoom)).roundOutwards(); + + /* Find visible area */ + cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, ibox.width(), ibox.height()); + Inkscape::DrawingContext ct(s, ibox.min()); + /* Render */ + trace_drawing->render(ct, ibox); + double R = 0, G = 0, B = 0, A = 0; + ink_cairo_surface_average_color(s, R, G, B, A); + cairo_surface_destroy(s); + + return SP_RGBA32_F_COMPOSE (R, G, B, A); +} + +void CloneTiler::clonetiler_trace_finish() +{ + if (trace_doc) { + trace_doc->getRoot()->invoke_hide(trace_visionkey); + delete trace_drawing; + trace_doc = NULL; + trace_drawing = NULL; + } +} + +void CloneTiler::clonetiler_unclump(GtkWidget */*widget*/, void *) +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if (desktop == NULL) { + return; + } + + Inkscape::Selection *selection = sp_desktop_selection(desktop); + + // check if something is selected + if (selection->isEmpty() || g_slist_length((GSList *) selection->itemList()) > 1) { + sp_desktop_message_stack(desktop)->flash(Inkscape::WARNING_MESSAGE, _("Select one object whose tiled clones to unclump.")); + return; + } + + SPObject *obj = selection->singleItem(); + SPObject *parent = obj->parent; + + GSList *to_unclump = NULL; // not including the original + + for (SPObject *child = parent->firstChild(); child != NULL; child = child->next) { + if (clonetiler_is_a_clone_of (child, obj)) { + to_unclump = g_slist_prepend (to_unclump, child); + } + } + + sp_desktop_document(desktop)->ensureUpToDate(); + + unclump (to_unclump); + + g_slist_free (to_unclump); + + DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_DIALOG_CLONETILER, + _("Unclump tiled clones")); +} + +guint CloneTiler::clonetiler_number_of_clones(SPObject *obj) +{ + SPObject *parent = obj->parent; + + guint n = 0; + + for (SPObject *child = parent->firstChild(); child != NULL; child = child->next) { + if (clonetiler_is_a_clone_of (child, obj)) { + n ++; + } + } + + return n; +} + +void CloneTiler::clonetiler_remove(GtkWidget */*widget*/, GtkWidget *dlg, bool do_undo/* = true*/) +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if (desktop == NULL) { + return; + } + + Inkscape::Selection *selection = sp_desktop_selection(desktop); + + // check if something is selected + if (selection->isEmpty() || g_slist_length((GSList *) selection->itemList()) > 1) { + sp_desktop_message_stack(desktop)->flash(Inkscape::WARNING_MESSAGE, _("Select one object whose tiled clones to remove.")); + return; + } + + SPObject *obj = selection->singleItem(); + SPObject *parent = obj->parent; + +// remove old tiling + GSList *to_delete = NULL; + for (SPObject *child = parent->firstChild(); child != NULL; child = child->next) { + if (clonetiler_is_a_clone_of (child, obj)) { + to_delete = g_slist_prepend (to_delete, child); + } + } + for (GSList *i = to_delete; i; i = i->next) { + SP_OBJECT(i->data)->deleteObject(); + } + g_slist_free (to_delete); + + clonetiler_change_selection (NULL, selection, dlg); + + if (do_undo) { + DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_DIALOG_CLONETILER, + _("Delete tiled clones")); + } +} + +Geom::Rect CloneTiler::transform_rect(Geom::Rect const &r, Geom::Affine const &m) +{ + using Geom::X; + using Geom::Y; + Geom::Point const p1 = r.corner(1) * m; + Geom::Point const p2 = r.corner(2) * m; + Geom::Point const p3 = r.corner(3) * m; + Geom::Point const p4 = r.corner(4) * m; + return Geom::Rect( + Geom::Point( + std::min(std::min(p1[X], p2[X]), std::min(p3[X], p4[X])), + std::min(std::min(p1[Y], p2[Y]), std::min(p3[Y], p4[Y]))), + Geom::Point( + std::max(std::max(p1[X], p2[X]), std::max(p3[X], p4[X])), + std::max(std::max(p1[Y], p2[Y]), std::max(p3[Y], p4[Y])))); +} + +/** +Randomizes \a val by \a rand, with 0 < val < 1 and all values (including 0, 1) having the same +probability of being displaced. + */ +double CloneTiler::randomize01(double val, double rand) +{ + double base = MIN (val - rand, 1 - 2*rand); + if (base < 0) { + base = 0; + } + val = base + g_random_double_range (0, MIN (2 * rand, 1 - base)); + return CLAMP(val, 0, 1); // this should be unnecessary with the above provisions, but just in case... +} + + +void CloneTiler::clonetiler_apply(GtkWidget */*widget*/, GtkWidget *dlg) +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if (desktop == NULL) { + return; + } + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + Inkscape::Selection *selection = sp_desktop_selection(desktop); + + // check if something is selected + if (selection->isEmpty()) { + sp_desktop_message_stack(desktop)->flash(Inkscape::WARNING_MESSAGE, _("Select an object to clone.")); + return; + } + + // Check if more than one object is selected. + if (g_slist_length((GSList *) selection->itemList()) > 1) { + sp_desktop_message_stack(desktop)->flash(Inkscape::ERROR_MESSAGE, _("If you want to clone several objects, group them and clone the group.")); + return; + } + + // set "busy" cursor + desktop->setWaitingCursor(); + + // set statusbar text + GtkWidget *status = (GtkWidget *) g_object_get_data (G_OBJECT(dlg), "status"); + gtk_label_set_markup (GTK_LABEL(status), _("Creating tiled clones...")); + gtk_widget_queue_draw(GTK_WIDGET(status)); + gdk_window_process_all_updates(); + + SPObject *obj = selection->singleItem(); + SPItem *item = SP_IS_ITEM(obj) ? SP_ITEM(obj) : 0; + Inkscape::XML::Node *obj_repr = obj->getRepr(); + const char *id_href = g_strdup_printf("#%s", obj_repr->attribute("id")); + SPObject *parent = obj->parent; + + clonetiler_remove (NULL, dlg, false); + + double shiftx_per_i = 0.01 * prefs->getDoubleLimited(prefs_path + "shiftx_per_i", 0, -10000, 10000); + double shifty_per_i = 0.01 * prefs->getDoubleLimited(prefs_path + "shifty_per_i", 0, -10000, 10000); + double shiftx_per_j = 0.01 * prefs->getDoubleLimited(prefs_path + "shiftx_per_j", 0, -10000, 10000); + double shifty_per_j = 0.01 * prefs->getDoubleLimited(prefs_path + "shifty_per_j", 0, -10000, 10000); + double shiftx_rand = 0.01 * prefs->getDoubleLimited(prefs_path + "shiftx_rand", 0, 0, 1000); + double shifty_rand = 0.01 * prefs->getDoubleLimited(prefs_path + "shifty_rand", 0, 0, 1000); + double shiftx_exp = prefs->getDoubleLimited(prefs_path + "shiftx_exp", 1, 0, 10); + double shifty_exp = prefs->getDoubleLimited(prefs_path + "shifty_exp", 1, 0, 10); + bool shiftx_alternate = prefs->getBool(prefs_path + "shiftx_alternate"); + bool shifty_alternate = prefs->getBool(prefs_path + "shifty_alternate"); + bool shiftx_cumulate = prefs->getBool(prefs_path + "shiftx_cumulate"); + bool shifty_cumulate = prefs->getBool(prefs_path + "shifty_cumulate"); + bool shiftx_excludew = prefs->getBool(prefs_path + "shiftx_excludew"); + bool shifty_excludeh = prefs->getBool(prefs_path + "shifty_excludeh"); + + double scalex_per_i = 0.01 * prefs->getDoubleLimited(prefs_path + "scalex_per_i", 0, -100, 1000); + double scaley_per_i = 0.01 * prefs->getDoubleLimited(prefs_path + "scaley_per_i", 0, -100, 1000); + double scalex_per_j = 0.01 * prefs->getDoubleLimited(prefs_path + "scalex_per_j", 0, -100, 1000); + double scaley_per_j = 0.01 * prefs->getDoubleLimited(prefs_path + "scaley_per_j", 0, -100, 1000); + double scalex_rand = 0.01 * prefs->getDoubleLimited(prefs_path + "scalex_rand", 0, 0, 1000); + double scaley_rand = 0.01 * prefs->getDoubleLimited(prefs_path + "scaley_rand", 0, 0, 1000); + double scalex_exp = prefs->getDoubleLimited(prefs_path + "scalex_exp", 1, 0, 10); + double scaley_exp = prefs->getDoubleLimited(prefs_path + "scaley_exp", 1, 0, 10); + double scalex_log = prefs->getDoubleLimited(prefs_path + "scalex_log", 0, 0, 10); + double scaley_log = prefs->getDoubleLimited(prefs_path + "scaley_log", 0, 0, 10); + bool scalex_alternate = prefs->getBool(prefs_path + "scalex_alternate"); + bool scaley_alternate = prefs->getBool(prefs_path + "scaley_alternate"); + bool scalex_cumulate = prefs->getBool(prefs_path + "scalex_cumulate"); + bool scaley_cumulate = prefs->getBool(prefs_path + "scaley_cumulate"); + + double rotate_per_i = prefs->getDoubleLimited(prefs_path + "rotate_per_i", 0, -180, 180); + double rotate_per_j = prefs->getDoubleLimited(prefs_path + "rotate_per_j", 0, -180, 180); + double rotate_rand = 0.01 * prefs->getDoubleLimited(prefs_path + "rotate_rand", 0, 0, 100); + bool rotate_alternatei = prefs->getBool(prefs_path + "rotate_alternatei"); + bool rotate_alternatej = prefs->getBool(prefs_path + "rotate_alternatej"); + bool rotate_cumulatei = prefs->getBool(prefs_path + "rotate_cumulatei"); + bool rotate_cumulatej = prefs->getBool(prefs_path + "rotate_cumulatej"); + + double blur_per_i = 0.01 * prefs->getDoubleLimited(prefs_path + "blur_per_i", 0, 0, 100); + double blur_per_j = 0.01 * prefs->getDoubleLimited(prefs_path + "blur_per_j", 0, 0, 100); + bool blur_alternatei = prefs->getBool(prefs_path + "blur_alternatei"); + bool blur_alternatej = prefs->getBool(prefs_path + "blur_alternatej"); + double blur_rand = 0.01 * prefs->getDoubleLimited(prefs_path + "blur_rand", 0, 0, 100); + + double opacity_per_i = 0.01 * prefs->getDoubleLimited(prefs_path + "opacity_per_i", 0, 0, 100); + double opacity_per_j = 0.01 * prefs->getDoubleLimited(prefs_path + "opacity_per_j", 0, 0, 100); + bool opacity_alternatei = prefs->getBool(prefs_path + "opacity_alternatei"); + bool opacity_alternatej = prefs->getBool(prefs_path + "opacity_alternatej"); + double opacity_rand = 0.01 * prefs->getDoubleLimited(prefs_path + "opacity_rand", 0, 0, 100); + + Glib::ustring initial_color = prefs->getString(prefs_path + "initial_color"); + double hue_per_j = 0.01 * prefs->getDoubleLimited(prefs_path + "hue_per_j", 0, -100, 100); + double hue_per_i = 0.01 * prefs->getDoubleLimited(prefs_path + "hue_per_i", 0, -100, 100); + double hue_rand = 0.01 * prefs->getDoubleLimited(prefs_path + "hue_rand", 0, 0, 100); + double saturation_per_j = 0.01 * prefs->getDoubleLimited(prefs_path + "saturation_per_j", 0, -100, 100); + double saturation_per_i = 0.01 * prefs->getDoubleLimited(prefs_path + "saturation_per_i", 0, -100, 100); + double saturation_rand = 0.01 * prefs->getDoubleLimited(prefs_path + "saturation_rand", 0, 0, 100); + double lightness_per_j = 0.01 * prefs->getDoubleLimited(prefs_path + "lightness_per_j", 0, -100, 100); + double lightness_per_i = 0.01 * prefs->getDoubleLimited(prefs_path + "lightness_per_i", 0, -100, 100); + double lightness_rand = 0.01 * prefs->getDoubleLimited(prefs_path + "lightness_rand", 0, 0, 100); + bool color_alternatej = prefs->getBool(prefs_path + "color_alternatej"); + bool color_alternatei = prefs->getBool(prefs_path + "color_alternatei"); + + int type = prefs->getInt(prefs_path + "symmetrygroup", 0); + bool keepbbox = prefs->getBool(prefs_path + "keepbbox", true); + int imax = prefs->getInt(prefs_path + "imax", 2); + int jmax = prefs->getInt(prefs_path + "jmax", 2); + + bool fillrect = prefs->getBool(prefs_path + "fillrect"); + double fillwidth = prefs->getDoubleLimited(prefs_path + "fillwidth", 50, 0, 1e6); + double fillheight = prefs->getDoubleLimited(prefs_path + "fillheight", 50, 0, 1e6); + + bool dotrace = prefs->getBool(prefs_path + "dotrace"); + int pick = prefs->getInt(prefs_path + "pick"); + bool pick_to_presence = prefs->getBool(prefs_path + "pick_to_presence"); + bool pick_to_size = prefs->getBool(prefs_path + "pick_to_size"); + bool pick_to_color = prefs->getBool(prefs_path + "pick_to_color"); + bool pick_to_opacity = prefs->getBool(prefs_path + "pick_to_opacity"); + double rand_picked = 0.01 * prefs->getDoubleLimited(prefs_path + "rand_picked", 0, 0, 100); + bool invert_picked = prefs->getBool(prefs_path + "invert_picked"); + double gamma_picked = prefs->getDoubleLimited(prefs_path + "gamma_picked", 0, -10, 10); + + if (dotrace) { + clonetiler_trace_setup (sp_desktop_document(desktop), 1.0, item); + } + + Geom::Point center; + double w = 0; + double h = 0; + double x0 = 0; + double y0 = 0; + + if (keepbbox && + obj_repr->attribute("inkscape:tile-w") && + obj_repr->attribute("inkscape:tile-h") && + obj_repr->attribute("inkscape:tile-x0") && + obj_repr->attribute("inkscape:tile-y0") && + obj_repr->attribute("inkscape:tile-cx") && + obj_repr->attribute("inkscape:tile-cy")) { + + double cx = 0; + double cy = 0; + sp_repr_get_double (obj_repr, "inkscape:tile-cx", &cx); + sp_repr_get_double (obj_repr, "inkscape:tile-cy", &cy); + center = Geom::Point (cx, cy); + + sp_repr_get_double (obj_repr, "inkscape:tile-w", &w); + sp_repr_get_double (obj_repr, "inkscape:tile-h", &h); + sp_repr_get_double (obj_repr, "inkscape:tile-x0", &x0); + sp_repr_get_double (obj_repr, "inkscape:tile-y0", &y0); + } else { + bool prefs_bbox = prefs->getBool("/tools/bounding_box", false); + SPItem::BBoxType bbox_type = ( !prefs_bbox ? + SPItem::VISUAL_BBOX : SPItem::GEOMETRIC_BBOX ); + Geom::OptRect r = item->documentBounds(bbox_type); + if (r) { + w = r->dimensions()[Geom::X]; + h = r->dimensions()[Geom::Y]; + x0 = r->min()[Geom::X]; + y0 = r->min()[Geom::Y]; + center = desktop->dt2doc(item->getCenter()); + + sp_repr_set_svg_double(obj_repr, "inkscape:tile-cx", center[Geom::X]); + sp_repr_set_svg_double(obj_repr, "inkscape:tile-cy", center[Geom::Y]); + sp_repr_set_svg_double(obj_repr, "inkscape:tile-w", w); + sp_repr_set_svg_double(obj_repr, "inkscape:tile-h", h); + sp_repr_set_svg_double(obj_repr, "inkscape:tile-x0", x0); + sp_repr_set_svg_double(obj_repr, "inkscape:tile-y0", y0); + } else { + center = Geom::Point(0, 0); + w = h = 0; + x0 = y0 = 0; + } + } + + Geom::Point cur(0, 0); + Geom::Rect bbox_original (Geom::Point (x0, y0), Geom::Point (x0 + w, y0 + h)); + double perimeter_original = (w + h)/4; + + // The integers i and j are reserved for tile column and row. + // The doubles x and y are used for coordinates + for (int i = 0; + fillrect? + (fabs(cur[Geom::X]) < fillwidth && i < 200) // prevent "freezing" with too large fillrect, arbitrarily limit rows + : (i < imax); + i ++) { + for (int j = 0; + fillrect? + (fabs(cur[Geom::Y]) < fillheight && j < 200) // prevent "freezing" with too large fillrect, arbitrarily limit cols + : (j < jmax); + j ++) { + + // Note: We create a clone at 0,0 too, right over the original, in case our clones are colored + + // Get transform from symmetry, shift, scale, rotation + Geom::Affine t = clonetiler_get_transform (type, i, j, center[Geom::X], center[Geom::Y], w, h, + shiftx_per_i, shifty_per_i, + shiftx_per_j, shifty_per_j, + shiftx_rand, shifty_rand, + shiftx_exp, shifty_exp, + shiftx_alternate, shifty_alternate, + shiftx_cumulate, shifty_cumulate, + shiftx_excludew, shifty_excludeh, + scalex_per_i, scaley_per_i, + scalex_per_j, scaley_per_j, + scalex_rand, scaley_rand, + scalex_exp, scaley_exp, + scalex_log, scaley_log, + scalex_alternate, scaley_alternate, + scalex_cumulate, scaley_cumulate, + rotate_per_i, rotate_per_j, + rotate_rand, + rotate_alternatei, rotate_alternatej, + rotate_cumulatei, rotate_cumulatej ); + + cur = center * t - center; + if (fillrect) { + if ((cur[Geom::X] > fillwidth) || (cur[Geom::Y] > fillheight)) { // off limits + continue; + } + } + + gchar color_string[32]; *color_string = 0; + + // Color tab + if (!initial_color.empty()) { + guint32 rgba = sp_svg_read_color (initial_color.data(), 0x000000ff); + float hsl[3]; + sp_color_rgb_to_hsl_floatv (hsl, SP_RGBA32_R_F(rgba), SP_RGBA32_G_F(rgba), SP_RGBA32_B_F(rgba)); + + double eff_i = (color_alternatei? (i%2) : (i)); + double eff_j = (color_alternatej? (j%2) : (j)); + + hsl[0] += hue_per_i * eff_i + hue_per_j * eff_j + hue_rand * g_random_double_range (-1, 1); + double notused; + hsl[0] = modf( hsl[0], ¬used ); // Restrict to 0-1 + hsl[1] += saturation_per_i * eff_i + saturation_per_j * eff_j + saturation_rand * g_random_double_range (-1, 1); + hsl[1] = CLAMP (hsl[1], 0, 1); + hsl[2] += lightness_per_i * eff_i + lightness_per_j * eff_j + lightness_rand * g_random_double_range (-1, 1); + hsl[2] = CLAMP (hsl[2], 0, 1); + + float rgb[3]; + sp_color_hsl_to_rgb_floatv (rgb, hsl[0], hsl[1], hsl[2]); + sp_svg_write_color(color_string, sizeof(color_string), SP_RGBA32_F_COMPOSE(rgb[0], rgb[1], rgb[2], 1.0)); + } + + // Blur + double blur = 0.0; + { + int eff_i = (blur_alternatei? (i%2) : (i)); + int eff_j = (blur_alternatej? (j%2) : (j)); + blur = (blur_per_i * eff_i + blur_per_j * eff_j + blur_rand * g_random_double_range (-1, 1)); + blur = CLAMP (blur, 0, 1); + } + + // Opacity + double opacity = 1.0; + { + int eff_i = (opacity_alternatei? (i%2) : (i)); + int eff_j = (opacity_alternatej? (j%2) : (j)); + opacity = 1 - (opacity_per_i * eff_i + opacity_per_j * eff_j + opacity_rand * g_random_double_range (-1, 1)); + opacity = CLAMP (opacity, 0, 1); + } + + // Trace tab + if (dotrace) { + Geom::Rect bbox_t = transform_rect (bbox_original, t); + + guint32 rgba = clonetiler_trace_pick (bbox_t); + float r = SP_RGBA32_R_F(rgba); + float g = SP_RGBA32_G_F(rgba); + float b = SP_RGBA32_B_F(rgba); + float a = SP_RGBA32_A_F(rgba); + + float hsl[3]; + sp_color_rgb_to_hsl_floatv (hsl, r, g, b); + + gdouble val = 0; + switch (pick) { + case PICK_COLOR: + val = 1 - hsl[2]; // inverse lightness; to match other picks where black = max + break; + case PICK_OPACITY: + val = a; + break; + case PICK_R: + val = r; + break; + case PICK_G: + val = g; + break; + case PICK_B: + val = b; + break; + case PICK_H: + val = hsl[0]; + break; + case PICK_S: + val = hsl[1]; + break; + case PICK_L: + val = 1 - hsl[2]; + break; + default: + break; + } + + if (rand_picked > 0) { + val = randomize01 (val, rand_picked); + r = randomize01 (r, rand_picked); + g = randomize01 (g, rand_picked); + b = randomize01 (b, rand_picked); + } + + if (gamma_picked != 0) { + double power; + if (gamma_picked > 0) + power = 1/(1 + fabs(gamma_picked)); + else + power = 1 + fabs(gamma_picked); + + val = pow (val, power); + r = pow (r, power); + g = pow (g, power); + b = pow (b, power); + } + + if (invert_picked) { + val = 1 - val; + r = 1 - r; + g = 1 - g; + b = 1 - b; + } + + val = CLAMP (val, 0, 1); + r = CLAMP (r, 0, 1); + g = CLAMP (g, 0, 1); + b = CLAMP (b, 0, 1); + + // recompose tweaked color + rgba = SP_RGBA32_F_COMPOSE(r, g, b, a); + + if (pick_to_presence) { + if (g_random_double_range (0, 1) > val) { + continue; // skip! + } + } + if (pick_to_size) { + t = Geom::Translate(-center[Geom::X], -center[Geom::Y]) * Geom::Scale (val, val) * Geom::Translate(center[Geom::X], center[Geom::Y]) * t; + } + if (pick_to_opacity) { + opacity *= val; + } + if (pick_to_color) { + sp_svg_write_color(color_string, sizeof(color_string), rgba); + } + } + + if (opacity < 1e-6) { // invisibly transparent, skip + continue; + } + + if (fabs(t[0]) + fabs (t[1]) + fabs(t[2]) + fabs(t[3]) < 1e-6) { // too small, skip + continue; + } + + // Create the clone + Inkscape::XML::Node *clone = obj_repr->document()->createElement("svg:use"); + clone->setAttribute("x", "0"); + clone->setAttribute("y", "0"); + clone->setAttribute("inkscape:tiled-clone-of", id_href); + clone->setAttribute("xlink:href", id_href); + + Geom::Point new_center; + bool center_set = false; + if (obj_repr->attribute("inkscape:transform-center-x") || obj_repr->attribute("inkscape:transform-center-y")) { + new_center = desktop->dt2doc(item->getCenter()) * t; + center_set = true; + } + + gchar *affinestr=sp_svg_transform_write(t); + clone->setAttribute("transform", affinestr); + g_free(affinestr); + + if (opacity < 1.0) { + sp_repr_set_css_double(clone, "opacity", opacity); + } + + if (*color_string) { + clone->setAttribute("fill", color_string); + clone->setAttribute("stroke", color_string); + } + + // add the new clone to the top of the original's parent + parent->getRepr()->appendChild(clone); + + if (blur > 0.0) { + SPObject *clone_object = sp_desktop_document(desktop)->getObjectByRepr(clone); + double perimeter = perimeter_original * t.descrim(); + double radius = blur * perimeter; + // this is necessary for all newly added clones to have correct bboxes, + // otherwise filters won't work: + sp_desktop_document(desktop)->ensureUpToDate(); + // it's hard to figure out exact width/height of the tile without having an object + // that we can take bbox of; however here we only need a lower bound so that blur + // margins are not too small, and the perimeter should work + SPFilter *constructed = new_filter_gaussian_blur(sp_desktop_document(desktop), radius, t.descrim(), t.expansionX(), t.expansionY(), perimeter, perimeter); + sp_style_set_property_url (clone_object, "filter", constructed, false); + } + + if (center_set) { + SPObject *clone_object = sp_desktop_document(desktop)->getObjectByRepr(clone); + if (clone_object && SP_IS_ITEM(clone_object)) { + clone_object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + SP_ITEM(clone_object)->setCenter(desktop->doc2dt(new_center)); + clone_object->updateRepr(); + } + } + + Inkscape::GC::release(clone); + } + cur[Geom::Y] = 0; + } + + if (dotrace) { + clonetiler_trace_finish (); + } + + clonetiler_change_selection (NULL, selection, dlg); + + desktop->clearWaitingCursor(); + + DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_DIALOG_CLONETILER, + _("Create tiled clones")); +} + +GtkWidget * CloneTiler::clonetiler_new_tab(GtkWidget *nb, const gchar *label) +{ + GtkWidget *l = gtk_label_new_with_mnemonic (label); + GtkWidget *vb = gtk_vbox_new (FALSE, VB_MARGIN); + gtk_container_set_border_width (GTK_CONTAINER (vb), VB_MARGIN); + gtk_notebook_append_page (GTK_NOTEBOOK (nb), vb, l); + return vb; +} + +void CloneTiler::clonetiler_checkbox_toggled(GtkToggleButton *tb, gpointer *data) +{ + const gchar *attr = (const gchar *) data; + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setBool(prefs_path + attr, gtk_toggle_button_get_active(tb)); +} + +GtkWidget * CloneTiler::clonetiler_checkbox(const char *tip, const char *attr) +{ + GtkWidget *hb = gtk_hbox_new(FALSE, VB_MARGIN); + + GtkWidget *b = gtk_check_button_new (); + gtk_widget_set_tooltip_text (b, tip); + + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + bool value = prefs->getBool(prefs_path + attr); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(b), value); + + gtk_box_pack_end (GTK_BOX (hb), b, FALSE, TRUE, 0); + g_signal_connect ( G_OBJECT (b), "clicked", + G_CALLBACK (clonetiler_checkbox_toggled), (gpointer) attr); + + g_object_set_data (G_OBJECT(b), "uncheckable", GINT_TO_POINTER(TRUE)); + + return hb; +} + +void CloneTiler::clonetiler_value_changed(GtkAdjustment *adj, gpointer data) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + const gchar *pref = (const gchar *) data; + prefs->setDouble(prefs_path + pref, gtk_adjustment_get_value (adj)); +} + +GtkWidget * CloneTiler::clonetiler_spinbox(const char *tip, const char *attr, double lower, double upper, const gchar *suffix, bool exponent/* = false*/) +{ + GtkWidget *hb = gtk_hbox_new(FALSE, 0); + + { + Gtk::Adjustment *a; + if (exponent) { + a = new Gtk::Adjustment (1.0, lower, upper, 0.01, 0.05, 0); + } else { + a = new Gtk::Adjustment (0.0, lower, upper, 0.1, 0.5, 0); + } + + Inkscape::UI::Widget::SpinButton *sb; + if (exponent) { + sb = new Inkscape::UI::Widget::SpinButton (*a, 0.01, 2); + } else { + sb = new Inkscape::UI::Widget::SpinButton (*a, 0.1, 1); + } + + sb->set_tooltip_text (tip); + sb->set_width_chars (5); + sb->set_digits(3); + gtk_box_pack_start (GTK_BOX (hb), GTK_WIDGET(sb->gobj()), FALSE, FALSE, SB_MARGIN); + + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + double value = prefs->getDoubleLimited(prefs_path + attr, exponent? 1.0 : 0.0, lower, upper); + a->set_value (value); + // TODO: C++ification + g_signal_connect(G_OBJECT(a->gobj()), "value_changed", + G_CALLBACK(clonetiler_value_changed), (gpointer) attr); + + if (exponent) { + sb->set_data ("oneable", GINT_TO_POINTER(TRUE)); + } else { + sb->set_data ("zeroable", GINT_TO_POINTER(TRUE)); + } + } + + { + GtkWidget *l = gtk_label_new (""); + gtk_label_set_markup (GTK_LABEL(l), suffix); + gtk_misc_set_alignment (GTK_MISC (l), 1.0, 0); + gtk_box_pack_start (GTK_BOX (hb), l, FALSE, FALSE, 0); + } + + return hb; +} + +void CloneTiler::clonetiler_symgroup_changed(GtkComboBox *cb, gpointer /*data*/) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + gint group_new = gtk_combo_box_get_active (cb); + prefs->setInt(prefs_path + "symmetrygroup", group_new); +} + +void CloneTiler::clonetiler_xy_changed(GtkAdjustment *adj, gpointer data) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + const gchar *pref = (const gchar *) data; + prefs->setInt(prefs_path + pref, (int) floor(gtk_adjustment_get_value (adj) + 0.5)); +} + +void CloneTiler::clonetiler_keep_bbox_toggled(GtkToggleButton *tb, gpointer /*data*/) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setBool(prefs_path + "keepbbox", gtk_toggle_button_get_active(tb)); +} + +void CloneTiler::clonetiler_pick_to(GtkToggleButton *tb, gpointer data) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + const gchar *pref = (const gchar *) data; + prefs->setBool(prefs_path + pref, gtk_toggle_button_get_active(tb)); +} + + +void CloneTiler::clonetiler_reset_recursive(GtkWidget *w) +{ + if (w && GTK_IS_OBJECT(w)) { + { + int r = GPOINTER_TO_INT (g_object_get_data(G_OBJECT(w), "zeroable")); + if (r && GTK_IS_SPIN_BUTTON(w)) { // spinbutton + GtkAdjustment *a = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON(w)); + gtk_adjustment_set_value (a, 0); + } + } + { + int r = GPOINTER_TO_INT (g_object_get_data(G_OBJECT(w), "oneable")); + if (r && GTK_IS_SPIN_BUTTON(w)) { // spinbutton + GtkAdjustment *a = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON(w)); + gtk_adjustment_set_value (a, 1); + } + } + { + int r = GPOINTER_TO_INT (g_object_get_data(G_OBJECT(w), "uncheckable")); + if (r && GTK_IS_TOGGLE_BUTTON(w)) { // checkbox + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(w), FALSE); + } + } + } + + if (GTK_IS_CONTAINER(w)) { + GList *ch = gtk_container_get_children (GTK_CONTAINER(w)); + for (GList *i = ch; i != NULL; i = i->next) { + clonetiler_reset_recursive (GTK_WIDGET(i->data)); + } + g_list_free (ch); + } +} + +void CloneTiler::clonetiler_reset(GtkWidget */*widget*/, GtkWidget *dlg) +{ + clonetiler_reset_recursive (dlg); +} + +void CloneTiler::clonetiler_table_attach(GtkWidget *table, GtkWidget *widget, float align, int row, int col) +{ + GtkWidget *a = gtk_alignment_new (align, 0, 0, 0); + gtk_container_add(GTK_CONTAINER(a), widget); + gtk_table_attach ( GTK_TABLE (table), a, col, col + 1, row, row + 1, (GtkAttachOptions)4, (GtkAttachOptions)0, 0, 0 ); +} + +GtkWidget * CloneTiler::clonetiler_table_x_y_rand(int values) +{ + GtkWidget *table = gtk_table_new (values + 2, 5, FALSE); + gtk_container_set_border_width (GTK_CONTAINER (table), VB_MARGIN); + gtk_table_set_row_spacings (GTK_TABLE (table), 6); + gtk_table_set_col_spacings (GTK_TABLE (table), 8); + + { + GtkWidget *hb = gtk_hbox_new (FALSE, 0); + + GtkWidget *i = sp_icon_new (Inkscape::ICON_SIZE_DECORATION, INKSCAPE_ICON("object-rows")); + gtk_box_pack_start (GTK_BOX (hb), i, FALSE, FALSE, 2); + + GtkWidget *l = gtk_label_new (""); + gtk_label_set_markup (GTK_LABEL(l), _("Per row:")); + gtk_box_pack_start (GTK_BOX (hb), l, FALSE, FALSE, 2); + + clonetiler_table_attach (table, hb, 0, 1, 2); + } + + { + GtkWidget *hb = gtk_hbox_new (FALSE, 0); + + GtkWidget *i = sp_icon_new (Inkscape::ICON_SIZE_DECORATION, INKSCAPE_ICON("object-columns")); + gtk_box_pack_start (GTK_BOX (hb), i, FALSE, FALSE, 2); + + GtkWidget *l = gtk_label_new (""); + gtk_label_set_markup (GTK_LABEL(l), _("Per column:")); + gtk_box_pack_start (GTK_BOX (hb), l, FALSE, FALSE, 2); + + clonetiler_table_attach (table, hb, 0, 1, 3); + } + + { + GtkWidget *l = gtk_label_new (""); + gtk_label_set_markup (GTK_LABEL(l), _("Randomize:")); + clonetiler_table_attach (table, l, 0, 1, 4); + } + + return table; +} + +void CloneTiler::clonetiler_pick_switched(GtkToggleButton */*tb*/, gpointer data) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + guint v = GPOINTER_TO_INT (data); + prefs->setInt(prefs_path + "pick", v); +} + + +void CloneTiler::clonetiler_switch_to_create(GtkToggleButton */*tb*/, GtkWidget *dlg) +{ + GtkWidget *rowscols = (GtkWidget *) g_object_get_data (G_OBJECT(dlg), "rowscols"); + GtkWidget *widthheight = (GtkWidget *) g_object_get_data (G_OBJECT(dlg), "widthheight"); + + if (rowscols) { + gtk_widget_set_sensitive (rowscols, TRUE); + } + if (widthheight) { + gtk_widget_set_sensitive (widthheight, FALSE); + } + + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setBool(prefs_path + "fillrect", false); +} + + +void CloneTiler::clonetiler_switch_to_fill(GtkToggleButton */*tb*/, GtkWidget *dlg) +{ + GtkWidget *rowscols = (GtkWidget *) g_object_get_data (G_OBJECT(dlg), "rowscols"); + GtkWidget *widthheight = (GtkWidget *) g_object_get_data (G_OBJECT(dlg), "widthheight"); + + if (rowscols) { + gtk_widget_set_sensitive (rowscols, FALSE); + } + if (widthheight) { + gtk_widget_set_sensitive (widthheight, TRUE); + } + + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setBool(prefs_path + "fillrect", true); +} + + + + +void CloneTiler::clonetiler_fill_width_changed(GtkAdjustment *adj, GtkWidget *u) +{ + gdouble const raw_dist = gtk_adjustment_get_value (adj); + SPUnit const &unit = *sp_unit_selector_get_unit(SP_UNIT_SELECTOR(u)); + gdouble const pixels = sp_units_get_pixels (raw_dist, unit); + + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble(prefs_path + "fillwidth", pixels); +} + +void CloneTiler::clonetiler_fill_height_changed(GtkAdjustment *adj, GtkWidget *u) +{ + gdouble const raw_dist = gtk_adjustment_get_value (adj); + SPUnit const &unit = *sp_unit_selector_get_unit(SP_UNIT_SELECTOR(u)); + gdouble const pixels = sp_units_get_pixels (raw_dist, unit); + + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble(prefs_path + "fillheight", pixels); +} + + +void CloneTiler::clonetiler_do_pick_toggled(GtkToggleButton *tb, GtkWidget *dlg) +{ + GtkWidget *vvb = (GtkWidget *) g_object_get_data (G_OBJECT(dlg), "dotrace"); + + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setBool(prefs_path + "dotrace", gtk_toggle_button_get_active (tb)); + + if (vvb) { + gtk_widget_set_sensitive (vvb, gtk_toggle_button_get_active (tb)); + } +} + + +} +} +} + + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/ui/dialog/clonetiler.h b/src/ui/dialog/clonetiler.h new file mode 100644 index 000000000..2cad30e9e --- /dev/null +++ b/src/ui/dialog/clonetiler.h @@ -0,0 +1,183 @@ +/** @file + * @brief Clone tiling dialog + */ +/* Authors: + * bulia byak + * + * Copyright (C) 2004 Authors + * Released under the GNU GPL, read the file 'COPYING' for more information + */ +#ifndef __SP_CLONE_TILER_H__ +#define __SP_CLONE_TILER_H__ + +#include "ui/widget/panel.h" +#include +#include + +#include "ui/dialog/desktop-tracker.h" +#include "ui/widget/color-picker.h" +#include "sp-root.h" + +namespace Inkscape { +namespace UI { +namespace Dialog { + +class CloneTiler : public Widget::Panel { +public: + CloneTiler(); + virtual ~CloneTiler(); + + static CloneTiler &getInstance() { return *new CloneTiler(); } + +protected: + + GtkWidget * clonetiler_new_tab(GtkWidget *nb, const gchar *label); + GtkWidget * clonetiler_table_x_y_rand(int values); + GtkWidget * clonetiler_spinbox(const char *tip, const char *attr, double lower, double upper, const gchar *suffix, bool exponent = false); + GtkWidget * clonetiler_checkbox(const char *tip, const char *attr); + void clonetiler_table_attach(GtkWidget *table, GtkWidget *widget, float align, int row, int col); + + static void clonetiler_symgroup_changed(GtkComboBox *cb, gpointer /*data*/); + static void clonetiler_remove(GtkWidget */*widget*/, GtkWidget *dlg, bool do_undo = true); + static void on_picker_color_changed(guint rgba); + static void clonetiler_trace_hide_tiled_clones_recursively(SPObject *from); + static void clonetiler_checkbox_toggled(GtkToggleButton *tb, gpointer *data); + static void clonetiler_pick_switched(GtkToggleButton */*tb*/, gpointer data); + static void clonetiler_do_pick_toggled(GtkToggleButton *tb, GtkWidget *dlg); + static void clonetiler_pick_to(GtkToggleButton *tb, gpointer data); + static void clonetiler_xy_changed(GtkAdjustment *adj, gpointer data); + static void clonetiler_fill_width_changed(GtkAdjustment *adj, GtkWidget *u); + static void clonetiler_fill_height_changed(GtkAdjustment *adj, GtkWidget *u); + static void clonetiler_switch_to_create(GtkToggleButton */*tb*/, GtkWidget *dlg); + static void clonetiler_switch_to_fill(GtkToggleButton */*tb*/, GtkWidget *dlg); + static void clonetiler_keep_bbox_toggled(GtkToggleButton *tb, gpointer /*data*/); + static void clonetiler_apply(GtkWidget */*widget*/, GtkWidget *dlg); + static void clonetiler_unclump(GtkWidget */*widget*/, void *); + static void clonetiler_change_selection(Inkscape::Application * /*inkscape*/, Inkscape::Selection *selection, GtkWidget *dlg); + static void clonetiler_external_change(Inkscape::Application * /*inkscape*/, GtkWidget *dlg); + static void clonetiler_disconnect_gsignal(GObject *widget, gpointer source); + static void clonetiler_reset(GtkWidget */*widget*/, GtkWidget *dlg); + static guint clonetiler_number_of_clones(SPObject *obj); + static void clonetiler_trace_setup(SPDocument *doc, gdouble zoom, SPItem *original); + static guint32 clonetiler_trace_pick(Geom::Rect box); + static void clonetiler_trace_finish(); + static bool clonetiler_is_a_clone_of(SPObject *tile, SPObject *obj); + static Geom::Rect transform_rect(Geom::Rect const &r, Geom::Affine const &m); + static double randomize01(double val, double rand); + static void clonetiler_value_changed(GtkAdjustment *adj, gpointer data); + static void clonetiler_reset_recursive(GtkWidget *w); + + static Geom::Affine clonetiler_get_transform( // symmetry group + int type, + + // row, column + int i, int j, + + // center, width, height of the tile + double cx, double cy, + double w, double h, + + // values from the dialog: + // Shift + double shiftx_per_i, double shifty_per_i, + double shiftx_per_j, double shifty_per_j, + double shiftx_rand, double shifty_rand, + double shiftx_exp, double shifty_exp, + int shiftx_alternate, int shifty_alternate, + int shiftx_cumulate, int shifty_cumulate, + int shiftx_excludew, int shifty_excludeh, + + // Scale + double scalex_per_i, double scaley_per_i, + double scalex_per_j, double scaley_per_j, + double scalex_rand, double scaley_rand, + double scalex_exp, double scaley_exp, + double scalex_log, double scaley_log, + int scalex_alternate, int scaley_alternate, + int scalex_cumulate, int scaley_cumulate, + + // Rotation + double rotate_per_i, double rotate_per_j, + double rotate_rand, + int rotate_alternatei, int rotate_alternatej, + int rotate_cumulatei, int rotate_cumulatej + ); + + +private: + CloneTiler(CloneTiler const &d); + CloneTiler& operator=(CloneTiler const &d); + + GtkWidget *dlg; + SPDesktop *desktop; + DesktopTracker deskTrack; + Inkscape::UI::Widget::ColorPicker *color_picker; + GtkSizeGroup* table_row_labels; + + sigc::connection desktopChangeConn; + sigc::connection selectChangedConn; + sigc::connection subselChangedConn; + sigc::connection selectModifiedConn; + sigc::connection color_changed_connection; + + /** + * Can be invoked for setting the desktop. Currently not used. + */ + void setDesktop(SPDesktop *desktop); + + /** + * Is invoked by the desktop tracker when the desktop changes. + */ + void setTargetDesktop(SPDesktop *desktop); + +}; + + +enum { + PICK_COLOR, + PICK_OPACITY, + PICK_R, + PICK_G, + PICK_B, + PICK_H, + PICK_S, + PICK_L +}; + +enum { + TILE_P1, + TILE_P2, + TILE_PM, + TILE_PG, + TILE_CM, + TILE_PMM, + TILE_PMG, + TILE_PGG, + TILE_CMM, + TILE_P4, + TILE_P4M, + TILE_P4G, + TILE_P3, + TILE_P31M, + TILE_P3M1, + TILE_P6, + TILE_P6M +}; + +} // namespace Dialog +} // namespace UI +} // namespace Inkscape + + +#endif + +/* + 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/dialog-manager.cpp b/src/ui/dialog/dialog-manager.cpp index 2e7ffa1c2..60011ca9d 100644 --- a/src/ui/dialog/dialog-manager.cpp +++ b/src/ui/dialog/dialog-manager.cpp @@ -51,6 +51,7 @@ #include "ui/dialog/spellcheck.h" #include "ui/dialog/export.h" #include "ui/dialog/xml-tree.h" +#include "ui/dialog/clonetiler.h" #ifdef ENABLE_SVG_FONTS #include "ui/dialog/svg-fonts-dialog.h" @@ -129,6 +130,7 @@ DialogManager::DialogManager() { registerFactory("SpellCheck", &create); registerFactory("Export", &create); registerFactory("XmlTree", &create); + registerFactory("CloneTiler", &create); } else { @@ -163,6 +165,7 @@ DialogManager::DialogManager() { registerFactory("SpellCheck", &create); registerFactory("Export", &create); registerFactory("XmlTree", &create); + registerFactory("CloneTiler", &create); } } diff --git a/src/verbs.cpp b/src/verbs.cpp index b890e64a5..9b750e123 100644 --- a/src/verbs.cpp +++ b/src/verbs.cpp @@ -39,7 +39,6 @@ #include "bind/javabind.h" #include "desktop.h" #include "desktop-handles.h" -#include "dialogs/clonetiler.h" #include "dialogs/find.h" #include "display/curve.h" #include "document.h" @@ -67,6 +66,7 @@ #include "sp-namedview.h" #include "text-chemistry.h" #include "tools-switch.h" +#include "ui/dialog/clonetiler.h" #include "ui/dialog/dialog-manager.h" #include "ui/dialog/document-properties.h" #include "ui/dialog/extensions.h" @@ -1844,7 +1844,8 @@ void DialogVerb::perform(SPAction *action, void *data) inkscape_dialogs_toggle(); break; case SP_VERB_DIALOG_CLONETILER: - clonetiler_dialog(); + //clonetiler_dialog(); + dt->_dlg_mgr->showDialog("CloneTiler"); break; case SP_VERB_DIALOG_ATTR: //sp_item_dialog(); -- cgit v1.2.3 From d3342f38918218447781880efc982ef36bf82817 Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Sat, 24 Mar 2012 08:42:19 +0100 Subject: Translations. POTFILE update (clonetiler move). (bzr r11126) --- po/POTFILES.in | 2 +- po/inkscape.pot | 3485 ++++++++++++++++++++++++++++++------------------------- 2 files changed, 1894 insertions(+), 1593 deletions(-) diff --git a/po/POTFILES.in b/po/POTFILES.in index 8bdc7cce0..b20d61b1f 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -45,7 +45,7 @@ src/connector-context.cpp src/context-fns.cpp src/desktop-events.cpp src/desktop.cpp -src/dialogs/clonetiler.cpp +src/ui/dialog/clonetiler.cpp src/ui/dialog/export.cpp src/dialogs/find.cpp src/ui/dialog/spellcheck.cpp diff --git a/po/inkscape.pot b/po/inkscape.pot index 71bcd3eb4..61843fcec 100644 --- a/po/inkscape.pot +++ b/po/inkscape.pot @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: inkscape-devel@lists.sourceforge.net\n" -"POT-Creation-Date: 2012-03-09 13:09+0100\n" +"POT-Creation-Date: 2012-03-24 08:41+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -737,7 +737,7 @@ msgstr "" #. Pencil #: ../share/filters/filters.svg.h:1 -#: ../src/ui/dialog/inkscape-preferences.cpp:402 ../src/verbs.cpp:2465 +#: ../src/ui/dialog/inkscape-preferences.cpp:401 ../src/verbs.cpp:2464 msgid "Pencil" msgstr "" @@ -1436,8 +1436,8 @@ msgstr "" msgid "Black Light" msgstr "" -#: ../share/filters/filters.svg.h:1 ../src/dialogs/clonetiler.cpp:2520 -#: ../src/dialogs/clonetiler.cpp:2659 +#: ../share/filters/filters.svg.h:1 ../src/ui/dialog/clonetiler.cpp:806 +#: ../src/ui/dialog/clonetiler.cpp:945 #: ../src/extension/internal/bitmap/colorize.cpp:52 #: ../src/extension/internal/filter/bumps.h:101 #: ../src/extension/internal/filter/bumps.h:324 @@ -3624,7 +3624,7 @@ msgid "Defines the direction and magnitude of the extrusion" msgstr "" #: ../src/sp-flowtext.cpp:365 ../src/sp-text.cpp:423 -#: ../src/text-context.cpp:1615 +#: ../src/text-context.cpp:1631 msgid " [truncated]" msgstr "" @@ -3770,674 +3770,611 @@ msgstr "" msgid "No next zoom." msgstr "" -#: ../src/dialogs/clonetiler.cpp:160 -msgid "Nothing selected." -msgstr "" - -#: ../src/dialogs/clonetiler.cpp:166 -msgid "More than one object selected." -msgstr "" - -#: ../src/dialogs/clonetiler.cpp:173 -#, c-format -msgid "Object has %d tiled clones." -msgstr "" - -#: ../src/dialogs/clonetiler.cpp:178 -msgid "Object has no tiled clones." -msgstr "" - -#: ../src/dialogs/clonetiler.cpp:925 -msgid "Select one object whose tiled clones to unclump." -msgstr "" - -#: ../src/dialogs/clonetiler.cpp:947 -msgid "Unclump tiled clones" -msgstr "" - -#: ../src/dialogs/clonetiler.cpp:976 -msgid "Select one object whose tiled clones to remove." -msgstr "" - -#: ../src/dialogs/clonetiler.cpp:999 -msgid "Delete tiled clones" -msgstr "" - -#: ../src/dialogs/clonetiler.cpp:1046 ../src/selection-chemistry.cpp:2049 -msgid "Select an object to clone." -msgstr "" - -#: ../src/dialogs/clonetiler.cpp:1052 -msgid "" -"If you want to clone several objects, group them and clone the " -"group." -msgstr "" - -#: ../src/dialogs/clonetiler.cpp:1061 -msgid "Creating tiled clones..." -msgstr "" - -#: ../src/dialogs/clonetiler.cpp:1466 -msgid "Create tiled clones" -msgstr "" - -#: ../src/dialogs/clonetiler.cpp:1648 -msgid "Per row:" -msgstr "" - -#: ../src/dialogs/clonetiler.cpp:1661 -msgid "Per column:" -msgstr "" - -#: ../src/dialogs/clonetiler.cpp:1669 -msgid "Randomize:" -msgstr "" - -#: ../src/dialogs/clonetiler.cpp:1816 +#: ../src/ui/dialog/clonetiler.cpp:107 msgid "_Symmetry" msgstr "" #. TRANSLATORS: "translation" means "shift" / "displacement" here. -#: ../src/dialogs/clonetiler.cpp:1828 +#: ../src/ui/dialog/clonetiler.cpp:119 msgid "P1: simple translation" msgstr "" -#: ../src/dialogs/clonetiler.cpp:1829 +#: ../src/ui/dialog/clonetiler.cpp:120 msgid "P2: 180° rotation" msgstr "" -#: ../src/dialogs/clonetiler.cpp:1830 +#: ../src/ui/dialog/clonetiler.cpp:121 msgid "PM: reflection" msgstr "" #. TRANSLATORS: "glide reflection" is a reflection and a translation combined. #. For more info, see http://mathforum.org/sum95/suzanne/symsusan.html -#: ../src/dialogs/clonetiler.cpp:1833 +#: ../src/ui/dialog/clonetiler.cpp:124 msgid "PG: glide reflection" msgstr "" -#: ../src/dialogs/clonetiler.cpp:1834 +#: ../src/ui/dialog/clonetiler.cpp:125 msgid "CM: reflection + glide reflection" msgstr "" -#: ../src/dialogs/clonetiler.cpp:1835 +#: ../src/ui/dialog/clonetiler.cpp:126 msgid "PMM: reflection + reflection" msgstr "" -#: ../src/dialogs/clonetiler.cpp:1836 +#: ../src/ui/dialog/clonetiler.cpp:127 msgid "PMG: reflection + 180° rotation" msgstr "" -#: ../src/dialogs/clonetiler.cpp:1837 +#: ../src/ui/dialog/clonetiler.cpp:128 msgid "PGG: glide reflection + 180° rotation" msgstr "" -#: ../src/dialogs/clonetiler.cpp:1838 +#: ../src/ui/dialog/clonetiler.cpp:129 msgid "CMM: reflection + reflection + 180° rotation" msgstr "" -#: ../src/dialogs/clonetiler.cpp:1839 +#: ../src/ui/dialog/clonetiler.cpp:130 msgid "P4: 90° rotation" msgstr "" -#: ../src/dialogs/clonetiler.cpp:1840 +#: ../src/ui/dialog/clonetiler.cpp:131 msgid "P4M: 90° rotation + 45° reflection" msgstr "" -#: ../src/dialogs/clonetiler.cpp:1841 +#: ../src/ui/dialog/clonetiler.cpp:132 msgid "P4G: 90° rotation + 90° reflection" msgstr "" -#: ../src/dialogs/clonetiler.cpp:1842 +#: ../src/ui/dialog/clonetiler.cpp:133 msgid "P3: 120° rotation" msgstr "" -#: ../src/dialogs/clonetiler.cpp:1843 +#: ../src/ui/dialog/clonetiler.cpp:134 msgid "P31M: reflection + 120° rotation, dense" msgstr "" -#: ../src/dialogs/clonetiler.cpp:1844 +#: ../src/ui/dialog/clonetiler.cpp:135 msgid "P3M1: reflection + 120° rotation, sparse" msgstr "" -#: ../src/dialogs/clonetiler.cpp:1845 +#: ../src/ui/dialog/clonetiler.cpp:136 msgid "P6: 60° rotation" msgstr "" -#: ../src/dialogs/clonetiler.cpp:1846 +#: ../src/ui/dialog/clonetiler.cpp:137 msgid "P6M: reflection + 60° rotation" msgstr "" -#: ../src/dialogs/clonetiler.cpp:1868 +#: ../src/ui/dialog/clonetiler.cpp:157 msgid "Select one of the 17 symmetry groups for the tiling" msgstr "" -#: ../src/dialogs/clonetiler.cpp:1889 +#: ../src/ui/dialog/clonetiler.cpp:175 msgid "S_hift" msgstr "" #. TRANSLATORS: "shift" means: the tiles will be shifted (offset) horizontally by this amount -#: ../src/dialogs/clonetiler.cpp:1899 +#: ../src/ui/dialog/clonetiler.cpp:185 #, no-c-format msgid "Shift X:" msgstr "" -#: ../src/dialogs/clonetiler.cpp:1907 +#: ../src/ui/dialog/clonetiler.cpp:193 #, no-c-format msgid "Horizontal shift per row (in % of tile width)" msgstr "" -#: ../src/dialogs/clonetiler.cpp:1915 +#: ../src/ui/dialog/clonetiler.cpp:201 #, no-c-format msgid "Horizontal shift per column (in % of tile width)" msgstr "" -#: ../src/dialogs/clonetiler.cpp:1921 +#: ../src/ui/dialog/clonetiler.cpp:207 msgid "Randomize the horizontal shift by this percentage" msgstr "" #. TRANSLATORS: "shift" means: the tiles will be shifted (offset) vertically by this amount -#: ../src/dialogs/clonetiler.cpp:1931 +#: ../src/ui/dialog/clonetiler.cpp:217 #, no-c-format msgid "Shift Y:" msgstr "" -#: ../src/dialogs/clonetiler.cpp:1939 +#: ../src/ui/dialog/clonetiler.cpp:225 #, no-c-format msgid "Vertical shift per row (in % of tile height)" msgstr "" -#: ../src/dialogs/clonetiler.cpp:1947 +#: ../src/ui/dialog/clonetiler.cpp:233 #, no-c-format msgid "Vertical shift per column (in % of tile height)" msgstr "" -#: ../src/dialogs/clonetiler.cpp:1954 +#: ../src/ui/dialog/clonetiler.cpp:240 msgid "Randomize the vertical shift by this percentage" msgstr "" -#: ../src/dialogs/clonetiler.cpp:1962 ../src/dialogs/clonetiler.cpp:2108 +#: ../src/ui/dialog/clonetiler.cpp:248 ../src/ui/dialog/clonetiler.cpp:394 msgid "Exponent:" msgstr "" -#: ../src/dialogs/clonetiler.cpp:1969 +#: ../src/ui/dialog/clonetiler.cpp:255 msgid "Whether rows are spaced evenly (1), converge (<1) or diverge (>1)" msgstr "" -#: ../src/dialogs/clonetiler.cpp:1976 +#: ../src/ui/dialog/clonetiler.cpp:262 msgid "Whether columns are spaced evenly (1), converge (<1) or diverge (>1)" msgstr "" #. TRANSLATORS: "Alternate" is a verb here -#: ../src/dialogs/clonetiler.cpp:1984 ../src/dialogs/clonetiler.cpp:2148 -#: ../src/dialogs/clonetiler.cpp:2224 ../src/dialogs/clonetiler.cpp:2297 -#: ../src/dialogs/clonetiler.cpp:2343 ../src/dialogs/clonetiler.cpp:2465 +#: ../src/ui/dialog/clonetiler.cpp:270 ../src/ui/dialog/clonetiler.cpp:434 +#: ../src/ui/dialog/clonetiler.cpp:510 ../src/ui/dialog/clonetiler.cpp:583 +#: ../src/ui/dialog/clonetiler.cpp:629 ../src/ui/dialog/clonetiler.cpp:751 msgid "Alternate:" msgstr "" -#: ../src/dialogs/clonetiler.cpp:1990 +#: ../src/ui/dialog/clonetiler.cpp:276 msgid "Alternate the sign of shifts for each row" msgstr "" -#: ../src/dialogs/clonetiler.cpp:1995 +#: ../src/ui/dialog/clonetiler.cpp:281 msgid "Alternate the sign of shifts for each column" msgstr "" #. TRANSLATORS: "Cumulate" is a verb here -#: ../src/dialogs/clonetiler.cpp:2002 ../src/dialogs/clonetiler.cpp:2166 -#: ../src/dialogs/clonetiler.cpp:2242 +#: ../src/ui/dialog/clonetiler.cpp:288 ../src/ui/dialog/clonetiler.cpp:452 +#: ../src/ui/dialog/clonetiler.cpp:528 msgid "Cumulate:" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2008 +#: ../src/ui/dialog/clonetiler.cpp:294 msgid "Cumulate the shifts for each row" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2013 +#: ../src/ui/dialog/clonetiler.cpp:299 msgid "Cumulate the shifts for each column" msgstr "" #. TRANSLATORS: "Cumulate" is a verb here -#: ../src/dialogs/clonetiler.cpp:2020 +#: ../src/ui/dialog/clonetiler.cpp:306 msgid "Exclude tile:" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2026 +#: ../src/ui/dialog/clonetiler.cpp:312 msgid "Exclude tile height in shift" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2031 +#: ../src/ui/dialog/clonetiler.cpp:317 msgid "Exclude tile width in shift" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2040 +#: ../src/ui/dialog/clonetiler.cpp:326 msgid "Sc_ale" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2048 +#: ../src/ui/dialog/clonetiler.cpp:334 msgid "Scale X:" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2056 +#: ../src/ui/dialog/clonetiler.cpp:342 #, no-c-format msgid "Horizontal scale per row (in % of tile width)" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2064 +#: ../src/ui/dialog/clonetiler.cpp:350 #, no-c-format msgid "Horizontal scale per column (in % of tile width)" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2070 +#: ../src/ui/dialog/clonetiler.cpp:356 msgid "Randomize the horizontal scale by this percentage" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2078 +#: ../src/ui/dialog/clonetiler.cpp:364 msgid "Scale Y:" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2086 +#: ../src/ui/dialog/clonetiler.cpp:372 #, no-c-format msgid "Vertical scale per row (in % of tile height)" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2094 +#: ../src/ui/dialog/clonetiler.cpp:380 #, no-c-format msgid "Vertical scale per column (in % of tile height)" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2100 +#: ../src/ui/dialog/clonetiler.cpp:386 msgid "Randomize the vertical scale by this percentage" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2114 +#: ../src/ui/dialog/clonetiler.cpp:400 msgid "Whether row scaling is uniform (1), converge (<1) or diverge (>1)" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2120 +#: ../src/ui/dialog/clonetiler.cpp:406 msgid "Whether column scaling is uniform (1), converge (<1) or diverge (>1)" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2128 +#: ../src/ui/dialog/clonetiler.cpp:414 msgid "Base:" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2134 ../src/dialogs/clonetiler.cpp:2140 +#: ../src/ui/dialog/clonetiler.cpp:420 ../src/ui/dialog/clonetiler.cpp:426 msgid "" "Base for a logarithmic spiral: not used (0), converge (<1), or diverge (>1)" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2154 +#: ../src/ui/dialog/clonetiler.cpp:440 msgid "Alternate the sign of scales for each row" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2159 +#: ../src/ui/dialog/clonetiler.cpp:445 msgid "Alternate the sign of scales for each column" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2172 +#: ../src/ui/dialog/clonetiler.cpp:458 msgid "Cumulate the scales for each row" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2177 +#: ../src/ui/dialog/clonetiler.cpp:463 msgid "Cumulate the scales for each column" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2186 +#: ../src/ui/dialog/clonetiler.cpp:472 msgid "_Rotation" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2194 +#: ../src/ui/dialog/clonetiler.cpp:480 msgid "Angle:" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2202 +#: ../src/ui/dialog/clonetiler.cpp:488 #, no-c-format msgid "Rotate tiles by this angle for each row" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2210 +#: ../src/ui/dialog/clonetiler.cpp:496 #, no-c-format msgid "Rotate tiles by this angle for each column" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2216 +#: ../src/ui/dialog/clonetiler.cpp:502 msgid "Randomize the rotation angle by this percentage" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2230 +#: ../src/ui/dialog/clonetiler.cpp:516 msgid "Alternate the rotation direction for each row" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2235 +#: ../src/ui/dialog/clonetiler.cpp:521 msgid "Alternate the rotation direction for each column" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2248 +#: ../src/ui/dialog/clonetiler.cpp:534 msgid "Cumulate the rotation for each row" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2253 +#: ../src/ui/dialog/clonetiler.cpp:539 msgid "Cumulate the rotation for each column" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2262 +#: ../src/ui/dialog/clonetiler.cpp:548 msgid "_Blur & opacity" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2271 +#: ../src/ui/dialog/clonetiler.cpp:557 msgid "Blur:" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2277 +#: ../src/ui/dialog/clonetiler.cpp:563 msgid "Blur tiles by this percentage for each row" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2283 +#: ../src/ui/dialog/clonetiler.cpp:569 msgid "Blur tiles by this percentage for each column" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2289 +#: ../src/ui/dialog/clonetiler.cpp:575 msgid "Randomize the tile blur by this percentage" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2303 +#: ../src/ui/dialog/clonetiler.cpp:589 msgid "Alternate the sign of blur change for each row" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2308 +#: ../src/ui/dialog/clonetiler.cpp:594 msgid "Alternate the sign of blur change for each column" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2317 +#: ../src/ui/dialog/clonetiler.cpp:603 msgid "Opacity:" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2323 +#: ../src/ui/dialog/clonetiler.cpp:609 msgid "Decrease tile opacity by this percentage for each row" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2329 +#: ../src/ui/dialog/clonetiler.cpp:615 msgid "Decrease tile opacity by this percentage for each column" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2335 +#: ../src/ui/dialog/clonetiler.cpp:621 msgid "Randomize the tile opacity by this percentage" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2349 +#: ../src/ui/dialog/clonetiler.cpp:635 msgid "Alternate the sign of opacity change for each row" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2354 +#: ../src/ui/dialog/clonetiler.cpp:640 msgid "Alternate the sign of opacity change for each column" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2362 +#: ../src/ui/dialog/clonetiler.cpp:648 msgid "Co_lor" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2367 +#: ../src/ui/dialog/clonetiler.cpp:653 msgid "Initial color: " msgstr "" -#: ../src/dialogs/clonetiler.cpp:2371 +#: ../src/ui/dialog/clonetiler.cpp:657 msgid "Initial color of tiled clones" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2371 +#: ../src/ui/dialog/clonetiler.cpp:657 msgid "" "Initial color for clones (works only if the original has unset fill or " "stroke)" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2386 +#: ../src/ui/dialog/clonetiler.cpp:672 msgid "H:" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2392 +#: ../src/ui/dialog/clonetiler.cpp:678 msgid "Change the tile hue by this percentage for each row" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2398 +#: ../src/ui/dialog/clonetiler.cpp:684 msgid "Change the tile hue by this percentage for each column" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2404 +#: ../src/ui/dialog/clonetiler.cpp:690 msgid "Randomize the tile hue by this percentage" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2413 +#: ../src/ui/dialog/clonetiler.cpp:699 msgid "S:" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2419 +#: ../src/ui/dialog/clonetiler.cpp:705 msgid "Change the color saturation by this percentage for each row" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2425 +#: ../src/ui/dialog/clonetiler.cpp:711 msgid "Change the color saturation by this percentage for each column" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2431 +#: ../src/ui/dialog/clonetiler.cpp:717 msgid "Randomize the color saturation by this percentage" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2439 +#: ../src/ui/dialog/clonetiler.cpp:725 msgid "L:" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2445 +#: ../src/ui/dialog/clonetiler.cpp:731 msgid "Change the color lightness by this percentage for each row" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2451 +#: ../src/ui/dialog/clonetiler.cpp:737 msgid "Change the color lightness by this percentage for each column" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2457 +#: ../src/ui/dialog/clonetiler.cpp:743 msgid "Randomize the color lightness by this percentage" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2471 +#: ../src/ui/dialog/clonetiler.cpp:757 msgid "Alternate the sign of color changes for each row" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2476 +#: ../src/ui/dialog/clonetiler.cpp:762 msgid "Alternate the sign of color changes for each column" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2484 +#: ../src/ui/dialog/clonetiler.cpp:770 msgid "_Trace" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2491 +#: ../src/ui/dialog/clonetiler.cpp:777 msgid "Trace the drawing under the tiles" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2495 +#: ../src/ui/dialog/clonetiler.cpp:781 msgid "" "For each clone, pick a value from the drawing in that clone's location and " "apply it to the clone" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2509 +#: ../src/ui/dialog/clonetiler.cpp:795 msgid "1. Pick from the drawing:" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2521 +#: ../src/ui/dialog/clonetiler.cpp:807 msgid "Pick the visible color and opacity" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2528 ../src/dialogs/clonetiler.cpp:2669 +#: ../src/ui/dialog/clonetiler.cpp:814 ../src/ui/dialog/clonetiler.cpp:955 #: ../src/extension/internal/bitmap/opacity.cpp:38 #: ../src/extension/internal/filter/transparency.h:279 #: ../src/widgets/toolbox.cpp:4722 ../share/extensions/interp_att_g.inx.h:14 msgid "Opacity" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2529 +#: ../src/ui/dialog/clonetiler.cpp:815 msgid "Pick the total accumulated opacity" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2536 +#: ../src/ui/dialog/clonetiler.cpp:822 msgid "R" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2537 +#: ../src/ui/dialog/clonetiler.cpp:823 msgid "Pick the Red component of the color" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2544 +#: ../src/ui/dialog/clonetiler.cpp:830 msgid "G" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2545 +#: ../src/ui/dialog/clonetiler.cpp:831 msgid "Pick the Green component of the color" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2552 +#: ../src/ui/dialog/clonetiler.cpp:838 msgid "B" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2553 +#: ../src/ui/dialog/clonetiler.cpp:839 msgid "Pick the Blue component of the color" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2560 +#: ../src/ui/dialog/clonetiler.cpp:846 msgctxt "Clonetiler color hue" msgid "H" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2561 +#: ../src/ui/dialog/clonetiler.cpp:847 msgid "Pick the hue of the color" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2568 +#: ../src/ui/dialog/clonetiler.cpp:854 msgctxt "Clonetiler color saturation" msgid "S" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2569 +#: ../src/ui/dialog/clonetiler.cpp:855 msgid "Pick the saturation of the color" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2576 +#: ../src/ui/dialog/clonetiler.cpp:862 msgctxt "Clonetiler color lightness" msgid "L" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2577 +#: ../src/ui/dialog/clonetiler.cpp:863 msgid "Pick the lightness of the color" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2587 +#: ../src/ui/dialog/clonetiler.cpp:873 msgid "2. Tweak the picked value:" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2597 +#: ../src/ui/dialog/clonetiler.cpp:883 msgid "Gamma-correct:" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2601 +#: ../src/ui/dialog/clonetiler.cpp:887 msgid "Shift the mid-range of the picked value upwards (>0) or downwards (<0)" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2608 +#: ../src/ui/dialog/clonetiler.cpp:894 msgid "Randomize:" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2612 +#: ../src/ui/dialog/clonetiler.cpp:898 msgid "Randomize the picked value by this percentage" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2619 +#: ../src/ui/dialog/clonetiler.cpp:905 msgid "Invert:" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2623 +#: ../src/ui/dialog/clonetiler.cpp:909 msgid "Invert the picked value" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2629 +#: ../src/ui/dialog/clonetiler.cpp:915 msgid "3. Apply the value to the clones':" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2639 +#: ../src/ui/dialog/clonetiler.cpp:925 msgid "Presence" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2642 +#: ../src/ui/dialog/clonetiler.cpp:928 msgid "" "Each clone is created with the probability determined by the picked value in " "that point" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2649 +#: ../src/ui/dialog/clonetiler.cpp:935 msgid "Size" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2652 +#: ../src/ui/dialog/clonetiler.cpp:938 msgid "Each clone's size is determined by the picked value in that point" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2662 +#: ../src/ui/dialog/clonetiler.cpp:948 msgid "" "Each clone is painted by the picked color (the original must have unset fill " "or stroke)" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2672 +#: ../src/ui/dialog/clonetiler.cpp:958 msgid "Each clone's opacity is determined by the picked value in that point" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2700 +#: ../src/ui/dialog/clonetiler.cpp:986 msgid "How many rows in the tiling" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2722 +#: ../src/ui/dialog/clonetiler.cpp:1008 msgid "How many columns in the tiling" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2753 +#: ../src/ui/dialog/clonetiler.cpp:1039 msgid "Width of the rectangle to be filled" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2779 +#: ../src/ui/dialog/clonetiler.cpp:1065 msgid "Height of the rectangle to be filled" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2796 +#: ../src/ui/dialog/clonetiler.cpp:1082 msgid "Rows, columns: " msgstr "" -#: ../src/dialogs/clonetiler.cpp:2797 +#: ../src/ui/dialog/clonetiler.cpp:1083 msgid "Create the specified number of rows and columns" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2806 +#: ../src/ui/dialog/clonetiler.cpp:1092 msgid "Width, height: " msgstr "" -#: ../src/dialogs/clonetiler.cpp:2807 +#: ../src/ui/dialog/clonetiler.cpp:1093 msgid "Fill the specified width and height with the tiling" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2823 +#: ../src/ui/dialog/clonetiler.cpp:1109 msgid "Use saved size and position of the tile" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2826 +#: ../src/ui/dialog/clonetiler.cpp:1112 msgid "" "Pretend that the size and position of the tile are the same as the last time " "you tiled it (if any), instead of using the current size" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2850 +#: ../src/ui/dialog/clonetiler.cpp:1136 msgid " _Create " msgstr "" -#: ../src/dialogs/clonetiler.cpp:2852 +#: ../src/ui/dialog/clonetiler.cpp:1138 msgid "Create and tile the clones of the selection" msgstr "" @@ -4446,39 +4383,102 @@ msgstr "" #. diagrams on the left in the following screenshot: #. http://www.inkscape.org/screenshots/gallery/inkscape-0.42-CVS-tiles-unclump.png #. So unclumping is the process of spreading a number of objects out more evenly. -#: ../src/dialogs/clonetiler.cpp:2867 +#: ../src/ui/dialog/clonetiler.cpp:1153 msgid " _Unclump " msgstr "" -#: ../src/dialogs/clonetiler.cpp:2868 +#: ../src/ui/dialog/clonetiler.cpp:1154 msgid "Spread out clones to reduce clumping; can be applied repeatedly" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2874 +#: ../src/ui/dialog/clonetiler.cpp:1160 msgid " Re_move " msgstr "" -#: ../src/dialogs/clonetiler.cpp:2875 +#: ../src/ui/dialog/clonetiler.cpp:1161 msgid "Remove existing tiled clones of the selected object (siblings only)" msgstr "" -#: ../src/dialogs/clonetiler.cpp:2891 +#: ../src/ui/dialog/clonetiler.cpp:1177 msgid " R_eset " msgstr "" #. TRANSLATORS: "change" is a noun here -#: ../src/dialogs/clonetiler.cpp:2893 +#: ../src/ui/dialog/clonetiler.cpp:1179 msgid "" "Reset all shifts, scales, rotates, opacity and color changes in the dialog " "to zero" msgstr "" +#: ../src/ui/dialog/clonetiler.cpp:1252 +msgid "Nothing selected." +msgstr "" + +#: ../src/ui/dialog/clonetiler.cpp:1258 +msgid "More than one object selected." +msgstr "" + +#: ../src/ui/dialog/clonetiler.cpp:1265 +#, c-format +msgid "Object has %d tiled clones." +msgstr "" + +#: ../src/ui/dialog/clonetiler.cpp:1270 +msgid "Object has no tiled clones." +msgstr "" + +#: ../src/ui/dialog/clonetiler.cpp:1990 +msgid "Select one object whose tiled clones to unclump." +msgstr "" + +#: ../src/ui/dialog/clonetiler.cpp:2012 +msgid "Unclump tiled clones" +msgstr "" + +#: ../src/ui/dialog/clonetiler.cpp:2041 +msgid "Select one object whose tiled clones to remove." +msgstr "" + +#: ../src/ui/dialog/clonetiler.cpp:2064 +msgid "Delete tiled clones" +msgstr "" + +#: ../src/ui/dialog/clonetiler.cpp:2111 ../src/selection-chemistry.cpp:2057 +msgid "Select an object to clone." +msgstr "" + +#: ../src/ui/dialog/clonetiler.cpp:2117 +msgid "" +"If you want to clone several objects, group them and clone the " +"group." +msgstr "" + +#: ../src/ui/dialog/clonetiler.cpp:2126 +msgid "Creating tiled clones..." +msgstr "" + +#: ../src/ui/dialog/clonetiler.cpp:2531 +msgid "Create tiled clones" +msgstr "" + +#: ../src/ui/dialog/clonetiler.cpp:2713 +msgid "Per row:" +msgstr "" + +#: ../src/ui/dialog/clonetiler.cpp:2726 +msgid "Per column:" +msgstr "" + +#: ../src/ui/dialog/clonetiler.cpp:2734 +msgid "Randomize:" +msgstr "" + #: ../src/ui/dialog/export.cpp:107 ../src/widgets/toolbox.cpp:1775 #: ../src/widgets/toolbox.cpp:1783 ../share/extensions/gears.inx.h:8 msgid "Units:" msgstr "" -#: ../src/ui/dialog/export.cpp:109 ../src/ui/widget/preferences-widget.cpp:702 +#: ../src/ui/dialog/export.cpp:109 ../src/ui/widget/preferences-widget.cpp:706 msgid "_Browse..." msgstr "" @@ -4556,8 +4556,8 @@ msgid "_Height:" msgstr "" #: ../src/ui/dialog/export.cpp:235 -#: ../src/ui/dialog/inkscape-preferences.cpp:1306 -#: ../src/ui/dialog/inkscape-preferences.cpp:1309 +#: ../src/ui/dialog/inkscape-preferences.cpp:1315 +#: ../src/ui/dialog/inkscape-preferences.cpp:1318 msgid "dpi" msgstr "" @@ -4613,22 +4613,22 @@ msgid "Select a filename for exporting" msgstr "" #. TRANSLATORS: "%s" is replaced with "exact" or "partial" when this string is displayed -#: ../src/dialogs/find.cpp:379 ../src/ui/dialog/find.cpp:447 +#: ../src/dialogs/find.cpp:379 ../src/ui/dialog/find.cpp:824 #, c-format msgid "%d object found (out of %d), %s match." msgid_plural "%d objects found (out of %d), %s match." msgstr[0] "" msgstr[1] "" -#: ../src/dialogs/find.cpp:382 ../src/ui/dialog/find.cpp:450 +#: ../src/dialogs/find.cpp:382 ../src/ui/dialog/find.cpp:827 msgid "exact" msgstr "" -#: ../src/dialogs/find.cpp:382 ../src/ui/dialog/find.cpp:450 +#: ../src/dialogs/find.cpp:382 ../src/ui/dialog/find.cpp:827 msgid "partial" msgstr "" -#: ../src/dialogs/find.cpp:389 ../src/ui/dialog/find.cpp:457 +#: ../src/dialogs/find.cpp:389 ../src/ui/dialog/find.cpp:845 msgid "No objects found" msgstr "" @@ -4636,194 +4636,192 @@ msgstr "" msgid "T_ype: " msgstr "" -#: ../src/dialogs/find.cpp:552 ../src/ui/dialog/find.cpp:71 +#: ../src/dialogs/find.cpp:552 msgid "Search in all object types" msgstr "" -#: ../src/dialogs/find.cpp:552 ../src/ui/dialog/find.cpp:71 +#: ../src/dialogs/find.cpp:552 ../src/ui/dialog/find.cpp:93 msgid "All types" msgstr "" -#: ../src/dialogs/find.cpp:563 ../src/ui/dialog/find.cpp:72 +#: ../src/dialogs/find.cpp:563 msgid "Search all shapes" msgstr "" -#: ../src/dialogs/find.cpp:563 ../src/ui/dialog/find.cpp:72 +#: ../src/dialogs/find.cpp:563 msgid "All shapes" msgstr "" -#: ../src/dialogs/find.cpp:580 ../src/ui/dialog/find.cpp:73 +#: ../src/dialogs/find.cpp:580 ../src/ui/dialog/find.cpp:94 msgid "Search rectangles" msgstr "" -#: ../src/dialogs/find.cpp:580 ../src/ui/dialog/find.cpp:73 +#: ../src/dialogs/find.cpp:580 ../src/ui/dialog/find.cpp:94 msgid "Rectangles" msgstr "" -#: ../src/dialogs/find.cpp:585 ../src/ui/dialog/find.cpp:74 +#: ../src/dialogs/find.cpp:585 ../src/ui/dialog/find.cpp:95 msgid "Search ellipses, arcs, circles" msgstr "" -#: ../src/dialogs/find.cpp:585 ../src/ui/dialog/find.cpp:74 +#: ../src/dialogs/find.cpp:585 ../src/ui/dialog/find.cpp:95 msgid "Ellipses" msgstr "" -#: ../src/dialogs/find.cpp:590 ../src/ui/dialog/find.cpp:75 +#: ../src/dialogs/find.cpp:590 ../src/ui/dialog/find.cpp:96 msgid "Search stars and polygons" msgstr "" -#: ../src/dialogs/find.cpp:590 ../src/ui/dialog/find.cpp:75 +#: ../src/dialogs/find.cpp:590 ../src/ui/dialog/find.cpp:96 msgid "Stars" msgstr "" -#: ../src/dialogs/find.cpp:595 ../src/ui/dialog/find.cpp:76 +#: ../src/dialogs/find.cpp:595 ../src/ui/dialog/find.cpp:97 msgid "Search spirals" msgstr "" -#: ../src/dialogs/find.cpp:595 ../src/ui/dialog/find.cpp:76 +#: ../src/dialogs/find.cpp:595 ../src/ui/dialog/find.cpp:97 msgid "Spirals" msgstr "" #. TRANSLATORS: polyline is a set of connected straight line segments #. http://www.w3.org/TR/SVG11/shapes.html#PolylineElement -#: ../src/dialogs/find.cpp:608 ../src/ui/dialog/find.cpp:77 +#: ../src/dialogs/find.cpp:608 ../src/ui/dialog/find.cpp:98 msgid "Search paths, lines, polylines" msgstr "" -#: ../src/dialogs/find.cpp:608 ../src/ui/dialog/find.cpp:77 +#: ../src/dialogs/find.cpp:608 ../src/ui/dialog/find.cpp:98 #: ../src/widgets/toolbox.cpp:2439 msgid "Paths" msgstr "" -#: ../src/dialogs/find.cpp:613 ../src/ui/dialog/find.cpp:78 +#: ../src/dialogs/find.cpp:613 ../src/ui/dialog/find.cpp:99 msgid "Search text objects" msgstr "" -#: ../src/dialogs/find.cpp:613 ../src/ui/dialog/find.cpp:78 +#: ../src/dialogs/find.cpp:613 ../src/ui/dialog/find.cpp:99 msgid "Texts" msgstr "" -#: ../src/dialogs/find.cpp:618 ../src/ui/dialog/find.cpp:79 +#: ../src/dialogs/find.cpp:618 ../src/ui/dialog/find.cpp:100 msgid "Search groups" msgstr "" -#: ../src/dialogs/find.cpp:618 ../src/ui/dialog/find.cpp:79 +#: ../src/dialogs/find.cpp:618 ../src/ui/dialog/find.cpp:100 msgid "Groups" msgstr "" -#: ../src/dialogs/find.cpp:623 ../src/ui/dialog/find.cpp:82 +#: ../src/dialogs/find.cpp:623 ../src/ui/dialog/find.cpp:103 msgid "Search clones" msgstr "" #. TRANSLATORS: "Clones" is a noun indicating type of object to find -#: ../src/dialogs/find.cpp:625 ../src/ui/dialog/find.cpp:82 +#: ../src/dialogs/find.cpp:625 ../src/ui/dialog/find.cpp:103 msgctxt "Find dialog" msgid "Clones" msgstr "" -#: ../src/dialogs/find.cpp:630 ../src/ui/dialog/find.cpp:83 +#: ../src/dialogs/find.cpp:630 ../src/ui/dialog/find.cpp:105 msgid "Search images" msgstr "" -#: ../src/dialogs/find.cpp:630 ../src/ui/dialog/find.cpp:83 +#: ../src/dialogs/find.cpp:630 ../src/ui/dialog/find.cpp:105 #: ../share/extensions/embedimage.inx.h:3 #: ../share/extensions/extractimage.inx.h:4 msgid "Images" msgstr "" -#: ../src/dialogs/find.cpp:635 ../src/ui/dialog/find.cpp:84 +#: ../src/dialogs/find.cpp:635 ../src/ui/dialog/find.cpp:106 msgid "Search offset objects" msgstr "" -#: ../src/dialogs/find.cpp:635 ../src/ui/dialog/find.cpp:84 +#: ../src/dialogs/find.cpp:635 ../src/ui/dialog/find.cpp:106 msgid "Offsets" msgstr "" -#: ../src/dialogs/find.cpp:700 ../src/ui/dialog/find.cpp:62 +#: ../src/dialogs/find.cpp:700 msgid "_Text:" msgstr "" -#: ../src/dialogs/find.cpp:700 ../src/ui/dialog/find.cpp:62 +#: ../src/dialogs/find.cpp:700 msgid "Find objects by their text content (exact or partial match)" msgstr "" -#: ../src/dialogs/find.cpp:701 ../src/ui/dialog/find.cpp:63 -#: ../src/ui/dialog/object-properties.cpp:42 +#: ../src/dialogs/find.cpp:701 ../src/ui/dialog/object-properties.cpp:42 #: ../src/ui/dialog/object-properties.cpp:249 #: ../src/ui/dialog/object-properties.cpp:306 #: ../src/ui/dialog/object-properties.cpp:313 msgid "_ID:" msgstr "" -#: ../src/dialogs/find.cpp:701 ../src/ui/dialog/find.cpp:63 +#: ../src/dialogs/find.cpp:701 msgid "Find objects by the value of the id attribute (exact or partial match)" msgstr "" -#: ../src/dialogs/find.cpp:702 ../src/ui/dialog/find.cpp:64 +#: ../src/dialogs/find.cpp:702 msgid "_Style:" msgstr "" -#: ../src/dialogs/find.cpp:702 ../src/ui/dialog/find.cpp:64 +#: ../src/dialogs/find.cpp:702 msgid "" "Find objects by the value of the style attribute (exact or partial match)" msgstr "" -#: ../src/dialogs/find.cpp:703 ../src/ui/dialog/find.cpp:65 +#: ../src/dialogs/find.cpp:703 msgid "_Attribute:" msgstr "" -#: ../src/dialogs/find.cpp:703 ../src/ui/dialog/find.cpp:65 +#: ../src/dialogs/find.cpp:703 msgid "Find objects by the name of an attribute (exact or partial match)" msgstr "" -#: ../src/dialogs/find.cpp:717 ../src/ui/dialog/find.cpp:66 +#: ../src/dialogs/find.cpp:717 msgid "Search in s_election" msgstr "" -#: ../src/dialogs/find.cpp:721 ../src/ui/dialog/find.cpp:66 +#: ../src/dialogs/find.cpp:721 ../src/ui/dialog/find.cpp:72 msgid "Limit search to the current selection" msgstr "" -#: ../src/dialogs/find.cpp:726 ../src/ui/dialog/find.cpp:67 +#: ../src/dialogs/find.cpp:726 msgid "Search in current _layer" msgstr "" -#: ../src/dialogs/find.cpp:730 ../src/ui/dialog/find.cpp:67 +#: ../src/dialogs/find.cpp:730 ../src/ui/dialog/find.cpp:71 msgid "Limit search to the current layer" msgstr "" -#: ../src/dialogs/find.cpp:735 ../src/ui/dialog/find.cpp:68 +#: ../src/dialogs/find.cpp:735 ../src/ui/dialog/find.cpp:81 msgid "Include _hidden" msgstr "" -#: ../src/dialogs/find.cpp:739 ../src/ui/dialog/find.cpp:68 +#: ../src/dialogs/find.cpp:739 ../src/ui/dialog/find.cpp:81 msgid "Include hidden objects in search" msgstr "" -#: ../src/dialogs/find.cpp:744 ../src/ui/dialog/find.cpp:69 +#: ../src/dialogs/find.cpp:744 msgid "Include l_ocked" msgstr "" -#: ../src/dialogs/find.cpp:748 ../src/ui/dialog/find.cpp:69 +#: ../src/dialogs/find.cpp:748 ../src/ui/dialog/find.cpp:82 msgid "Include locked objects in search" msgstr "" #. TRANSLATORS: "Clear" is a verb here #: ../src/dialogs/find.cpp:759 ../src/ui/dialog/debug.cpp:76 -#: ../src/ui/dialog/find.cpp:86 ../src/ui/dialog/messages.cpp:47 -#: ../src/ui/dialog/scriptdialog.cpp:179 +#: ../src/ui/dialog/messages.cpp:47 ../src/ui/dialog/scriptdialog.cpp:179 msgid "_Clear" msgstr "" -#: ../src/dialogs/find.cpp:759 ../src/ui/dialog/find.cpp:86 +#: ../src/dialogs/find.cpp:759 msgid "Clear values" msgstr "" -#: ../src/dialogs/find.cpp:760 ../src/ui/dialog/find.cpp:87 +#: ../src/dialogs/find.cpp:760 ../src/ui/dialog/find.cpp:110 msgid "_Find" msgstr "" -#: ../src/dialogs/find.cpp:760 ../src/ui/dialog/find.cpp:87 +#: ../src/dialogs/find.cpp:760 msgid "Select objects matching all of the fields you filled in" msgstr "" @@ -4902,7 +4900,8 @@ msgstr "" msgid "Fix spelling" msgstr "" -#: ../src/ui/dialog/text-edit.cpp:66 ../src/ui/dialog/svg-fonts-dialog.cpp:909 +#: ../src/ui/dialog/text-edit.cpp:66 ../src/ui/dialog/find.cpp:90 +#: ../src/ui/dialog/svg-fonts-dialog.cpp:909 msgid "_Font" msgstr "" @@ -4958,112 +4957,112 @@ msgstr "" msgid "Spacing between lines (percent of font size)" msgstr "" -#: ../src/ui/dialog/text-edit.cpp:566 ../src/text-context.cpp:1508 +#: ../src/ui/dialog/text-edit.cpp:565 ../src/text-context.cpp:1519 msgid "Set text style" msgstr "" -#: ../src/ui/dialog/xml-tree.cpp:68 ../src/ui/dialog/xml-tree.cpp:117 +#: ../src/ui/dialog/xml-tree.cpp:71 ../src/ui/dialog/xml-tree.cpp:120 msgid "New element node" msgstr "" -#: ../src/ui/dialog/xml-tree.cpp:69 ../src/ui/dialog/xml-tree.cpp:123 +#: ../src/ui/dialog/xml-tree.cpp:72 ../src/ui/dialog/xml-tree.cpp:126 msgid "New text node" msgstr "" -#: ../src/ui/dialog/xml-tree.cpp:70 ../src/ui/dialog/xml-tree.cpp:137 +#: ../src/ui/dialog/xml-tree.cpp:73 ../src/ui/dialog/xml-tree.cpp:140 msgid "nodeAsInXMLdialogTooltip|Delete node" msgstr "" -#: ../src/ui/dialog/xml-tree.cpp:71 ../src/ui/dialog/xml-tree.cpp:129 -#: ../src/ui/dialog/xml-tree.cpp:999 +#: ../src/ui/dialog/xml-tree.cpp:74 ../src/ui/dialog/xml-tree.cpp:132 +#: ../src/ui/dialog/xml-tree.cpp:947 msgid "Duplicate node" msgstr "" -#: ../src/ui/dialog/xml-tree.cpp:77 ../src/ui/dialog/xml-tree.cpp:181 -#: ../src/ui/dialog/xml-tree.cpp:1033 +#: ../src/ui/dialog/xml-tree.cpp:80 ../src/ui/dialog/xml-tree.cpp:184 +#: ../src/ui/dialog/xml-tree.cpp:981 msgid "Delete attribute" msgstr "" -#: ../src/ui/dialog/xml-tree.cpp:81 +#: ../src/ui/dialog/xml-tree.cpp:84 msgid "Set" msgstr "" -#: ../src/ui/dialog/xml-tree.cpp:112 +#: ../src/ui/dialog/xml-tree.cpp:115 msgid "Drag to reorder nodes" msgstr "" -#: ../src/ui/dialog/xml-tree.cpp:143 ../src/ui/dialog/xml-tree.cpp:144 -#: ../src/ui/dialog/xml-tree.cpp:1158 +#: ../src/ui/dialog/xml-tree.cpp:146 ../src/ui/dialog/xml-tree.cpp:147 +#: ../src/ui/dialog/xml-tree.cpp:1102 msgid "Unindent node" msgstr "" -#: ../src/ui/dialog/xml-tree.cpp:148 ../src/ui/dialog/xml-tree.cpp:149 -#: ../src/ui/dialog/xml-tree.cpp:1136 +#: ../src/ui/dialog/xml-tree.cpp:151 ../src/ui/dialog/xml-tree.cpp:152 +#: ../src/ui/dialog/xml-tree.cpp:1080 msgid "Indent node" msgstr "" -#: ../src/ui/dialog/xml-tree.cpp:153 ../src/ui/dialog/xml-tree.cpp:154 -#: ../src/ui/dialog/xml-tree.cpp:1087 +#: ../src/ui/dialog/xml-tree.cpp:156 ../src/ui/dialog/xml-tree.cpp:157 +#: ../src/ui/dialog/xml-tree.cpp:1031 msgid "Raise node" msgstr "" -#: ../src/ui/dialog/xml-tree.cpp:158 ../src/ui/dialog/xml-tree.cpp:159 -#: ../src/ui/dialog/xml-tree.cpp:1105 +#: ../src/ui/dialog/xml-tree.cpp:161 ../src/ui/dialog/xml-tree.cpp:162 +#: ../src/ui/dialog/xml-tree.cpp:1049 msgid "Lower node" msgstr "" -#: ../src/ui/dialog/xml-tree.cpp:197 +#: ../src/ui/dialog/xml-tree.cpp:201 msgid "Attribute name" msgstr "" -#: ../src/ui/dialog/xml-tree.cpp:212 +#: ../src/ui/dialog/xml-tree.cpp:216 msgid "Attribute value" msgstr "" -#: ../src/ui/dialog/xml-tree.cpp:302 +#: ../src/ui/dialog/xml-tree.cpp:306 msgid "Click to select nodes, drag to rearrange." msgstr "" -#: ../src/ui/dialog/xml-tree.cpp:313 +#: ../src/ui/dialog/xml-tree.cpp:317 msgid "Click attribute to edit." msgstr "" -#: ../src/ui/dialog/xml-tree.cpp:317 +#: ../src/ui/dialog/xml-tree.cpp:321 #, c-format msgid "" "Attribute %s selected. Press Ctrl+Enter when done editing to " "commit changes." msgstr "" -#: ../src/ui/dialog/xml-tree.cpp:574 +#: ../src/ui/dialog/xml-tree.cpp:578 msgid "Drag XML subtree" msgstr "" -#: ../src/ui/dialog/xml-tree.cpp:906 +#: ../src/ui/dialog/xml-tree.cpp:854 msgid "New element node..." msgstr "" -#: ../src/ui/dialog/xml-tree.cpp:928 +#: ../src/ui/dialog/xml-tree.cpp:876 msgid "Cancel" msgstr "" -#: ../src/ui/dialog/xml-tree.cpp:934 +#: ../src/ui/dialog/xml-tree.cpp:882 msgid "Create" msgstr "" -#: ../src/ui/dialog/xml-tree.cpp:965 +#: ../src/ui/dialog/xml-tree.cpp:913 msgid "Create new element node" msgstr "" -#: ../src/ui/dialog/xml-tree.cpp:981 +#: ../src/ui/dialog/xml-tree.cpp:929 msgid "Create new text node" msgstr "" -#: ../src/ui/dialog/xml-tree.cpp:1014 +#: ../src/ui/dialog/xml-tree.cpp:962 msgid "nodeAsInXMLinHistoryDialog|Delete node" msgstr "" -#: ../src/ui/dialog/xml-tree.cpp:1057 +#: ../src/ui/dialog/xml-tree.cpp:1005 msgid "Change attribute" msgstr "" @@ -5076,8 +5075,8 @@ msgid "_Origin X:" msgstr "" #: ../src/display/canvas-axonomgrid.cpp:331 ../src/display/canvas-grid.cpp:702 -#: ../src/ui/dialog/inkscape-preferences.cpp:658 -#: ../src/ui/dialog/inkscape-preferences.cpp:683 +#: ../src/ui/dialog/inkscape-preferences.cpp:667 +#: ../src/ui/dialog/inkscape-preferences.cpp:692 msgid "X coordinate of grid origin" msgstr "" @@ -5086,8 +5085,8 @@ msgid "O_rigin Y:" msgstr "" #: ../src/display/canvas-axonomgrid.cpp:333 ../src/display/canvas-grid.cpp:704 -#: ../src/ui/dialog/inkscape-preferences.cpp:659 -#: ../src/ui/dialog/inkscape-preferences.cpp:684 +#: ../src/ui/dialog/inkscape-preferences.cpp:668 +#: ../src/ui/dialog/inkscape-preferences.cpp:693 msgid "Y coordinate of grid origin" msgstr "" @@ -5096,29 +5095,29 @@ msgid "Spacing _Y:" msgstr "" #: ../src/display/canvas-axonomgrid.cpp:335 -#: ../src/ui/dialog/inkscape-preferences.cpp:687 +#: ../src/ui/dialog/inkscape-preferences.cpp:696 msgid "Base length of z-axis" msgstr "" #: ../src/display/canvas-axonomgrid.cpp:337 -#: ../src/ui/dialog/inkscape-preferences.cpp:690 +#: ../src/ui/dialog/inkscape-preferences.cpp:699 #: ../src/widgets/toolbox.cpp:3817 msgid "Angle X:" msgstr "" #: ../src/display/canvas-axonomgrid.cpp:337 -#: ../src/ui/dialog/inkscape-preferences.cpp:690 +#: ../src/ui/dialog/inkscape-preferences.cpp:699 msgid "Angle of x-axis" msgstr "" #: ../src/display/canvas-axonomgrid.cpp:339 -#: ../src/ui/dialog/inkscape-preferences.cpp:691 +#: ../src/ui/dialog/inkscape-preferences.cpp:700 #: ../src/widgets/toolbox.cpp:3896 msgid "Angle Z:" msgstr "" #: ../src/display/canvas-axonomgrid.cpp:339 -#: ../src/ui/dialog/inkscape-preferences.cpp:691 +#: ../src/ui/dialog/inkscape-preferences.cpp:700 msgid "Angle of z-axis" msgstr "" @@ -5201,12 +5200,12 @@ msgid "Spacing _X:" msgstr "" #: ../src/display/canvas-grid.cpp:706 -#: ../src/ui/dialog/inkscape-preferences.cpp:664 +#: ../src/ui/dialog/inkscape-preferences.cpp:673 msgid "Distance between vertical grid lines" msgstr "" #: ../src/display/canvas-grid.cpp:708 -#: ../src/ui/dialog/inkscape-preferences.cpp:665 +#: ../src/ui/dialog/inkscape-preferences.cpp:674 msgid "Distance between horizontal grid lines" msgstr "" @@ -5536,11 +5535,11 @@ msgid "[Unchanged]" msgstr "" #. Edit -#: ../src/event-log.cpp:264 ../src/event-log.cpp:267 ../src/verbs.cpp:2219 +#: ../src/event-log.cpp:264 ../src/event-log.cpp:267 ../src/verbs.cpp:2218 msgid "_Undo" msgstr "" -#: ../src/event-log.cpp:274 ../src/event-log.cpp:278 ../src/verbs.cpp:2221 +#: ../src/event-log.cpp:274 ../src/event-log.cpp:278 ../src/verbs.cpp:2220 msgid "_Redo" msgstr "" @@ -5712,7 +5711,7 @@ msgstr "" #: ../src/extension/internal/bitmap/adaptiveThreshold.cpp:43 #: ../src/extension/internal/filter/color.h:1044 #: ../src/extension/internal/filter/paint.h:357 -#: ../src/widgets/gradient-vector.cpp:826 +#: ../src/widgets/gradient-vector.cpp:848 #: ../share/extensions/printing_marks.inx.h:10 msgid "Offset:" msgstr "" @@ -6132,6 +6131,7 @@ msgstr "" #: ../src/extension/internal/bitmap/opacity.cpp:40 #: ../src/extension/internal/filter/blurs.h:333 #: ../src/ui/dialog/filter-effects-dialog.cpp:2286 +#: ../src/ui/widget/object-composite-settings.cpp:65 #: ../src/widgets/toolbox.cpp:5925 msgid "Opacity:" msgstr "" @@ -6241,7 +6241,7 @@ msgstr "" #: ../src/extension/internal/bitmap/threshold.cpp:40 #: ../src/extension/internal/bitmap/unsharpmask.cpp:46 -#: ../src/ui/dialog/inkscape-preferences.cpp:1098 +#: ../src/ui/dialog/inkscape-preferences.cpp:1107 #: ../src/widgets/toolbox.cpp:8665 msgid "Threshold:" msgstr "" @@ -6729,7 +6729,7 @@ msgstr "" #: ../src/extension/internal/filter/paint.h:712 #: ../src/extension/internal/filter/textures.h:77 #: ../src/extension/internal/filter/transparency.h:61 -#: ../src/filter-enums.cpp:51 ../src/ui/dialog/inkscape-preferences.cpp:586 +#: ../src/filter-enums.cpp:51 ../src/ui/dialog/inkscape-preferences.cpp:588 msgid "Normal" msgstr "" @@ -6818,7 +6818,7 @@ msgstr "" #: ../src/extension/internal/filter/bumps.h:100 #: ../src/extension/internal/filter/bumps.h:334 -#: ../share/extensions/measure.inx.h:10 +#: ../share/extensions/measure.inx.h:27 msgid "Precision:" msgstr "" @@ -7664,7 +7664,7 @@ msgstr "" #: ../src/extension/internal/filter/overlays.h:59 #: ../src/extension/internal/filter/paint.h:700 -#: ../src/extension/internal/filter/shadows.h:59 +#: ../src/extension/internal/filter/shadows.h:59 ../src/ui/dialog/find.cpp:83 #: ../src/ui/dialog/tracedialog.cpp:626 #: ../share/extensions/color_custom.inx.h:14 #: ../share/extensions/color_randomize.inx.h:6 @@ -7854,7 +7854,7 @@ msgstr "" #: ../src/extension/internal/filter/paint.h:594 #: ../src/extension/internal/filter/paint.h:871 -#: ../src/ui/widget/filter-effect-chooser.cpp:25 +#: ../src/ui/widget/filter-effect-chooser.cpp:26 msgid "Blend mode:" msgstr "" @@ -8108,29 +8108,37 @@ msgstr "" msgid "Repaint anything visible monochrome" msgstr "" -#: ../src/extension/internal/gdkpixbuf-input.cpp:159 +#: ../src/extension/internal/gdkpixbuf-input.cpp:163 #, c-format -msgid "%s Bitmap Input" +msgid "%s bitmap image import" msgstr "" -#: ../src/extension/internal/gdkpixbuf-input.cpp:165 +#: ../src/extension/internal/gdkpixbuf-input.cpp:169 msgid "Link or embed image:" msgstr "" -#: ../src/extension/internal/gdkpixbuf-input.cpp:166 +#: ../src/extension/internal/gdkpixbuf-input.cpp:170 msgid "Embed" msgstr "" -#: ../src/extension/internal/gdkpixbuf-input.cpp:167 +#: ../src/extension/internal/gdkpixbuf-input.cpp:171 msgid "Link" msgstr "" -#: ../src/extension/internal/gdkpixbuf-input.cpp:169 +#: ../src/extension/internal/gdkpixbuf-input.cpp:173 msgid "" "Embed results in stand-alone, larger SVG files. Link references a file " "outside this SVG document and all files must be moved together." msgstr "" +#: ../src/extension/internal/gdkpixbuf-input.cpp:174 +msgid "Hide the dialog next time and always apply the same action." +msgstr "" + +#: ../src/extension/internal/gdkpixbuf-input.cpp:174 +msgid "Don't ask again" +msgstr "" + #: ../src/extension/internal/gimpgrad.cpp:272 msgid "GIMP Gradients" msgstr "" @@ -8195,7 +8203,7 @@ msgstr "" #: ../src/extension/internal/grid.cpp:212 #: ../src/ui/dialog/document-properties.cpp:147 -#: ../src/ui/dialog/inkscape-preferences.cpp:699 +#: ../src/ui/dialog/inkscape-preferences.cpp:708 #: ../src/widgets/toolbox.cpp:2529 msgid "Grids" msgstr "" @@ -8547,7 +8555,7 @@ msgid "Document saved." msgstr "" #. We are saving for the first time; create a unique default filename -#: ../src/file.cpp:792 ../src/file.cpp:1233 +#: ../src/file.cpp:792 ../src/file.cpp:1259 #, c-format msgid "drawing%s" msgstr "" @@ -8578,7 +8586,7 @@ msgstr "" msgid "Saving document..." msgstr "" -#: ../src/file.cpp:1093 ../src/ui/dialog/ocaldialogs.cpp:1120 +#: ../src/file.cpp:1093 ../src/ui/dialog/ocaldialogs.cpp:1117 msgid "Import" msgstr "" @@ -8586,11 +8594,11 @@ msgstr "" msgid "Select file to import" msgstr "" -#: ../src/file.cpp:1255 +#: ../src/file.cpp:1281 msgid "Select file to export to" msgstr "" -#: ../src/file.cpp:1508 +#: ../src/file.cpp:1534 msgid "Import Clip Art" msgstr "" @@ -8675,7 +8683,7 @@ msgid "Luminance to Alpha" msgstr "" #. File -#: ../src/filter-enums.cpp:70 ../src/interface.cpp:839 ../src/verbs.cpp:2186 +#: ../src/filter-enums.cpp:70 ../src/interface.cpp:839 ../src/verbs.cpp:2185 #: ../share/extensions/jessyInk_mouseHandler.inx.h:1 #: ../share/extensions/jessyInk_transitions.inx.h:2 msgid "Default" @@ -8685,7 +8693,7 @@ msgstr "" msgid "Arithmetic" msgstr "" -#: ../src/filter-enums.cpp:92 ../src/selection-chemistry.cpp:437 +#: ../src/filter-enums.cpp:92 ../src/selection-chemistry.cpp:445 #: ../src/widgets/gradient-selector.cpp:140 msgid "Duplicate" msgstr "" @@ -8697,15 +8705,15 @@ msgstr "" #: ../src/filter-enums.cpp:94 ../src/live_effects/lpe-ruler.cpp:34 #: ../src/ui/dialog/filter-effects-dialog.cpp:487 #: ../src/ui/dialog/filter-effects-dialog.cpp:489 -#: ../src/ui/dialog/inkscape-preferences.cpp:319 -#: ../src/ui/dialog/inkscape-preferences.cpp:585 -#: ../src/ui/dialog/inkscape-preferences.cpp:1147 -#: ../src/ui/dialog/inkscape-preferences.cpp:1293 -#: ../src/ui/dialog/inkscape-preferences.cpp:1352 +#: ../src/ui/dialog/inkscape-preferences.cpp:318 +#: ../src/ui/dialog/inkscape-preferences.cpp:587 +#: ../src/ui/dialog/inkscape-preferences.cpp:1156 +#: ../src/ui/dialog/inkscape-preferences.cpp:1302 +#: ../src/ui/dialog/inkscape-preferences.cpp:1360 #: ../src/ui/dialog/input.cpp:610 ../src/ui/dialog/input.cpp:612 #: ../src/ui/dialog/input.cpp:614 ../src/ui/dialog/input.cpp:1281 -#: ../src/ui/dialog/input.cpp:1284 ../src/verbs.cpp:2183 -#: ../src/widgets/stroke-style.cpp:364 ../src/widgets/toolbox.cpp:4288 +#: ../src/ui/dialog/input.cpp:1284 ../src/verbs.cpp:2182 +#: ../src/widgets/toolbox.cpp:4288 #: ../share/extensions/gcodetools_area.inx.h:32 #: ../share/extensions/gcodetools_dxf_points.inx.h:15 #: ../share/extensions/gcodetools_engraving.inx.h:19 @@ -8758,7 +8766,7 @@ msgstr "" msgid "Hue" msgstr "" -#: ../src/flood-context.cpp:251 ../src/ui/dialog/inkscape-preferences.cpp:843 +#: ../src/flood-context.cpp:251 ../src/ui/dialog/inkscape-preferences.cpp:852 #: ../src/widgets/sp-color-icc-selector.cpp:233 #: ../src/widgets/sp-color-icc-selector.cpp:234 #: ../src/widgets/sp-color-scales.cpp:433 @@ -8919,7 +8927,7 @@ msgstr[0] "" msgstr[1] "" #: ../src/gradient-context.cpp:391 ../src/gradient-context.cpp:484 -#: ../src/ui/dialog/swatches.cpp:187 ../src/widgets/gradient-vector.cpp:743 +#: ../src/ui/dialog/swatches.cpp:187 ../src/widgets/gradient-vector.cpp:751 msgid "Add gradient stop" msgstr "" @@ -8966,7 +8974,7 @@ msgstr "" msgid "Move gradient handle" msgstr "" -#: ../src/gradient-drag.cpp:994 ../src/widgets/gradient-vector.cpp:774 +#: ../src/gradient-drag.cpp:994 ../src/widgets/gradient-vector.cpp:784 msgid "Delete gradient stop" msgstr "" @@ -9081,7 +9089,7 @@ msgstr "" msgid "Percent" msgstr "" -#: ../src/helper/units.cpp:42 ../src/ui/dialog/inkscape-preferences.cpp:1157 +#: ../src/helper/units.cpp:42 ../src/ui/dialog/inkscape-preferences.cpp:1166 msgid "%" msgstr "" @@ -9711,8 +9719,8 @@ msgstr "" msgid "Dockitem which 'owns' this tablabel" msgstr "" -#: ../src/libgdl/gdl-dock.c:176 ../src/ui/dialog/inkscape-preferences.cpp:580 -#: ../src/ui/dialog/inkscape-preferences.cpp:607 +#: ../src/libgdl/gdl-dock.c:176 ../src/ui/dialog/inkscape-preferences.cpp:579 +#: ../src/ui/dialog/inkscape-preferences.cpp:609 msgid "Floating" msgstr "" @@ -11044,11 +11052,11 @@ msgid "_New" msgstr "" #. " \n" -#: ../src/menus-skeleton.h:45 ../src/verbs.cpp:2435 ../src/verbs.cpp:2441 +#: ../src/menus-skeleton.h:45 ../src/verbs.cpp:2434 ../src/verbs.cpp:2440 msgid "_Edit" msgstr "" -#: ../src/menus-skeleton.h:55 ../src/verbs.cpp:2231 +#: ../src/menus-skeleton.h:55 ../src/verbs.cpp:2230 msgid "Paste Si_ze" msgstr "" @@ -11567,7 +11575,7 @@ msgstr "" msgid "Unique URI to a related document" msgstr "" -#: ../src/rdf.cpp:263 ../src/ui/dialog/inkscape-preferences.cpp:1371 +#: ../src/rdf.cpp:263 ../src/ui/dialog/inkscape-preferences.cpp:1379 msgid "Language:" msgstr "" @@ -11729,7 +11737,7 @@ msgstr "" msgid "Nothing was deleted." msgstr "" -#: ../src/selection-chemistry.cpp:333 ../src/text-context.cpp:1020 +#: ../src/selection-chemistry.cpp:333 ../src/text-context.cpp:1031 #: ../src/ui/dialog/swatches.cpp:209 ../src/ui/dialog/swatches.cpp:272 #: ../src/widgets/toolbox.cpp:1479 ../src/widgets/toolbox.cpp:6360 msgid "Delete" @@ -11739,349 +11747,349 @@ msgstr "" msgid "Select object(s) to duplicate." msgstr "" -#: ../src/selection-chemistry.cpp:462 +#: ../src/selection-chemistry.cpp:470 msgid "Delete all" msgstr "" -#: ../src/selection-chemistry.cpp:648 +#: ../src/selection-chemistry.cpp:656 msgid "Select some objects to group." msgstr "" -#: ../src/selection-chemistry.cpp:663 ../src/selection-describer.cpp:52 +#: ../src/selection-chemistry.cpp:671 ../src/selection-describer.cpp:52 msgid "Group" msgstr "" -#: ../src/selection-chemistry.cpp:677 +#: ../src/selection-chemistry.cpp:685 msgid "Select a group to ungroup." msgstr "" -#: ../src/selection-chemistry.cpp:718 +#: ../src/selection-chemistry.cpp:726 msgid "No groups to ungroup in the selection." msgstr "" -#: ../src/selection-chemistry.cpp:724 ../src/sp-item-group.cpp:501 +#: ../src/selection-chemistry.cpp:732 ../src/sp-item-group.cpp:501 msgid "Ungroup" msgstr "" -#: ../src/selection-chemistry.cpp:810 +#: ../src/selection-chemistry.cpp:818 msgid "Select object(s) to raise." msgstr "" -#: ../src/selection-chemistry.cpp:816 ../src/selection-chemistry.cpp:876 -#: ../src/selection-chemistry.cpp:910 ../src/selection-chemistry.cpp:974 +#: ../src/selection-chemistry.cpp:824 ../src/selection-chemistry.cpp:884 +#: ../src/selection-chemistry.cpp:918 ../src/selection-chemistry.cpp:982 msgid "" "You cannot raise/lower objects from different groups or layers." msgstr "" #. TRANSLATORS: "Raise" means "to raise an object" in the undo history -#: ../src/selection-chemistry.cpp:856 +#: ../src/selection-chemistry.cpp:864 msgctxt "Undo action" msgid "Raise" msgstr "" -#: ../src/selection-chemistry.cpp:868 +#: ../src/selection-chemistry.cpp:876 msgid "Select object(s) to raise to top." msgstr "" -#: ../src/selection-chemistry.cpp:891 +#: ../src/selection-chemistry.cpp:899 msgid "Raise to top" msgstr "" -#: ../src/selection-chemistry.cpp:904 +#: ../src/selection-chemistry.cpp:912 msgid "Select object(s) to lower." msgstr "" -#: ../src/selection-chemistry.cpp:954 +#: ../src/selection-chemistry.cpp:962 msgid "Lower" msgstr "" -#: ../src/selection-chemistry.cpp:966 +#: ../src/selection-chemistry.cpp:974 msgid "Select object(s) to lower to bottom." msgstr "" -#: ../src/selection-chemistry.cpp:1001 +#: ../src/selection-chemistry.cpp:1009 msgid "Lower to bottom" msgstr "" -#: ../src/selection-chemistry.cpp:1008 +#: ../src/selection-chemistry.cpp:1016 msgid "Nothing to undo." msgstr "" -#: ../src/selection-chemistry.cpp:1016 +#: ../src/selection-chemistry.cpp:1024 msgid "Nothing to redo." msgstr "" -#: ../src/selection-chemistry.cpp:1077 +#: ../src/selection-chemistry.cpp:1085 msgid "Paste" msgstr "" -#: ../src/selection-chemistry.cpp:1085 +#: ../src/selection-chemistry.cpp:1093 msgid "Paste style" msgstr "" -#: ../src/selection-chemistry.cpp:1095 +#: ../src/selection-chemistry.cpp:1103 msgid "Paste live path effect" msgstr "" -#: ../src/selection-chemistry.cpp:1116 +#: ../src/selection-chemistry.cpp:1124 msgid "Select object(s) to remove live path effects from." msgstr "" -#: ../src/selection-chemistry.cpp:1128 +#: ../src/selection-chemistry.cpp:1136 msgid "Remove live path effect" msgstr "" -#: ../src/selection-chemistry.cpp:1139 +#: ../src/selection-chemistry.cpp:1147 msgid "Select object(s) to remove filters from." msgstr "" -#: ../src/selection-chemistry.cpp:1149 +#: ../src/selection-chemistry.cpp:1157 #: ../src/ui/dialog/filter-effects-dialog.cpp:1380 msgid "Remove filter" msgstr "" -#: ../src/selection-chemistry.cpp:1158 +#: ../src/selection-chemistry.cpp:1166 msgid "Paste size" msgstr "" -#: ../src/selection-chemistry.cpp:1167 +#: ../src/selection-chemistry.cpp:1175 msgid "Paste size separately" msgstr "" -#: ../src/selection-chemistry.cpp:1177 +#: ../src/selection-chemistry.cpp:1185 msgid "Select object(s) to move to the layer above." msgstr "" -#: ../src/selection-chemistry.cpp:1203 +#: ../src/selection-chemistry.cpp:1211 msgid "Raise to next layer" msgstr "" -#: ../src/selection-chemistry.cpp:1210 +#: ../src/selection-chemistry.cpp:1218 msgid "No more layers above." msgstr "" -#: ../src/selection-chemistry.cpp:1222 +#: ../src/selection-chemistry.cpp:1230 msgid "Select object(s) to move to the layer below." msgstr "" -#: ../src/selection-chemistry.cpp:1248 +#: ../src/selection-chemistry.cpp:1256 msgid "Lower to previous layer" msgstr "" -#: ../src/selection-chemistry.cpp:1255 +#: ../src/selection-chemistry.cpp:1263 msgid "No more layers below." msgstr "" -#: ../src/selection-chemistry.cpp:1478 +#: ../src/selection-chemistry.cpp:1486 msgid "Remove transform" msgstr "" -#: ../src/selection-chemistry.cpp:1581 +#: ../src/selection-chemistry.cpp:1589 msgid "Rotate 90° CCW" msgstr "" -#: ../src/selection-chemistry.cpp:1581 +#: ../src/selection-chemistry.cpp:1589 msgid "Rotate 90° CW" msgstr "" -#: ../src/selection-chemistry.cpp:1602 ../src/seltrans.cpp:476 +#: ../src/selection-chemistry.cpp:1610 ../src/seltrans.cpp:476 #: ../src/ui/dialog/transformation.cpp:743 msgid "Rotate" msgstr "" -#: ../src/selection-chemistry.cpp:1649 +#: ../src/selection-chemistry.cpp:1657 msgid "Rotate by pixels" msgstr "" -#: ../src/selection-chemistry.cpp:1679 ../src/seltrans.cpp:473 +#: ../src/selection-chemistry.cpp:1687 ../src/seltrans.cpp:473 #: ../src/ui/dialog/transformation.cpp:722 #: ../share/extensions/interp_att_g.inx.h:19 msgid "Scale" msgstr "" -#: ../src/selection-chemistry.cpp:1704 +#: ../src/selection-chemistry.cpp:1712 msgid "Scale by whole factor" msgstr "" -#: ../src/selection-chemistry.cpp:1719 +#: ../src/selection-chemistry.cpp:1727 msgid "Move vertically" msgstr "" -#: ../src/selection-chemistry.cpp:1722 +#: ../src/selection-chemistry.cpp:1730 msgid "Move horizontally" msgstr "" -#: ../src/selection-chemistry.cpp:1725 ../src/selection-chemistry.cpp:1751 +#: ../src/selection-chemistry.cpp:1733 ../src/selection-chemistry.cpp:1759 #: ../src/seltrans.cpp:470 ../src/ui/dialog/transformation.cpp:661 msgid "Move" msgstr "" -#: ../src/selection-chemistry.cpp:1745 +#: ../src/selection-chemistry.cpp:1753 msgid "Move vertically by pixels" msgstr "" -#: ../src/selection-chemistry.cpp:1748 +#: ../src/selection-chemistry.cpp:1756 msgid "Move horizontally by pixels" msgstr "" -#: ../src/selection-chemistry.cpp:1880 +#: ../src/selection-chemistry.cpp:1888 msgid "The selection has no applied path effect." msgstr "" -#: ../src/selection-chemistry.cpp:2083 +#: ../src/selection-chemistry.cpp:2091 msgctxt "Action" msgid "Clone" msgstr "" -#: ../src/selection-chemistry.cpp:2099 +#: ../src/selection-chemistry.cpp:2107 msgid "Select clones to relink." msgstr "" -#: ../src/selection-chemistry.cpp:2106 +#: ../src/selection-chemistry.cpp:2114 msgid "Copy an object to clipboard to relink clones to." msgstr "" -#: ../src/selection-chemistry.cpp:2130 +#: ../src/selection-chemistry.cpp:2138 msgid "No clones to relink in the selection." msgstr "" -#: ../src/selection-chemistry.cpp:2133 +#: ../src/selection-chemistry.cpp:2141 msgid "Relink clone" msgstr "" -#: ../src/selection-chemistry.cpp:2147 +#: ../src/selection-chemistry.cpp:2155 msgid "Select clones to unlink." msgstr "" -#: ../src/selection-chemistry.cpp:2201 +#: ../src/selection-chemistry.cpp:2209 msgid "No clones to unlink in the selection." msgstr "" -#: ../src/selection-chemistry.cpp:2205 +#: ../src/selection-chemistry.cpp:2213 msgid "Unlink clone" msgstr "" -#: ../src/selection-chemistry.cpp:2218 +#: ../src/selection-chemistry.cpp:2226 msgid "" "Select a clone to go to its original. Select a linked offset " "to go to its source. Select a text on path to go to the path. Select " "a flowed text to go to its frame." msgstr "" -#: ../src/selection-chemistry.cpp:2251 +#: ../src/selection-chemistry.cpp:2259 msgid "" "Cannot find the object to select (orphaned clone, offset, textpath, " "flowed text?)" msgstr "" -#: ../src/selection-chemistry.cpp:2257 +#: ../src/selection-chemistry.cpp:2265 msgid "" "The object you're trying to select is not visible (it is in <" "defs>)" msgstr "" -#: ../src/selection-chemistry.cpp:2302 +#: ../src/selection-chemistry.cpp:2310 msgid "Select one path to clone." msgstr "" -#: ../src/selection-chemistry.cpp:2306 +#: ../src/selection-chemistry.cpp:2314 msgid "Select one path to clone." msgstr "" -#: ../src/selection-chemistry.cpp:2340 +#: ../src/selection-chemistry.cpp:2348 msgid "Clone original path" msgstr "" -#: ../src/selection-chemistry.cpp:2361 +#: ../src/selection-chemistry.cpp:2369 msgid "Select object(s) to convert to marker." msgstr "" -#: ../src/selection-chemistry.cpp:2429 +#: ../src/selection-chemistry.cpp:2437 msgid "Objects to marker" msgstr "" -#: ../src/selection-chemistry.cpp:2457 +#: ../src/selection-chemistry.cpp:2465 msgid "Select object(s) to convert to guides." msgstr "" -#: ../src/selection-chemistry.cpp:2469 +#: ../src/selection-chemistry.cpp:2477 msgid "Objects to guides" msgstr "" -#: ../src/selection-chemistry.cpp:2486 +#: ../src/selection-chemistry.cpp:2494 msgid "Select object(s) to convert to pattern." msgstr "" -#: ../src/selection-chemistry.cpp:2574 +#: ../src/selection-chemistry.cpp:2582 msgid "Objects to pattern" msgstr "" -#: ../src/selection-chemistry.cpp:2590 +#: ../src/selection-chemistry.cpp:2598 msgid "Select an object with pattern fill to extract objects from." msgstr "" -#: ../src/selection-chemistry.cpp:2643 +#: ../src/selection-chemistry.cpp:2651 msgid "No pattern fills in the selection." msgstr "" -#: ../src/selection-chemistry.cpp:2646 +#: ../src/selection-chemistry.cpp:2654 msgid "Pattern to objects" msgstr "" -#: ../src/selection-chemistry.cpp:2728 +#: ../src/selection-chemistry.cpp:2736 msgid "Select object(s) to make a bitmap copy." msgstr "" -#: ../src/selection-chemistry.cpp:2732 +#: ../src/selection-chemistry.cpp:2740 msgid "Rendering bitmap..." msgstr "" -#: ../src/selection-chemistry.cpp:2906 +#: ../src/selection-chemistry.cpp:2914 msgid "Create bitmap" msgstr "" -#: ../src/selection-chemistry.cpp:2938 +#: ../src/selection-chemistry.cpp:2946 msgid "Select object(s) to create clippath or mask from." msgstr "" -#: ../src/selection-chemistry.cpp:2941 +#: ../src/selection-chemistry.cpp:2949 msgid "Select mask object and object(s) to apply clippath or mask to." msgstr "" -#: ../src/selection-chemistry.cpp:3122 +#: ../src/selection-chemistry.cpp:3130 msgid "Set clipping path" msgstr "" -#: ../src/selection-chemistry.cpp:3124 +#: ../src/selection-chemistry.cpp:3132 msgid "Set mask" msgstr "" -#: ../src/selection-chemistry.cpp:3139 +#: ../src/selection-chemistry.cpp:3147 msgid "Select object(s) to remove clippath or mask from." msgstr "" -#: ../src/selection-chemistry.cpp:3250 +#: ../src/selection-chemistry.cpp:3258 msgid "Release clipping path" msgstr "" -#: ../src/selection-chemistry.cpp:3252 +#: ../src/selection-chemistry.cpp:3260 msgid "Release mask" msgstr "" -#: ../src/selection-chemistry.cpp:3271 +#: ../src/selection-chemistry.cpp:3279 msgid "Select object(s) to fit canvas to." msgstr "" #. Fit Page -#: ../src/selection-chemistry.cpp:3291 ../src/verbs.cpp:2696 +#: ../src/selection-chemistry.cpp:3299 ../src/verbs.cpp:2695 msgid "Fit Page to Selection" msgstr "" -#: ../src/selection-chemistry.cpp:3320 ../src/verbs.cpp:2698 +#: ../src/selection-chemistry.cpp:3328 ../src/verbs.cpp:2697 msgid "Fit Page to Drawing" msgstr "" -#: ../src/selection-chemistry.cpp:3341 ../src/verbs.cpp:2700 +#: ../src/selection-chemistry.cpp:3349 ../src/verbs.cpp:2699 msgid "Fit Page to Selection or Drawing" msgstr "" @@ -12097,7 +12105,7 @@ msgstr "" #. Ellipse #: ../src/selection-describer.cpp:48 ../src/selection-describer.cpp:73 -#: ../src/ui/dialog/inkscape-preferences.cpp:390 ../src/verbs.cpp:2459 +#: ../src/ui/dialog/inkscape-preferences.cpp:389 ../src/verbs.cpp:2458 #: ../src/widgets/toolbox.cpp:4291 msgid "Ellipse" msgstr "" @@ -12124,19 +12132,19 @@ msgstr "" #. Rectangle #: ../src/selection-describer.cpp:64 -#: ../src/ui/dialog/inkscape-preferences.cpp:380 ../src/verbs.cpp:2455 +#: ../src/ui/dialog/inkscape-preferences.cpp:379 ../src/verbs.cpp:2454 msgid "Rectangle" msgstr "" #. 3D box #: ../src/selection-describer.cpp:66 -#: ../src/ui/dialog/inkscape-preferences.cpp:385 ../src/verbs.cpp:2457 +#: ../src/ui/dialog/inkscape-preferences.cpp:384 ../src/verbs.cpp:2456 msgid "3D Box" msgstr "" #. Text #: ../src/selection-describer.cpp:68 -#: ../src/ui/dialog/inkscape-preferences.cpp:426 ../src/verbs.cpp:2471 +#: ../src/ui/dialog/inkscape-preferences.cpp:425 ../src/verbs.cpp:2470 #: ../share/extensions/lorem_ipsum.inx.h:7 #: ../share/extensions/replace_font.inx.h:10 ../share/extensions/split.inx.h:6 #: ../share/extensions/text_braille.inx.h:2 @@ -12164,14 +12172,14 @@ msgstr "" #. Spiral #: ../src/selection-describer.cpp:77 -#: ../src/ui/dialog/inkscape-preferences.cpp:398 ../src/verbs.cpp:2463 +#: ../src/ui/dialog/inkscape-preferences.cpp:397 ../src/verbs.cpp:2462 #: ../share/extensions/gcodetools_area.inx.h:45 msgid "Spiral" msgstr "" #. Star #: ../src/selection-describer.cpp:79 -#: ../src/ui/dialog/inkscape-preferences.cpp:394 ../src/verbs.cpp:2461 +#: ../src/ui/dialog/inkscape-preferences.cpp:393 ../src/verbs.cpp:2460 #: ../src/widgets/toolbox.cpp:3128 msgid "Star" msgstr "" @@ -12398,7 +12406,7 @@ msgstr "" msgid "Create Guides Around the Page" msgstr "" -#: ../src/sp-guide.cpp:327 ../src/verbs.cpp:2291 +#: ../src/sp-guide.cpp:327 ../src/verbs.cpp:2290 msgid "Delete All Guides" msgstr "" @@ -12809,7 +12817,7 @@ msgstr "" msgid "The flowed text(s) must be visible in order to be put on a path." msgstr "" -#: ../src/text-chemistry.cpp:195 ../src/verbs.cpp:2311 +#: ../src/text-chemistry.cpp:195 ../src/verbs.cpp:2310 msgid "Put text on path" msgstr "" @@ -12821,7 +12829,7 @@ msgstr "" msgid "No texts-on-paths in the selection." msgstr "" -#: ../src/text-chemistry.cpp:231 ../src/verbs.cpp:2313 +#: ../src/text-chemistry.cpp:231 ../src/verbs.cpp:2312 msgid "Remove text from path" msgstr "" @@ -12893,7 +12901,7 @@ msgstr "" msgid "Unicode (Enter to finish): %s: %s" msgstr "" -#: ../src/text-context.cpp:576 ../src/text-context.cpp:874 +#: ../src/text-context.cpp:576 ../src/text-context.cpp:885 msgid "Unicode (Enter to finish): " msgstr "" @@ -12902,111 +12910,111 @@ msgstr "" msgid "Flowed text frame: %s × %s" msgstr "" -#: ../src/text-context.cpp:708 +#: ../src/text-context.cpp:719 msgid "Type text; Enter to start new line." msgstr "" -#: ../src/text-context.cpp:719 +#: ../src/text-context.cpp:730 msgid "Flowed text is created." msgstr "" -#: ../src/text-context.cpp:721 +#: ../src/text-context.cpp:732 msgid "Create flowed text" msgstr "" -#: ../src/text-context.cpp:723 +#: ../src/text-context.cpp:734 msgid "" "The frame is too small for the current font size. Flowed text not " "created." msgstr "" -#: ../src/text-context.cpp:859 +#: ../src/text-context.cpp:870 msgid "No-break space" msgstr "" -#: ../src/text-context.cpp:861 +#: ../src/text-context.cpp:872 msgid "Insert no-break space" msgstr "" -#: ../src/text-context.cpp:898 +#: ../src/text-context.cpp:909 msgid "Make bold" msgstr "" -#: ../src/text-context.cpp:916 +#: ../src/text-context.cpp:927 msgid "Make italic" msgstr "" -#: ../src/text-context.cpp:955 +#: ../src/text-context.cpp:966 msgid "New line" msgstr "" -#: ../src/text-context.cpp:989 +#: ../src/text-context.cpp:1000 msgid "Backspace" msgstr "" -#: ../src/text-context.cpp:1037 +#: ../src/text-context.cpp:1048 msgid "Kern to the left" msgstr "" -#: ../src/text-context.cpp:1062 +#: ../src/text-context.cpp:1073 msgid "Kern to the right" msgstr "" -#: ../src/text-context.cpp:1087 +#: ../src/text-context.cpp:1098 msgid "Kern up" msgstr "" -#: ../src/text-context.cpp:1112 +#: ../src/text-context.cpp:1123 msgid "Kern down" msgstr "" -#: ../src/text-context.cpp:1188 +#: ../src/text-context.cpp:1199 msgid "Rotate counterclockwise" msgstr "" -#: ../src/text-context.cpp:1209 +#: ../src/text-context.cpp:1220 msgid "Rotate clockwise" msgstr "" -#: ../src/text-context.cpp:1226 +#: ../src/text-context.cpp:1237 msgid "Contract line spacing" msgstr "" -#: ../src/text-context.cpp:1233 +#: ../src/text-context.cpp:1244 msgid "Contract letter spacing" msgstr "" -#: ../src/text-context.cpp:1251 +#: ../src/text-context.cpp:1262 msgid "Expand line spacing" msgstr "" -#: ../src/text-context.cpp:1258 +#: ../src/text-context.cpp:1269 msgid "Expand letter spacing" msgstr "" -#: ../src/text-context.cpp:1386 +#: ../src/text-context.cpp:1397 msgid "Paste text" msgstr "" -#: ../src/text-context.cpp:1632 +#: ../src/text-context.cpp:1648 #, c-format msgid "" "Type or edit flowed text (%d characters%s); Enter to start new " "paragraph." msgstr "" -#: ../src/text-context.cpp:1634 +#: ../src/text-context.cpp:1650 #, c-format msgid "Type or edit text (%d characters%s); Enter to start new line." msgstr "" -#: ../src/text-context.cpp:1642 ../src/tools-switch.cpp:199 +#: ../src/text-context.cpp:1658 ../src/tools-switch.cpp:199 msgid "" "Click to select or create text, drag to create flowed text; " "then type." msgstr "" -#: ../src/text-context.cpp:1747 +#: ../src/text-context.cpp:1760 msgid "Type text" msgstr "" @@ -13280,126 +13288,137 @@ msgid "Blur tweak" msgstr "" #. check whether something is selected -#: ../src/ui/clipboard.cpp:260 +#: ../src/ui/clipboard.cpp:261 msgid "Nothing was copied." msgstr "" -#: ../src/ui/clipboard.cpp:332 ../src/ui/clipboard.cpp:541 -#: ../src/ui/clipboard.cpp:564 +#: ../src/ui/clipboard.cpp:333 ../src/ui/clipboard.cpp:542 +#: ../src/ui/clipboard.cpp:565 msgid "Nothing on the clipboard." msgstr "" -#: ../src/ui/clipboard.cpp:390 +#: ../src/ui/clipboard.cpp:391 msgid "Select object(s) to paste style to." msgstr "" -#: ../src/ui/clipboard.cpp:401 ../src/ui/clipboard.cpp:418 +#: ../src/ui/clipboard.cpp:402 ../src/ui/clipboard.cpp:419 msgid "No style on the clipboard." msgstr "" -#: ../src/ui/clipboard.cpp:443 +#: ../src/ui/clipboard.cpp:444 msgid "Select object(s) to paste size to." msgstr "" -#: ../src/ui/clipboard.cpp:450 +#: ../src/ui/clipboard.cpp:451 msgid "No size on the clipboard." msgstr "" -#: ../src/ui/clipboard.cpp:503 +#: ../src/ui/clipboard.cpp:504 msgid "Select object(s) to paste live path effect to." msgstr "" #. no_effect: -#: ../src/ui/clipboard.cpp:528 +#: ../src/ui/clipboard.cpp:529 msgid "No effect on the clipboard." msgstr "" -#: ../src/ui/clipboard.cpp:547 ../src/ui/clipboard.cpp:575 +#: ../src/ui/clipboard.cpp:548 ../src/ui/clipboard.cpp:576 msgid "Clipboard does not contain a path." msgstr "" #. Item dialog -#: ../src/ui/context-menu.cpp:107 ../src/verbs.cpp:2637 +#: ../src/ui/context-menu.cpp:108 ../src/verbs.cpp:2636 msgid "_Object Properties..." msgstr "" #. Select item -#: ../src/ui/context-menu.cpp:117 +#: ../src/ui/context-menu.cpp:118 msgid "_Select This" msgstr "" #. Create link -#: ../src/ui/context-menu.cpp:127 +#: ../src/ui/context-menu.cpp:128 msgid "_Create Link" msgstr "" #. Set mask -#: ../src/ui/context-menu.cpp:134 +#: ../src/ui/context-menu.cpp:135 msgid "Set Mask" msgstr "" #. Release mask -#: ../src/ui/context-menu.cpp:145 +#: ../src/ui/context-menu.cpp:146 msgid "Release Mask" msgstr "" #. Set Clip -#: ../src/ui/context-menu.cpp:156 +#: ../src/ui/context-menu.cpp:157 msgid "Set _Clip" msgstr "" #. Release Clip -#: ../src/ui/context-menu.cpp:167 +#: ../src/ui/context-menu.cpp:168 msgid "Release C_lip" msgstr "" -#: ../src/ui/context-menu.cpp:284 +#: ../src/ui/context-menu.cpp:285 msgid "Create link" msgstr "" #. "Ungroup" -#: ../src/ui/context-menu.cpp:300 ../src/verbs.cpp:2307 +#: ../src/ui/context-menu.cpp:301 ../src/verbs.cpp:2306 msgid "_Ungroup" msgstr "" #. Link dialog -#: ../src/ui/context-menu.cpp:338 +#: ../src/ui/context-menu.cpp:339 msgid "Link _Properties..." msgstr "" #. Select item -#: ../src/ui/context-menu.cpp:344 +#: ../src/ui/context-menu.cpp:345 msgid "_Follow Link" msgstr "" #. Reset transformations -#: ../src/ui/context-menu.cpp:349 +#: ../src/ui/context-menu.cpp:350 msgid "_Remove Link" msgstr "" -#. Link dialog -#: ../src/ui/context-menu.cpp:395 +#. Image properties +#: ../src/ui/context-menu.cpp:400 msgid "Image _Properties..." msgstr "" -#: ../src/ui/context-menu.cpp:401 +#. Edit externally +#: ../src/ui/context-menu.cpp:407 msgid "Edit Externally..." msgstr "" +#: ../src/ui/context-menu.cpp:418 +msgctxt "Context menu" +msgid "Embed Image" +msgstr "" + +#: ../src/ui/context-menu.cpp:430 +msgctxt "Context menu" +msgid "Extract Image..." +msgstr "" + #. Item dialog #. Fill and Stroke dialog -#: ../src/ui/context-menu.cpp:526 ../src/ui/context-menu.cpp:576 -#: ../src/verbs.cpp:2602 +#: ../src/ui/context-menu.cpp:614 ../src/ui/context-menu.cpp:664 +#: ../src/verbs.cpp:2601 msgid "_Fill and Stroke..." msgstr "" #. Edit Text dialog -#: ../src/ui/context-menu.cpp:583 ../src/verbs.cpp:2617 +#: ../src/ui/context-menu.cpp:671 ../src/verbs.cpp:2616 msgid "_Text and Font..." msgstr "" #. Spellcheck dialog -#: ../src/ui/context-menu.cpp:590 ../src/verbs.cpp:2625 +#: ../src/ui/context-menu.cpp:678 ../src/verbs.cpp:2624 msgid "Check Spellin_g..." msgstr "" @@ -13974,7 +13993,7 @@ msgstr "" msgid "Guides" msgstr "" -#: ../src/ui/dialog/document-properties.cpp:148 ../src/verbs.cpp:2542 +#: ../src/ui/dialog/document-properties.cpp:148 ../src/verbs.cpp:2541 msgid "Snap" msgstr "" @@ -14022,7 +14041,7 @@ msgstr "" #. Inkscape::GC::release(defsRepr); #. inform the document, so we can undo #. Color Management -#: ../src/ui/dialog/document-properties.cpp:421 ../src/verbs.cpp:2712 +#: ../src/ui/dialog/document-properties.cpp:421 ../src/verbs.cpp:2711 msgid "Link Color Profile" msgstr "" @@ -14159,7 +14178,8 @@ msgstr "" #: ../share/extensions/jessyInk_view.inx.h:3 #: ../share/extensions/layout_nup.inx.h:15 #: ../share/extensions/lindenmayer.inx.h:23 -#: ../share/extensions/lorem_ipsum.inx.h:1 ../share/extensions/measure.inx.h:2 +#: ../share/extensions/lorem_ipsum.inx.h:1 +#: ../share/extensions/measure.inx.h:19 #: ../share/extensions/pathalongpath.inx.h:5 #: ../share/extensions/pathscatter.inx.h:6 #: ../share/extensions/radiusrand.inx.h:1 ../share/extensions/split.inx.h:1 @@ -14916,6 +14936,178 @@ msgstr "" msgid "Set filter primitive attribute" msgstr "" +#: ../src/ui/dialog/find.cpp:67 +msgid "F_ind:" +msgstr "" + +#: ../src/ui/dialog/find.cpp:67 +msgid "Find objects by their content (exact or partial match)" +msgstr "" + +#: ../src/ui/dialog/find.cpp:68 +msgid "Re_place:" +msgstr "" + +#: ../src/ui/dialog/find.cpp:68 +msgid "Replace found objects with this value " +msgstr "" + +#: ../src/ui/dialog/find.cpp:70 +msgid "_All" +msgstr "" + +#: ../src/ui/dialog/find.cpp:70 +msgid "Search in all layers" +msgstr "" + +#: ../src/ui/dialog/find.cpp:71 +msgid "Current _layer" +msgstr "" + +#: ../src/ui/dialog/find.cpp:72 +msgid "S_election" +msgstr "" + +#: ../src/ui/dialog/find.cpp:73 +msgid "Te_xt" +msgstr "" + +#: ../src/ui/dialog/find.cpp:73 +msgid "Search in text objects" +msgstr "" + +#: ../src/ui/dialog/find.cpp:74 +msgid "_Properties" +msgstr "" + +#: ../src/ui/dialog/find.cpp:74 +msgid "Search in object properties, styles, attributes and IDs" +msgstr "" + +#: ../src/ui/dialog/find.cpp:75 +msgid "Search in" +msgstr "" + +#: ../src/ui/dialog/find.cpp:76 +msgid "Scope" +msgstr "" + +#: ../src/ui/dialog/find.cpp:79 +msgid "Case sensiti_ve" +msgstr "" + +#: ../src/ui/dialog/find.cpp:79 +msgid "Match upper/lower case" +msgstr "" + +#: ../src/ui/dialog/find.cpp:80 +msgid "E_xact match" +msgstr "" + +#: ../src/ui/dialog/find.cpp:80 +msgid "Match whole objects only" +msgstr "" + +#: ../src/ui/dialog/find.cpp:82 +msgid "Include loc_ked" +msgstr "" + +#: ../src/ui/dialog/find.cpp:84 +msgid "General" +msgstr "" + +#: ../src/ui/dialog/find.cpp:86 +msgid "_ID" +msgstr "" + +#: ../src/ui/dialog/find.cpp:86 +msgid "Search id name" +msgstr "" + +#: ../src/ui/dialog/find.cpp:87 +msgid "Attribute _Name" +msgstr "" + +#: ../src/ui/dialog/find.cpp:87 +msgid "Search attribute name" +msgstr "" + +#: ../src/ui/dialog/find.cpp:88 +msgid "Attribute _Value" +msgstr "" + +#: ../src/ui/dialog/find.cpp:88 +msgid "Search attribute value" +msgstr "" + +#: ../src/ui/dialog/find.cpp:89 +msgid "_Style" +msgstr "" + +#: ../src/ui/dialog/find.cpp:89 +msgid "Search style" +msgstr "" + +#: ../src/ui/dialog/find.cpp:90 +msgid "Search fonts" +msgstr "" + +#: ../src/ui/dialog/find.cpp:91 +msgid "Properties" +msgstr "" + +#: ../src/ui/dialog/find.cpp:93 +msgid "Search all object types" +msgstr "" + +#: ../src/ui/dialog/find.cpp:107 +msgid "Object Types" +msgstr "" + +#: ../src/ui/dialog/find.cpp:110 +msgid "Select all objects matching the selected fields " +msgstr "" + +#: ../src/ui/dialog/find.cpp:111 +msgid "_Replace All" +msgstr "" + +#: ../src/ui/dialog/find.cpp:111 +msgid "Replace all the matching objects" +msgstr "" + +#: ../src/ui/dialog/find.cpp:782 +msgid "Nothing to replace" +msgstr "" + +#: ../src/ui/dialog/find.cpp:828 +msgid "objects" +msgstr "" + +#: ../src/ui/dialog/find.cpp:828 +msgid "replaced" +msgstr "" + +#: ../src/ui/dialog/find.cpp:828 +msgid "found" +msgstr "" + +#: ../src/ui/dialog/find.cpp:836 +msgid "Text Replace" +msgstr "" + +#: ../src/ui/dialog/find.cpp:840 +msgid "Not found" +msgstr "" + +#: ../src/ui/dialog/find.cpp:866 +msgid "Select an object" +msgstr "" + +#: ../src/ui/dialog/find.cpp:884 +msgid "Select a property" +msgstr "" + #: ../src/ui/dialog/glyphs.cpp:53 ../src/ui/dialog/glyphs.cpp:145 msgid "all" msgstr "" @@ -15710,333 +15902,333 @@ msgstr "" msgid "Selection only or whole document" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:170 +#: ../src/ui/dialog/inkscape-preferences.cpp:169 msgid "Show selection cue" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:171 +#: ../src/ui/dialog/inkscape-preferences.cpp:170 msgid "" "Whether selected objects display a selection cue (the same as in selector)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:177 +#: ../src/ui/dialog/inkscape-preferences.cpp:176 msgid "Enable gradient editing" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:178 +#: ../src/ui/dialog/inkscape-preferences.cpp:177 msgid "Whether selected objects display gradient editing controls" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:183 +#: ../src/ui/dialog/inkscape-preferences.cpp:182 msgid "Conversion to guides uses edges instead of bounding box" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:184 +#: ../src/ui/dialog/inkscape-preferences.cpp:183 msgid "" "Converting an object to guides places these along the object's true edges " "(imitating the object's shape), not along the bounding box" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:191 +#: ../src/ui/dialog/inkscape-preferences.cpp:190 msgid "Ctrl+click dot size:" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:191 +#: ../src/ui/dialog/inkscape-preferences.cpp:190 msgid "times current stroke width" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:192 +#: ../src/ui/dialog/inkscape-preferences.cpp:191 msgid "Size of dots created with Ctrl+click (relative to current stroke width)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:207 +#: ../src/ui/dialog/inkscape-preferences.cpp:206 msgid "No objects selected to take the style from." msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:216 +#: ../src/ui/dialog/inkscape-preferences.cpp:215 msgid "" "More than one object selected. Cannot take style from multiple " "objects." msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:249 +#: ../src/ui/dialog/inkscape-preferences.cpp:248 msgid "Style of new objects" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:251 +#: ../src/ui/dialog/inkscape-preferences.cpp:250 msgid "Last used style" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:253 +#: ../src/ui/dialog/inkscape-preferences.cpp:252 msgid "Apply the style you last set on an object" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:258 +#: ../src/ui/dialog/inkscape-preferences.cpp:257 msgid "This tool's own style:" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:262 +#: ../src/ui/dialog/inkscape-preferences.cpp:261 msgid "" "Each tool may store its own style to apply to the newly created objects. Use " "the button below to set it." msgstr "" #. style swatch -#: ../src/ui/dialog/inkscape-preferences.cpp:266 +#: ../src/ui/dialog/inkscape-preferences.cpp:265 msgid "Take from selection" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:271 +#: ../src/ui/dialog/inkscape-preferences.cpp:270 msgid "This tool's style of new objects" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:278 +#: ../src/ui/dialog/inkscape-preferences.cpp:277 msgid "Remember the style of the (first) selected object as this tool's style" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:283 +#: ../src/ui/dialog/inkscape-preferences.cpp:282 msgid "Tools" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:286 +#: ../src/ui/dialog/inkscape-preferences.cpp:285 msgid "Bounding box to use" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:287 +#: ../src/ui/dialog/inkscape-preferences.cpp:286 msgid "Visual bounding box" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:289 +#: ../src/ui/dialog/inkscape-preferences.cpp:288 msgid "This bounding box includes stroke width, markers, filter margins, etc." msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:290 +#: ../src/ui/dialog/inkscape-preferences.cpp:289 msgid "Geometric bounding box" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:292 +#: ../src/ui/dialog/inkscape-preferences.cpp:291 msgid "This bounding box includes only the bare path" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:294 +#: ../src/ui/dialog/inkscape-preferences.cpp:293 msgid "Conversion to guides" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:295 +#: ../src/ui/dialog/inkscape-preferences.cpp:294 msgid "Keep objects after conversion to guides" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:297 +#: ../src/ui/dialog/inkscape-preferences.cpp:296 msgid "" "When converting an object to guides, don't delete the object after the " "conversion" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:298 +#: ../src/ui/dialog/inkscape-preferences.cpp:297 msgid "Treat groups as a single object" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:300 +#: ../src/ui/dialog/inkscape-preferences.cpp:299 msgid "" "Treat groups as a single object during conversion to guides rather than " "converting each child separately" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:302 +#: ../src/ui/dialog/inkscape-preferences.cpp:301 msgid "Average all sketches" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:303 +#: ../src/ui/dialog/inkscape-preferences.cpp:302 msgid "Width is in absolute units" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:304 +#: ../src/ui/dialog/inkscape-preferences.cpp:303 msgid "Select new path" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:305 +#: ../src/ui/dialog/inkscape-preferences.cpp:304 msgid "Don't attach connectors to text objects" msgstr "" #. Selector -#: ../src/ui/dialog/inkscape-preferences.cpp:308 +#: ../src/ui/dialog/inkscape-preferences.cpp:307 msgid "Selector" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:311 +#: ../src/ui/dialog/inkscape-preferences.cpp:310 msgid "When transforming, show" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:312 +#: ../src/ui/dialog/inkscape-preferences.cpp:311 msgid "Objects" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:314 +#: ../src/ui/dialog/inkscape-preferences.cpp:313 msgid "Show the actual objects when moving or transforming" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:315 +#: ../src/ui/dialog/inkscape-preferences.cpp:314 msgid "Box outline" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:317 +#: ../src/ui/dialog/inkscape-preferences.cpp:316 msgid "Show only a box outline of the objects when moving or transforming" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:318 +#: ../src/ui/dialog/inkscape-preferences.cpp:317 msgid "Per-object selection cue" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:321 +#: ../src/ui/dialog/inkscape-preferences.cpp:320 msgid "No per-object selection indication" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:322 +#: ../src/ui/dialog/inkscape-preferences.cpp:321 msgid "Mark" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:324 +#: ../src/ui/dialog/inkscape-preferences.cpp:323 msgid "Each selected object has a diamond mark in the top left corner" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:325 +#: ../src/ui/dialog/inkscape-preferences.cpp:324 msgid "Box" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:327 +#: ../src/ui/dialog/inkscape-preferences.cpp:326 msgid "Each selected object displays its bounding box" msgstr "" #. Node -#: ../src/ui/dialog/inkscape-preferences.cpp:330 +#: ../src/ui/dialog/inkscape-preferences.cpp:329 msgid "Node" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:333 +#: ../src/ui/dialog/inkscape-preferences.cpp:332 msgid "Path outline" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:334 +#: ../src/ui/dialog/inkscape-preferences.cpp:333 msgid "Path outline color" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:335 +#: ../src/ui/dialog/inkscape-preferences.cpp:334 msgid "Selects the color used for showing the path outline" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:336 +#: ../src/ui/dialog/inkscape-preferences.cpp:335 msgid "Always show outline" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:337 +#: ../src/ui/dialog/inkscape-preferences.cpp:336 msgid "Show outlines for all paths, not only invisible paths" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:338 +#: ../src/ui/dialog/inkscape-preferences.cpp:337 msgid "Update outline when dragging nodes" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:339 +#: ../src/ui/dialog/inkscape-preferences.cpp:338 msgid "" "Update the outline when dragging or transforming nodes; if this is off, the " "outline will only update when completing a drag" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:340 +#: ../src/ui/dialog/inkscape-preferences.cpp:339 msgid "Update paths when dragging nodes" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:341 +#: ../src/ui/dialog/inkscape-preferences.cpp:340 msgid "" "Update paths when dragging or transforming nodes; if this is off, paths will " "only be updated when completing a drag" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:342 +#: ../src/ui/dialog/inkscape-preferences.cpp:341 msgid "Show path direction on outlines" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:343 +#: ../src/ui/dialog/inkscape-preferences.cpp:342 msgid "" "Visualize the direction of selected paths by drawing small arrows in the " "middle of each outline segment" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:344 +#: ../src/ui/dialog/inkscape-preferences.cpp:343 msgid "Show temporary path outline" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:345 +#: ../src/ui/dialog/inkscape-preferences.cpp:344 msgid "When hovering over a path, briefly flash its outline" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:346 +#: ../src/ui/dialog/inkscape-preferences.cpp:345 msgid "Show temporary outline for selected paths" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:347 +#: ../src/ui/dialog/inkscape-preferences.cpp:346 msgid "Show temporary outline even when a path is selected for editing" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:349 +#: ../src/ui/dialog/inkscape-preferences.cpp:348 msgid "Flash time:" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:349 +#: ../src/ui/dialog/inkscape-preferences.cpp:348 msgid "" "Specifies how long the path outline will be visible after a mouse-over (in " "milliseconds); specify 0 to have the outline shown until mouse leaves the " "path" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:350 +#: ../src/ui/dialog/inkscape-preferences.cpp:349 msgid "Editing preferences" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:351 +#: ../src/ui/dialog/inkscape-preferences.cpp:350 msgid "Show transform handles for single nodes" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:352 +#: ../src/ui/dialog/inkscape-preferences.cpp:351 msgid "Show transform handles even when only a single node is selected" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:353 +#: ../src/ui/dialog/inkscape-preferences.cpp:352 msgid "Deleting nodes preserves shape" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:354 +#: ../src/ui/dialog/inkscape-preferences.cpp:353 msgid "" "Move handles next to deleted nodes to resemble original shape; hold Ctrl to " "get the other behavior" msgstr "" #. Tweak -#: ../src/ui/dialog/inkscape-preferences.cpp:357 ../src/verbs.cpp:2451 +#: ../src/ui/dialog/inkscape-preferences.cpp:356 ../src/verbs.cpp:2450 msgid "Tweak" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:358 +#: ../src/ui/dialog/inkscape-preferences.cpp:357 msgid "Object paint style" msgstr "" #. Zoom -#: ../src/ui/dialog/inkscape-preferences.cpp:363 ../src/verbs.cpp:2475 +#: ../src/ui/dialog/inkscape-preferences.cpp:362 ../src/verbs.cpp:2474 #: ../src/widgets/desktop-widget.cpp:505 msgid "Zoom" msgstr "" #. Measure -#: ../src/ui/dialog/inkscape-preferences.cpp:368 ../src/verbs.cpp:2477 -#: ../share/extensions/measure.inx.h:6 +#: ../src/ui/dialog/inkscape-preferences.cpp:367 ../src/verbs.cpp:2476 +#: ../share/extensions/measure.inx.h:23 msgid "Measure" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:370 +#: ../src/ui/dialog/inkscape-preferences.cpp:369 msgid "Ignore first and last points" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:371 +#: ../src/ui/dialog/inkscape-preferences.cpp:370 msgid "" "The start and end of the measurement tool's control line will not be " "considered for calculating lengths. Only lengths between actual curve " @@ -16044,77 +16236,77 @@ msgid "" msgstr "" #. Shapes -#: ../src/ui/dialog/inkscape-preferences.cpp:374 +#: ../src/ui/dialog/inkscape-preferences.cpp:373 msgid "Shapes" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:406 +#: ../src/ui/dialog/inkscape-preferences.cpp:405 msgid "Sketch mode" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:408 +#: ../src/ui/dialog/inkscape-preferences.cpp:407 msgid "" "If on, the sketch result will be the normal average of all sketches made, " "instead of averaging the old result with the new sketch" msgstr "" #. Pen -#: ../src/ui/dialog/inkscape-preferences.cpp:411 -#: ../src/ui/dialog/input.cpp:1195 ../src/verbs.cpp:2467 +#: ../src/ui/dialog/inkscape-preferences.cpp:410 +#: ../src/ui/dialog/input.cpp:1195 ../src/verbs.cpp:2466 msgid "Pen" msgstr "" #. Calligraphy -#: ../src/ui/dialog/inkscape-preferences.cpp:417 ../src/verbs.cpp:2469 +#: ../src/ui/dialog/inkscape-preferences.cpp:416 ../src/verbs.cpp:2468 msgid "Calligraphy" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:421 +#: ../src/ui/dialog/inkscape-preferences.cpp:420 msgid "" "If on, pen width is in absolute units (px) independent of zoom; otherwise " "pen width depends on zoom so that it looks the same at any zoom" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:423 +#: ../src/ui/dialog/inkscape-preferences.cpp:422 msgid "" "If on, each newly created object will be selected (deselecting previous " "selection)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:431 +#: ../src/ui/dialog/inkscape-preferences.cpp:430 msgid "Show font samples in the drop-down list" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:432 +#: ../src/ui/dialog/inkscape-preferences.cpp:431 msgid "" "Show font samples alongside font names in the drop-down list in Text bar" msgstr "" #. Spray -#: ../src/ui/dialog/inkscape-preferences.cpp:437 ../src/verbs.cpp:2453 +#: ../src/ui/dialog/inkscape-preferences.cpp:436 ../src/verbs.cpp:2452 msgid "Spray" msgstr "" #. Eraser -#: ../src/ui/dialog/inkscape-preferences.cpp:442 ../src/verbs.cpp:2487 +#: ../src/ui/dialog/inkscape-preferences.cpp:441 ../src/verbs.cpp:2486 msgid "Eraser" msgstr "" #. Paint Bucket -#: ../src/ui/dialog/inkscape-preferences.cpp:446 ../src/verbs.cpp:2483 +#: ../src/ui/dialog/inkscape-preferences.cpp:445 ../src/verbs.cpp:2482 msgid "Paint Bucket" msgstr "" #. Gradient -#: ../src/ui/dialog/inkscape-preferences.cpp:451 ../src/verbs.cpp:2473 +#: ../src/ui/dialog/inkscape-preferences.cpp:450 ../src/verbs.cpp:2472 msgid "Gradient" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:453 +#: ../src/ui/dialog/inkscape-preferences.cpp:452 msgid "Prevent sharing of gradient definitions" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:455 +#: ../src/ui/dialog/inkscape-preferences.cpp:454 msgid "" "When on, shared gradient definitions are automatically forked on change; " "uncheck to allow sharing of gradient definitions so that editing one object " @@ -16122,749 +16314,773 @@ msgid "" msgstr "" #. Dropper -#: ../src/ui/dialog/inkscape-preferences.cpp:458 ../src/verbs.cpp:2479 +#: ../src/ui/dialog/inkscape-preferences.cpp:457 ../src/verbs.cpp:2478 msgid "Dropper" msgstr "" #. Connector -#: ../src/ui/dialog/inkscape-preferences.cpp:463 ../src/verbs.cpp:2481 +#: ../src/ui/dialog/inkscape-preferences.cpp:462 ../src/verbs.cpp:2480 msgid "Connector" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:466 +#: ../src/ui/dialog/inkscape-preferences.cpp:465 msgid "If on, connector attachment points will not be shown for text objects" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:476 +#: ../src/ui/dialog/inkscape-preferences.cpp:475 msgid "Interface" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:479 +#: ../src/ui/dialog/inkscape-preferences.cpp:478 msgid "System default" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:479 +#: ../src/ui/dialog/inkscape-preferences.cpp:478 msgid "Albanian (sq)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:479 +#: ../src/ui/dialog/inkscape-preferences.cpp:478 msgid "Amharic (am)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:479 +#: ../src/ui/dialog/inkscape-preferences.cpp:478 msgid "Arabic (ar)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:479 +#: ../src/ui/dialog/inkscape-preferences.cpp:478 msgid "Armenian (hy)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:479 +#: ../src/ui/dialog/inkscape-preferences.cpp:478 msgid "Azerbaijani (az)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:479 +#: ../src/ui/dialog/inkscape-preferences.cpp:478 msgid "Basque (eu)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:479 +#: ../src/ui/dialog/inkscape-preferences.cpp:478 msgid "Belarusian (be)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:480 +#: ../src/ui/dialog/inkscape-preferences.cpp:479 msgid "Bulgarian (bg)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:480 +#: ../src/ui/dialog/inkscape-preferences.cpp:479 msgid "Bengali (bn)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:480 +#: ../src/ui/dialog/inkscape-preferences.cpp:479 msgid "Breton (br)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:480 +#: ../src/ui/dialog/inkscape-preferences.cpp:479 msgid "Catalan (ca)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:480 +#: ../src/ui/dialog/inkscape-preferences.cpp:479 msgid "Valencian Catalan (ca@valencia)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:480 +#: ../src/ui/dialog/inkscape-preferences.cpp:479 msgid "Chinese/China (zh_CN)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:481 +#: ../src/ui/dialog/inkscape-preferences.cpp:480 msgid "Chinese/Taiwan (zh_TW)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:481 +#: ../src/ui/dialog/inkscape-preferences.cpp:480 msgid "Croatian (hr)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:481 +#: ../src/ui/dialog/inkscape-preferences.cpp:480 msgid "Czech (cs)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:482 +#: ../src/ui/dialog/inkscape-preferences.cpp:481 msgid "Danish (da)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:482 +#: ../src/ui/dialog/inkscape-preferences.cpp:481 msgid "Dutch (nl)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:482 +#: ../src/ui/dialog/inkscape-preferences.cpp:481 msgid "Dzongkha (dz)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:482 +#: ../src/ui/dialog/inkscape-preferences.cpp:481 msgid "German (de)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:482 +#: ../src/ui/dialog/inkscape-preferences.cpp:481 msgid "Greek (el)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:482 +#: ../src/ui/dialog/inkscape-preferences.cpp:481 msgid "English (en)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:482 +#: ../src/ui/dialog/inkscape-preferences.cpp:481 msgid "English/Australia (en_AU)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:483 +#: ../src/ui/dialog/inkscape-preferences.cpp:482 msgid "English/Canada (en_CA)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:483 +#: ../src/ui/dialog/inkscape-preferences.cpp:482 msgid "English/Great Britain (en_GB)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:483 +#: ../src/ui/dialog/inkscape-preferences.cpp:482 msgid "Pig Latin (en_US@piglatin)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:484 +#: ../src/ui/dialog/inkscape-preferences.cpp:483 msgid "Esperanto (eo)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:484 +#: ../src/ui/dialog/inkscape-preferences.cpp:483 msgid "Estonian (et)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:484 +#: ../src/ui/dialog/inkscape-preferences.cpp:483 msgid "Farsi (fa)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:484 +#: ../src/ui/dialog/inkscape-preferences.cpp:483 msgid "Finnish (fi)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:485 +#: ../src/ui/dialog/inkscape-preferences.cpp:484 msgid "French (fr)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:485 +#: ../src/ui/dialog/inkscape-preferences.cpp:484 msgid "Irish (ga)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:485 +#: ../src/ui/dialog/inkscape-preferences.cpp:484 msgid "Galician (gl)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:485 +#: ../src/ui/dialog/inkscape-preferences.cpp:484 msgid "Hebrew (he)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:485 +#: ../src/ui/dialog/inkscape-preferences.cpp:484 msgid "Hungarian (hu)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:486 +#: ../src/ui/dialog/inkscape-preferences.cpp:485 msgid "Indonesian (id)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:486 +#: ../src/ui/dialog/inkscape-preferences.cpp:485 msgid "Italian (it)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:486 +#: ../src/ui/dialog/inkscape-preferences.cpp:485 msgid "Japanese (ja)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:486 +#: ../src/ui/dialog/inkscape-preferences.cpp:485 msgid "Khmer (km)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:486 +#: ../src/ui/dialog/inkscape-preferences.cpp:485 msgid "Kinyarwanda (rw)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:486 +#: ../src/ui/dialog/inkscape-preferences.cpp:485 msgid "Korean (ko)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:486 +#: ../src/ui/dialog/inkscape-preferences.cpp:485 msgid "Lithuanian (lt)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:486 +#: ../src/ui/dialog/inkscape-preferences.cpp:485 +msgid "Latvian (lv)" +msgstr "" + +#: ../src/ui/dialog/inkscape-preferences.cpp:485 msgid "Macedonian (mk)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:487 +#: ../src/ui/dialog/inkscape-preferences.cpp:486 msgid "Mongolian (mn)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:487 +#: ../src/ui/dialog/inkscape-preferences.cpp:486 msgid "Nepali (ne)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:487 +#: ../src/ui/dialog/inkscape-preferences.cpp:486 msgid "Norwegian Bokmål (nb)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:487 +#: ../src/ui/dialog/inkscape-preferences.cpp:486 msgid "Norwegian Nynorsk (nn)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:487 +#: ../src/ui/dialog/inkscape-preferences.cpp:486 msgid "Panjabi (pa)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:488 +#: ../src/ui/dialog/inkscape-preferences.cpp:487 msgid "Polish (pl)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:488 +#: ../src/ui/dialog/inkscape-preferences.cpp:487 msgid "Portuguese (pt)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:488 +#: ../src/ui/dialog/inkscape-preferences.cpp:487 msgid "Portuguese/Brazil (pt_BR)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:488 +#: ../src/ui/dialog/inkscape-preferences.cpp:487 msgid "Romanian (ro)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:488 +#: ../src/ui/dialog/inkscape-preferences.cpp:487 msgid "Russian (ru)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:489 +#: ../src/ui/dialog/inkscape-preferences.cpp:488 msgid "Serbian (sr)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:489 +#: ../src/ui/dialog/inkscape-preferences.cpp:488 msgid "Serbian in Latin script (sr@latin)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:489 +#: ../src/ui/dialog/inkscape-preferences.cpp:488 msgid "Slovak (sk)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:489 +#: ../src/ui/dialog/inkscape-preferences.cpp:488 msgid "Slovenian (sl)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:489 +#: ../src/ui/dialog/inkscape-preferences.cpp:488 msgid "Spanish (es)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:489 +#: ../src/ui/dialog/inkscape-preferences.cpp:488 msgid "Spanish/Mexico (es_MX)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:490 +#: ../src/ui/dialog/inkscape-preferences.cpp:489 msgid "Swedish (sv)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:490 +#: ../src/ui/dialog/inkscape-preferences.cpp:489 msgid "Telugu (te_IN)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:490 +#: ../src/ui/dialog/inkscape-preferences.cpp:489 msgid "Thai (th)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:490 +#: ../src/ui/dialog/inkscape-preferences.cpp:489 msgid "Turkish (tr)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:490 +#: ../src/ui/dialog/inkscape-preferences.cpp:489 msgid "Ukrainian (uk)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:490 +#: ../src/ui/dialog/inkscape-preferences.cpp:489 msgid "Vietnamese (vi)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:522 +#: ../src/ui/dialog/inkscape-preferences.cpp:521 msgid "Language (requires restart):" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:523 +#: ../src/ui/dialog/inkscape-preferences.cpp:522 msgid "Set the language for menus and number formats" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:525 +#: ../src/ui/dialog/inkscape-preferences.cpp:524 msgid "Large" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:525 +#: ../src/ui/dialog/inkscape-preferences.cpp:524 msgid "Small" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:525 +#: ../src/ui/dialog/inkscape-preferences.cpp:524 msgid "Smaller" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:529 +#: ../src/ui/dialog/inkscape-preferences.cpp:528 msgid "Toolbox icon size:" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:530 +#: ../src/ui/dialog/inkscape-preferences.cpp:529 msgid "Set the size for the tool icons (requires restart)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:533 +#: ../src/ui/dialog/inkscape-preferences.cpp:532 msgid "Control bar icon size:" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:534 +#: ../src/ui/dialog/inkscape-preferences.cpp:533 msgid "" "Set the size for the icons in tools' control bars to use (requires restart)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:537 +#: ../src/ui/dialog/inkscape-preferences.cpp:536 msgid "Secondary toolbar icon size:" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:538 +#: ../src/ui/dialog/inkscape-preferences.cpp:537 msgid "" "Set the size for the icons in secondary toolbars to use (requires restart)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:541 +#: ../src/ui/dialog/inkscape-preferences.cpp:540 msgid "Work-around color sliders not drawing" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:543 +#: ../src/ui/dialog/inkscape-preferences.cpp:542 msgid "" "When on, will attempt to work around bugs in certain GTK themes drawing " "color sliders" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:549 +#: ../src/ui/dialog/inkscape-preferences.cpp:548 msgid "Clear list" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:554 +#: ../src/ui/dialog/inkscape-preferences.cpp:553 msgid "Maximum documents in Open Recent:" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:555 +#: ../src/ui/dialog/inkscape-preferences.cpp:554 msgid "" "Set the maximum length of the Open Recent list in the File menu, or clear " "the list" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:558 +#: ../src/ui/dialog/inkscape-preferences.cpp:557 msgid "Zoom correction factor (in %):" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:559 +#: ../src/ui/dialog/inkscape-preferences.cpp:558 msgid "" "Adjust the slider until the length of the ruler on your screen matches its " "real length. This information is used when zooming to 1:1, 1:2, etc., to " "display objects in their true sizes" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:562 +#: ../src/ui/dialog/inkscape-preferences.cpp:561 msgid "Enable dynamic relayout for incomplete sections" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:564 +#: ../src/ui/dialog/inkscape-preferences.cpp:563 msgid "" "When on, will allow dynamic layout of components that are not completely " "finished being refactored" msgstr "" #. show infobox -#: ../src/ui/dialog/inkscape-preferences.cpp:567 +#: ../src/ui/dialog/inkscape-preferences.cpp:566 msgid "Show filter primitives infobox" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:569 +#: ../src/ui/dialog/inkscape-preferences.cpp:568 msgid "" "Show icons and descriptions for the filter primitives available at the " "filter effects dialog" msgstr "" #. Windows -#: ../src/ui/dialog/inkscape-preferences.cpp:572 +#: ../src/ui/dialog/inkscape-preferences.cpp:571 msgid "Save and restore window geometry for each document" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:573 +#: ../src/ui/dialog/inkscape-preferences.cpp:572 msgid "Remember and use last window's geometry" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:574 +#: ../src/ui/dialog/inkscape-preferences.cpp:573 msgid "Don't save window geometry" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:576 +#: ../src/ui/dialog/inkscape-preferences.cpp:575 msgid "Save and restore dialogs status" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:577 -#: ../src/ui/dialog/inkscape-preferences.cpp:599 +#: ../src/ui/dialog/inkscape-preferences.cpp:576 +#: ../src/ui/dialog/inkscape-preferences.cpp:601 msgid "Don't save dialogs status" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:579 -#: ../src/ui/dialog/inkscape-preferences.cpp:605 +#: ../src/ui/dialog/inkscape-preferences.cpp:578 +#: ../src/ui/dialog/inkscape-preferences.cpp:607 msgid "Dockable" msgstr "" +#: ../src/ui/dialog/inkscape-preferences.cpp:581 +msgid "Native open/save dialogs" +msgstr "" + #: ../src/ui/dialog/inkscape-preferences.cpp:582 +msgid "GTK open/save dialogs" +msgstr "" + +#: ../src/ui/dialog/inkscape-preferences.cpp:584 msgid "Dialogs are hidden in taskbar" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:583 +#: ../src/ui/dialog/inkscape-preferences.cpp:585 msgid "Zoom when window is resized" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:584 +#: ../src/ui/dialog/inkscape-preferences.cpp:586 msgid "Show close button on dialogs" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:587 +#: ../src/ui/dialog/inkscape-preferences.cpp:589 msgid "Aggressive" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:589 +#: ../src/ui/dialog/inkscape-preferences.cpp:591 msgid "Saving window geometry (size and position)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:591 +#: ../src/ui/dialog/inkscape-preferences.cpp:593 msgid "Let the window manager determine placement of all windows" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:593 +#: ../src/ui/dialog/inkscape-preferences.cpp:595 msgid "" "Remember and use the last window's geometry (saves geometry to user " "preferences)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:595 +#: ../src/ui/dialog/inkscape-preferences.cpp:597 msgid "" "Save and restore window geometry for each document (saves geometry in the " "document)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:597 +#: ../src/ui/dialog/inkscape-preferences.cpp:599 msgid "Saving dialogs status" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:601 +#: ../src/ui/dialog/inkscape-preferences.cpp:603 msgid "" "Save and restore dialogs status (the last open windows dialogs are saved " "when it closes)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:603 +#: ../src/ui/dialog/inkscape-preferences.cpp:605 msgid "Dialog behavior (requires restart)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:610 -msgid "Dialogs on top:" +#: ../src/ui/dialog/inkscape-preferences.cpp:611 +msgid "Desktop integration" msgstr "" #: ../src/ui/dialog/inkscape-preferences.cpp:613 -msgid "Dialogs are treated as regular windows" +msgid "Use Windows like open and save dialogs" msgstr "" #: ../src/ui/dialog/inkscape-preferences.cpp:615 +msgid "Use GTK open and save dialogs " +msgstr "" + +#: ../src/ui/dialog/inkscape-preferences.cpp:619 +msgid "Dialogs on top:" +msgstr "" + +#: ../src/ui/dialog/inkscape-preferences.cpp:622 +msgid "Dialogs are treated as regular windows" +msgstr "" + +#: ../src/ui/dialog/inkscape-preferences.cpp:624 msgid "Dialogs stay on top of document windows" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:617 +#: ../src/ui/dialog/inkscape-preferences.cpp:626 msgid "Same as Normal but may work better with some window managers" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:621 +#: ../src/ui/dialog/inkscape-preferences.cpp:630 msgid "Dialog Transparency" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:623 +#: ../src/ui/dialog/inkscape-preferences.cpp:632 msgid "Opacity when focused:" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:625 +#: ../src/ui/dialog/inkscape-preferences.cpp:634 msgid "Opacity when unfocused:" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:627 +#: ../src/ui/dialog/inkscape-preferences.cpp:636 msgid "Time of opacity change animation:" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:630 +#: ../src/ui/dialog/inkscape-preferences.cpp:639 msgid "Miscellaneous" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:633 +#: ../src/ui/dialog/inkscape-preferences.cpp:642 msgid "Whether dialog windows are to be hidden in the window manager taskbar" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:636 +#: ../src/ui/dialog/inkscape-preferences.cpp:645 msgid "" "Zoom drawing when document window is resized, to keep the same area visible " "(this is the default which can be changed in any window using the button " "above the right scrollbar)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:638 +#: ../src/ui/dialog/inkscape-preferences.cpp:647 msgid "Whether dialog windows have a close button (requires restart)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:639 +#: ../src/ui/dialog/inkscape-preferences.cpp:648 msgid "Windows" msgstr "" #. Grids -#: ../src/ui/dialog/inkscape-preferences.cpp:642 +#: ../src/ui/dialog/inkscape-preferences.cpp:651 msgid "Major grid line emphasizing" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:644 +#: ../src/ui/dialog/inkscape-preferences.cpp:653 msgid "Don't emphasize gridlines when zoomed out" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:645 +#: ../src/ui/dialog/inkscape-preferences.cpp:654 msgid "" "If set and zoomed out, the gridlines will be shown in normal color instead " "of major grid line color" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:647 +#: ../src/ui/dialog/inkscape-preferences.cpp:656 msgid "Default grid settings" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:653 -#: ../src/ui/dialog/inkscape-preferences.cpp:678 +#: ../src/ui/dialog/inkscape-preferences.cpp:662 +#: ../src/ui/dialog/inkscape-preferences.cpp:687 msgid "Grid units:" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:658 -#: ../src/ui/dialog/inkscape-preferences.cpp:683 +#: ../src/ui/dialog/inkscape-preferences.cpp:667 +#: ../src/ui/dialog/inkscape-preferences.cpp:692 msgid "Origin X:" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:659 -#: ../src/ui/dialog/inkscape-preferences.cpp:684 +#: ../src/ui/dialog/inkscape-preferences.cpp:668 +#: ../src/ui/dialog/inkscape-preferences.cpp:693 msgid "Origin Y:" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:664 +#: ../src/ui/dialog/inkscape-preferences.cpp:673 msgid "Spacing X:" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:665 -#: ../src/ui/dialog/inkscape-preferences.cpp:687 +#: ../src/ui/dialog/inkscape-preferences.cpp:674 +#: ../src/ui/dialog/inkscape-preferences.cpp:696 msgid "Spacing Y:" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:667 -#: ../src/ui/dialog/inkscape-preferences.cpp:668 -#: ../src/ui/dialog/inkscape-preferences.cpp:692 -#: ../src/ui/dialog/inkscape-preferences.cpp:693 +#: ../src/ui/dialog/inkscape-preferences.cpp:676 +#: ../src/ui/dialog/inkscape-preferences.cpp:677 +#: ../src/ui/dialog/inkscape-preferences.cpp:701 +#: ../src/ui/dialog/inkscape-preferences.cpp:702 msgid "Grid line color:" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:668 -#: ../src/ui/dialog/inkscape-preferences.cpp:693 +#: ../src/ui/dialog/inkscape-preferences.cpp:677 +#: ../src/ui/dialog/inkscape-preferences.cpp:702 msgid "Color used for normal grid lines" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:669 -#: ../src/ui/dialog/inkscape-preferences.cpp:670 -#: ../src/ui/dialog/inkscape-preferences.cpp:694 -#: ../src/ui/dialog/inkscape-preferences.cpp:695 +#: ../src/ui/dialog/inkscape-preferences.cpp:678 +#: ../src/ui/dialog/inkscape-preferences.cpp:679 +#: ../src/ui/dialog/inkscape-preferences.cpp:703 +#: ../src/ui/dialog/inkscape-preferences.cpp:704 msgid "Major grid line color:" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:670 -#: ../src/ui/dialog/inkscape-preferences.cpp:695 +#: ../src/ui/dialog/inkscape-preferences.cpp:679 +#: ../src/ui/dialog/inkscape-preferences.cpp:704 msgid "Color used for major (highlighted) grid lines" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:672 -#: ../src/ui/dialog/inkscape-preferences.cpp:697 +#: ../src/ui/dialog/inkscape-preferences.cpp:681 +#: ../src/ui/dialog/inkscape-preferences.cpp:706 msgid "Major grid line every:" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:673 +#: ../src/ui/dialog/inkscape-preferences.cpp:682 msgid "Show dots instead of lines" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:674 +#: ../src/ui/dialog/inkscape-preferences.cpp:683 msgid "If set, display dots at gridpoints instead of gridlines" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:746 -msgid "Input-output" +#: ../src/ui/dialog/inkscape-preferences.cpp:755 +msgid "Input/Output" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:749 +#: ../src/ui/dialog/inkscape-preferences.cpp:758 msgid "Use current directory for \"Save As ...\"" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:751 +#: ../src/ui/dialog/inkscape-preferences.cpp:760 msgid "" "When this option is on, the \"Save as...\" and \"Save a Copy\" dialogs will " "always open in the directory where the currently open document is; when it's " "off, each will open in the directory where you last saved a file using it" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:753 +#: ../src/ui/dialog/inkscape-preferences.cpp:762 msgid "Add label comments to printing output" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:755 +#: ../src/ui/dialog/inkscape-preferences.cpp:764 msgid "" "When on, a comment will be added to the raw print output, marking the " "rendered output for an object with its label" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:759 +#: ../src/ui/dialog/inkscape-preferences.cpp:768 msgid "Grab sensitivity:" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:759 -#: ../src/ui/dialog/inkscape-preferences.cpp:762 -#: ../src/ui/dialog/inkscape-preferences.cpp:1084 -#: ../src/ui/dialog/inkscape-preferences.cpp:1088 -#: ../src/ui/dialog/inkscape-preferences.cpp:1098 +#: ../src/ui/dialog/inkscape-preferences.cpp:768 +#: ../src/ui/dialog/inkscape-preferences.cpp:771 +#: ../src/ui/dialog/inkscape-preferences.cpp:1093 +#: ../src/ui/dialog/inkscape-preferences.cpp:1097 +#: ../src/ui/dialog/inkscape-preferences.cpp:1107 msgid "pixels" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:760 +#: ../src/ui/dialog/inkscape-preferences.cpp:769 msgid "" "How close on the screen you need to be to an object to be able to grab it " "with mouse (in screen pixels)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:762 +#: ../src/ui/dialog/inkscape-preferences.cpp:771 msgid "Click/drag threshold:" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:763 +#: ../src/ui/dialog/inkscape-preferences.cpp:772 msgid "" "Maximum mouse drag (in screen pixels) which is considered a click, not a drag" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:765 +#: ../src/ui/dialog/inkscape-preferences.cpp:774 msgid "Use pressure-sensitive tablet (requires restart)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:767 +#: ../src/ui/dialog/inkscape-preferences.cpp:776 msgid "" "Use the capabilities of a tablet or other pressure-sensitive device. Disable " "this only if you have problems with the tablet (you can still use it as a " "mouse)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:769 +#: ../src/ui/dialog/inkscape-preferences.cpp:778 msgid "Switch tool based on tablet device (requires restart)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:771 +#: ../src/ui/dialog/inkscape-preferences.cpp:780 msgid "" "Change tool as different devices are used on the tablet (pen, eraser, mouse)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:772 +#: ../src/ui/dialog/inkscape-preferences.cpp:781 msgid "Input devices" msgstr "" #. SVG output options -#: ../src/ui/dialog/inkscape-preferences.cpp:775 +#: ../src/ui/dialog/inkscape-preferences.cpp:784 msgid "Use named colors" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:776 +#: ../src/ui/dialog/inkscape-preferences.cpp:785 msgid "" "If set, write the CSS name of the color when available (e.g. 'red' or " "'magenta') instead of the numeric value" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:778 +#: ../src/ui/dialog/inkscape-preferences.cpp:787 msgid "XML formatting" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:780 +#: ../src/ui/dialog/inkscape-preferences.cpp:789 msgid "Inline attributes" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:781 +#: ../src/ui/dialog/inkscape-preferences.cpp:790 msgid "Put attributes on the same line as the element tag" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:784 +#: ../src/ui/dialog/inkscape-preferences.cpp:793 msgid "Indent, spaces:" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:784 +#: ../src/ui/dialog/inkscape-preferences.cpp:793 msgid "" "The number of spaces to use for indenting nested elements; set to 0 for no " "indentation" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:786 +#: ../src/ui/dialog/inkscape-preferences.cpp:795 msgid "Path data" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:788 +#: ../src/ui/dialog/inkscape-preferences.cpp:797 msgid "Allow relative coordinates" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:789 +#: ../src/ui/dialog/inkscape-preferences.cpp:798 msgid "If set, relative coordinates may be used in path data" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:791 +#: ../src/ui/dialog/inkscape-preferences.cpp:800 msgid "Force repeat commands" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:792 +#: ../src/ui/dialog/inkscape-preferences.cpp:801 msgid "" "Force repeating of the same path command (for example, 'L 1,2 L 3,4' instead " "of 'L 1,2 3,4')" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:794 +#: ../src/ui/dialog/inkscape-preferences.cpp:803 msgid "Numbers" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:797 +#: ../src/ui/dialog/inkscape-preferences.cpp:806 msgid "Numeric precision:" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:797 +#: ../src/ui/dialog/inkscape-preferences.cpp:806 msgid "Significant figures of the values written to the SVG file" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:800 +#: ../src/ui/dialog/inkscape-preferences.cpp:809 msgid "Minimum exponent:" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:800 +#: ../src/ui/dialog/inkscape-preferences.cpp:809 msgid "" "The smallest number written to SVG is 10 to the power of this exponent; " "anything smaller is written as zero" @@ -16872,56 +17088,56 @@ msgstr "" #. Code to add controls for attribute checking options #. Add incorrect style properties options -#: ../src/ui/dialog/inkscape-preferences.cpp:805 +#: ../src/ui/dialog/inkscape-preferences.cpp:814 msgid "Improper Attributes Actions" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:807 -#: ../src/ui/dialog/inkscape-preferences.cpp:815 -#: ../src/ui/dialog/inkscape-preferences.cpp:823 +#: ../src/ui/dialog/inkscape-preferences.cpp:816 +#: ../src/ui/dialog/inkscape-preferences.cpp:824 +#: ../src/ui/dialog/inkscape-preferences.cpp:832 msgid "Print warnings" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:808 +#: ../src/ui/dialog/inkscape-preferences.cpp:817 msgid "" "Print warning if invalid or non-useful attributes found. Database files " "located in inkscape_data_dir/attributes." msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:809 +#: ../src/ui/dialog/inkscape-preferences.cpp:818 msgid "Remove attributes" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:810 +#: ../src/ui/dialog/inkscape-preferences.cpp:819 msgid "Delete invalid or non-useful attributes from element tag." msgstr "" #. Add incorrect style properties options -#: ../src/ui/dialog/inkscape-preferences.cpp:813 +#: ../src/ui/dialog/inkscape-preferences.cpp:822 msgid "Inappropriate Style Properties Actions" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:816 +#: ../src/ui/dialog/inkscape-preferences.cpp:825 msgid "" "Print warning if inappropriate style properties found (i.e. 'font-family' " "set on a ). Database files located in inkscape_data_dir/attributes." msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:817 -#: ../src/ui/dialog/inkscape-preferences.cpp:825 +#: ../src/ui/dialog/inkscape-preferences.cpp:826 +#: ../src/ui/dialog/inkscape-preferences.cpp:834 msgid "Remove style properties" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:818 +#: ../src/ui/dialog/inkscape-preferences.cpp:827 msgid "Delete inappropriate style properties." msgstr "" #. Add default or inherited style properties options -#: ../src/ui/dialog/inkscape-preferences.cpp:821 +#: ../src/ui/dialog/inkscape-preferences.cpp:830 msgid "Non-useful Style Properties Actions" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:824 +#: ../src/ui/dialog/inkscape-preferences.cpp:833 msgid "" "Print warning if redundant style properties found (i.e. if a property has " "the default value and a different value is not inherited or if value is the " @@ -16929,164 +17145,164 @@ msgid "" "attributes." msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:826 +#: ../src/ui/dialog/inkscape-preferences.cpp:835 msgid "Delete redundant style properties." msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:828 +#: ../src/ui/dialog/inkscape-preferences.cpp:837 msgid "Check Attributes and Style Properties on:" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:830 +#: ../src/ui/dialog/inkscape-preferences.cpp:839 msgid "Reading" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:831 +#: ../src/ui/dialog/inkscape-preferences.cpp:840 msgid "" "Check attributes and style properties on reading in SVG files (including " "those internal to Inkscape which will slow down startup)." msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:832 +#: ../src/ui/dialog/inkscape-preferences.cpp:841 msgid "Editing" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:833 +#: ../src/ui/dialog/inkscape-preferences.cpp:842 msgid "" "Check attributes and style properties while editing SVG files (may slow down " "Inkscape, mostly useful for debugging)." msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:834 +#: ../src/ui/dialog/inkscape-preferences.cpp:843 msgid "Writing" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:835 +#: ../src/ui/dialog/inkscape-preferences.cpp:844 msgid "Check attributes and style properties on writing out SVG files." msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:837 +#: ../src/ui/dialog/inkscape-preferences.cpp:846 msgid "SVG output" msgstr "" #. TRANSLATORS: see http://www.newsandtech.com/issues/2004/03-04/pt/03-04_rendering.htm -#: ../src/ui/dialog/inkscape-preferences.cpp:843 +#: ../src/ui/dialog/inkscape-preferences.cpp:852 msgid "Perceptual" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:843 +#: ../src/ui/dialog/inkscape-preferences.cpp:852 msgid "Relative Colorimetric" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:843 +#: ../src/ui/dialog/inkscape-preferences.cpp:852 msgid "Absolute Colorimetric" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:847 +#: ../src/ui/dialog/inkscape-preferences.cpp:856 msgid "(Note: Color management has been disabled in this build)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:851 +#: ../src/ui/dialog/inkscape-preferences.cpp:860 msgid "Display adjustment" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:861 +#: ../src/ui/dialog/inkscape-preferences.cpp:870 #, c-format msgid "" "The ICC profile to use to calibrate display output.\n" "Searched directories:%s" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:862 +#: ../src/ui/dialog/inkscape-preferences.cpp:871 msgid "Display profile:" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:867 +#: ../src/ui/dialog/inkscape-preferences.cpp:876 msgid "Retrieve profile from display" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:870 +#: ../src/ui/dialog/inkscape-preferences.cpp:879 msgid "Retrieve profiles from those attached to displays via XICC" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:872 +#: ../src/ui/dialog/inkscape-preferences.cpp:881 msgid "Retrieve profiles from those attached to displays" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:877 +#: ../src/ui/dialog/inkscape-preferences.cpp:886 msgid "Display rendering intent:" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:878 +#: ../src/ui/dialog/inkscape-preferences.cpp:887 msgid "The rendering intent to use to calibrate display output" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:880 +#: ../src/ui/dialog/inkscape-preferences.cpp:889 msgid "Proofing" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:882 +#: ../src/ui/dialog/inkscape-preferences.cpp:891 msgid "Simulate output on screen" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:884 +#: ../src/ui/dialog/inkscape-preferences.cpp:893 msgid "Simulates output of target device" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:886 +#: ../src/ui/dialog/inkscape-preferences.cpp:895 msgid "Mark out of gamut colors" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:888 +#: ../src/ui/dialog/inkscape-preferences.cpp:897 msgid "Highlights colors that are out of gamut for the target device" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:893 +#: ../src/ui/dialog/inkscape-preferences.cpp:902 msgid "Out of gamut warning color:" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:894 +#: ../src/ui/dialog/inkscape-preferences.cpp:903 msgid "Selects the color used for out of gamut warning" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:896 +#: ../src/ui/dialog/inkscape-preferences.cpp:905 msgid "Device profile:" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:897 +#: ../src/ui/dialog/inkscape-preferences.cpp:906 msgid "The ICC profile to use to simulate device output" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:900 +#: ../src/ui/dialog/inkscape-preferences.cpp:909 msgid "Device rendering intent:" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:901 +#: ../src/ui/dialog/inkscape-preferences.cpp:910 msgid "The rendering intent to use to calibrate device output" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:903 +#: ../src/ui/dialog/inkscape-preferences.cpp:912 msgid "Black point compensation" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:905 +#: ../src/ui/dialog/inkscape-preferences.cpp:914 msgid "Enables black point compensation" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:907 +#: ../src/ui/dialog/inkscape-preferences.cpp:916 msgid "Preserve black" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:912 +#: ../src/ui/dialog/inkscape-preferences.cpp:921 msgid "(LittleCMS 1.15 or later required)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:914 +#: ../src/ui/dialog/inkscape-preferences.cpp:923 msgid "Preserve K channel in CMYK -> CMYK transforms" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:928 -#: ../src/ui/dialog/inkscape-preferences.cpp:930 +#: ../src/ui/dialog/inkscape-preferences.cpp:937 +#: ../src/ui/dialog/inkscape-preferences.cpp:939 #: ../src/widgets/sp-color-icc-selector.cpp:308 #: ../src/widgets/sp-color-icc-selector.cpp:311 #: ../src/widgets/sp-color-icc-selector.cpp:598 @@ -17094,43 +17310,43 @@ msgstr "" msgid "" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:984 +#: ../src/ui/dialog/inkscape-preferences.cpp:993 msgid "Color management" msgstr "" #. Autosave options -#: ../src/ui/dialog/inkscape-preferences.cpp:987 +#: ../src/ui/dialog/inkscape-preferences.cpp:996 msgid "Enable autosave (requires restart)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:988 +#: ../src/ui/dialog/inkscape-preferences.cpp:997 msgid "" "Automatically save the current document(s) at a given interval, thus " "minimizing loss in case of a crash" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:990 +#: ../src/ui/dialog/inkscape-preferences.cpp:999 msgid "Interval (in minutes):" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:990 +#: ../src/ui/dialog/inkscape-preferences.cpp:999 msgid "Interval (in minutes) at which document will be autosaved" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:992 +#: ../src/ui/dialog/inkscape-preferences.cpp:1001 msgctxt "Filesystem" msgid "Path:" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:992 +#: ../src/ui/dialog/inkscape-preferences.cpp:1001 msgid "The directory where autosaves will be written" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:994 +#: ../src/ui/dialog/inkscape-preferences.cpp:1003 msgid "Maximum number of autosaves:" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:994 +#: ../src/ui/dialog/inkscape-preferences.cpp:1003 msgid "" "Maximum number of autosaved files; use this to limit the storage space used" msgstr "" @@ -17147,49 +17363,49 @@ msgstr "" #. _autosave_autosave_interval.signal_changed().connect( sigc::ptr_fun(inkscape_autosave_init), TRUE ); #. #. ----------- -#: ../src/ui/dialog/inkscape-preferences.cpp:1009 +#: ../src/ui/dialog/inkscape-preferences.cpp:1018 msgid "Autosave" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1013 +#: ../src/ui/dialog/inkscape-preferences.cpp:1022 msgid "Open Clip Art Library Server Name:" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1014 +#: ../src/ui/dialog/inkscape-preferences.cpp:1023 msgid "" "The server name of the Open Clip Art Library webdav server; it's used by the " "Import and Export to OCAL function" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1016 +#: ../src/ui/dialog/inkscape-preferences.cpp:1025 msgid "Open Clip Art Library Username:" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1017 +#: ../src/ui/dialog/inkscape-preferences.cpp:1026 msgid "The username used to log into Open Clip Art Library" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1019 +#: ../src/ui/dialog/inkscape-preferences.cpp:1028 msgid "Open Clip Art Library Password:" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1020 +#: ../src/ui/dialog/inkscape-preferences.cpp:1029 msgid "The password used to log into Open Clip Art Library" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1021 +#: ../src/ui/dialog/inkscape-preferences.cpp:1030 msgid "Open Clip Art" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1026 +#: ../src/ui/dialog/inkscape-preferences.cpp:1035 msgid "Behavior" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1030 +#: ../src/ui/dialog/inkscape-preferences.cpp:1039 msgid "Simplification threshold:" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1031 +#: ../src/ui/dialog/inkscape-preferences.cpp:1040 msgid "" "How strong is the Node tool's Simplify command by default. If you invoke " "this command several times in quick succession, it will act more and more " @@ -17197,402 +17413,402 @@ msgid "" msgstr "" #. Selecting options -#: ../src/ui/dialog/inkscape-preferences.cpp:1034 +#: ../src/ui/dialog/inkscape-preferences.cpp:1043 msgid "Select in all layers" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1035 +#: ../src/ui/dialog/inkscape-preferences.cpp:1044 msgid "Select only within current layer" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1036 +#: ../src/ui/dialog/inkscape-preferences.cpp:1045 msgid "Select in current layer and sublayers" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1037 +#: ../src/ui/dialog/inkscape-preferences.cpp:1046 msgid "Ignore hidden objects and layers" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1038 +#: ../src/ui/dialog/inkscape-preferences.cpp:1047 msgid "Ignore locked objects and layers" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1039 +#: ../src/ui/dialog/inkscape-preferences.cpp:1048 msgid "Deselect upon layer change" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1041 +#: ../src/ui/dialog/inkscape-preferences.cpp:1050 msgid "Ctrl+A, Tab, Shift+Tab" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1043 +#: ../src/ui/dialog/inkscape-preferences.cpp:1052 msgid "Make keyboard selection commands work on objects in all layers" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1045 +#: ../src/ui/dialog/inkscape-preferences.cpp:1054 msgid "Make keyboard selection commands work on objects in current layer only" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1047 +#: ../src/ui/dialog/inkscape-preferences.cpp:1056 msgid "" "Make keyboard selection commands work on objects in current layer and all " "its sublayers" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1049 +#: ../src/ui/dialog/inkscape-preferences.cpp:1058 msgid "" "Uncheck this to be able to select objects that are hidden (either by " "themselves or by being in a hidden layer)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1051 +#: ../src/ui/dialog/inkscape-preferences.cpp:1060 msgid "" "Uncheck this to be able to select objects that are locked (either by " "themselves or by being in a locked layer)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1054 +#: ../src/ui/dialog/inkscape-preferences.cpp:1063 msgid "" "Uncheck this to be able to keep the current objects selected when the " "current layer changes" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1056 +#: ../src/ui/dialog/inkscape-preferences.cpp:1065 msgid "Selecting" msgstr "" #. Transforms options -#: ../src/ui/dialog/inkscape-preferences.cpp:1059 +#: ../src/ui/dialog/inkscape-preferences.cpp:1068 #: ../src/widgets/select-toolbar.cpp:561 msgid "Scale stroke width" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1060 +#: ../src/ui/dialog/inkscape-preferences.cpp:1069 msgid "Scale rounded corners in rectangles" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1061 +#: ../src/ui/dialog/inkscape-preferences.cpp:1070 msgid "Transform gradients" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1062 +#: ../src/ui/dialog/inkscape-preferences.cpp:1071 msgid "Transform patterns" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1063 +#: ../src/ui/dialog/inkscape-preferences.cpp:1072 msgid "Optimized" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1064 +#: ../src/ui/dialog/inkscape-preferences.cpp:1073 msgid "Preserved" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1067 +#: ../src/ui/dialog/inkscape-preferences.cpp:1076 #: ../src/widgets/select-toolbar.cpp:562 msgid "When scaling objects, scale the stroke width by the same proportion" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1069 +#: ../src/ui/dialog/inkscape-preferences.cpp:1078 #: ../src/widgets/select-toolbar.cpp:573 msgid "When scaling rectangles, scale the radii of rounded corners" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1071 +#: ../src/ui/dialog/inkscape-preferences.cpp:1080 #: ../src/widgets/select-toolbar.cpp:584 msgid "Move gradients (in fill or stroke) along with the objects" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1073 +#: ../src/ui/dialog/inkscape-preferences.cpp:1082 #: ../src/widgets/select-toolbar.cpp:595 msgid "Move patterns (in fill or stroke) along with the objects" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1074 +#: ../src/ui/dialog/inkscape-preferences.cpp:1083 msgid "Store transformation" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1076 +#: ../src/ui/dialog/inkscape-preferences.cpp:1085 msgid "" "If possible, apply transformation to objects without adding a transform= " "attribute" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1078 +#: ../src/ui/dialog/inkscape-preferences.cpp:1087 msgid "Always store transformation as a transform= attribute on objects" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1080 +#: ../src/ui/dialog/inkscape-preferences.cpp:1089 msgid "Transforms" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1084 +#: ../src/ui/dialog/inkscape-preferences.cpp:1093 msgid "Mouse wheel scrolls by:" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1085 +#: ../src/ui/dialog/inkscape-preferences.cpp:1094 msgid "" "One mouse wheel notch scrolls by this distance in screen pixels " "(horizontally with Shift)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1086 +#: ../src/ui/dialog/inkscape-preferences.cpp:1095 msgid "Ctrl+arrows" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1088 +#: ../src/ui/dialog/inkscape-preferences.cpp:1097 msgid "Scroll by:" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1089 +#: ../src/ui/dialog/inkscape-preferences.cpp:1098 msgid "Pressing Ctrl+arrow key scrolls by this distance (in screen pixels)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1091 +#: ../src/ui/dialog/inkscape-preferences.cpp:1100 msgid "Acceleration:" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1092 +#: ../src/ui/dialog/inkscape-preferences.cpp:1101 msgid "" "Pressing and holding Ctrl+arrow will gradually speed up scrolling (0 for no " "acceleration)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1093 +#: ../src/ui/dialog/inkscape-preferences.cpp:1102 msgid "Autoscrolling" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1095 +#: ../src/ui/dialog/inkscape-preferences.cpp:1104 msgid "Speed:" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1096 +#: ../src/ui/dialog/inkscape-preferences.cpp:1105 msgid "" "How fast the canvas autoscrolls when you drag beyond canvas edge (0 to turn " "autoscroll off)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1099 +#: ../src/ui/dialog/inkscape-preferences.cpp:1108 msgid "" "How far (in screen pixels) you need to be from the canvas edge to trigger " "autoscroll; positive is outside the canvas, negative is within the canvas" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1100 +#: ../src/ui/dialog/inkscape-preferences.cpp:1109 msgid "Left mouse button pans when Space is pressed" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1102 +#: ../src/ui/dialog/inkscape-preferences.cpp:1111 msgid "" "When on, pressing and holding Space and dragging with left mouse button pans " "canvas (as in Adobe Illustrator); when off, Space temporarily switches to " "Selector tool (default)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1103 +#: ../src/ui/dialog/inkscape-preferences.cpp:1112 msgid "Mouse wheel zooms by default" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1105 +#: ../src/ui/dialog/inkscape-preferences.cpp:1114 msgid "" "When on, mouse wheel zooms without Ctrl and scrolls canvas with Ctrl; when " "off, it zooms with Ctrl and scrolls without Ctrl" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1106 +#: ../src/ui/dialog/inkscape-preferences.cpp:1115 msgid "Scrolling" msgstr "" #. Snapping options -#: ../src/ui/dialog/inkscape-preferences.cpp:1109 +#: ../src/ui/dialog/inkscape-preferences.cpp:1118 msgid "Enable snap indicator" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1111 +#: ../src/ui/dialog/inkscape-preferences.cpp:1120 msgid "After snapping, a symbol is drawn at the point that has snapped" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1114 +#: ../src/ui/dialog/inkscape-preferences.cpp:1123 msgid "Delay (in ms):" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1115 +#: ../src/ui/dialog/inkscape-preferences.cpp:1124 msgid "" "Postpone snapping as long as the mouse is moving, and then wait an " "additional fraction of a second. This additional delay is specified here. " "When set to zero or to a very small number, snapping will be immediate." msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1117 +#: ../src/ui/dialog/inkscape-preferences.cpp:1126 msgid "Only snap the node closest to the pointer" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1119 +#: ../src/ui/dialog/inkscape-preferences.cpp:1128 msgid "" "Only try to snap the node that is initially closest to the mouse pointer" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1122 +#: ../src/ui/dialog/inkscape-preferences.cpp:1131 msgid "Weight factor:" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1123 +#: ../src/ui/dialog/inkscape-preferences.cpp:1132 msgid "" "When multiple snap solutions are found, then Inkscape can either prefer the " "closest transformation (when set to 0), or prefer the node that was " "initially the closest to the pointer (when set to 1)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1125 +#: ../src/ui/dialog/inkscape-preferences.cpp:1134 msgid "Snap the mouse pointer when dragging a constrained knot" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1127 +#: ../src/ui/dialog/inkscape-preferences.cpp:1136 msgid "" "When dragging a knot along a constraint line, then snap the position of the " "mouse pointer instead of snapping the projection of the knot onto the " "constraint line" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1129 +#: ../src/ui/dialog/inkscape-preferences.cpp:1138 msgid "Snapping" msgstr "" #. nudgedistance is limited to 1000 in select-context.cpp: use the same limit here -#: ../src/ui/dialog/inkscape-preferences.cpp:1134 +#: ../src/ui/dialog/inkscape-preferences.cpp:1143 msgid "Arrow keys move by:" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1135 +#: ../src/ui/dialog/inkscape-preferences.cpp:1144 msgid "" "Pressing an arrow key moves selected object(s) or node(s) by this distance" msgstr "" #. defaultscale is limited to 1000 in select-context.cpp: use the same limit here -#: ../src/ui/dialog/inkscape-preferences.cpp:1138 +#: ../src/ui/dialog/inkscape-preferences.cpp:1147 msgid "> and < scale by:" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1139 +#: ../src/ui/dialog/inkscape-preferences.cpp:1148 msgid "Pressing > or < scales selection up or down by this increment" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1141 +#: ../src/ui/dialog/inkscape-preferences.cpp:1150 msgid "Inset/Outset by:" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1142 +#: ../src/ui/dialog/inkscape-preferences.cpp:1151 msgid "Inset and Outset commands displace the path by this distance" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1143 +#: ../src/ui/dialog/inkscape-preferences.cpp:1152 msgid "Compass-like display of angles" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1145 +#: ../src/ui/dialog/inkscape-preferences.cpp:1154 msgid "" "When on, angles are displayed with 0 at north, 0 to 360 range, positive " "clockwise; otherwise with 0 at east, -180 to 180 range, positive " "counterclockwise" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1151 +#: ../src/ui/dialog/inkscape-preferences.cpp:1160 msgid "Rotation snaps every:" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1151 +#: ../src/ui/dialog/inkscape-preferences.cpp:1160 msgid "degrees" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1152 +#: ../src/ui/dialog/inkscape-preferences.cpp:1161 msgid "" "Rotating with Ctrl pressed snaps every that much degrees; also, pressing " "[ or ] rotates by this amount" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1153 +#: ../src/ui/dialog/inkscape-preferences.cpp:1162 msgid "Relative snapping of guideline angles" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1155 +#: ../src/ui/dialog/inkscape-preferences.cpp:1164 msgid "" "When on, the snap angles when rotating a guideline will be relative to the " "original angle" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1157 +#: ../src/ui/dialog/inkscape-preferences.cpp:1166 msgid "Zoom in/out by:" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1158 +#: ../src/ui/dialog/inkscape-preferences.cpp:1167 msgid "" "Zoom tool click, +/- keys, and middle click zoom in and out by this " "multiplier" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1159 +#: ../src/ui/dialog/inkscape-preferences.cpp:1168 msgid "Steps" msgstr "" #. Clones options -#: ../src/ui/dialog/inkscape-preferences.cpp:1162 +#: ../src/ui/dialog/inkscape-preferences.cpp:1171 msgid "Move in parallel" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1164 +#: ../src/ui/dialog/inkscape-preferences.cpp:1173 msgid "Stay unmoved" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1166 +#: ../src/ui/dialog/inkscape-preferences.cpp:1175 msgid "Move according to transform" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1168 +#: ../src/ui/dialog/inkscape-preferences.cpp:1177 msgid "Are unlinked" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1170 +#: ../src/ui/dialog/inkscape-preferences.cpp:1179 msgid "Are deleted" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1173 +#: ../src/ui/dialog/inkscape-preferences.cpp:1182 msgid "Moving original: clones and linked offsets" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1175 +#: ../src/ui/dialog/inkscape-preferences.cpp:1184 msgid "Clones are translated by the same vector as their original" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1177 +#: ../src/ui/dialog/inkscape-preferences.cpp:1186 msgid "Clones preserve their positions when their original is moved" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1179 +#: ../src/ui/dialog/inkscape-preferences.cpp:1188 msgid "" "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" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1180 +#: ../src/ui/dialog/inkscape-preferences.cpp:1189 msgid "Deleting original: clones" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1182 +#: ../src/ui/dialog/inkscape-preferences.cpp:1191 msgid "Orphaned clones are converted to regular objects" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1184 +#: ../src/ui/dialog/inkscape-preferences.cpp:1193 msgid "Orphaned clones are deleted along with their original" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1186 +#: ../src/ui/dialog/inkscape-preferences.cpp:1195 msgid "Duplicating original+clones/linked offset" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1188 +#: ../src/ui/dialog/inkscape-preferences.cpp:1197 msgid "Relink duplicated clones" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1190 +#: ../src/ui/dialog/inkscape-preferences.cpp:1199 msgid "" "When duplicating a selection containing both a clone and its original " "(possibly in groups), relink the duplicated clone to the duplicated original " @@ -17600,97 +17816,97 @@ msgid "" msgstr "" #. TRANSLATORS: Heading for the Inkscape Preferences "Clones" Page -#: ../src/ui/dialog/inkscape-preferences.cpp:1193 +#: ../src/ui/dialog/inkscape-preferences.cpp:1202 msgid "Clones" msgstr "" #. Clip paths and masks options -#: ../src/ui/dialog/inkscape-preferences.cpp:1196 +#: ../src/ui/dialog/inkscape-preferences.cpp:1205 msgid "When applying, use the topmost selected object as clippath/mask" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1198 +#: ../src/ui/dialog/inkscape-preferences.cpp:1207 msgid "" "Uncheck this to use the bottom selected object as the clipping path or mask" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1199 +#: ../src/ui/dialog/inkscape-preferences.cpp:1208 msgid "Remove clippath/mask object after applying" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1201 +#: ../src/ui/dialog/inkscape-preferences.cpp:1210 msgid "" "After applying, remove the object used as the clipping path or mask from the " "drawing" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1203 +#: ../src/ui/dialog/inkscape-preferences.cpp:1212 msgid "Before applying" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1205 +#: ../src/ui/dialog/inkscape-preferences.cpp:1214 msgid "Do not group clipped/masked objects" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1206 +#: ../src/ui/dialog/inkscape-preferences.cpp:1215 msgid "Enclose every clipped/masked object in its own group" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1207 +#: ../src/ui/dialog/inkscape-preferences.cpp:1216 msgid "Put all clipped/masked objects into one group" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1210 +#: ../src/ui/dialog/inkscape-preferences.cpp:1219 msgid "Apply clippath/mask to every object" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1213 +#: ../src/ui/dialog/inkscape-preferences.cpp:1222 msgid "Apply clippath/mask to groups containing single object" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1216 +#: ../src/ui/dialog/inkscape-preferences.cpp:1225 msgid "Apply clippath/mask to group containing all objects" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1218 +#: ../src/ui/dialog/inkscape-preferences.cpp:1227 msgid "After releasing" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1220 +#: ../src/ui/dialog/inkscape-preferences.cpp:1229 msgid "Ungroup automatically created groups" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1222 +#: ../src/ui/dialog/inkscape-preferences.cpp:1231 msgid "Ungroup groups created when setting clip/mask" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1224 +#: ../src/ui/dialog/inkscape-preferences.cpp:1233 msgid "Clippaths and masks" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1232 +#: ../src/ui/dialog/inkscape-preferences.cpp:1241 msgid "Number of Threads:" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1232 -#: ../src/ui/dialog/inkscape-preferences.cpp:1410 +#: ../src/ui/dialog/inkscape-preferences.cpp:1241 +#: ../src/ui/dialog/inkscape-preferences.cpp:1418 msgid "(requires restart)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1233 +#: ../src/ui/dialog/inkscape-preferences.cpp:1242 msgid "Configure number of processors/threads to use when rendering filters" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1237 +#: ../src/ui/dialog/inkscape-preferences.cpp:1246 msgid "Rendering cache size:" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1237 +#: ../src/ui/dialog/inkscape-preferences.cpp:1246 msgctxt "mebibyte (2^20 bytes) abbreviation" msgid "MiB" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1237 +#: ../src/ui/dialog/inkscape-preferences.cpp:1246 msgid "" "Set the amount of memory per document which can be used to store rendered " "parts of the drawing for later reuse; set to zero to disable caching" @@ -17698,281 +17914,281 @@ msgstr "" #. blur quality #. filter quality -#: ../src/ui/dialog/inkscape-preferences.cpp:1240 -#: ../src/ui/dialog/inkscape-preferences.cpp:1264 +#: ../src/ui/dialog/inkscape-preferences.cpp:1249 +#: ../src/ui/dialog/inkscape-preferences.cpp:1273 msgid "Best quality (slowest)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1242 -#: ../src/ui/dialog/inkscape-preferences.cpp:1266 +#: ../src/ui/dialog/inkscape-preferences.cpp:1251 +#: ../src/ui/dialog/inkscape-preferences.cpp:1275 msgid "Better quality (slower)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1244 -#: ../src/ui/dialog/inkscape-preferences.cpp:1268 +#: ../src/ui/dialog/inkscape-preferences.cpp:1253 +#: ../src/ui/dialog/inkscape-preferences.cpp:1277 msgid "Average quality" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1246 -#: ../src/ui/dialog/inkscape-preferences.cpp:1270 +#: ../src/ui/dialog/inkscape-preferences.cpp:1255 +#: ../src/ui/dialog/inkscape-preferences.cpp:1279 msgid "Lower quality (faster)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1248 -#: ../src/ui/dialog/inkscape-preferences.cpp:1272 +#: ../src/ui/dialog/inkscape-preferences.cpp:1257 +#: ../src/ui/dialog/inkscape-preferences.cpp:1281 msgid "Lowest quality (fastest)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1251 +#: ../src/ui/dialog/inkscape-preferences.cpp:1260 msgid "Gaussian blur quality for display" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1253 -#: ../src/ui/dialog/inkscape-preferences.cpp:1277 +#: ../src/ui/dialog/inkscape-preferences.cpp:1262 +#: ../src/ui/dialog/inkscape-preferences.cpp:1286 msgid "" "Best quality, but display may be very slow at high zooms (bitmap export " "always uses best quality)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1255 -#: ../src/ui/dialog/inkscape-preferences.cpp:1279 +#: ../src/ui/dialog/inkscape-preferences.cpp:1264 +#: ../src/ui/dialog/inkscape-preferences.cpp:1288 msgid "Better quality, but slower display" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1257 -#: ../src/ui/dialog/inkscape-preferences.cpp:1281 +#: ../src/ui/dialog/inkscape-preferences.cpp:1266 +#: ../src/ui/dialog/inkscape-preferences.cpp:1290 msgid "Average quality, acceptable display speed" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1259 -#: ../src/ui/dialog/inkscape-preferences.cpp:1283 +#: ../src/ui/dialog/inkscape-preferences.cpp:1268 +#: ../src/ui/dialog/inkscape-preferences.cpp:1292 msgid "Lower quality (some artifacts), but display is faster" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1261 -#: ../src/ui/dialog/inkscape-preferences.cpp:1285 +#: ../src/ui/dialog/inkscape-preferences.cpp:1270 +#: ../src/ui/dialog/inkscape-preferences.cpp:1294 msgid "Lowest quality (considerable artifacts), but display is fastest" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1275 +#: ../src/ui/dialog/inkscape-preferences.cpp:1284 msgid "Filter effects quality for display" msgstr "" #. build custom preferences tab -#: ../src/ui/dialog/inkscape-preferences.cpp:1287 +#: ../src/ui/dialog/inkscape-preferences.cpp:1296 #: ../src/ui/dialog/print.cpp:224 msgid "Rendering" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1293 +#: ../src/ui/dialog/inkscape-preferences.cpp:1302 msgid "2x2" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1293 +#: ../src/ui/dialog/inkscape-preferences.cpp:1302 msgid "4x4" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1293 +#: ../src/ui/dialog/inkscape-preferences.cpp:1302 msgid "8x8" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1293 +#: ../src/ui/dialog/inkscape-preferences.cpp:1302 msgid "16x16" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1297 +#: ../src/ui/dialog/inkscape-preferences.cpp:1306 msgid "Oversample bitmaps:" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1300 +#: ../src/ui/dialog/inkscape-preferences.cpp:1309 msgid "Automatically reload bitmaps" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1302 +#: ../src/ui/dialog/inkscape-preferences.cpp:1311 msgid "Automatically reload linked images when file is changed on disk" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1304 +#: ../src/ui/dialog/inkscape-preferences.cpp:1313 msgid "Bitmap editor:" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1306 +#: ../src/ui/dialog/inkscape-preferences.cpp:1315 msgid "Default export resolution:" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1307 +#: ../src/ui/dialog/inkscape-preferences.cpp:1316 msgid "Default bitmap resolution (in dots per inch) in the Export dialog" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1309 +#: ../src/ui/dialog/inkscape-preferences.cpp:1318 msgid "Resolution for Create Bitmap Copy:" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1310 +#: ../src/ui/dialog/inkscape-preferences.cpp:1319 msgid "Resolution used by the Create Bitmap Copy command" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1312 +#: ../src/ui/dialog/inkscape-preferences.cpp:1321 msgid "Always embed" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1312 +#: ../src/ui/dialog/inkscape-preferences.cpp:1321 msgid "Always link" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1312 +#: ../src/ui/dialog/inkscape-preferences.cpp:1321 msgid "Ask" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1315 +#: ../src/ui/dialog/inkscape-preferences.cpp:1324 msgid "Bitmap import:" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1319 +#: ../src/ui/dialog/inkscape-preferences.cpp:1327 msgid "Bitmaps" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1372 +#: ../src/ui/dialog/inkscape-preferences.cpp:1380 msgid "Set the main spell check language" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1375 +#: ../src/ui/dialog/inkscape-preferences.cpp:1383 msgid "Second language:" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1376 +#: ../src/ui/dialog/inkscape-preferences.cpp:1384 msgid "" "Set the second spell check language; checking will only stop on words " "unknown in ALL chosen languages" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1379 +#: ../src/ui/dialog/inkscape-preferences.cpp:1387 msgid "Third language:" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1380 +#: ../src/ui/dialog/inkscape-preferences.cpp:1388 msgid "" "Set the third spell check language; checking will only stop on words unknown " "in ALL chosen languages" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1382 +#: ../src/ui/dialog/inkscape-preferences.cpp:1390 msgid "Ignore words with digits" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1384 +#: ../src/ui/dialog/inkscape-preferences.cpp:1392 msgid "Ignore words containing digits, such as \"R2D2\"" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1386 +#: ../src/ui/dialog/inkscape-preferences.cpp:1394 msgid "Ignore words in ALL CAPITALS" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1388 +#: ../src/ui/dialog/inkscape-preferences.cpp:1396 msgid "Ignore words in all capitals, such as \"IUPAC\"" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1390 +#: ../src/ui/dialog/inkscape-preferences.cpp:1398 msgid "Spellcheck" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1410 +#: ../src/ui/dialog/inkscape-preferences.cpp:1418 msgid "Latency skew:" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1411 +#: ../src/ui/dialog/inkscape-preferences.cpp:1419 msgid "" "Factor by which the event clock is skewed from the actual time (0.9766 on " "some systems)" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1413 +#: ../src/ui/dialog/inkscape-preferences.cpp:1421 msgid "Pre-render named icons" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1415 +#: ../src/ui/dialog/inkscape-preferences.cpp:1423 msgid "" "When on, named icons will be rendered before displaying the ui. This is for " "working around bugs in GTK+ named icon notification" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1423 +#: ../src/ui/dialog/inkscape-preferences.cpp:1431 msgid "System info" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1427 +#: ../src/ui/dialog/inkscape-preferences.cpp:1435 msgid "User config: " msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1427 +#: ../src/ui/dialog/inkscape-preferences.cpp:1435 msgid "Location of users configuration" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1431 +#: ../src/ui/dialog/inkscape-preferences.cpp:1439 msgid "User preferences: " msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1431 +#: ../src/ui/dialog/inkscape-preferences.cpp:1439 msgid "Location of the users preferences file" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1435 +#: ../src/ui/dialog/inkscape-preferences.cpp:1443 msgid "User extensions: " msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1435 +#: ../src/ui/dialog/inkscape-preferences.cpp:1443 msgid "Location of the users extensions" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1439 +#: ../src/ui/dialog/inkscape-preferences.cpp:1447 msgid "User cache: " msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1439 +#: ../src/ui/dialog/inkscape-preferences.cpp:1447 msgid "Location of users cache" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1447 +#: ../src/ui/dialog/inkscape-preferences.cpp:1455 msgid "Temporary files: " msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1447 +#: ../src/ui/dialog/inkscape-preferences.cpp:1455 msgid "Location of the temporary files used for autosave" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1451 +#: ../src/ui/dialog/inkscape-preferences.cpp:1459 msgid "Inkscape data: " msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1451 +#: ../src/ui/dialog/inkscape-preferences.cpp:1459 msgid "Location of Inkscape data" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1455 +#: ../src/ui/dialog/inkscape-preferences.cpp:1463 msgid "Inkscape extensions: " msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1455 +#: ../src/ui/dialog/inkscape-preferences.cpp:1463 msgid "Location of the Inkscape extensions" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1464 +#: ../src/ui/dialog/inkscape-preferences.cpp:1472 msgid "System data: " msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1464 +#: ../src/ui/dialog/inkscape-preferences.cpp:1472 msgid "Locations of system data" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1488 +#: ../src/ui/dialog/inkscape-preferences.cpp:1496 msgid "Icon theme: " msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1488 +#: ../src/ui/dialog/inkscape-preferences.cpp:1496 msgid "Location of icon themes" msgstr "" -#: ../src/ui/dialog/inkscape-preferences.cpp:1490 +#: ../src/ui/dialog/inkscape-preferences.cpp:1498 #: ../src/widgets/sp-color-gtkselector.cpp:50 msgid "System" msgstr "" @@ -18030,7 +18246,7 @@ msgstr "" msgid "_Use pressure-sensitive tablet (requires restart)" msgstr "" -#: ../src/ui/dialog/input.cpp:888 ../src/verbs.cpp:2192 +#: ../src/ui/dialog/input.cpp:888 ../src/verbs.cpp:2191 msgid "_Save" msgstr "" @@ -18073,7 +18289,7 @@ msgid "Rename layer" msgstr "" #. TRANSLATORS: This means "The layer has been renamed" -#: ../src/ui/dialog/layer-properties.cpp:199 +#: ../src/ui/dialog/layer-properties.cpp:199 ../src/ui/dialog/layers.cpp:533 msgid "Renamed layer" msgstr "" @@ -18105,32 +18321,32 @@ msgstr "" msgid "Unlock layer" msgstr "" -#: ../src/ui/dialog/layers.cpp:648 +#: ../src/ui/dialog/layers.cpp:650 msgctxt "Layers" msgid "New" msgstr "" -#: ../src/ui/dialog/layers.cpp:654 +#: ../src/ui/dialog/layers.cpp:656 msgctxt "Layers" msgid "Top" msgstr "" -#: ../src/ui/dialog/layers.cpp:660 +#: ../src/ui/dialog/layers.cpp:662 msgctxt "Layers" msgid "Up" msgstr "" -#: ../src/ui/dialog/layers.cpp:666 +#: ../src/ui/dialog/layers.cpp:668 msgctxt "Layers" msgid "Dn" msgstr "" -#: ../src/ui/dialog/layers.cpp:672 +#: ../src/ui/dialog/layers.cpp:674 msgctxt "Layers" msgid "Bot" msgstr "" -#: ../src/ui/dialog/layers.cpp:682 +#: ../src/ui/dialog/layers.cpp:684 msgid "X" msgstr "" @@ -18292,8 +18508,8 @@ msgstr "" msgid "L_ock" msgstr "" -#: ../src/ui/dialog/object-properties.cpp:50 ../src/verbs.cpp:2433 -#: ../src/verbs.cpp:2439 +#: ../src/ui/dialog/object-properties.cpp:50 ../src/verbs.cpp:2432 +#: ../src/verbs.cpp:2438 msgid "_Set" msgstr "" @@ -18372,57 +18588,57 @@ msgstr "" msgid "Clipart found" msgstr "" -#: ../src/ui/dialog/ocaldialogs.cpp:675 +#: ../src/ui/dialog/ocaldialogs.cpp:673 msgid "Downloading image..." msgstr "" -#: ../src/ui/dialog/ocaldialogs.cpp:824 +#: ../src/ui/dialog/ocaldialogs.cpp:821 msgid "Could not download image" msgstr "" -#: ../src/ui/dialog/ocaldialogs.cpp:834 +#: ../src/ui/dialog/ocaldialogs.cpp:831 msgid "Clipart downloaded successfully" msgstr "" -#: ../src/ui/dialog/ocaldialogs.cpp:848 +#: ../src/ui/dialog/ocaldialogs.cpp:845 msgid "Could not download thumbnail file" msgstr "" -#: ../src/ui/dialog/ocaldialogs.cpp:925 +#: ../src/ui/dialog/ocaldialogs.cpp:922 msgid "No description" msgstr "" -#: ../src/ui/dialog/ocaldialogs.cpp:993 +#: ../src/ui/dialog/ocaldialogs.cpp:990 msgid "Searching clipart..." msgstr "" -#: ../src/ui/dialog/ocaldialogs.cpp:1029 +#: ../src/ui/dialog/ocaldialogs.cpp:1026 msgid "Could not connect to the Open Clip Art Library" msgstr "" -#: ../src/ui/dialog/ocaldialogs.cpp:1048 +#: ../src/ui/dialog/ocaldialogs.cpp:1045 msgid "Could not parse search results" msgstr "" -#: ../src/ui/dialog/ocaldialogs.cpp:1084 +#: ../src/ui/dialog/ocaldialogs.cpp:1081 msgid "No clipart named" msgstr "" -#: ../src/ui/dialog/ocaldialogs.cpp:1084 +#: ../src/ui/dialog/ocaldialogs.cpp:1081 msgid "was found." msgstr "" -#: ../src/ui/dialog/ocaldialogs.cpp:1085 +#: ../src/ui/dialog/ocaldialogs.cpp:1082 msgid "" "Please make sure all keywords are spelled correctly, or try again with " "different keywords." msgstr "" -#: ../src/ui/dialog/ocaldialogs.cpp:1113 +#: ../src/ui/dialog/ocaldialogs.cpp:1110 msgid "Search" msgstr "" -#: ../src/ui/dialog/ocaldialogs.cpp:1119 +#: ../src/ui/dialog/ocaldialogs.cpp:1116 msgid "Close" msgstr "" @@ -18548,7 +18764,7 @@ msgid "From selection..." msgstr "" #: ../src/ui/dialog/svg-fonts-dialog.cpp:701 -#: ../src/ui/widget/preferences-widget.cpp:654 +#: ../src/ui/widget/preferences-widget.cpp:658 msgid "Reset" msgstr "" @@ -18646,7 +18862,7 @@ msgid "Set stroke" msgstr "" #: ../src/ui/dialog/swatches.cpp:281 ../src/widgets/gradient-selector.cpp:146 -#: ../src/widgets/gradient-toolbar.cpp:483 +#: ../src/widgets/gradient-toolbar.cpp:486 msgid "Edit..." msgstr "" @@ -19577,7 +19793,6 @@ msgid "Rotation center: drag to change the origin of transforms" msgstr "" #: ../src/ui/widget/filter-effect-chooser.cpp:27 -#: ../src/ui/widget/filter-effect-chooser.cpp:29 msgid "_Blur:" msgstr "" @@ -19605,15 +19820,11 @@ msgstr "" msgid "MetadataLicence|Other" msgstr "" -#: ../src/ui/widget/object-composite-settings.cpp:66 -msgid "_Opacity (%):" -msgstr "" - -#: ../src/ui/widget/object-composite-settings.cpp:176 +#: ../src/ui/widget/object-composite-settings.cpp:187 msgid "Change blur" msgstr "" -#: ../src/ui/widget/object-composite-settings.cpp:216 +#: ../src/ui/widget/object-composite-settings.cpp:227 #: ../src/ui/widget/selected-style.cpp:863 #: ../src/ui/widget/selected-style.cpp:1157 msgid "Change opacity" @@ -19772,7 +19983,7 @@ msgctxt "Swatches" msgid "Wrap" msgstr "" -#: ../src/ui/widget/preferences-widget.cpp:788 +#: ../src/ui/widget/preferences-widget.cpp:792 msgid "Select a bitmap editor" msgstr "" @@ -19832,6 +20043,7 @@ msgstr "" #: ../src/ui/widget/selected-style.cpp:165 #: ../src/ui/widget/selected-style.cpp:1032 #: ../src/ui/widget/selected-style.cpp:1033 +#: ../src/widgets/gradient-toolbar.cpp:215 msgid "Nothing selected" msgstr "" @@ -19852,7 +20064,6 @@ msgstr "" #: ../src/ui/widget/selected-style.cpp:175 #: ../src/ui/widget/style-swatch.cpp:284 -#: ../src/widgets/paint-selector.cpp:1019 msgid "Pattern fill" msgstr "" @@ -20312,1593 +20523,1593 @@ msgstr "" #. TRANSLATORS: If you have translated the tutorial-basic.en.svgz file to your language, #. then translate this string as "tutorial-basic.LANG.svgz" (where LANG is your language #. code); otherwise leave as "tutorial-basic.svg". -#: ../src/verbs.cpp:1940 +#: ../src/verbs.cpp:1939 msgid "tutorial-basic.svg" msgstr "" #. TRANSLATORS: See "tutorial-basic.svg" comment. -#: ../src/verbs.cpp:1944 +#: ../src/verbs.cpp:1943 msgid "tutorial-shapes.svg" msgstr "" #. TRANSLATORS: See "tutorial-basic.svg" comment. -#: ../src/verbs.cpp:1948 +#: ../src/verbs.cpp:1947 msgid "tutorial-advanced.svg" msgstr "" #. TRANSLATORS: See "tutorial-basic.svg" comment. -#: ../src/verbs.cpp:1952 +#: ../src/verbs.cpp:1951 msgid "tutorial-tracing.svg" msgstr "" #. TRANSLATORS: See "tutorial-basic.svg" comment. -#: ../src/verbs.cpp:1956 +#: ../src/verbs.cpp:1955 msgid "tutorial-calligraphy.svg" msgstr "" #. TRANSLATORS: See "tutorial-basic.svg" comment. -#: ../src/verbs.cpp:1960 +#: ../src/verbs.cpp:1959 msgid "tutorial-interpolate.svg" msgstr "" #. TRANSLATORS: See "tutorial-basic.svg" comment. -#: ../src/verbs.cpp:1964 +#: ../src/verbs.cpp:1963 msgid "tutorial-elements.svg" msgstr "" #. TRANSLATORS: See "tutorial-basic.svg" comment. -#: ../src/verbs.cpp:1968 +#: ../src/verbs.cpp:1967 msgid "tutorial-tips.svg" msgstr "" -#: ../src/verbs.cpp:2156 ../src/verbs.cpp:2704 +#: ../src/verbs.cpp:2155 ../src/verbs.cpp:2703 msgid "Unlock all objects in the current layer" msgstr "" -#: ../src/verbs.cpp:2160 ../src/verbs.cpp:2706 +#: ../src/verbs.cpp:2159 ../src/verbs.cpp:2705 msgid "Unlock all objects in all layers" msgstr "" -#: ../src/verbs.cpp:2164 ../src/verbs.cpp:2708 +#: ../src/verbs.cpp:2163 ../src/verbs.cpp:2707 msgid "Unhide all objects in the current layer" msgstr "" -#: ../src/verbs.cpp:2168 ../src/verbs.cpp:2710 +#: ../src/verbs.cpp:2167 ../src/verbs.cpp:2709 msgid "Unhide all objects in all layers" msgstr "" -#: ../src/verbs.cpp:2183 +#: ../src/verbs.cpp:2182 msgid "Does nothing" msgstr "" -#: ../src/verbs.cpp:2186 +#: ../src/verbs.cpp:2185 msgid "Create new document from the default template" msgstr "" -#: ../src/verbs.cpp:2188 +#: ../src/verbs.cpp:2187 msgid "_Open..." msgstr "" -#: ../src/verbs.cpp:2189 +#: ../src/verbs.cpp:2188 msgid "Open an existing document" msgstr "" -#: ../src/verbs.cpp:2190 +#: ../src/verbs.cpp:2189 msgid "Re_vert" msgstr "" -#: ../src/verbs.cpp:2191 +#: ../src/verbs.cpp:2190 msgid "Revert to the last saved version of document (changes will be lost)" msgstr "" -#: ../src/verbs.cpp:2192 +#: ../src/verbs.cpp:2191 msgid "Save document" msgstr "" -#: ../src/verbs.cpp:2194 +#: ../src/verbs.cpp:2193 msgid "Save _As..." msgstr "" -#: ../src/verbs.cpp:2195 +#: ../src/verbs.cpp:2194 msgid "Save document under a new name" msgstr "" -#: ../src/verbs.cpp:2196 +#: ../src/verbs.cpp:2195 msgid "Save a Cop_y..." msgstr "" -#: ../src/verbs.cpp:2197 +#: ../src/verbs.cpp:2196 msgid "Save a copy of the document under a new name" msgstr "" -#: ../src/verbs.cpp:2198 +#: ../src/verbs.cpp:2197 msgid "_Print..." msgstr "" -#: ../src/verbs.cpp:2198 +#: ../src/verbs.cpp:2197 msgid "Print document" msgstr "" #. TRANSLATORS: "Vacuum Defs" means "Clean up defs" (so as to remove unused definitions) -#: ../src/verbs.cpp:2201 +#: ../src/verbs.cpp:2200 msgid "Vac_uum Defs" msgstr "" -#: ../src/verbs.cpp:2201 +#: ../src/verbs.cpp:2200 msgid "" "Remove unused definitions (such as gradients or clipping paths) from the <" "defs> of the document" msgstr "" -#: ../src/verbs.cpp:2203 +#: ../src/verbs.cpp:2202 msgid "_Import..." msgstr "" -#: ../src/verbs.cpp:2204 +#: ../src/verbs.cpp:2203 msgid "Import a bitmap or SVG image into this document" msgstr "" -#: ../src/verbs.cpp:2205 ../src/verbs.cpp:2657 +#: ../src/verbs.cpp:2204 ../src/verbs.cpp:2656 msgid "_Export Bitmap..." msgstr "" -#: ../src/verbs.cpp:2206 ../src/verbs.cpp:2658 +#: ../src/verbs.cpp:2205 ../src/verbs.cpp:2657 msgid "Export this document or a selection as a bitmap image" msgstr "" -#: ../src/verbs.cpp:2207 +#: ../src/verbs.cpp:2206 msgid "Import Clip Art..." msgstr "" -#: ../src/verbs.cpp:2208 +#: ../src/verbs.cpp:2207 msgid "Import clipart from Open Clip Art Library" msgstr "" #. new FileVerb(SP_VERB_FILE_EXPORT_TO_OCAL, "FileExportToOCAL", N_("Export To Open Clip Art Library"), N_("Export this document to Open Clip Art Library"), INKSCAPE_ICON_DOCUMENT_EXPORT_OCAL), -#: ../src/verbs.cpp:2210 +#: ../src/verbs.cpp:2209 msgid "N_ext Window" msgstr "" -#: ../src/verbs.cpp:2211 +#: ../src/verbs.cpp:2210 msgid "Switch to the next document window" msgstr "" -#: ../src/verbs.cpp:2212 +#: ../src/verbs.cpp:2211 msgid "P_revious Window" msgstr "" -#: ../src/verbs.cpp:2213 +#: ../src/verbs.cpp:2212 msgid "Switch to the previous document window" msgstr "" -#: ../src/verbs.cpp:2214 +#: ../src/verbs.cpp:2213 msgid "_Close" msgstr "" -#: ../src/verbs.cpp:2215 +#: ../src/verbs.cpp:2214 msgid "Close this document window" msgstr "" -#: ../src/verbs.cpp:2216 +#: ../src/verbs.cpp:2215 msgid "_Quit" msgstr "" -#: ../src/verbs.cpp:2216 +#: ../src/verbs.cpp:2215 msgid "Quit Inkscape" msgstr "" -#: ../src/verbs.cpp:2219 +#: ../src/verbs.cpp:2218 msgid "Undo last action" msgstr "" -#: ../src/verbs.cpp:2222 +#: ../src/verbs.cpp:2221 msgid "Do again the last undone action" msgstr "" -#: ../src/verbs.cpp:2223 +#: ../src/verbs.cpp:2222 msgid "Cu_t" msgstr "" -#: ../src/verbs.cpp:2224 +#: ../src/verbs.cpp:2223 msgid "Cut selection to clipboard" msgstr "" -#: ../src/verbs.cpp:2225 +#: ../src/verbs.cpp:2224 msgid "_Copy" msgstr "" -#: ../src/verbs.cpp:2226 +#: ../src/verbs.cpp:2225 msgid "Copy selection to clipboard" msgstr "" -#: ../src/verbs.cpp:2227 +#: ../src/verbs.cpp:2226 msgid "_Paste" msgstr "" -#: ../src/verbs.cpp:2228 +#: ../src/verbs.cpp:2227 msgid "Paste objects from clipboard to mouse point, or paste text" msgstr "" -#: ../src/verbs.cpp:2229 +#: ../src/verbs.cpp:2228 msgid "Paste _Style" msgstr "" -#: ../src/verbs.cpp:2230 +#: ../src/verbs.cpp:2229 msgid "Apply the style of the copied object to selection" msgstr "" -#: ../src/verbs.cpp:2232 +#: ../src/verbs.cpp:2231 msgid "Scale selection to match the size of the copied object" msgstr "" -#: ../src/verbs.cpp:2233 +#: ../src/verbs.cpp:2232 msgid "Paste _Width" msgstr "" -#: ../src/verbs.cpp:2234 +#: ../src/verbs.cpp:2233 msgid "Scale selection horizontally to match the width of the copied object" msgstr "" -#: ../src/verbs.cpp:2235 +#: ../src/verbs.cpp:2234 msgid "Paste _Height" msgstr "" -#: ../src/verbs.cpp:2236 +#: ../src/verbs.cpp:2235 msgid "Scale selection vertically to match the height of the copied object" msgstr "" -#: ../src/verbs.cpp:2237 +#: ../src/verbs.cpp:2236 msgid "Paste Size Separately" msgstr "" -#: ../src/verbs.cpp:2238 +#: ../src/verbs.cpp:2237 msgid "Scale each selected object to match the size of the copied object" msgstr "" -#: ../src/verbs.cpp:2239 +#: ../src/verbs.cpp:2238 msgid "Paste Width Separately" msgstr "" -#: ../src/verbs.cpp:2240 +#: ../src/verbs.cpp:2239 msgid "" "Scale each selected object horizontally to match the width of the copied " "object" msgstr "" -#: ../src/verbs.cpp:2241 +#: ../src/verbs.cpp:2240 msgid "Paste Height Separately" msgstr "" -#: ../src/verbs.cpp:2242 +#: ../src/verbs.cpp:2241 msgid "" "Scale each selected object vertically to match the height of the copied " "object" msgstr "" -#: ../src/verbs.cpp:2243 +#: ../src/verbs.cpp:2242 msgid "Paste _In Place" msgstr "" -#: ../src/verbs.cpp:2244 +#: ../src/verbs.cpp:2243 msgid "Paste objects from clipboard to the original location" msgstr "" -#: ../src/verbs.cpp:2245 +#: ../src/verbs.cpp:2244 msgid "Paste Path _Effect" msgstr "" -#: ../src/verbs.cpp:2246 +#: ../src/verbs.cpp:2245 msgid "Apply the path effect of the copied object to selection" msgstr "" -#: ../src/verbs.cpp:2247 +#: ../src/verbs.cpp:2246 msgid "Remove Path _Effect" msgstr "" -#: ../src/verbs.cpp:2248 +#: ../src/verbs.cpp:2247 msgid "Remove any path effects from selected objects" msgstr "" -#: ../src/verbs.cpp:2249 +#: ../src/verbs.cpp:2248 msgid "_Remove Filters" msgstr "" -#: ../src/verbs.cpp:2250 +#: ../src/verbs.cpp:2249 msgid "Remove any filters from selected objects" msgstr "" -#: ../src/verbs.cpp:2251 +#: ../src/verbs.cpp:2250 msgid "_Delete" msgstr "" -#: ../src/verbs.cpp:2252 +#: ../src/verbs.cpp:2251 msgid "Delete selection" msgstr "" -#: ../src/verbs.cpp:2253 +#: ../src/verbs.cpp:2252 msgid "Duplic_ate" msgstr "" -#: ../src/verbs.cpp:2254 +#: ../src/verbs.cpp:2253 msgid "Duplicate selected objects" msgstr "" -#: ../src/verbs.cpp:2255 +#: ../src/verbs.cpp:2254 msgid "Create Clo_ne" msgstr "" -#: ../src/verbs.cpp:2256 +#: ../src/verbs.cpp:2255 msgid "Create a clone (a copy linked to the original) of selected object" msgstr "" -#: ../src/verbs.cpp:2257 +#: ../src/verbs.cpp:2256 msgid "Unlin_k Clone" msgstr "" -#: ../src/verbs.cpp:2258 +#: ../src/verbs.cpp:2257 msgid "" "Cut the selected clones' links to the originals, turning them into " "standalone objects" msgstr "" -#: ../src/verbs.cpp:2259 +#: ../src/verbs.cpp:2258 msgid "Relink to Copied" msgstr "" -#: ../src/verbs.cpp:2260 +#: ../src/verbs.cpp:2259 msgid "Relink the selected clones to the object currently on the clipboard" msgstr "" -#: ../src/verbs.cpp:2261 +#: ../src/verbs.cpp:2260 msgid "Select _Original" msgstr "" -#: ../src/verbs.cpp:2262 +#: ../src/verbs.cpp:2261 msgid "Select the object to which the selected clone is linked" msgstr "" -#: ../src/verbs.cpp:2263 +#: ../src/verbs.cpp:2262 msgid "Clone original path (LPE)" msgstr "" -#: ../src/verbs.cpp:2264 +#: ../src/verbs.cpp:2263 msgid "" "Creates a new path, applies the Clone original LPE, and refers it to the " "selected path" msgstr "" -#: ../src/verbs.cpp:2265 +#: ../src/verbs.cpp:2264 msgid "Objects to _Marker" msgstr "" -#: ../src/verbs.cpp:2266 +#: ../src/verbs.cpp:2265 msgid "Convert selection to a line marker" msgstr "" -#: ../src/verbs.cpp:2267 +#: ../src/verbs.cpp:2266 msgid "Objects to Gu_ides" msgstr "" -#: ../src/verbs.cpp:2268 +#: ../src/verbs.cpp:2267 msgid "" "Convert selected objects to a collection of guidelines aligned with their " "edges" msgstr "" -#: ../src/verbs.cpp:2269 +#: ../src/verbs.cpp:2268 msgid "Objects to Patter_n" msgstr "" -#: ../src/verbs.cpp:2270 +#: ../src/verbs.cpp:2269 msgid "Convert selection to a rectangle with tiled pattern fill" msgstr "" -#: ../src/verbs.cpp:2271 +#: ../src/verbs.cpp:2270 msgid "Pattern to _Objects" msgstr "" -#: ../src/verbs.cpp:2272 +#: ../src/verbs.cpp:2271 msgid "Extract objects from a tiled pattern fill" msgstr "" -#: ../src/verbs.cpp:2273 +#: ../src/verbs.cpp:2272 msgid "Clea_r All" msgstr "" -#: ../src/verbs.cpp:2274 +#: ../src/verbs.cpp:2273 msgid "Delete all objects from document" msgstr "" -#: ../src/verbs.cpp:2275 +#: ../src/verbs.cpp:2274 msgid "Select Al_l" msgstr "" -#: ../src/verbs.cpp:2276 +#: ../src/verbs.cpp:2275 msgid "Select all objects or all nodes" msgstr "" -#: ../src/verbs.cpp:2277 +#: ../src/verbs.cpp:2276 msgid "Select All in All La_yers" msgstr "" -#: ../src/verbs.cpp:2278 +#: ../src/verbs.cpp:2277 msgid "Select all objects in all visible and unlocked layers" msgstr "" -#: ../src/verbs.cpp:2279 +#: ../src/verbs.cpp:2278 msgid "In_vert Selection" msgstr "" -#: ../src/verbs.cpp:2280 +#: ../src/verbs.cpp:2279 msgid "Invert selection (unselect what is selected and select everything else)" msgstr "" -#: ../src/verbs.cpp:2281 +#: ../src/verbs.cpp:2280 msgid "Invert in All Layers" msgstr "" -#: ../src/verbs.cpp:2282 +#: ../src/verbs.cpp:2281 msgid "Invert selection in all visible and unlocked layers" msgstr "" -#: ../src/verbs.cpp:2283 +#: ../src/verbs.cpp:2282 msgid "Select Next" msgstr "" -#: ../src/verbs.cpp:2284 +#: ../src/verbs.cpp:2283 msgid "Select next object or node" msgstr "" -#: ../src/verbs.cpp:2285 +#: ../src/verbs.cpp:2284 msgid "Select Previous" msgstr "" -#: ../src/verbs.cpp:2286 +#: ../src/verbs.cpp:2285 msgid "Select previous object or node" msgstr "" -#: ../src/verbs.cpp:2287 +#: ../src/verbs.cpp:2286 msgid "D_eselect" msgstr "" -#: ../src/verbs.cpp:2288 +#: ../src/verbs.cpp:2287 msgid "Deselect any selected objects or nodes" msgstr "" -#: ../src/verbs.cpp:2289 +#: ../src/verbs.cpp:2288 msgid "Create _Guides Around the Page" msgstr "" -#: ../src/verbs.cpp:2290 ../src/verbs.cpp:2292 +#: ../src/verbs.cpp:2289 ../src/verbs.cpp:2291 msgid "Create four guides aligned with the page borders" msgstr "" -#: ../src/verbs.cpp:2293 +#: ../src/verbs.cpp:2292 msgid "Next path effect parameter" msgstr "" -#: ../src/verbs.cpp:2294 +#: ../src/verbs.cpp:2293 msgid "Show next editable path effect parameter" msgstr "" #. Selection -#: ../src/verbs.cpp:2297 +#: ../src/verbs.cpp:2296 msgid "Raise to _Top" msgstr "" -#: ../src/verbs.cpp:2298 +#: ../src/verbs.cpp:2297 msgid "Raise selection to top" msgstr "" -#: ../src/verbs.cpp:2299 +#: ../src/verbs.cpp:2298 msgid "Lower to _Bottom" msgstr "" -#: ../src/verbs.cpp:2300 +#: ../src/verbs.cpp:2299 msgid "Lower selection to bottom" msgstr "" -#: ../src/verbs.cpp:2301 +#: ../src/verbs.cpp:2300 msgid "_Raise" msgstr "" -#: ../src/verbs.cpp:2302 +#: ../src/verbs.cpp:2301 msgid "Raise selection one step" msgstr "" -#: ../src/verbs.cpp:2303 +#: ../src/verbs.cpp:2302 msgid "_Lower" msgstr "" -#: ../src/verbs.cpp:2304 +#: ../src/verbs.cpp:2303 msgid "Lower selection one step" msgstr "" -#: ../src/verbs.cpp:2305 +#: ../src/verbs.cpp:2304 msgid "_Group" msgstr "" -#: ../src/verbs.cpp:2306 +#: ../src/verbs.cpp:2305 msgid "Group selected objects" msgstr "" -#: ../src/verbs.cpp:2308 +#: ../src/verbs.cpp:2307 msgid "Ungroup selected groups" msgstr "" -#: ../src/verbs.cpp:2310 +#: ../src/verbs.cpp:2309 msgid "_Put on Path" msgstr "" -#: ../src/verbs.cpp:2312 +#: ../src/verbs.cpp:2311 msgid "_Remove from Path" msgstr "" -#: ../src/verbs.cpp:2314 +#: ../src/verbs.cpp:2313 msgid "Remove Manual _Kerns" msgstr "" #. TRANSLATORS: "glyph": An image used in the visual representation of characters; #. roughly speaking, how a character looks. A font is a set of glyphs. -#: ../src/verbs.cpp:2317 +#: ../src/verbs.cpp:2316 msgid "Remove all manual kerns and glyph rotations from a text object" msgstr "" -#: ../src/verbs.cpp:2319 +#: ../src/verbs.cpp:2318 msgid "_Union" msgstr "" -#: ../src/verbs.cpp:2320 +#: ../src/verbs.cpp:2319 msgid "Create union of selected paths" msgstr "" -#: ../src/verbs.cpp:2321 +#: ../src/verbs.cpp:2320 msgid "_Intersection" msgstr "" -#: ../src/verbs.cpp:2322 +#: ../src/verbs.cpp:2321 msgid "Create intersection of selected paths" msgstr "" -#: ../src/verbs.cpp:2323 +#: ../src/verbs.cpp:2322 msgid "_Difference" msgstr "" -#: ../src/verbs.cpp:2324 +#: ../src/verbs.cpp:2323 msgid "Create difference of selected paths (bottom minus top)" msgstr "" -#: ../src/verbs.cpp:2325 +#: ../src/verbs.cpp:2324 msgid "E_xclusion" msgstr "" -#: ../src/verbs.cpp:2326 +#: ../src/verbs.cpp:2325 msgid "" "Create exclusive OR of selected paths (those parts that belong to only one " "path)" msgstr "" -#: ../src/verbs.cpp:2327 +#: ../src/verbs.cpp:2326 msgid "Di_vision" msgstr "" -#: ../src/verbs.cpp:2328 +#: ../src/verbs.cpp:2327 msgid "Cut the bottom path into pieces" msgstr "" #. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the #. Advanced tutorial for more info -#: ../src/verbs.cpp:2331 +#: ../src/verbs.cpp:2330 msgid "Cut _Path" msgstr "" -#: ../src/verbs.cpp:2332 +#: ../src/verbs.cpp:2331 msgid "Cut the bottom path's stroke into pieces, removing fill" msgstr "" #. TRANSLATORS: "outset": expand a shape by offsetting the object's path, #. i.e. by displacing it perpendicular to the path in each point. #. See also the Advanced Tutorial for explanation. -#: ../src/verbs.cpp:2336 +#: ../src/verbs.cpp:2335 msgid "Outs_et" msgstr "" -#: ../src/verbs.cpp:2337 +#: ../src/verbs.cpp:2336 msgid "Outset selected paths" msgstr "" -#: ../src/verbs.cpp:2339 +#: ../src/verbs.cpp:2338 msgid "O_utset Path by 1 px" msgstr "" -#: ../src/verbs.cpp:2340 +#: ../src/verbs.cpp:2339 msgid "Outset selected paths by 1 px" msgstr "" -#: ../src/verbs.cpp:2342 +#: ../src/verbs.cpp:2341 msgid "O_utset Path by 10 px" msgstr "" -#: ../src/verbs.cpp:2343 +#: ../src/verbs.cpp:2342 msgid "Outset selected paths by 10 px" msgstr "" #. TRANSLATORS: "inset": contract a shape by offsetting the object's path, #. i.e. by displacing it perpendicular to the path in each point. #. See also the Advanced Tutorial for explanation. -#: ../src/verbs.cpp:2347 +#: ../src/verbs.cpp:2346 msgid "I_nset" msgstr "" -#: ../src/verbs.cpp:2348 +#: ../src/verbs.cpp:2347 msgid "Inset selected paths" msgstr "" -#: ../src/verbs.cpp:2350 +#: ../src/verbs.cpp:2349 msgid "I_nset Path by 1 px" msgstr "" -#: ../src/verbs.cpp:2351 +#: ../src/verbs.cpp:2350 msgid "Inset selected paths by 1 px" msgstr "" -#: ../src/verbs.cpp:2353 +#: ../src/verbs.cpp:2352 msgid "I_nset Path by 10 px" msgstr "" -#: ../src/verbs.cpp:2354 +#: ../src/verbs.cpp:2353 msgid "Inset selected paths by 10 px" msgstr "" -#: ../src/verbs.cpp:2356 +#: ../src/verbs.cpp:2355 msgid "D_ynamic Offset" msgstr "" -#: ../src/verbs.cpp:2356 +#: ../src/verbs.cpp:2355 msgid "Create a dynamic offset object" msgstr "" -#: ../src/verbs.cpp:2358 +#: ../src/verbs.cpp:2357 msgid "_Linked Offset" msgstr "" -#: ../src/verbs.cpp:2359 +#: ../src/verbs.cpp:2358 msgid "Create a dynamic offset object linked to the original path" msgstr "" -#: ../src/verbs.cpp:2361 +#: ../src/verbs.cpp:2360 msgid "_Stroke to Path" msgstr "" -#: ../src/verbs.cpp:2362 +#: ../src/verbs.cpp:2361 msgid "Convert selected object's stroke to paths" msgstr "" -#: ../src/verbs.cpp:2363 +#: ../src/verbs.cpp:2362 msgid "Si_mplify" msgstr "" -#: ../src/verbs.cpp:2364 +#: ../src/verbs.cpp:2363 msgid "Simplify selected paths (remove extra nodes)" msgstr "" -#: ../src/verbs.cpp:2365 +#: ../src/verbs.cpp:2364 msgid "_Reverse" msgstr "" -#: ../src/verbs.cpp:2366 +#: ../src/verbs.cpp:2365 msgid "Reverse the direction of selected paths (useful for flipping markers)" msgstr "" #. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) -#: ../src/verbs.cpp:2368 +#: ../src/verbs.cpp:2367 msgid "_Trace Bitmap..." msgstr "" -#: ../src/verbs.cpp:2369 +#: ../src/verbs.cpp:2368 msgid "Create one or more paths from a bitmap by tracing it" msgstr "" -#: ../src/verbs.cpp:2370 +#: ../src/verbs.cpp:2369 msgid "_Make a Bitmap Copy" msgstr "" -#: ../src/verbs.cpp:2371 +#: ../src/verbs.cpp:2370 msgid "Export selection to a bitmap and insert it into document" msgstr "" -#: ../src/verbs.cpp:2372 +#: ../src/verbs.cpp:2371 msgid "_Combine" msgstr "" -#: ../src/verbs.cpp:2373 +#: ../src/verbs.cpp:2372 msgid "Combine several paths into one" msgstr "" #. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the #. Advanced tutorial for more info -#: ../src/verbs.cpp:2376 +#: ../src/verbs.cpp:2375 msgid "Break _Apart" msgstr "" -#: ../src/verbs.cpp:2377 +#: ../src/verbs.cpp:2376 msgid "Break selected paths into subpaths" msgstr "" -#: ../src/verbs.cpp:2378 +#: ../src/verbs.cpp:2377 msgid "Ro_ws and Columns..." msgstr "" -#: ../src/verbs.cpp:2379 +#: ../src/verbs.cpp:2378 msgid "Arrange selected objects in a table" msgstr "" #. Layer -#: ../src/verbs.cpp:2381 +#: ../src/verbs.cpp:2380 msgid "_Add Layer..." msgstr "" -#: ../src/verbs.cpp:2382 +#: ../src/verbs.cpp:2381 msgid "Create a new layer" msgstr "" -#: ../src/verbs.cpp:2383 +#: ../src/verbs.cpp:2382 msgid "Re_name Layer..." msgstr "" -#: ../src/verbs.cpp:2384 +#: ../src/verbs.cpp:2383 msgid "Rename the current layer" msgstr "" -#: ../src/verbs.cpp:2385 +#: ../src/verbs.cpp:2384 msgid "Switch to Layer Abov_e" msgstr "" -#: ../src/verbs.cpp:2386 +#: ../src/verbs.cpp:2385 msgid "Switch to the layer above the current" msgstr "" -#: ../src/verbs.cpp:2387 +#: ../src/verbs.cpp:2386 msgid "Switch to Layer Belo_w" msgstr "" -#: ../src/verbs.cpp:2388 +#: ../src/verbs.cpp:2387 msgid "Switch to the layer below the current" msgstr "" -#: ../src/verbs.cpp:2389 +#: ../src/verbs.cpp:2388 msgid "Move Selection to Layer Abo_ve" msgstr "" -#: ../src/verbs.cpp:2390 +#: ../src/verbs.cpp:2389 msgid "Move selection to the layer above the current" msgstr "" -#: ../src/verbs.cpp:2391 +#: ../src/verbs.cpp:2390 msgid "Move Selection to Layer Bel_ow" msgstr "" -#: ../src/verbs.cpp:2392 +#: ../src/verbs.cpp:2391 msgid "Move selection to the layer below the current" msgstr "" -#: ../src/verbs.cpp:2393 +#: ../src/verbs.cpp:2392 msgid "Layer to _Top" msgstr "" -#: ../src/verbs.cpp:2394 +#: ../src/verbs.cpp:2393 msgid "Raise the current layer to the top" msgstr "" -#: ../src/verbs.cpp:2395 +#: ../src/verbs.cpp:2394 msgid "Layer to _Bottom" msgstr "" -#: ../src/verbs.cpp:2396 +#: ../src/verbs.cpp:2395 msgid "Lower the current layer to the bottom" msgstr "" -#: ../src/verbs.cpp:2397 +#: ../src/verbs.cpp:2396 msgid "_Raise Layer" msgstr "" -#: ../src/verbs.cpp:2398 +#: ../src/verbs.cpp:2397 msgid "Raise the current layer" msgstr "" -#: ../src/verbs.cpp:2399 +#: ../src/verbs.cpp:2398 msgid "_Lower Layer" msgstr "" -#: ../src/verbs.cpp:2400 +#: ../src/verbs.cpp:2399 msgid "Lower the current layer" msgstr "" -#: ../src/verbs.cpp:2401 +#: ../src/verbs.cpp:2400 msgid "D_uplicate Current Layer" msgstr "" -#: ../src/verbs.cpp:2402 +#: ../src/verbs.cpp:2401 msgid "Duplicate an existing layer" msgstr "" -#: ../src/verbs.cpp:2403 +#: ../src/verbs.cpp:2402 msgid "_Delete Current Layer" msgstr "" -#: ../src/verbs.cpp:2404 +#: ../src/verbs.cpp:2403 msgid "Delete the current layer" msgstr "" -#: ../src/verbs.cpp:2405 +#: ../src/verbs.cpp:2404 msgid "_Show/hide other layers" msgstr "" -#: ../src/verbs.cpp:2406 +#: ../src/verbs.cpp:2405 msgid "Solo the current layer" msgstr "" #. Object -#: ../src/verbs.cpp:2409 +#: ../src/verbs.cpp:2408 msgid "Rotate _90° CW" msgstr "" #. This is shared between tooltips and statusbar, so they #. must use UTF-8, not HTML entities for special characters. -#: ../src/verbs.cpp:2412 +#: ../src/verbs.cpp:2411 msgid "Rotate selection 90° clockwise" msgstr "" -#: ../src/verbs.cpp:2413 +#: ../src/verbs.cpp:2412 msgid "Rotate 9_0° CCW" msgstr "" #. This is shared between tooltips and statusbar, so they #. must use UTF-8, not HTML entities for special characters. -#: ../src/verbs.cpp:2416 +#: ../src/verbs.cpp:2415 msgid "Rotate selection 90° counter-clockwise" msgstr "" -#: ../src/verbs.cpp:2417 +#: ../src/verbs.cpp:2416 msgid "Remove _Transformations" msgstr "" -#: ../src/verbs.cpp:2418 +#: ../src/verbs.cpp:2417 msgid "Remove transformations from object" msgstr "" -#: ../src/verbs.cpp:2419 +#: ../src/verbs.cpp:2418 msgid "_Object to Path" msgstr "" -#: ../src/verbs.cpp:2420 +#: ../src/verbs.cpp:2419 msgid "Convert selected object to path" msgstr "" -#: ../src/verbs.cpp:2421 +#: ../src/verbs.cpp:2420 msgid "_Flow into Frame" msgstr "" -#: ../src/verbs.cpp:2422 +#: ../src/verbs.cpp:2421 msgid "" "Put text into a frame (path or shape), creating a flowed text linked to the " "frame object" msgstr "" -#: ../src/verbs.cpp:2423 +#: ../src/verbs.cpp:2422 msgid "_Unflow" msgstr "" -#: ../src/verbs.cpp:2424 +#: ../src/verbs.cpp:2423 msgid "Remove text from frame (creates a single-line text object)" msgstr "" -#: ../src/verbs.cpp:2425 +#: ../src/verbs.cpp:2424 msgid "_Convert to Text" msgstr "" -#: ../src/verbs.cpp:2426 +#: ../src/verbs.cpp:2425 msgid "Convert flowed text to regular text object (preserves appearance)" msgstr "" -#: ../src/verbs.cpp:2428 +#: ../src/verbs.cpp:2427 msgid "Flip _Horizontal" msgstr "" -#: ../src/verbs.cpp:2428 +#: ../src/verbs.cpp:2427 msgid "Flip selected objects horizontally" msgstr "" -#: ../src/verbs.cpp:2431 +#: ../src/verbs.cpp:2430 msgid "Flip _Vertical" msgstr "" -#: ../src/verbs.cpp:2431 +#: ../src/verbs.cpp:2430 msgid "Flip selected objects vertically" msgstr "" -#: ../src/verbs.cpp:2434 +#: ../src/verbs.cpp:2433 msgid "Apply mask to selection (using the topmost object as mask)" msgstr "" -#: ../src/verbs.cpp:2436 +#: ../src/verbs.cpp:2435 msgid "Edit mask" msgstr "" -#: ../src/verbs.cpp:2437 ../src/verbs.cpp:2443 +#: ../src/verbs.cpp:2436 ../src/verbs.cpp:2442 msgid "_Release" msgstr "" -#: ../src/verbs.cpp:2438 +#: ../src/verbs.cpp:2437 msgid "Remove mask from selection" msgstr "" -#: ../src/verbs.cpp:2440 +#: ../src/verbs.cpp:2439 msgid "" "Apply clipping path to selection (using the topmost object as clipping path)" msgstr "" -#: ../src/verbs.cpp:2442 +#: ../src/verbs.cpp:2441 msgid "Edit clipping path" msgstr "" -#: ../src/verbs.cpp:2444 +#: ../src/verbs.cpp:2443 msgid "Remove clipping path from selection" msgstr "" #. Tools -#: ../src/verbs.cpp:2447 +#: ../src/verbs.cpp:2446 msgid "Select" msgstr "" -#: ../src/verbs.cpp:2448 +#: ../src/verbs.cpp:2447 msgid "Select and transform objects" msgstr "" -#: ../src/verbs.cpp:2449 +#: ../src/verbs.cpp:2448 msgid "Node Edit" msgstr "" -#: ../src/verbs.cpp:2450 +#: ../src/verbs.cpp:2449 msgid "Edit paths by nodes" msgstr "" -#: ../src/verbs.cpp:2452 +#: ../src/verbs.cpp:2451 msgid "Tweak objects by sculpting or painting" msgstr "" -#: ../src/verbs.cpp:2454 +#: ../src/verbs.cpp:2453 msgid "Spray objects by sculpting or painting" msgstr "" -#: ../src/verbs.cpp:2456 +#: ../src/verbs.cpp:2455 msgid "Create rectangles and squares" msgstr "" -#: ../src/verbs.cpp:2458 +#: ../src/verbs.cpp:2457 msgid "Create 3D boxes" msgstr "" -#: ../src/verbs.cpp:2460 +#: ../src/verbs.cpp:2459 msgid "Create circles, ellipses, and arcs" msgstr "" -#: ../src/verbs.cpp:2462 +#: ../src/verbs.cpp:2461 msgid "Create stars and polygons" msgstr "" -#: ../src/verbs.cpp:2464 +#: ../src/verbs.cpp:2463 msgid "Create spirals" msgstr "" -#: ../src/verbs.cpp:2466 +#: ../src/verbs.cpp:2465 msgid "Draw freehand lines" msgstr "" -#: ../src/verbs.cpp:2468 +#: ../src/verbs.cpp:2467 msgid "Draw Bezier curves and straight lines" msgstr "" -#: ../src/verbs.cpp:2470 +#: ../src/verbs.cpp:2469 msgid "Draw calligraphic or brush strokes" msgstr "" -#: ../src/verbs.cpp:2472 +#: ../src/verbs.cpp:2471 msgid "Create and edit text objects" msgstr "" -#: ../src/verbs.cpp:2474 +#: ../src/verbs.cpp:2473 msgid "Create and edit gradients" msgstr "" -#: ../src/verbs.cpp:2476 +#: ../src/verbs.cpp:2475 msgid "Zoom in or out" msgstr "" -#: ../src/verbs.cpp:2478 +#: ../src/verbs.cpp:2477 msgid "Measurement tool" msgstr "" -#: ../src/verbs.cpp:2480 +#: ../src/verbs.cpp:2479 msgid "Pick colors from image" msgstr "" -#: ../src/verbs.cpp:2482 +#: ../src/verbs.cpp:2481 msgid "Create diagram connectors" msgstr "" -#: ../src/verbs.cpp:2484 +#: ../src/verbs.cpp:2483 msgid "Fill bounded areas" msgstr "" -#: ../src/verbs.cpp:2485 +#: ../src/verbs.cpp:2484 msgid "LPE Edit" msgstr "" -#: ../src/verbs.cpp:2486 +#: ../src/verbs.cpp:2485 msgid "Edit Path Effect parameters" msgstr "" -#: ../src/verbs.cpp:2488 +#: ../src/verbs.cpp:2487 msgid "Erase existing paths" msgstr "" -#: ../src/verbs.cpp:2489 +#: ../src/verbs.cpp:2488 msgid "LPE Tool" msgstr "" -#: ../src/verbs.cpp:2490 +#: ../src/verbs.cpp:2489 msgid "Do geometric constructions" msgstr "" #. Tool prefs -#: ../src/verbs.cpp:2492 +#: ../src/verbs.cpp:2491 msgid "Selector Preferences" msgstr "" -#: ../src/verbs.cpp:2493 +#: ../src/verbs.cpp:2492 msgid "Open Preferences for the Selector tool" msgstr "" -#: ../src/verbs.cpp:2494 +#: ../src/verbs.cpp:2493 msgid "Node Tool Preferences" msgstr "" -#: ../src/verbs.cpp:2495 +#: ../src/verbs.cpp:2494 msgid "Open Preferences for the Node tool" msgstr "" -#: ../src/verbs.cpp:2496 +#: ../src/verbs.cpp:2495 msgid "Tweak Tool Preferences" msgstr "" -#: ../src/verbs.cpp:2497 +#: ../src/verbs.cpp:2496 msgid "Open Preferences for the Tweak tool" msgstr "" -#: ../src/verbs.cpp:2498 +#: ../src/verbs.cpp:2497 msgid "Spray Tool Preferences" msgstr "" -#: ../src/verbs.cpp:2499 +#: ../src/verbs.cpp:2498 msgid "Open Preferences for the Spray tool" msgstr "" -#: ../src/verbs.cpp:2500 +#: ../src/verbs.cpp:2499 msgid "Rectangle Preferences" msgstr "" -#: ../src/verbs.cpp:2501 +#: ../src/verbs.cpp:2500 msgid "Open Preferences for the Rectangle tool" msgstr "" -#: ../src/verbs.cpp:2502 +#: ../src/verbs.cpp:2501 msgid "3D Box Preferences" msgstr "" -#: ../src/verbs.cpp:2503 +#: ../src/verbs.cpp:2502 msgid "Open Preferences for the 3D Box tool" msgstr "" -#: ../src/verbs.cpp:2504 +#: ../src/verbs.cpp:2503 msgid "Ellipse Preferences" msgstr "" -#: ../src/verbs.cpp:2505 +#: ../src/verbs.cpp:2504 msgid "Open Preferences for the Ellipse tool" msgstr "" -#: ../src/verbs.cpp:2506 +#: ../src/verbs.cpp:2505 msgid "Star Preferences" msgstr "" -#: ../src/verbs.cpp:2507 +#: ../src/verbs.cpp:2506 msgid "Open Preferences for the Star tool" msgstr "" -#: ../src/verbs.cpp:2508 +#: ../src/verbs.cpp:2507 msgid "Spiral Preferences" msgstr "" -#: ../src/verbs.cpp:2509 +#: ../src/verbs.cpp:2508 msgid "Open Preferences for the Spiral tool" msgstr "" -#: ../src/verbs.cpp:2510 +#: ../src/verbs.cpp:2509 msgid "Pencil Preferences" msgstr "" -#: ../src/verbs.cpp:2511 +#: ../src/verbs.cpp:2510 msgid "Open Preferences for the Pencil tool" msgstr "" -#: ../src/verbs.cpp:2512 +#: ../src/verbs.cpp:2511 msgid "Pen Preferences" msgstr "" -#: ../src/verbs.cpp:2513 +#: ../src/verbs.cpp:2512 msgid "Open Preferences for the Pen tool" msgstr "" -#: ../src/verbs.cpp:2514 +#: ../src/verbs.cpp:2513 msgid "Calligraphic Preferences" msgstr "" -#: ../src/verbs.cpp:2515 +#: ../src/verbs.cpp:2514 msgid "Open Preferences for the Calligraphy tool" msgstr "" -#: ../src/verbs.cpp:2516 +#: ../src/verbs.cpp:2515 msgid "Text Preferences" msgstr "" -#: ../src/verbs.cpp:2517 +#: ../src/verbs.cpp:2516 msgid "Open Preferences for the Text tool" msgstr "" -#: ../src/verbs.cpp:2518 +#: ../src/verbs.cpp:2517 msgid "Gradient Preferences" msgstr "" -#: ../src/verbs.cpp:2519 +#: ../src/verbs.cpp:2518 msgid "Open Preferences for the Gradient tool" msgstr "" -#: ../src/verbs.cpp:2520 +#: ../src/verbs.cpp:2519 msgid "Zoom Preferences" msgstr "" -#: ../src/verbs.cpp:2521 +#: ../src/verbs.cpp:2520 msgid "Open Preferences for the Zoom tool" msgstr "" -#: ../src/verbs.cpp:2522 +#: ../src/verbs.cpp:2521 msgid "Measure Preferences" msgstr "" -#: ../src/verbs.cpp:2523 +#: ../src/verbs.cpp:2522 msgid "Open Preferences for the Measure tool" msgstr "" -#: ../src/verbs.cpp:2524 +#: ../src/verbs.cpp:2523 msgid "Dropper Preferences" msgstr "" -#: ../src/verbs.cpp:2525 +#: ../src/verbs.cpp:2524 msgid "Open Preferences for the Dropper tool" msgstr "" -#: ../src/verbs.cpp:2526 +#: ../src/verbs.cpp:2525 msgid "Connector Preferences" msgstr "" -#: ../src/verbs.cpp:2527 +#: ../src/verbs.cpp:2526 msgid "Open Preferences for the Connector tool" msgstr "" -#: ../src/verbs.cpp:2528 +#: ../src/verbs.cpp:2527 msgid "Paint Bucket Preferences" msgstr "" -#: ../src/verbs.cpp:2529 +#: ../src/verbs.cpp:2528 msgid "Open Preferences for the Paint Bucket tool" msgstr "" -#: ../src/verbs.cpp:2530 +#: ../src/verbs.cpp:2529 msgid "Eraser Preferences" msgstr "" -#: ../src/verbs.cpp:2531 +#: ../src/verbs.cpp:2530 msgid "Open Preferences for the Eraser tool" msgstr "" -#: ../src/verbs.cpp:2532 +#: ../src/verbs.cpp:2531 msgid "LPE Tool Preferences" msgstr "" -#: ../src/verbs.cpp:2533 +#: ../src/verbs.cpp:2532 msgid "Open Preferences for the LPETool tool" msgstr "" #. Zoom/View -#: ../src/verbs.cpp:2536 +#: ../src/verbs.cpp:2535 msgid "Zoom In" msgstr "" -#: ../src/verbs.cpp:2536 +#: ../src/verbs.cpp:2535 msgid "Zoom in" msgstr "" -#: ../src/verbs.cpp:2537 +#: ../src/verbs.cpp:2536 msgid "Zoom Out" msgstr "" -#: ../src/verbs.cpp:2537 +#: ../src/verbs.cpp:2536 msgid "Zoom out" msgstr "" -#: ../src/verbs.cpp:2538 +#: ../src/verbs.cpp:2537 msgid "_Rulers" msgstr "" -#: ../src/verbs.cpp:2538 +#: ../src/verbs.cpp:2537 msgid "Show or hide the canvas rulers" msgstr "" -#: ../src/verbs.cpp:2539 +#: ../src/verbs.cpp:2538 msgid "Scroll_bars" msgstr "" -#: ../src/verbs.cpp:2539 +#: ../src/verbs.cpp:2538 msgid "Show or hide the canvas scrollbars" msgstr "" -#: ../src/verbs.cpp:2540 +#: ../src/verbs.cpp:2539 msgid "_Grid" msgstr "" -#: ../src/verbs.cpp:2540 +#: ../src/verbs.cpp:2539 msgid "Show or hide the grid" msgstr "" -#: ../src/verbs.cpp:2541 +#: ../src/verbs.cpp:2540 msgid "G_uides" msgstr "" -#: ../src/verbs.cpp:2541 +#: ../src/verbs.cpp:2540 msgid "Show or hide guides (drag from a ruler to create a guide)" msgstr "" -#: ../src/verbs.cpp:2542 +#: ../src/verbs.cpp:2541 msgid "Enable snapping" msgstr "" -#: ../src/verbs.cpp:2543 +#: ../src/verbs.cpp:2542 msgid "Nex_t Zoom" msgstr "" -#: ../src/verbs.cpp:2543 +#: ../src/verbs.cpp:2542 msgid "Next zoom (from the history of zooms)" msgstr "" -#: ../src/verbs.cpp:2545 +#: ../src/verbs.cpp:2544 msgid "Pre_vious Zoom" msgstr "" -#: ../src/verbs.cpp:2545 +#: ../src/verbs.cpp:2544 msgid "Previous zoom (from the history of zooms)" msgstr "" -#: ../src/verbs.cpp:2547 +#: ../src/verbs.cpp:2546 msgid "Zoom 1:_1" msgstr "" -#: ../src/verbs.cpp:2547 +#: ../src/verbs.cpp:2546 msgid "Zoom to 1:1" msgstr "" -#: ../src/verbs.cpp:2549 +#: ../src/verbs.cpp:2548 msgid "Zoom 1:_2" msgstr "" -#: ../src/verbs.cpp:2549 +#: ../src/verbs.cpp:2548 msgid "Zoom to 1:2" msgstr "" -#: ../src/verbs.cpp:2551 +#: ../src/verbs.cpp:2550 msgid "_Zoom 2:1" msgstr "" -#: ../src/verbs.cpp:2551 +#: ../src/verbs.cpp:2550 msgid "Zoom to 2:1" msgstr "" -#: ../src/verbs.cpp:2554 +#: ../src/verbs.cpp:2553 msgid "_Fullscreen" msgstr "" -#: ../src/verbs.cpp:2554 +#: ../src/verbs.cpp:2553 msgid "Stretch this document window to full screen" msgstr "" -#: ../src/verbs.cpp:2557 +#: ../src/verbs.cpp:2556 msgid "Toggle _Focus Mode" msgstr "" -#: ../src/verbs.cpp:2557 +#: ../src/verbs.cpp:2556 msgid "Remove excess toolbars to focus on drawing" msgstr "" -#: ../src/verbs.cpp:2559 +#: ../src/verbs.cpp:2558 msgid "Duplic_ate Window" msgstr "" -#: ../src/verbs.cpp:2559 +#: ../src/verbs.cpp:2558 msgid "Open a new window with the same document" msgstr "" -#: ../src/verbs.cpp:2561 +#: ../src/verbs.cpp:2560 msgid "_New View Preview" msgstr "" -#: ../src/verbs.cpp:2562 +#: ../src/verbs.cpp:2561 msgid "New View Preview" msgstr "" #. "view_new_preview" -#: ../src/verbs.cpp:2564 ../src/verbs.cpp:2572 +#: ../src/verbs.cpp:2563 ../src/verbs.cpp:2571 msgid "_Normal" msgstr "" -#: ../src/verbs.cpp:2565 +#: ../src/verbs.cpp:2564 msgid "Switch to normal display mode" msgstr "" -#: ../src/verbs.cpp:2566 +#: ../src/verbs.cpp:2565 msgid "No _Filters" msgstr "" -#: ../src/verbs.cpp:2567 +#: ../src/verbs.cpp:2566 msgid "Switch to normal display without filters" msgstr "" -#: ../src/verbs.cpp:2568 +#: ../src/verbs.cpp:2567 msgid "_Outline" msgstr "" -#: ../src/verbs.cpp:2569 +#: ../src/verbs.cpp:2568 msgid "Switch to outline (wireframe) display mode" msgstr "" #. new ZoomVerb(SP_VERB_VIEW_COLOR_MODE_PRINT_COLORS_PREVIEW, "ViewColorModePrintColorsPreview", N_("_Print Colors Preview"), #. N_("Switch to print colors preview mode"), NULL), -#: ../src/verbs.cpp:2570 ../src/verbs.cpp:2578 +#: ../src/verbs.cpp:2569 ../src/verbs.cpp:2577 msgid "_Toggle" msgstr "" -#: ../src/verbs.cpp:2571 +#: ../src/verbs.cpp:2570 msgid "Toggle between normal and outline display modes" msgstr "" -#: ../src/verbs.cpp:2573 +#: ../src/verbs.cpp:2572 msgid "Switch to normal color display mode" msgstr "" -#: ../src/verbs.cpp:2574 +#: ../src/verbs.cpp:2573 msgid "_Grayscale" msgstr "" -#: ../src/verbs.cpp:2575 +#: ../src/verbs.cpp:2574 msgid "Switch to grayscale display mode" msgstr "" -#: ../src/verbs.cpp:2579 +#: ../src/verbs.cpp:2578 msgid "Toggle between normal and grayscale color display modes" msgstr "" -#: ../src/verbs.cpp:2581 +#: ../src/verbs.cpp:2580 msgid "Color-managed view" msgstr "" -#: ../src/verbs.cpp:2582 +#: ../src/verbs.cpp:2581 msgid "Toggle color-managed display for this document window" msgstr "" -#: ../src/verbs.cpp:2584 +#: ../src/verbs.cpp:2583 msgid "Ico_n Preview..." msgstr "" -#: ../src/verbs.cpp:2585 +#: ../src/verbs.cpp:2584 msgid "Open a window to preview objects at different icon resolutions" msgstr "" -#: ../src/verbs.cpp:2586 +#: ../src/verbs.cpp:2585 msgid "_Page" msgstr "" -#: ../src/verbs.cpp:2587 +#: ../src/verbs.cpp:2586 msgid "Zoom to fit page in window" msgstr "" -#: ../src/verbs.cpp:2588 +#: ../src/verbs.cpp:2587 msgid "Page _Width" msgstr "" -#: ../src/verbs.cpp:2589 +#: ../src/verbs.cpp:2588 msgid "Zoom to fit page width in window" msgstr "" -#: ../src/verbs.cpp:2590 +#: ../src/verbs.cpp:2589 msgid "_Drawing" msgstr "" -#: ../src/verbs.cpp:2591 +#: ../src/verbs.cpp:2590 msgid "Zoom to fit drawing in window" msgstr "" -#: ../src/verbs.cpp:2592 +#: ../src/verbs.cpp:2591 msgid "_Selection" msgstr "" -#: ../src/verbs.cpp:2593 +#: ../src/verbs.cpp:2592 msgid "Zoom to fit selection in window" msgstr "" #. Dialogs -#: ../src/verbs.cpp:2596 +#: ../src/verbs.cpp:2595 msgid "In_kscape Preferences..." msgstr "" -#: ../src/verbs.cpp:2597 +#: ../src/verbs.cpp:2596 msgid "Edit global Inkscape preferences" msgstr "" -#: ../src/verbs.cpp:2598 +#: ../src/verbs.cpp:2597 msgid "_Document Properties..." msgstr "" -#: ../src/verbs.cpp:2599 +#: ../src/verbs.cpp:2598 msgid "Edit properties of this document (to be saved with the document)" msgstr "" -#: ../src/verbs.cpp:2600 +#: ../src/verbs.cpp:2599 msgid "Document _Metadata..." msgstr "" -#: ../src/verbs.cpp:2601 +#: ../src/verbs.cpp:2600 msgid "Edit document metadata (to be saved with the document)" msgstr "" -#: ../src/verbs.cpp:2603 +#: ../src/verbs.cpp:2602 msgid "" "Edit objects' colors, gradients, arrowheads, and other fill and stroke " "properties..." msgstr "" -#: ../src/verbs.cpp:2604 +#: ../src/verbs.cpp:2603 msgid "Gl_yphs..." msgstr "" -#: ../src/verbs.cpp:2605 +#: ../src/verbs.cpp:2604 msgid "Select characters from a glyphs palette" msgstr "" #. TRANSLATORS: "Swatches" means: color samples -#: ../src/verbs.cpp:2607 +#: ../src/verbs.cpp:2606 msgid "S_watches..." msgstr "" -#: ../src/verbs.cpp:2608 +#: ../src/verbs.cpp:2607 msgid "Select colors from a swatches palette" msgstr "" -#: ../src/verbs.cpp:2609 +#: ../src/verbs.cpp:2608 msgid "Transfor_m..." msgstr "" -#: ../src/verbs.cpp:2610 +#: ../src/verbs.cpp:2609 msgid "Precisely control objects' transformations" msgstr "" -#: ../src/verbs.cpp:2611 +#: ../src/verbs.cpp:2610 msgid "_Align and Distribute..." msgstr "" -#: ../src/verbs.cpp:2612 +#: ../src/verbs.cpp:2611 msgid "Align and distribute objects" msgstr "" -#: ../src/verbs.cpp:2613 +#: ../src/verbs.cpp:2612 msgid "_Spray options..." msgstr "" -#: ../src/verbs.cpp:2614 +#: ../src/verbs.cpp:2613 msgid "Some options for the spray" msgstr "" -#: ../src/verbs.cpp:2615 +#: ../src/verbs.cpp:2614 msgid "Undo _History..." msgstr "" -#: ../src/verbs.cpp:2616 +#: ../src/verbs.cpp:2615 msgid "Undo History" msgstr "" -#: ../src/verbs.cpp:2618 +#: ../src/verbs.cpp:2617 msgid "View and select font family, font size and other text properties" msgstr "" -#: ../src/verbs.cpp:2619 +#: ../src/verbs.cpp:2618 msgid "_XML Editor..." msgstr "" -#: ../src/verbs.cpp:2620 +#: ../src/verbs.cpp:2619 msgid "View and edit the XML tree of the document" msgstr "" -#: ../src/verbs.cpp:2621 +#: ../src/verbs.cpp:2620 msgid "_Find..." msgstr "" -#: ../src/verbs.cpp:2622 +#: ../src/verbs.cpp:2621 msgid "Find objects in document" msgstr "" -#: ../src/verbs.cpp:2623 +#: ../src/verbs.cpp:2622 msgid "Find and _Replace Text..." msgstr "" -#: ../src/verbs.cpp:2624 +#: ../src/verbs.cpp:2623 msgid "Find and replace text in document" msgstr "" -#: ../src/verbs.cpp:2626 +#: ../src/verbs.cpp:2625 msgid "Check spelling of text in document" msgstr "" -#: ../src/verbs.cpp:2627 +#: ../src/verbs.cpp:2626 msgid "_Messages..." msgstr "" -#: ../src/verbs.cpp:2628 +#: ../src/verbs.cpp:2627 msgid "View debug messages" msgstr "" -#: ../src/verbs.cpp:2629 +#: ../src/verbs.cpp:2628 msgid "S_cripts..." msgstr "" -#: ../src/verbs.cpp:2630 +#: ../src/verbs.cpp:2629 msgid "Run scripts" msgstr "" -#: ../src/verbs.cpp:2631 +#: ../src/verbs.cpp:2630 msgid "Show/Hide D_ialogs" msgstr "" -#: ../src/verbs.cpp:2632 +#: ../src/verbs.cpp:2631 msgid "Show or hide all open dialogs" msgstr "" -#: ../src/verbs.cpp:2633 +#: ../src/verbs.cpp:2632 msgid "Create Tiled Clones..." msgstr "" -#: ../src/verbs.cpp:2634 +#: ../src/verbs.cpp:2633 msgid "" "Create multiple clones of selected object, arranging them into a pattern or " "scattering" msgstr "" -#: ../src/verbs.cpp:2635 +#: ../src/verbs.cpp:2634 msgid "_Object attributes..." msgstr "" -#: ../src/verbs.cpp:2636 +#: ../src/verbs.cpp:2635 msgid "Edit the object attributes..." msgstr "" -#: ../src/verbs.cpp:2638 +#: ../src/verbs.cpp:2637 msgid "Edit the ID, locked and visible status, and other object properties" msgstr "" @@ -21906,218 +22117,218 @@ msgstr "" #. new DialogVerb(SP_VERB_XMPP_CLIENT, "DialogXmppClient", #. N_("_Instant Messaging..."), N_("Jabber Instant Messaging Client"), NULL), #. #endif -#: ../src/verbs.cpp:2643 +#: ../src/verbs.cpp:2642 msgid "_Input Devices..." msgstr "" -#: ../src/verbs.cpp:2644 +#: ../src/verbs.cpp:2643 msgid "Configure extended input devices, such as a graphics tablet" msgstr "" -#: ../src/verbs.cpp:2645 +#: ../src/verbs.cpp:2644 msgid "_Extensions..." msgstr "" -#: ../src/verbs.cpp:2646 +#: ../src/verbs.cpp:2645 msgid "Query information about extensions" msgstr "" -#: ../src/verbs.cpp:2647 +#: ../src/verbs.cpp:2646 msgid "Layer_s..." msgstr "" -#: ../src/verbs.cpp:2648 +#: ../src/verbs.cpp:2647 msgid "View Layers" msgstr "" -#: ../src/verbs.cpp:2649 +#: ../src/verbs.cpp:2648 msgid "Path E_ffects ..." msgstr "" -#: ../src/verbs.cpp:2650 +#: ../src/verbs.cpp:2649 msgid "Manage, edit, and apply path effects" msgstr "" -#: ../src/verbs.cpp:2651 +#: ../src/verbs.cpp:2650 msgid "Filter _Editor..." msgstr "" -#: ../src/verbs.cpp:2652 +#: ../src/verbs.cpp:2651 msgid "Manage, edit, and apply SVG filters" msgstr "" -#: ../src/verbs.cpp:2653 +#: ../src/verbs.cpp:2652 msgid "SVG Font Editor..." msgstr "" -#: ../src/verbs.cpp:2654 +#: ../src/verbs.cpp:2653 msgid "Edit SVG fonts" msgstr "" -#: ../src/verbs.cpp:2655 +#: ../src/verbs.cpp:2654 msgid "Print Colors..." msgstr "" -#: ../src/verbs.cpp:2656 +#: ../src/verbs.cpp:2655 msgid "" "Select which color separations to render in Print Colors Preview rendermode" msgstr "" #. Help -#: ../src/verbs.cpp:2661 +#: ../src/verbs.cpp:2660 msgid "About E_xtensions" msgstr "" -#: ../src/verbs.cpp:2662 +#: ../src/verbs.cpp:2661 msgid "Information on Inkscape extensions" msgstr "" -#: ../src/verbs.cpp:2663 +#: ../src/verbs.cpp:2662 msgid "About _Memory" msgstr "" -#: ../src/verbs.cpp:2664 +#: ../src/verbs.cpp:2663 msgid "Memory usage information" msgstr "" -#: ../src/verbs.cpp:2665 +#: ../src/verbs.cpp:2664 msgid "_About Inkscape" msgstr "" -#: ../src/verbs.cpp:2666 +#: ../src/verbs.cpp:2665 msgid "Inkscape version, authors, license" msgstr "" #. new HelpVerb(SP_VERB_SHOW_LICENSE, "ShowLicense", N_("_License"), #. N_("Distribution terms"), /*"show_license"*/"inkscape_options"), #. Tutorials -#: ../src/verbs.cpp:2671 +#: ../src/verbs.cpp:2670 msgid "Inkscape: _Basic" msgstr "" -#: ../src/verbs.cpp:2672 +#: ../src/verbs.cpp:2671 msgid "Getting started with Inkscape" msgstr "" #. "tutorial_basic" -#: ../src/verbs.cpp:2673 +#: ../src/verbs.cpp:2672 msgid "Inkscape: _Shapes" msgstr "" -#: ../src/verbs.cpp:2674 +#: ../src/verbs.cpp:2673 msgid "Using shape tools to create and edit shapes" msgstr "" -#: ../src/verbs.cpp:2675 +#: ../src/verbs.cpp:2674 msgid "Inkscape: _Advanced" msgstr "" -#: ../src/verbs.cpp:2676 +#: ../src/verbs.cpp:2675 msgid "Advanced Inkscape topics" msgstr "" #. "tutorial_advanced" #. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) -#: ../src/verbs.cpp:2678 +#: ../src/verbs.cpp:2677 msgid "Inkscape: T_racing" msgstr "" -#: ../src/verbs.cpp:2679 +#: ../src/verbs.cpp:2678 msgid "Using bitmap tracing" msgstr "" #. "tutorial_tracing" -#: ../src/verbs.cpp:2680 +#: ../src/verbs.cpp:2679 msgid "Inkscape: _Calligraphy" msgstr "" -#: ../src/verbs.cpp:2681 +#: ../src/verbs.cpp:2680 msgid "Using the Calligraphy pen tool" msgstr "" -#: ../src/verbs.cpp:2682 +#: ../src/verbs.cpp:2681 msgid "Inkscape: _Interpolate" msgstr "" -#: ../src/verbs.cpp:2683 +#: ../src/verbs.cpp:2682 msgid "Using the interpolate extension" msgstr "" #. "tutorial_interpolate" -#: ../src/verbs.cpp:2684 +#: ../src/verbs.cpp:2683 msgid "_Elements of Design" msgstr "" -#: ../src/verbs.cpp:2685 +#: ../src/verbs.cpp:2684 msgid "Principles of design in the tutorial form" msgstr "" #. "tutorial_design" -#: ../src/verbs.cpp:2686 +#: ../src/verbs.cpp:2685 msgid "_Tips and Tricks" msgstr "" -#: ../src/verbs.cpp:2687 +#: ../src/verbs.cpp:2686 msgid "Miscellaneous tips and tricks" msgstr "" #. "tutorial_tips" #. Effect -- renamed Extension -#: ../src/verbs.cpp:2690 +#: ../src/verbs.cpp:2689 msgid "Previous Exte_nsion" msgstr "" -#: ../src/verbs.cpp:2691 +#: ../src/verbs.cpp:2690 msgid "Repeat the last extension with the same settings" msgstr "" -#: ../src/verbs.cpp:2692 +#: ../src/verbs.cpp:2691 msgid "_Previous Extension Settings..." msgstr "" -#: ../src/verbs.cpp:2693 +#: ../src/verbs.cpp:2692 msgid "Repeat the last extension with new settings" msgstr "" -#: ../src/verbs.cpp:2697 +#: ../src/verbs.cpp:2696 msgid "Fit the page to the current selection" msgstr "" -#: ../src/verbs.cpp:2699 +#: ../src/verbs.cpp:2698 msgid "Fit the page to the drawing" msgstr "" -#: ../src/verbs.cpp:2701 +#: ../src/verbs.cpp:2700 msgid "" "Fit the page to the current selection or the drawing if there is no selection" msgstr "" #. LockAndHide -#: ../src/verbs.cpp:2703 +#: ../src/verbs.cpp:2702 msgid "Unlock All" msgstr "" -#: ../src/verbs.cpp:2705 +#: ../src/verbs.cpp:2704 msgid "Unlock All in All Layers" msgstr "" -#: ../src/verbs.cpp:2707 +#: ../src/verbs.cpp:2706 msgid "Unhide All" msgstr "" -#: ../src/verbs.cpp:2709 +#: ../src/verbs.cpp:2708 msgid "Unhide All in All Layers" msgstr "" -#: ../src/verbs.cpp:2713 +#: ../src/verbs.cpp:2712 msgid "Link an ICC color profile" msgstr "" -#: ../src/verbs.cpp:2714 +#: ../src/verbs.cpp:2713 msgid "Remove Color Profile" msgstr "" -#: ../src/verbs.cpp:2715 +#: ../src/verbs.cpp:2714 msgid "Remove a linked ICC color profile" msgstr "" @@ -22125,7 +22336,7 @@ msgstr "" msgid "Dash pattern" msgstr "" -#: ../src/widgets/dash-selector.cpp:73 +#: ../src/widgets/dash-selector.cpp:67 msgid "Pattern offset" msgstr "" @@ -22255,21 +22466,21 @@ msgid "Set pattern on stroke" msgstr "" #. Family frame -#: ../src/widgets/font-selector.cpp:143 +#: ../src/widgets/font-selector.cpp:144 msgid "Font family" msgstr "" #. Style frame -#: ../src/widgets/font-selector.cpp:174 +#: ../src/widgets/font-selector.cpp:175 msgctxt "Font selector" msgid "Style" msgstr "" -#: ../src/widgets/font-selector.cpp:208 ../src/widgets/toolbox.cpp:7752 +#: ../src/widgets/font-selector.cpp:209 ../src/widgets/toolbox.cpp:7752 msgid "Font size (px)" msgstr "" -#: ../src/widgets/font-selector.cpp:213 ../share/extensions/dots.inx.h:2 +#: ../src/widgets/font-selector.cpp:214 ../share/extensions/dots.inx.h:2 msgid "Font size:" msgstr "" @@ -22296,31 +22507,27 @@ msgstr "" msgid "Repeat:" msgstr "" -#: ../src/widgets/gradient-toolbar.cpp:156 +#: ../src/widgets/gradient-toolbar.cpp:165 msgid "Assign gradient to object" msgstr "" -#: ../src/widgets/gradient-toolbar.cpp:190 -msgid "No gradients" +#: ../src/widgets/gradient-toolbar.cpp:209 +msgid "No gradients" msgstr "" -#: ../src/widgets/gradient-toolbar.cpp:200 -msgid "Nothing selected" +#: ../src/widgets/gradient-toolbar.cpp:223 +msgid "No gradient" msgstr "" -#: ../src/widgets/gradient-toolbar.cpp:211 -msgid "No gradients in selection" +#: ../src/widgets/gradient-toolbar.cpp:231 +msgid "Multiple gradients" msgstr "" -#: ../src/widgets/gradient-toolbar.cpp:221 -msgid "Multiple gradients" -msgstr "" - -#: ../src/widgets/gradient-toolbar.cpp:484 +#: ../src/widgets/gradient-toolbar.cpp:487 msgid "Edit the stops of the gradient" msgstr "" -#: ../src/widgets/gradient-toolbar.cpp:542 ../src/widgets/toolbox.cpp:3021 +#: ../src/widgets/gradient-toolbar.cpp:545 ../src/widgets/toolbox.cpp:3021 #: ../src/widgets/toolbox.cpp:3103 ../src/widgets/toolbox.cpp:3429 #: ../src/widgets/toolbox.cpp:3467 ../src/widgets/toolbox.cpp:4094 #: ../src/widgets/toolbox.cpp:4118 ../src/widgets/toolbox.cpp:5754 @@ -22328,101 +22535,100 @@ msgstr "" msgid "New:" msgstr "" -#: ../src/widgets/gradient-toolbar.cpp:555 +#: ../src/widgets/gradient-toolbar.cpp:558 msgid "Create linear gradient" msgstr "" -#: ../src/widgets/gradient-toolbar.cpp:568 +#: ../src/widgets/gradient-toolbar.cpp:571 msgid "Create radial (elliptic or circular) gradient" msgstr "" #. TODO replace aux_toolbox_space(tbl, AUX_SPACING); -#: ../src/widgets/gradient-toolbar.cpp:584 +#: ../src/widgets/gradient-toolbar.cpp:587 msgid "on" msgstr "" -#: ../src/widgets/gradient-toolbar.cpp:597 +#: ../src/widgets/gradient-toolbar.cpp:600 msgid "Create gradient in the fill" msgstr "" -#: ../src/widgets/gradient-toolbar.cpp:610 +#: ../src/widgets/gradient-toolbar.cpp:613 msgid "Create gradient in the stroke" msgstr "" #. FIXME: implement averaging of all parameters for multiple selected #. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); -#: ../src/widgets/gradient-toolbar.cpp:625 ../src/widgets/toolbox.cpp:3023 +#: ../src/widgets/gradient-toolbar.cpp:628 ../src/widgets/toolbox.cpp:3023 #: ../src/widgets/toolbox.cpp:3437 ../src/widgets/toolbox.cpp:3455 #: ../src/widgets/toolbox.cpp:4096 ../src/widgets/toolbox.cpp:4107 #: ../src/widgets/toolbox.cpp:5757 ../src/widgets/toolbox.cpp:5768 msgid "Change:" msgstr "" -#: ../src/widgets/gradient-vector.cpp:278 -#: ../src/widgets/paint-selector.cpp:906 ../src/widgets/stroke-style.cpp:419 +#: ../src/widgets/gradient-vector.cpp:296 +#: ../src/widgets/paint-selector.cpp:916 msgid "No document selected" msgstr "" -#: ../src/widgets/gradient-vector.cpp:284 +#: ../src/widgets/gradient-vector.cpp:301 msgid "No gradients in document" msgstr "" -#: ../src/widgets/gradient-vector.cpp:290 +#: ../src/widgets/gradient-vector.cpp:306 msgid "No gradient selected" msgstr "" -#: ../src/widgets/gradient-vector.cpp:554 +#: ../src/widgets/gradient-vector.cpp:566 msgid "No stops in gradient" msgstr "" -#: ../src/widgets/gradient-vector.cpp:668 +#: ../src/widgets/gradient-vector.cpp:677 msgid "Change gradient stop offset" msgstr "" #. TRANSLATORS: "Stop" means: a "phase" of a gradient -#: ../src/widgets/gradient-vector.cpp:807 +#: ../src/widgets/gradient-vector.cpp:830 msgid "Add stop" msgstr "" -#: ../src/widgets/gradient-vector.cpp:810 +#: ../src/widgets/gradient-vector.cpp:833 msgid "Add another control stop to gradient" msgstr "" -#: ../src/widgets/gradient-vector.cpp:812 +#: ../src/widgets/gradient-vector.cpp:835 msgid "Delete stop" msgstr "" -#: ../src/widgets/gradient-vector.cpp:815 +#: ../src/widgets/gradient-vector.cpp:838 msgid "Delete current control stop from gradient" msgstr "" #. TRANSLATORS: "Stop" means: a "phase" of a gradient -#: ../src/widgets/gradient-vector.cpp:871 +#: ../src/widgets/gradient-vector.cpp:897 msgid "Stop Color" msgstr "" -#: ../src/widgets/gradient-vector.cpp:901 +#: ../src/widgets/gradient-vector.cpp:927 msgid "Gradient editor" msgstr "" -#: ../src/widgets/gradient-vector.cpp:1189 +#: ../src/widgets/gradient-vector.cpp:1220 msgid "Change gradient stop color" msgstr "" -#: ../src/widgets/paint-selector.cpp:226 ../src/widgets/paint-selector.cpp:609 +#: ../src/widgets/paint-selector.cpp:226 msgid "No paint" msgstr "" -#: ../src/widgets/paint-selector.cpp:228 ../src/widgets/paint-selector.cpp:673 +#: ../src/widgets/paint-selector.cpp:228 msgid "Flat color" msgstr "" -#. sp_gradient_selector_set_mode(SP_GRADIENT_SELECTOR(gsel), SP_GRADIENT_SELECTOR_MODE_LINEAR); -#: ../src/widgets/paint-selector.cpp:230 ../src/widgets/paint-selector.cpp:736 +#: ../src/widgets/paint-selector.cpp:230 msgid "Linear gradient" msgstr "" -#: ../src/widgets/paint-selector.cpp:232 ../src/widgets/paint-selector.cpp:739 +#: ../src/widgets/paint-selector.cpp:232 msgid "Radial gradient" msgstr "" @@ -22447,27 +22653,48 @@ msgid "" "Fill is solid unless a subpath is counterdirectional (fill-rule: nonzero)" msgstr "" -#: ../src/widgets/paint-selector.cpp:576 -msgid "No objects" +#: ../src/widgets/paint-selector.cpp:583 +msgid "No objects" +msgstr "" + +#: ../src/widgets/paint-selector.cpp:594 +msgid "Multiple styles" +msgstr "" + +#: ../src/widgets/paint-selector.cpp:605 +msgid "Paint is undefined" +msgstr "" + +#: ../src/widgets/paint-selector.cpp:616 +msgid "No paint" +msgstr "" + +#: ../src/widgets/paint-selector.cpp:682 +msgid "Flat color" msgstr "" -#: ../src/widgets/paint-selector.cpp:587 -msgid "Multiple styles" +#. sp_gradient_selector_set_mode(SP_GRADIENT_SELECTOR(gsel), SP_GRADIENT_SELECTOR_MODE_LINEAR); +#: ../src/widgets/paint-selector.cpp:746 +msgid "Linear gradient" msgstr "" -#: ../src/widgets/paint-selector.cpp:598 -msgid "Paint is undefined" +#: ../src/widgets/paint-selector.cpp:749 +msgid "Radial gradient" msgstr "" -#: ../src/widgets/paint-selector.cpp:1006 +#: ../src/widgets/paint-selector.cpp:1016 msgid "" "Use the Node tool to adjust position, scale, and rotation of the " "pattern on canvas. Use Object > Pattern > Objects to Pattern to " "create a new pattern from selection." msgstr "" -#: ../src/widgets/paint-selector.cpp:1094 -msgid "Swatch fill" +#: ../src/widgets/paint-selector.cpp:1029 +msgid "Pattern fill" +msgstr "" + +#: ../src/widgets/paint-selector.cpp:1104 +msgid "Swatch fill" msgstr "" #: ../src/widgets/select-toolbar.cpp:262 @@ -22749,11 +22976,11 @@ msgstr "" msgid "Wheel" msgstr "" -#: ../src/widgets/sp-xmlview-attr-list.cpp:46 +#: ../src/widgets/sp-xmlview-attr-list.cpp:52 msgid "Attribute" msgstr "" -#: ../src/widgets/sp-xmlview-attr-list.cpp:47 +#: ../src/widgets/sp-xmlview-attr-list.cpp:60 msgid "Value" msgstr "" @@ -22761,15 +22988,15 @@ msgstr "" msgid "Type text in a text node" msgstr "" -#: ../src/widgets/stroke-style.cpp:505 +#: ../src/widgets/stroke-style.cpp:193 msgid "Set markers" msgstr "" -#: ../src/widgets/stroke-style.cpp:687 +#: ../src/widgets/stroke-style.cpp:333 msgid "Stroke width" msgstr "" -#: ../src/widgets/stroke-style.cpp:689 +#: ../src/widgets/stroke-style.cpp:335 msgctxt "Stroke width" msgid "_Width:" msgstr "" @@ -22777,96 +23004,96 @@ msgstr "" #. Join type #. TRANSLATORS: The line join style specifies the shape to be used at the #. corners of paths. It can be "miter", "round" or "bevel". -#: ../src/widgets/stroke-style.cpp:712 +#: ../src/widgets/stroke-style.cpp:358 msgid "Join:" msgstr "" #. TRANSLATORS: Miter join: joining lines with a sharp (pointed) corner. #. For an example, draw a triangle with a large stroke width and modify the #. "Join" option (in the Fill and Stroke dialog). -#: ../src/widgets/stroke-style.cpp:724 +#: ../src/widgets/stroke-style.cpp:370 msgid "Miter join" msgstr "" #. TRANSLATORS: Round join: joining lines with a rounded corner. #. For an example, draw a triangle with a large stroke width and modify the #. "Join" option (in the Fill and Stroke dialog). -#: ../src/widgets/stroke-style.cpp:734 +#: ../src/widgets/stroke-style.cpp:380 msgid "Round join" msgstr "" #. TRANSLATORS: Bevel join: joining lines with a blunted (flattened) corner. #. For an example, draw a triangle with a large stroke width and modify the #. "Join" option (in the Fill and Stroke dialog). -#: ../src/widgets/stroke-style.cpp:744 +#: ../src/widgets/stroke-style.cpp:390 msgid "Bevel join" msgstr "" -#: ../src/widgets/stroke-style.cpp:764 +#: ../src/widgets/stroke-style.cpp:410 msgid "Maximum length of the miter (in units of stroke width)" msgstr "" -#: ../src/widgets/stroke-style.cpp:766 +#: ../src/widgets/stroke-style.cpp:412 msgid "Miter _limit:" msgstr "" #. Cap type #. TRANSLATORS: cap type specifies the shape for the ends of lines #. spw_label(t, _("_Cap:"), 0, i); -#: ../src/widgets/stroke-style.cpp:778 +#: ../src/widgets/stroke-style.cpp:424 msgid "Cap:" msgstr "" #. TRANSLATORS: Butt cap: the line shape does not extend beyond the end point #. of the line; the ends of the line are square -#: ../src/widgets/stroke-style.cpp:790 +#: ../src/widgets/stroke-style.cpp:436 msgid "Butt cap" msgstr "" #. TRANSLATORS: Round cap: the line shape extends beyond the end point of the #. line; the ends of the line are rounded -#: ../src/widgets/stroke-style.cpp:798 +#: ../src/widgets/stroke-style.cpp:444 msgid "Round cap" msgstr "" #. TRANSLATORS: Square cap: the line shape extends beyond the end point of the #. line; the ends of the line are square -#: ../src/widgets/stroke-style.cpp:806 +#: ../src/widgets/stroke-style.cpp:452 msgid "Square cap" msgstr "" #. Dash -#: ../src/widgets/stroke-style.cpp:812 +#: ../src/widgets/stroke-style.cpp:458 msgid "Dashes:" msgstr "" -#: ../src/widgets/stroke-style.cpp:835 +#: ../src/widgets/stroke-style.cpp:476 msgid "_Start Markers:" msgstr "" -#: ../src/widgets/stroke-style.cpp:836 +#: ../src/widgets/stroke-style.cpp:477 msgid "Start Markers are drawn on the first node of a path or shape" msgstr "" -#: ../src/widgets/stroke-style.cpp:847 +#: ../src/widgets/stroke-style.cpp:487 msgid "_Mid Markers:" msgstr "" -#: ../src/widgets/stroke-style.cpp:848 +#: ../src/widgets/stroke-style.cpp:488 msgid "" "Mid Markers are drawn on every node of a path or shape except the first and " "last nodes" msgstr "" -#: ../src/widgets/stroke-style.cpp:859 +#: ../src/widgets/stroke-style.cpp:498 msgid "_End Markers:" msgstr "" -#: ../src/widgets/stroke-style.cpp:860 +#: ../src/widgets/stroke-style.cpp:499 msgid "End Markers are drawn on the last node of a path or shape" msgstr "" -#: ../src/widgets/stroke-style.cpp:1213 ../src/widgets/stroke-style.cpp:1309 +#: ../src/widgets/stroke-style.cpp:851 ../src/widgets/stroke-style.cpp:948 msgid "Set stroke style" msgstr "" @@ -25194,7 +25421,7 @@ msgid "Visual" msgstr "" #: ../share/extensions/dimension.inx.h:5 ../share/extensions/dots.inx.h:13 -#: ../share/extensions/handles.inx.h:2 ../share/extensions/measure.inx.h:19 +#: ../share/extensions/handles.inx.h:2 ../share/extensions/measure.inx.h:38 msgid "Visualize Path" msgstr "" @@ -27707,40 +27934,114 @@ msgid "solid" msgstr "" #: ../share/extensions/measure.inx.h:1 -msgid "Font size (px):" +msgid "Angle 0" +msgstr "" + +#: ../share/extensions/measure.inx.h:2 +msgid "Angle 120" msgstr "" #: ../share/extensions/measure.inx.h:3 +msgid "Angle 135" +msgstr "" + +#: ../share/extensions/measure.inx.h:4 +msgid "Angle 150" +msgstr "" + +#: ../share/extensions/measure.inx.h:5 +msgid "Angle 180" +msgstr "" + +#: ../share/extensions/measure.inx.h:6 +msgid "Angle 210" +msgstr "" + +#: ../share/extensions/measure.inx.h:7 +msgid "Angle 225" +msgstr "" + +#: ../share/extensions/measure.inx.h:8 +msgid "Angle 240" +msgstr "" + +#: ../share/extensions/measure.inx.h:9 +msgid "Angle 270" +msgstr "" + +#: ../share/extensions/measure.inx.h:10 +msgid "Angle 30" +msgstr "" + +#: ../share/extensions/measure.inx.h:11 +msgid "Angle 300" +msgstr "" + +#: ../share/extensions/measure.inx.h:12 +msgid "Angle 315" +msgstr "" + +#: ../share/extensions/measure.inx.h:13 +msgid "Angle 330" +msgstr "" + +#: ../share/extensions/measure.inx.h:14 +msgid "Angle 45" +msgstr "" + +#: ../share/extensions/measure.inx.h:15 +msgid "Angle 60" +msgstr "" + +#: ../share/extensions/measure.inx.h:16 +msgid "Angle 90" +msgstr "" + +#: ../share/extensions/measure.inx.h:17 +msgid "Display Format: " +msgstr "" + +#: ../share/extensions/measure.inx.h:18 +msgid "Font size (px):" +msgstr "" + +#: ../share/extensions/measure.inx.h:20 msgid "Length" msgstr "" #. mm -#: ../share/extensions/measure.inx.h:5 +#: ../share/extensions/measure.inx.h:22 msgid "Length Unit:" msgstr "" -#: ../share/extensions/measure.inx.h:7 +#: ../share/extensions/measure.inx.h:24 msgid "Measure Path" msgstr "" -#: ../share/extensions/measure.inx.h:8 +#: ../share/extensions/measure.inx.h:25 msgid "Measurement Type: " msgstr "" -#: ../share/extensions/measure.inx.h:9 +#: ../share/extensions/measure.inx.h:26 msgid "Offset (px):" msgstr "" -#: ../share/extensions/measure.inx.h:11 +#: ../share/extensions/measure.inx.h:28 msgid "Scale Factor (Drawing:Real Length) = 1:" msgstr "" -#: ../share/extensions/measure.inx.h:13 +#: ../share/extensions/measure.inx.h:29 +msgid "Text On Path" +msgstr "" + +#: ../share/extensions/measure.inx.h:31 #, no-c-format msgid "" -"This effect measures the length, or area, of the selected path and adds it " -"as a text-on-path object with the selected unit.\n" +"This effect measures the length, or area, of the selected paths and adds it " +"as a text object with the selected units.\n" " \n" +" * Display format can be either Text-On-Path, or stand-alone text at a " +"specified angle.\n" " * The number of significant digits can be controlled by the Precision " "field.\n" " * The Offset field controls the distance from the text to the path.\n" @@ -27752,7 +28053,7 @@ msgid "" "0.03%." msgstr "" -#: ../share/extensions/measure.inx.h:20 +#: ../share/extensions/measure.inx.h:39 msgctxt "measure extension" msgid "Area" msgstr "" -- cgit v1.2.3 From f4f442c53ca362ea85e5c6b84d12ef745584a7d0 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Sat, 24 Mar 2012 20:57:21 +0100 Subject: partial 2geom update to obtain required method (bzr r11127) --- src/2geom/svg-path.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/2geom/svg-path.h b/src/2geom/svg-path.h index 89192fb72..591eb3aa2 100644 --- a/src/2geom/svg-path.h +++ b/src/2geom/svg-path.h @@ -120,6 +120,14 @@ public: large_arc, sweep, p); } + void append(Path const &other, Path::Stitching stitching = Path::NO_STITCHING) + { + if (!_in_path) { + moveTo(other.initialPoint()); + } + _path.append(other, stitching); + } + void closePath() { _path.close(); finish(); -- cgit v1.2.3 From 4e0750a27ddbb0eb338f2b2193b6a83c7e9a53a8 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Sat, 24 Mar 2012 20:58:21 +0100 Subject: powerstroke: add Spiro rounded join! (genius idea Jasper!) (bzr r11128) --- src/live_effects/lpe-powerstroke.cpp | 46 ++++++++++++++++++++++++++++++------ 1 file changed, 39 insertions(+), 7 deletions(-) diff --git a/src/live_effects/lpe-powerstroke.cpp b/src/live_effects/lpe-powerstroke.cpp index 1f521da5d..678b5cc67 100644 --- a/src/live_effects/lpe-powerstroke.cpp +++ b/src/live_effects/lpe-powerstroke.cpp @@ -28,6 +28,8 @@ #include <2geom/crossing.h> #include <2geom/ellipse.h> +#include "spiro.h" + namespace Geom { // should all be moved to 2geom at some point @@ -129,13 +131,15 @@ enum LineJoinType { LINEJOIN_BEVEL, LINEJOIN_ROUND, LINEJOIN_EXTRP_MITER, - LINEJOIN_MITER + LINEJOIN_MITER, + LINEJOIN_SPIRO }; static const Util::EnumData LineJoinTypeData[] = { {LINEJOIN_BEVEL, N_("Beveled"), "bevel"}, {LINEJOIN_ROUND, N_("Rounded"), "round"}, {LINEJOIN_EXTRP_MITER, N_("Extrapolated"), "extrapolated"}, {LINEJOIN_MITER, N_("Miter"), "miter"}, + {LINEJOIN_SPIRO, N_("Spiro"), "spiro"}, }; static const Util::EnumDataConverter LineJoinTypeConverter(LineJoinTypeData, sizeof(LineJoinTypeData)/sizeof(*LineJoinTypeData)); @@ -272,9 +276,11 @@ Geom::Path path_from_piecewise_fix_cusps( Geom::Piecewise { // discontinuity found, so fix it :-) discontinuity_data cusp = cusps[cusp_i]; + bool on_outside = ( sign*cusp.width*angle_between(cusp.der0, cusp.der1) < 0. ); + switch (jointype) { case LINEJOIN_ROUND: { - if ( sign*cusp.width*angle_between(cusp.der0, cusp.der1) < 0.) { + if (on_outside) { // we are on the outside: round corner /* for constant width paths, the rounding is a circular arc (rx == ry), for non-constant width paths, the rounding can be done with an ellipse but is hard and ambiguous. @@ -304,7 +310,7 @@ Geom::Path path_from_piecewise_fix_cusps( Geom::Piecewise break; } /* case LINEJOIN_NONE: { - if ( sign*cusp.width*angle_between(cusp.der0, cusp.der1) < 0.) { + if ( on_outside ) { // we are on the outside Geom::Point der1 = unitTangentAt(B[prev_i],1); Geom::Point point_on_path = B[prev_i].at1() - rot90(der1) * cusp.width; @@ -316,8 +322,7 @@ Geom::Path path_from_piecewise_fix_cusps( Geom::Piecewise } } */ case LINEJOIN_EXTRP_MITER: { - // first figure out whether we are on the outside or inside of the corner in the path - if ( sign*cusp.width*angle_between(cusp.der0, cusp.der1) < 0.) { + if (on_outside) { // we are on the outside, do something complicated to make it look good ;) Geom::Point der1 = unitTangentAt(B[prev_i],1); @@ -355,8 +360,7 @@ Geom::Path path_from_piecewise_fix_cusps( Geom::Piecewise break; } case LINEJOIN_MITER: { - // first figure out whether we are on the outside or inside of the corner in the path - if ( sign*cusp.width*angle_between(cusp.der0, cusp.der1) < 0.) { + if (on_outside) { // we are on the outside, do something complicated to make it look good ;) Geom::Point der1 = unitTangentAt(B[prev_i],1); @@ -379,6 +383,34 @@ Geom::Path path_from_piecewise_fix_cusps( Geom::Piecewise } break; } + case LINEJOIN_SPIRO: { + if (on_outside) { + Geom::Point tang1 = unitTangentAt(B[prev_i],1); + Geom::Point tang2 = unitTangentAt(B[i],0); + + Spiro::spiro_cp *controlpoints = g_new (Spiro::spiro_cp, 4); + controlpoints[0].x = (B[prev_i].at1() - sign*cusp.width*tang1)[Geom::X]; + controlpoints[0].y = (B[prev_i].at1() - sign*cusp.width*tang1)[Geom::Y]; + controlpoints[0].ty = '{'; + controlpoints[1].x = B[prev_i].at1()[Geom::X]; + controlpoints[1].y = B[prev_i].at1()[Geom::Y]; + controlpoints[1].ty = ']'; + controlpoints[2].x = B[i].at0()[Geom::X]; + controlpoints[2].y = B[i].at0()[Geom::Y]; + controlpoints[2].ty = '['; + controlpoints[3].x = (B[i].at0() + sign*cusp.width*tang2)[Geom::X]; + controlpoints[3].y = (B[i].at0() + sign*cusp.width*tang2)[Geom::Y]; + controlpoints[3].ty = '}'; + + Geom::Path spiro; + Spiro::spiro_run(controlpoints, 4, spiro); + pb.append(spiro.portion(1,spiro.size_open()-1), Geom::Path::STITCH_DISCONTINUOUS); + } else { + // we are on the inside, do a simple bevel to connect the paths + pb.lineTo(B[i].at0()); // default to bevel for too shallow cusp angles + } + break; + } case LINEJOIN_BEVEL: default: pb.lineTo(B[i].at0()); -- cgit v1.2.3 From 1ea6b68442a7e0df11e12e74a3b2ffc15640a797 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Sat, 24 Mar 2012 22:52:32 +0100 Subject: powerstroke: spiro join: more robust detection of tangent direction. fixes incorrect rounding for some paths. (bzr r11129) --- src/live_effects/lpe-powerstroke.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/live_effects/lpe-powerstroke.cpp b/src/live_effects/lpe-powerstroke.cpp index 678b5cc67..d3843dc92 100644 --- a/src/live_effects/lpe-powerstroke.cpp +++ b/src/live_effects/lpe-powerstroke.cpp @@ -5,7 +5,7 @@ /* Authors: * Johan Engelen * - * Copyright (C) 2010-2011 Authors + * Copyright (C) 2010-2012 Authors * * Released under GNU GPL, read the file 'COPYING' for more information */ @@ -388,9 +388,13 @@ Geom::Path path_from_piecewise_fix_cusps( Geom::Piecewise Geom::Point tang1 = unitTangentAt(B[prev_i],1); Geom::Point tang2 = unitTangentAt(B[i],0); + Geom::Point direction = B[i].at0() - B[prev_i].at1(); + double tang1_sign = dot(direction,tang1); + double tang2_sign = dot(direction,tang2); + Spiro::spiro_cp *controlpoints = g_new (Spiro::spiro_cp, 4); - controlpoints[0].x = (B[prev_i].at1() - sign*cusp.width*tang1)[Geom::X]; - controlpoints[0].y = (B[prev_i].at1() - sign*cusp.width*tang1)[Geom::Y]; + controlpoints[0].x = (B[prev_i].at1() - tang1_sign*tang1)[Geom::X]; + controlpoints[0].y = (B[prev_i].at1() - tang1_sign*tang1)[Geom::Y]; controlpoints[0].ty = '{'; controlpoints[1].x = B[prev_i].at1()[Geom::X]; controlpoints[1].y = B[prev_i].at1()[Geom::Y]; @@ -398,8 +402,8 @@ Geom::Path path_from_piecewise_fix_cusps( Geom::Piecewise controlpoints[2].x = B[i].at0()[Geom::X]; controlpoints[2].y = B[i].at0()[Geom::Y]; controlpoints[2].ty = '['; - controlpoints[3].x = (B[i].at0() + sign*cusp.width*tang2)[Geom::X]; - controlpoints[3].y = (B[i].at0() + sign*cusp.width*tang2)[Geom::Y]; + controlpoints[3].x = (B[i].at0() + tang2_sign*tang2)[Geom::X]; + controlpoints[3].y = (B[i].at0() + tang2_sign*tang2)[Geom::Y]; controlpoints[3].ty = '}'; Geom::Path spiro; -- cgit v1.2.3