=== modified file 'src/menus-skeleton.h' --- src/menus-skeleton.h 2012-03-03 12:39:55 +0000 +++ src/menus-skeleton.h 2012-03-28 02:46:00 +0000 @@ -78,6 +78,11 @@ " \n" " \n" " \n" +" \n" +" \n" +" \n" +" \n" +" \n" " \n" " \n" " \n" === modified file 'src/selection-chemistry.cpp' --- src/selection-chemistry.cpp 2012-03-18 17:39:50 +0000 +++ src/selection-chemistry.cpp 2012-03-28 04:56:23 +0000 @@ -151,6 +151,22 @@ } } +void SelectionHelper::selectSameFillStroke(SPDesktop *dt) +{ + sp_select_same_fill_stroke(dt, true, true); +} + +void SelectionHelper::selectSameFill(SPDesktop *dt) +{ + sp_select_same_fill_stroke(dt, true, false); +} + +void SelectionHelper::selectSameStroke(SPDesktop *dt) +{ + sp_select_same_fill_stroke(dt, false, true); +} + + void SelectionHelper::invert(SPDesktop *dt) { if (tools_isactive(dt, TOOLS_NODES)) { @@ -1610,6 +1626,101 @@ _("Rotate")); } +/* + * Selects all the visible items with the same fill and/or stroke style as the items in the current selection + * + * Params: + * desktop - set the selection on this desktop + * fill - select objects matching fill + * stroke - select objects matching stroke + */ +void sp_select_same_fill_stroke(SPDesktop *desktop, gboolean fill, gboolean stroke) +{ + if (!desktop) { + return; + } + + if (!fill && !stroke) { + return; + } + + GSList *all_list = get_all_items(NULL, desktop->currentRoot(), desktop, true, true, NULL); + GSList *all_matches = NULL; + + Inkscape::Selection *selection = sp_desktop_selection (desktop); + + for (GSList const* sel_iter = selection->itemList(); sel_iter; sel_iter = sel_iter->next) { + SPItem *sel = SP_ITEM(sel_iter->data); + GSList *matches = all_list; + if (fill) { + matches = sp_get_same_fill_or_stroke_items(sel, matches, TRUE); + } + if (stroke) { + matches = sp_get_same_fill_or_stroke_items(sel, matches, FALSE); + } + all_matches = g_slist_concat (all_matches, matches); + } + + selection->clear(); + selection->setList(all_matches); + + g_slist_free(all_matches); + g_slist_free(all_list); + +} + +GSList *sp_get_same_fill_or_stroke_items(SPItem *sel, GSList *src, gboolean fillorstroke) +{ + GSList *matches = NULL; + gboolean match = false; + + SPIPaint *sel_paint = (fillorstroke) ? &(sel->style->fill) : &(sel->style->stroke); + + for (GSList *i = src; i != NULL; i = i->next) { + SPItem *iter = SP_ITEM(i->data); + SPIPaint *iter_paint = (fillorstroke) ? &(iter->style->fill) : &(iter->style->stroke); + match = false; + if (sel_paint->isColor() && iter_paint->isColor() && + (sel_paint->value.color.toRGBA32(1.0) == iter_paint->value.color.toRGBA32(1.0))) { + match = true; + } + else if (sel_paint->isPaintserver() && iter_paint->isPaintserver()) { + + SPPaintServer *sel_server = (fillorstroke) ? + sel->style->getFillPaintServer() : sel->style->getStrokePaintServer(); + SPPaintServer *iter_server = (fillorstroke) ? + iter->style->getFillPaintServer() : iter->style->getStrokePaintServer(); + + if ((SP_IS_LINEARGRADIENT(sel_server) || SP_IS_RADIALGRADIENT(sel_server) || + (SP_IS_GRADIENT(sel_server) && SP_GRADIENT(sel_server)->getVector()->isSwatch())) && + (SP_IS_LINEARGRADIENT(iter_server) || SP_IS_RADIALGRADIENT(iter_server) || + (SP_IS_GRADIENT(iter_server) && SP_GRADIENT(iter_server)->getVector()->isSwatch()))) { + SPGradient *sel_vector = SP_GRADIENT(sel_server)->getVector(); + SPGradient *iter_vector = SP_GRADIENT(iter_server)->getVector(); + if (sel_vector == iter_vector) { + match = true; + } + } else if (SP_IS_PATTERN(sel_server) && SP_IS_PATTERN(iter_server)) { + SPPattern *sel_pat = pattern_getroot(SP_PATTERN(sel_server)); + SPPattern *iter_pat = pattern_getroot(SP_PATTERN(iter_server)); + if (sel_pat == iter_pat) { + match = true; + } + } + } + else if (sel_paint->noneSet && iter_paint->noneSet) { + match = true; + } + + if (match) { + matches = g_slist_prepend (matches, iter); + } + } + + return matches; +} + + // helper function: static Geom::Point === modified file 'src/selection-chemistry.h' --- src/selection-chemistry.h 2012-01-15 11:26:04 +0000 +++ src/selection-chemistry.h 2012-03-28 04:43:21 +0000 @@ -36,6 +36,9 @@ static void selectAll(SPDesktop *desktop); static void selectAllInAll(SPDesktop *desktop); static void selectNone(SPDesktop *desktop); + static void selectSameFillStroke(SPDesktop *dt); + static void selectSameFill(SPDesktop *dt); + static void selectSameStroke(SPDesktop *dt); static void invert(SPDesktop *desktop); static void invertAllInAll(SPDesktop *desktop); static void reverse(SPDesktop *dt); @@ -120,6 +123,9 @@ void sp_selection_edit_clip_or_mask(SPDesktop * dt, bool clip); +void sp_select_same_fill_stroke(SPDesktop *desktop, gboolean fill, gboolean stroke); +GSList *sp_get_same_fill_or_stroke_items(SPItem *sel, GSList *src, gboolean fillorstroke); + void scroll_to_show_item(SPDesktop *desktop, SPItem *item); void sp_undo (SPDesktop *desktop, SPDocument *doc); === modified file 'src/ui/context-menu.cpp' --- src/ui/context-menu.cpp 2012-03-22 17:08:31 +0000 +++ src/ui/context-menu.cpp 2012-03-28 03:58:57 +0000 @@ -25,6 +25,8 @@ #include "preferences.h" #include "verbs.h" +#include "selection-chemistry.h" + using Inkscape::DocumentUndo; static void sp_object_type_menu(GType type, SPObject *object, SPDesktop *desktop, GtkMenu *menu); @@ -90,6 +92,7 @@ static void sp_item_properties(GtkMenuItem *menuitem, SPItem *item); static void sp_item_select_this(GtkMenuItem *menuitem, SPItem *item); +static void sp_item_select_same_fill_stroke(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); @@ -124,6 +127,12 @@ } gtk_widget_show(w); gtk_menu_shell_append(GTK_MENU_SHELL(m), w); + /* Select same fill and stroke */ + w = gtk_menu_item_new_with_mnemonic(_("_Select Same Fill and Stroke")); + g_object_set_data(G_OBJECT(w), "desktop", desktop); + g_signal_connect(G_OBJECT(w), "activate", G_CALLBACK(sp_item_select_same_fill_stroke), 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); @@ -258,6 +267,16 @@ sp_desktop_selection(desktop)->set(item); } +static void sp_item_select_same_fill_stroke(GtkMenuItem *menuitem, SPItem *item) +{ + SPDesktop *desktop; + desktop = (SPDesktop*)g_object_get_data(G_OBJECT(menuitem), "desktop"); + g_return_if_fail(desktop != NULL); + + sp_select_same_fill_stroke(desktop, true, true); +} + + static void sp_item_create_link(GtkMenuItem *menuitem, SPItem *item) { g_assert(SP_IS_ITEM(item)); === modified file 'src/verbs.cpp' --- src/verbs.cpp 2012-03-24 05:24:22 +0000 +++ src/verbs.cpp 2012-03-28 03:58:51 +0000 @@ -961,6 +961,15 @@ case SP_VERB_EDIT_SELECT_ALL: SelectionHelper::selectAll(dt); break; + case SP_VERB_EDIT_SELECT_SAME_FILL_STROKE: + SelectionHelper::selectSameFillStroke(dt); + break; + case SP_VERB_EDIT_SELECT_SAME_FILL: + SelectionHelper::selectSameFill(dt); + break; + case SP_VERB_EDIT_SELECT_SAME_STROKE: + SelectionHelper::selectSameStroke(dt); + break; case SP_VERB_EDIT_INVERT: SelectionHelper::invert(dt); break; @@ -2275,6 +2284,14 @@ N_("Select all objects or all nodes"), GTK_STOCK_SELECT_ALL), new EditVerb(SP_VERB_EDIT_SELECT_ALL_IN_ALL_LAYERS, "EditSelectAllInAllLayers", N_("Select All in All La_yers"), N_("Select all objects in all visible and unlocked layers"), INKSCAPE_ICON("edit-select-all-layers")), + new EditVerb(SP_VERB_EDIT_SELECT_SAME_FILL_STROKE, "EditSelectSameFillStroke", N_("S_ame Fill and Stroke"), + N_("Select all objects with the same fill and stroke as the selected objects"), GTK_STOCK_SELECT_ALL), + new EditVerb(SP_VERB_EDIT_SELECT_SAME_FILL, "EditSelectSameFill", N_("Same _Fill"), + N_("Select all objects with the same fill as the selected objects"), GTK_STOCK_SELECT_ALL), + new EditVerb(SP_VERB_EDIT_SELECT_SAME_STROKE, "EditSelectSameStroke", N_("Same _Stroke"), + N_("Select all objects with the same stroke as the selected objects"), GTK_STOCK_SELECT_ALL), + new EditVerb(SP_VERB_EDIT_SELECT_SAME_FONT, "EditSelectSameFont", N_("Same F_ont"), + N_("Select all objects with the same font as the selected objects"), GTK_STOCK_SELECT_ALL), new EditVerb(SP_VERB_EDIT_INVERT, "EditInvert", N_("In_vert Selection"), N_("Invert selection (unselect what is selected and select everything else)"), INKSCAPE_ICON("edit-select-invert")), new EditVerb(SP_VERB_EDIT_INVERT_IN_ALL_LAYERS, "EditInvertInAllLayers", N_("Invert in All Layers"), === modified file 'src/verbs.h' --- src/verbs.h 2012-03-03 12:39:55 +0000 +++ src/verbs.h 2012-03-28 02:37:48 +0000 @@ -87,6 +87,10 @@ SP_VERB_EDIT_CLEAR_ALL, SP_VERB_EDIT_SELECT_ALL, SP_VERB_EDIT_SELECT_ALL_IN_ALL_LAYERS, + SP_VERB_EDIT_SELECT_SAME_FILL_STROKE, + SP_VERB_EDIT_SELECT_SAME_FILL, + SP_VERB_EDIT_SELECT_SAME_STROKE, + SP_VERB_EDIT_SELECT_SAME_FONT, SP_VERB_EDIT_INVERT, SP_VERB_EDIT_INVERT_IN_ALL_LAYERS, SP_VERB_EDIT_SELECT_NEXT,