X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;ds=sidebyside;f=src%2Fselection-chemistry.cpp;h=94e0b709ab8d519b2031e6700384541a40965778;hb=b53b8aff0aa55c2349ea10992daac23a929ae19f;hp=d4bc26c5d08a68879f9d9ae2a555ecced6bb3384;hpb=de85b07c6395bae59577144d3fb48a8f60975edb;p=inkscape.git diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index d4bc26c5d..94e0b709a 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -39,6 +39,9 @@ #include "sp-flowregion.h" #include "text-editing.h" #include "text-context.h" +#include "connector-context.h" +#include "sp-path.h" +#include "sp-conn-end.h" #include "dropper-context.h" #include #include "libnr/nr-matrix-rotate-ops.h" @@ -62,9 +65,12 @@ #include "sp-clippath.h" #include "sp-mask.h" #include "file.h" +#include "helper/png-write.h" #include "layer-fns.h" #include "context-fns.h" #include +#include "helper/units.h" +#include "sp-item.h" using NR::X; using NR::Y; @@ -208,11 +214,12 @@ void sp_selection_delete() if (tools_isactive (desktop, TOOLS_TEXT)) if (sp_text_delete_selection(desktop->event_context)) { - sp_document_done(SP_DT_DOCUMENT(desktop)); + sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT, + _("Delete text")); return; } - Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + Inkscape::Selection *selection = sp_desktop_selection(desktop); // check if something is selected if (selection->isEmpty()) { @@ -233,7 +240,8 @@ void sp_selection_delete() */ tools_switch ( desktop, tools_active ( desktop ) ); - sp_document_done(SP_DT_DOCUMENT(desktop)); + sp_document_done(sp_desktop_document(desktop), SP_VERB_EDIT_DELETE, + _("Delete")); } /* fixme: sequencing */ @@ -243,7 +251,7 @@ void sp_selection_duplicate() if (desktop == NULL) return; - Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + Inkscape::Selection *selection = sp_desktop_selection(desktop); // check if something is selected if (selection->isEmpty()) { @@ -271,7 +279,8 @@ void sp_selection_duplicate() Inkscape::GC::release(copy); } - sp_document_done(SP_DT_DOCUMENT(desktop)); + sp_document_done(sp_desktop_document(desktop), SP_VERB_EDIT_DUPLICATE, + _("Duplicate")); selection->setReprList(newsel); @@ -284,8 +293,8 @@ void sp_edit_clear_all() if (!dt) return; - SPDocument *doc = SP_DT_DOCUMENT(dt); - SP_DT_SELECTION(dt)->clear(); + SPDocument *doc = sp_desktop_document(dt); + sp_desktop_selection(dt)->clear(); g_return_if_fail(SP_IS_GROUP(dt->currentLayer())); GSList *items = sp_item_group_item_list(SP_GROUP(dt->currentLayer())); @@ -295,7 +304,8 @@ void sp_edit_clear_all() items = g_slist_remove(items, items->data); } - sp_document_done(doc); + sp_document_done(doc, SP_VERB_EDIT_CLEAR_ALL, + _("Delete all")); } GSList * @@ -326,7 +336,7 @@ void sp_edit_select_all_full (bool force_all_layers, bool invert) if (!dt) return; - Inkscape::Selection *selection = SP_DT_SELECTION(dt); + Inkscape::Selection *selection = sp_desktop_selection(dt); g_return_if_fail(SP_IS_GROUP(dt->currentLayer())); @@ -412,9 +422,9 @@ void sp_selection_group() if (desktop == NULL) return; - SPDocument *document = SP_DT_DOCUMENT (desktop); + SPDocument *document = sp_desktop_document (desktop); - Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + Inkscape::Selection *selection = sp_desktop_selection(desktop); // Check if something is selected. if (selection->isEmpty()) { @@ -496,7 +506,8 @@ void sp_selection_group() // Move to the position of the topmost, reduced by the number of items deleted from topmost_parent group->setPosition(topmost + 1); - sp_document_done(SP_DT_DOCUMENT(desktop)); + sp_document_done(sp_desktop_document(desktop), SP_VERB_SELECTION_GROUP, + _("Group")); selection->set(group); Inkscape::GC::release(group); @@ -508,7 +519,7 @@ void sp_selection_ungroup() if (desktop == NULL) return; - Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + Inkscape::Selection *selection = sp_desktop_selection(desktop); if (selection->isEmpty()) { desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select a group to ungroup.")); @@ -557,7 +568,8 @@ void sp_selection_ungroup() g_slist_free(items); - sp_document_done(SP_DT_DOCUMENT(desktop)); + sp_document_done(sp_desktop_document(desktop), SP_VERB_SELECTION_UNGROUP, + _("Ungroup")); } static SPGroup * @@ -617,7 +629,7 @@ sp_selection_raise() if (!desktop) return; - Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + Inkscape::Selection *selection = sp_desktop_selection(desktop); GSList const *items = (GSList *) selection->itemList(); if (!items) { @@ -658,7 +670,8 @@ sp_selection_raise() rev = g_slist_remove(rev, child); } - sp_document_done(SP_DT_DOCUMENT(desktop)); + sp_document_done(sp_desktop_document(desktop), SP_VERB_SELECTION_RAISE, + _("Raise")); } void sp_selection_raise_to_top() @@ -667,8 +680,8 @@ void sp_selection_raise_to_top() if (desktop == NULL) return; - SPDocument *document = SP_DT_DOCUMENT(desktop); - Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + SPDocument *document = sp_desktop_document(desktop); + Inkscape::Selection *selection = sp_desktop_selection(desktop); if (selection->isEmpty()) { desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select object(s) to raise to top.")); @@ -693,7 +706,8 @@ void sp_selection_raise_to_top() g_slist_free(rl); - sp_document_done(document); + sp_document_done(document, SP_VERB_SELECTION_TO_FRONT, + _("Raise to top")); } void @@ -703,7 +717,7 @@ sp_selection_lower() if (desktop == NULL) return; - Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + Inkscape::Selection *selection = sp_desktop_selection(desktop); GSList const *items = (GSList *) selection->itemList(); if (!items) { @@ -749,7 +763,8 @@ sp_selection_lower() rev = g_slist_remove(rev, child); } - sp_document_done(SP_DT_DOCUMENT(desktop)); + sp_document_done(sp_desktop_document(desktop), SP_VERB_SELECTION_LOWER, + _("Lower")); } @@ -759,8 +774,8 @@ void sp_selection_lower_to_bottom() if (desktop == NULL) return; - SPDocument *document = SP_DT_DOCUMENT(desktop); - Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + SPDocument *document = sp_desktop_document(desktop); + Inkscape::Selection *selection = sp_desktop_selection(desktop); if (selection->isEmpty()) { desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select object(s) to lower to bottom.")); @@ -797,20 +812,21 @@ void sp_selection_lower_to_bottom() g_slist_free(rl); - sp_document_done(document); + sp_document_done(document, SP_VERB_SELECTION_TO_BACK, + _("Lower to bottom")); } void sp_undo(SPDesktop *desktop, SPDocument *) { - if (!sp_document_undo(SP_DT_DOCUMENT(desktop))) + if (!sp_document_undo(sp_desktop_document(desktop))) desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Nothing to undo.")); } void sp_redo(SPDesktop *desktop, SPDocument *) { - if (!sp_document_redo(SP_DT_DOCUMENT(desktop))) + if (!sp_document_redo(sp_desktop_document(desktop))) desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Nothing to redo.")); } @@ -972,7 +988,7 @@ void sp_selection_copy() if (desktop == NULL) return; - Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + Inkscape::Selection *selection = sp_desktop_selection(desktop); if (tools_isactive (desktop, TOOLS_DROPPER)) { sp_dropper_context_copy(desktop->event_context); @@ -1066,13 +1082,13 @@ void sp_selection_paste(bool in_place) return; } - SPDocument *document = SP_DT_DOCUMENT(desktop); + SPDocument *document = sp_desktop_document(desktop); if (Inkscape::have_viable_layer(desktop, desktop->messageStack()) == false) { return; } - Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + Inkscape::Selection *selection = sp_desktop_selection(desktop); if (tools_isactive (desktop, TOOLS_TEXT)) { if (sp_text_paste_inline(desktop->event_context)) @@ -1097,7 +1113,7 @@ void sp_selection_paste(bool in_place) /* Snap the offset of the new item(s) to the grid */ /* FIXME: this gridsnap fiddling is a hack. */ - Inkscape::GridSnapper &s = desktop->namedview->grid_snapper; + Inkscape::GridSnapper &s = desktop->namedview->snap_manager.grid; gdouble const curr_gridsnap = s.getDistance(); s.setDistance(NR_HUGE); m = s.freeSnap(Inkscape::Snapper::SNAP_POINT, m, NULL).getPoint(); @@ -1105,7 +1121,8 @@ void sp_selection_paste(bool in_place) sp_selection_move_relative(selection, m); } - sp_document_done(document); + sp_document_done(document, SP_VERB_EDIT_PASTE, + _("Paste")); } void sp_selection_paste_style() @@ -1113,7 +1130,7 @@ void sp_selection_paste_style() SPDesktop *desktop = SP_ACTIVE_DESKTOP; if (desktop == NULL) return; - Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + Inkscape::Selection *selection = sp_desktop_selection(desktop); // check if something is in the clipboard if (clipboard == NULL) { @@ -1127,11 +1144,12 @@ void sp_selection_paste_style() return; } - paste_defs (&defs_clipboard, SP_DT_DOCUMENT(desktop)); + paste_defs (&defs_clipboard, sp_desktop_document(desktop)); sp_desktop_set_style (desktop, style_clipboard); - sp_document_done(SP_DT_DOCUMENT (desktop)); + sp_document_done(sp_desktop_document (desktop), SP_VERB_EDIT_PASTE_STYLE, + _("Paste style")); } void sp_selection_paste_size (bool apply_x, bool apply_y) @@ -1139,7 +1157,7 @@ void sp_selection_paste_size (bool apply_x, bool apply_y) SPDesktop *desktop = SP_ACTIVE_DESKTOP; if (desktop == NULL) return; - Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + Inkscape::Selection *selection = sp_desktop_selection(desktop); // check if something is in the clipboard if (size_clipboard.extent(NR::X) < 1e-6 || size_clipboard.extent(NR::Y) < 1e-6) { @@ -1166,7 +1184,8 @@ void sp_selection_paste_size (bool apply_x, bool apply_y) apply_x? scale_x : (desktop->isToolboxButtonActive ("lock")? scale_y : 1.0), apply_y? scale_y : (desktop->isToolboxButtonActive ("lock")? scale_x : 1.0))); - sp_document_done(SP_DT_DOCUMENT (desktop)); + sp_document_done(sp_desktop_document (desktop), SP_VERB_EDIT_PASTE_SIZE, + _("Paste size")); } void sp_selection_paste_size_separately (bool apply_x, bool apply_y) @@ -1174,7 +1193,7 @@ void sp_selection_paste_size_separately (bool apply_x, bool apply_y) SPDesktop *desktop = SP_ACTIVE_DESKTOP; if (desktop == NULL) return; - Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + Inkscape::Selection *selection = sp_desktop_selection(desktop); // check if something is in the clipboard if (size_clipboard.extent(NR::X) < 1e-6 || size_clipboard.extent(NR::Y) < 1e-6) { @@ -1206,14 +1225,15 @@ void sp_selection_paste_size_separately (bool apply_x, bool apply_y) } - sp_document_done(SP_DT_DOCUMENT (desktop)); + sp_document_done(sp_desktop_document (desktop), SP_VERB_EDIT_PASTE_SIZE_SEPARATELY, + _("Paste size separately")); } void sp_selection_to_next_layer () { SPDesktop *dt = SP_ACTIVE_DESKTOP; - Inkscape::Selection *selection = SP_DT_SELECTION(dt); + Inkscape::Selection *selection = sp_desktop_selection(dt); // check if something is selected if (selection->isEmpty()) { @@ -1223,18 +1243,31 @@ void sp_selection_to_next_layer () const GSList *items = g_slist_copy ((GSList *) selection->itemList()); + bool no_more = false; // Set to true, if no more layers above SPObject *next=Inkscape::next_layer(dt->currentRoot(), dt->currentLayer()); if (next) { GSList *temp_clip = NULL; sp_selection_copy_impl (items, &temp_clip, NULL, NULL); // we're in the same doc, so no need to copy defs sp_selection_delete_impl (items); - GSList *copied = sp_selection_paste_impl (SP_DT_DOCUMENT (dt), next, &temp_clip, NULL); + next=Inkscape::next_layer(dt->currentRoot(), dt->currentLayer()); // Fixes bug 1482973: crash while moving layers + GSList *copied; + if(next) { + copied = sp_selection_paste_impl (sp_desktop_document (dt), next, &temp_clip, NULL); + } else { + copied = sp_selection_paste_impl (sp_desktop_document (dt), dt->currentLayer(), &temp_clip, NULL); + no_more = true; + } selection->setReprList((GSList const *) copied); g_slist_free (copied); if (temp_clip) g_slist_free (temp_clip); - dt->setCurrentLayer(next); - sp_document_done(SP_DT_DOCUMENT (dt)); + if (next) dt->setCurrentLayer(next); + sp_document_done(sp_desktop_document (dt), SP_VERB_LAYER_MOVE_TO_NEXT, + _("Raise to next layer")); } else { + no_more = true; + } + + if (no_more) { dt->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("No more layers above.")); } @@ -1245,7 +1278,7 @@ void sp_selection_to_prev_layer () { SPDesktop *dt = SP_ACTIVE_DESKTOP; - Inkscape::Selection *selection = SP_DT_SELECTION(dt); + Inkscape::Selection *selection = sp_desktop_selection(dt); // check if something is selected if (selection->isEmpty()) { @@ -1255,18 +1288,31 @@ void sp_selection_to_prev_layer () const GSList *items = g_slist_copy ((GSList *) selection->itemList()); + bool no_more = false; // Set to true, if no more layers below SPObject *next=Inkscape::previous_layer(dt->currentRoot(), dt->currentLayer()); if (next) { GSList *temp_clip = NULL; sp_selection_copy_impl (items, &temp_clip, NULL, NULL); // we're in the same doc, so no need to copy defs sp_selection_delete_impl (items); - GSList *copied = sp_selection_paste_impl (SP_DT_DOCUMENT (dt), next, &temp_clip, NULL); + next=Inkscape::previous_layer(dt->currentRoot(), dt->currentLayer()); // Fixes bug 1482973: crash while moving layers + GSList *copied; + if(next) { + copied = sp_selection_paste_impl (sp_desktop_document (dt), next, &temp_clip, NULL); + } else { + copied = sp_selection_paste_impl (sp_desktop_document (dt), dt->currentLayer(), &temp_clip, NULL); + no_more = true; + } selection->setReprList((GSList const *) copied); g_slist_free (copied); if (temp_clip) g_slist_free (temp_clip); - dt->setCurrentLayer(next); - sp_document_done(SP_DT_DOCUMENT (dt)); + if (next) dt->setCurrentLayer(next); + sp_document_done(sp_desktop_document (dt), SP_VERB_LAYER_MOVE_TO_PREV, + _("Lower to previous layer")); } else { + no_more = true; + } + + if (no_more) { dt->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("No more layers below.")); } @@ -1301,7 +1347,21 @@ void sp_selection_apply_affine(Inkscape::Selection *selection, NR::Matrix const bool transform_textpath_with_path = (SP_IS_TEXT_TEXTPATH(item) && selection->includes( sp_textpath_get_path_item (SP_TEXTPATH(sp_object_first_child(SP_OBJECT(item)))) )); bool transform_flowtext_with_frame = (SP_IS_FLOWTEXT(item) && selection->includes( SP_FLOWTEXT(item)->get_frame (NULL))); // only the first frame so far bool transform_offset_with_source = (SP_IS_OFFSET(item) && SP_OFFSET (item)->sourceHref) && selection->includes( sp_offset_get_source (SP_OFFSET(item)) ); - + + // If we're moving a connector, we want to detach it + // from shapes that aren't part of the selection, but + // leave it attached if they are + if (cc_item_is_connector(item)) { + SPItem *attItem[2]; + SP_PATH(item)->connEndPair.getAttachedItems(attItem); + + for (int n = 0; n < 2; ++n) { + if (!selection->includes(attItem[n])) { + sp_conn_end_detach(item, n); + } + } + } + // "clones are unmoved when original is moved" preference int compensation = prefs_get_int_attribute("options.clonecompensation", "value", SP_CLONE_COMPENSATION_UNMOVED); bool prefs_unmoved = (compensation == SP_CLONE_COMPENSATION_UNMOVED); @@ -1386,7 +1446,7 @@ void sp_selection_remove_transform() if (desktop == NULL) return; - Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + Inkscape::Selection *selection = sp_desktop_selection(desktop); GSList const *l = (GSList *) selection->reprList(); while (l != NULL) { @@ -1394,7 +1454,8 @@ void sp_selection_remove_transform() l = l->next; } - sp_document_done(SP_DT_DOCUMENT(desktop)); + sp_document_done(sp_desktop_document(desktop), SP_VERB_OBJECT_FLATTEN, + _("Remove transform")); } void @@ -1490,7 +1551,7 @@ void sp_selection_rotate_90_cw() { SPDesktop *desktop = SP_ACTIVE_DESKTOP; - Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + Inkscape::Selection *selection = sp_desktop_selection(desktop); if (selection->isEmpty()) return; @@ -1502,7 +1563,8 @@ void sp_selection_rotate_90_cw() sp_item_rotate_rel(item, rot_neg_90); } - sp_document_done(SP_DT_DOCUMENT(desktop)); + sp_document_done(sp_desktop_document(desktop), SP_VERB_OBJECT_ROTATE_90_CCW, + _("Rotate 90° CW")); } @@ -1517,7 +1579,7 @@ void sp_selection_rotate_90_ccw() { SPDesktop *desktop = SP_ACTIVE_DESKTOP; - Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + Inkscape::Selection *selection = sp_desktop_selection(desktop); if (selection->isEmpty()) return; @@ -1529,7 +1591,8 @@ void sp_selection_rotate_90_ccw() sp_item_rotate_rel(item, rot_neg_90); } - sp_document_done(SP_DT_DOCUMENT(desktop)); + sp_document_done(sp_desktop_document(desktop), SP_VERB_OBJECT_ROTATE_90_CW, + _("Rotate 90° CCW")); } void @@ -1542,10 +1605,12 @@ sp_selection_rotate(Inkscape::Selection *selection, gdouble const angle_degrees) sp_selection_rotate_relative(selection, center, angle_degrees); - sp_document_maybe_done(SP_DT_DOCUMENT(selection->desktop()), + sp_document_maybe_done(sp_desktop_document(selection->desktop()), ( ( angle_degrees > 0 ) ? "selector:rotate:ccw" - : "selector:rotate:cw" )); + : "selector:rotate:cw" ), + SP_VERB_CONTEXT_SELECT, + _("Rotate")); } /** @@ -1569,10 +1634,12 @@ sp_selection_rotate_screen(Inkscape::Selection *selection, gdouble angle) sp_selection_rotate_relative(selection, center, zangle); - sp_document_maybe_done(SP_DT_DOCUMENT(selection->desktop()), + sp_document_maybe_done(sp_desktop_document(selection->desktop()), ( (angle > 0) ? "selector:rotate:ccw" - : "selector:rotate:cw" )); + : "selector:rotate:cw" ), + SP_VERB_CONTEXT_SELECT, + _("Rotate by pixels")); } void @@ -1593,10 +1660,12 @@ sp_selection_scale(Inkscape::Selection *selection, gdouble grow) double const times = 1.0 + grow / max_len; sp_selection_scale_relative(selection, center, NR::scale(times, times)); - sp_document_maybe_done(SP_DT_DOCUMENT(selection->desktop()), + sp_document_maybe_done(sp_desktop_document(selection->desktop()), ( (grow > 0) ? "selector:scale:larger" - : "selector:scale:smaller" )); + : "selector:scale:smaller" ), + SP_VERB_CONTEXT_SELECT, + _("Scale")); } void @@ -1614,14 +1683,15 @@ sp_selection_scale_times(Inkscape::Selection *selection, gdouble times) NR::Point const center(selection->bounds().midpoint()); sp_selection_scale_relative(selection, center, NR::scale(times, times)); - sp_document_done(SP_DT_DOCUMENT(selection->desktop())); + sp_document_done(sp_desktop_document(selection->desktop()), SP_VERB_CONTEXT_SELECT, + _("Scale by whole factor")); } void sp_selection_move(gdouble dx, gdouble dy) { SPDesktop *desktop = SP_ACTIVE_DESKTOP; - Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + Inkscape::Selection *selection = sp_desktop_selection(desktop); if (selection->isEmpty()) { return; } @@ -1629,11 +1699,14 @@ sp_selection_move(gdouble dx, gdouble dy) sp_selection_move_relative(selection, dx, dy); if (dx == 0) { - sp_document_maybe_done(SP_DT_DOCUMENT(desktop), "selector:move:vertical"); + sp_document_maybe_done(sp_desktop_document(desktop), "selector:move:vertical", SP_VERB_CONTEXT_SELECT, + _("Move vertically")); } else if (dy == 0) { - sp_document_maybe_done(SP_DT_DOCUMENT(desktop), "selector:move:horizontal"); + sp_document_maybe_done(sp_desktop_document(desktop), "selector:move:horizontal", SP_VERB_CONTEXT_SELECT, + _("Move horizontally")); } else { - sp_document_done(SP_DT_DOCUMENT(desktop)); + sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_SELECT, + _("Move")); } } @@ -1642,7 +1715,7 @@ sp_selection_move_screen(gdouble dx, gdouble dy) { SPDesktop *desktop = SP_ACTIVE_DESKTOP; - Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + Inkscape::Selection *selection = sp_desktop_selection(desktop); if (selection->isEmpty()) { return; } @@ -1654,11 +1727,14 @@ sp_selection_move_screen(gdouble dx, gdouble dy) sp_selection_move_relative(selection, zdx, zdy); if (dx == 0) { - sp_document_maybe_done(SP_DT_DOCUMENT(desktop), "selector:move:vertical"); + sp_document_maybe_done(sp_desktop_document(desktop), "selector:move:vertical", SP_VERB_CONTEXT_SELECT, + _("Nudge vertically by pixels")); } else if (dy == 0) { - sp_document_maybe_done(SP_DT_DOCUMENT(desktop), "selector:move:horizontal"); + sp_document_maybe_done(sp_desktop_document(desktop), "selector:move:horizontal", SP_VERB_CONTEXT_SELECT, + _("Nudge horizontally by pixels")); } else { - sp_document_done(SP_DT_DOCUMENT(desktop)); + sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_SELECT, + _("Move")); } } @@ -1719,7 +1795,7 @@ sp_selection_item_next(void) { SPDesktop *desktop = SP_ACTIVE_DESKTOP; g_return_if_fail(desktop != NULL); - Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + Inkscape::Selection *selection = sp_desktop_selection(desktop); PrefsSelectionContext inlayer = (PrefsSelectionContext)prefs_get_int_attribute ("options.kbselection", "inlayer", PREFS_SELECTION_LAYER); bool onlyvisible = prefs_get_int_attribute ("options.kbselection", "onlyvisible", 1); @@ -1749,7 +1825,7 @@ sp_selection_item_prev(void) SPDesktop *desktop = SP_ACTIVE_DESKTOP; g_return_if_fail(document != NULL); g_return_if_fail(desktop != NULL); - Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + Inkscape::Selection *selection = sp_desktop_selection(desktop); PrefsSelectionContext inlayer = (PrefsSelectionContext)prefs_get_int_attribute ("options.kbselection", "inlayer", PREFS_SELECTION_LAYER); bool onlyvisible = prefs_get_int_attribute ("options.kbselection", "onlyvisible", 1); @@ -1881,7 +1957,7 @@ sp_selection_clone() if (desktop == NULL) return; - Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + Inkscape::Selection *selection = sp_desktop_selection(desktop); // check if something is selected if (selection->isEmpty()) { @@ -1918,7 +1994,8 @@ sp_selection_clone() Inkscape::GC::release(clone); } - sp_document_done(SP_DT_DOCUMENT(desktop)); + sp_document_done(sp_desktop_document(desktop), SP_VERB_EDIT_CLONE, + _("Clone")); selection->setReprList(newsel); @@ -1932,7 +2009,7 @@ sp_selection_unlink() if (!desktop) return; - Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + Inkscape::Selection *selection = sp_desktop_selection(desktop); if (selection->isEmpty()) { desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select a clone to unlink.")); @@ -1969,7 +2046,8 @@ sp_selection_unlink() desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("No clones to unlink in the selection.")); } - sp_document_done(SP_DT_DOCUMENT(desktop)); + sp_document_done(sp_desktop_document(desktop), SP_VERB_EDIT_UNLINK_CLONE, + _("Unlink clone")); } void @@ -1979,7 +2057,7 @@ sp_select_clone_original() if (desktop == NULL) return; - Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + Inkscape::Selection *selection = sp_desktop_selection(desktop); SPItem *item = selection->singleItem(); @@ -2033,9 +2111,9 @@ sp_selection_tile(bool apply) if (desktop == NULL) return; - SPDocument *document = SP_DT_DOCUMENT(desktop); + SPDocument *document = sp_desktop_document(desktop); - Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + Inkscape::Selection *selection = sp_desktop_selection(desktop); // check if something is selected if (selection->isEmpty()) { @@ -2061,6 +2139,8 @@ sp_selection_tile(bool apply) // bottommost object, after sorting SPObject *parent = SP_OBJECT_PARENT (items->data); + NR::Matrix parent_transform = sp_item_i2root_affine(SP_ITEM(parent)); + // remember the position of the first item gint pos = SP_OBJECT_REPR (items->data)->position(); @@ -2088,7 +2168,7 @@ sp_selection_tile(bool apply) prefs_set_int_attribute("options.clonecompensation", "value", SP_CLONE_COMPENSATION_UNMOVED); const gchar *pat_id = pattern_tile (repr_copies, bounds, document, - NR::Matrix(NR::translate(desktop->dt2doc(NR::Point(r.min()[NR::X], r.max()[NR::Y])))), move); + NR::Matrix(NR::translate(desktop->dt2doc(NR::Point(r.min()[NR::X], r.max()[NR::Y])))) * parent_transform.inverse(), parent_transform * move); // restore compensation setting prefs_set_int_attribute("options.clonecompensation", "value", saved_compensation); @@ -2096,15 +2176,19 @@ sp_selection_tile(bool apply) if (apply) { Inkscape::XML::Node *rect = sp_repr_new ("svg:rect"); rect->setAttribute("style", g_strdup_printf("stroke:none;fill:url(#%s)", pat_id)); - sp_repr_set_svg_double(rect, "width", bounds.extent(NR::X)); - sp_repr_set_svg_double(rect, "height", bounds.extent(NR::Y)); - sp_repr_set_svg_double(rect, "x", bounds.min()[NR::X]); - sp_repr_set_svg_double(rect, "y", bounds.min()[NR::Y]); + + NR::Point min = bounds.min() * parent_transform.inverse(); + NR::Point max = bounds.max() * parent_transform.inverse(); + + sp_repr_set_svg_double(rect, "width", max[NR::X] - min[NR::X]); + sp_repr_set_svg_double(rect, "height", max[NR::Y] - min[NR::Y]); + sp_repr_set_svg_double(rect, "x", min[NR::X]); + sp_repr_set_svg_double(rect, "y", min[NR::Y]); // restore parent and position SP_OBJECT_REPR (parent)->appendChild(rect); rect->setPosition(pos > 0 ? pos : 0); - SPItem *rectangle = (SPItem *) SP_DT_DOCUMENT (desktop)->getObjectByRepr(rect); + SPItem *rectangle = (SPItem *) sp_desktop_document (desktop)->getObjectByRepr(rect); Inkscape::GC::release(rect); @@ -2114,7 +2198,8 @@ sp_selection_tile(bool apply) g_slist_free (items); - sp_document_done (document); + sp_document_done (document, SP_VERB_EDIT_TILE, + _("Objects to pattern")); } void @@ -2124,9 +2209,9 @@ sp_selection_untile() if (desktop == NULL) return; - SPDocument *document = SP_DT_DOCUMENT(desktop); + SPDocument *document = sp_desktop_document(desktop); - Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + Inkscape::Selection *selection = sp_desktop_selection(desktop); // check if something is selected if (selection->isEmpty()) { @@ -2185,7 +2270,8 @@ sp_selection_untile() if (!did) { desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("No pattern fills in the selection.")); } else { - sp_document_done(SP_DT_DOCUMENT(desktop)); + sp_document_done(sp_desktop_document(desktop), SP_VERB_EDIT_UNTILE, + _("Pattern to objects")); selection->setList(new_select); } } @@ -2197,9 +2283,9 @@ sp_selection_create_bitmap_copy () if (desktop == NULL) return; - SPDocument *document = SP_DT_DOCUMENT(desktop); + SPDocument *document = sp_desktop_document(desktop); - Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + Inkscape::Selection *selection = sp_desktop_selection(desktop); // check if something is selected if (selection->isEmpty()) { @@ -2289,7 +2375,7 @@ sp_selection_create_bitmap_copy () // Do the export sp_export_png_file(document, filepath, bbox.x0, bbox.y0, bbox.x1, bbox.y1, - width, height, + width, height, res, res, (guint32) 0xffffff00, NULL, NULL, true, /*bool force_overwrite,*/ @@ -2334,7 +2420,8 @@ sp_selection_create_bitmap_copy () gdk_pixbuf_unref (pb); // Complete undoable transaction - sp_document_done (document); + sp_document_done (document, SP_VERB_SELECTION_CREATE_BITMAP, + _("Create bitmap")); } g_free (filename); @@ -2359,17 +2446,17 @@ sp_selection_set_mask(bool apply_clip_path, bool apply_to_layer) if (desktop == NULL) return; - SPDocument *document = SP_DT_DOCUMENT(desktop); + SPDocument *document = sp_desktop_document(desktop); - Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + Inkscape::Selection *selection = sp_desktop_selection(desktop); // check if something is selected bool is_empty = selection->isEmpty(); if ( apply_to_layer && is_empty) { - desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select object(s) to create mask from.")); + desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select object(s) to create clippath or mask from.")); return; } else if (!apply_to_layer && ( is_empty || NULL == selection->itemList()->next )) { - desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select mask object and object(s) to apply mask to.")); + desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select mask object and object(s) to apply clippath or mask to.")); return; } @@ -2459,7 +2546,10 @@ sp_selection_set_mask(bool apply_clip_path, bool apply_to_layer) g_slist_free (mask_items); g_slist_free (apply_to_items); - sp_document_done (document); + if (apply_clip_path) + sp_document_done (document, SP_VERB_OBJECT_SET_CLIPPATH, _("Set clipping path")); + else + sp_document_done (document, SP_VERB_OBJECT_SET_MASK, _("Set mask")); } void sp_selection_unset_mask(bool apply_clip_path) { @@ -2467,12 +2557,12 @@ void sp_selection_unset_mask(bool apply_clip_path) { if (desktop == NULL) return; - SPDocument *document = SP_DT_DOCUMENT(desktop); - Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + SPDocument *document = sp_desktop_document(desktop); + Inkscape::Selection *selection = sp_desktop_selection(desktop); // check if something is selected if (selection->isEmpty()) { - desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select object(s) to remove mask from.")); + desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select object(s) to remove clippath or mask from.")); return; } @@ -2516,22 +2606,79 @@ void sp_selection_unset_mask(bool apply_clip_path) { obj->deleteObject(false); } + // remember parent and position of the item to which the clippath/mask was applied + Inkscape::XML::Node *parent = SP_OBJECT_REPR((*it).second)->parent(); + gint pos = SP_OBJECT_REPR((*it).second)->position(); + for (GSList *i = items_to_move; NULL != i; i = i->next) { - SPItem *item = SP_ITEM(desktop->currentLayer()->appendChildRepr((Inkscape::XML::Node *)i->data)); - selection->add((Inkscape::XML::Node *)i->data); + Inkscape::XML::Node *repr = (Inkscape::XML::Node *)i->data; + + // insert into parent, restore pos + parent->appendChild(repr); + repr->setPosition((pos + 1) > 0 ? (pos + 1) : 0); + + SPItem *mask_item = (SPItem *) sp_desktop_document (desktop)->getObjectByRepr(repr); + selection->add(repr); - // transform mask, so it is moved the same spot there mask was applied - NR::Matrix transform (item->transform); + // transform mask, so it is moved the same spot where mask was applied + NR::Matrix transform (mask_item->transform); transform *= (*it).second->transform; - sp_item_write_transform(item, SP_OBJECT_REPR(item), transform); + sp_item_write_transform(mask_item, SP_OBJECT_REPR(mask_item), transform); } g_slist_free (items_to_move); } - sp_document_done (document); + if (apply_clip_path) + sp_document_done (document, SP_VERB_OBJECT_UNSET_CLIPPATH, _("Release clipping path")); + else + sp_document_done (document, SP_VERB_OBJECT_UNSET_MASK, _("Release mask")); } +void fit_canvas_to_selection(SPDesktop *desktop) { + g_return_if_fail(desktop != NULL); + SPDocument *doc = sp_desktop_document(desktop); + + g_return_if_fail(doc != NULL); + g_return_if_fail(desktop->selection != NULL); + g_return_if_fail(!desktop->selection->isEmpty()); + NRRect bbox = {0,0,0,0}; + + desktop->selection->bounds(&bbox); + if (!empty(bbox)) { + doc->fitToRect(bbox); + } +}; + +void fit_canvas_to_drawing(SPDocument *doc) { + g_return_if_fail(doc != NULL); + NRRect bbox = {0,0,0,0}; + + sp_document_ensure_up_to_date (doc); + sp_item_invoke_bbox(SP_ITEM(doc->root), &bbox, sp_item_i2r_affine(SP_ITEM(doc->root)), TRUE); + + if (!empty(bbox)) { + doc->fitToRect(bbox); + } +}; + +void fit_canvas_to_selection_or_drawing(SPDesktop *desktop) { + g_return_if_fail(desktop != NULL); + SPDocument *doc = sp_desktop_document(desktop); + + g_return_if_fail(doc != NULL); + g_return_if_fail(desktop->selection != NULL); + + if (desktop->selection->isEmpty()) { + fit_canvas_to_drawing(doc); + } else { + fit_canvas_to_selection(desktop); + } + + sp_document_done(doc, SP_VERB_FIT_CANVAS_TO_DRAWING, + _("Fit page to selection")); +}; + /* Local Variables: mode:c++