X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fselection-chemistry.cpp;h=dfe47bee842f9b1b08aa2534c919099172723813;hb=24cd4c083c480d02226e8120b6211fea650a0004;hp=8e9bf45da237b7354988c383af9d3aab54c5e9bf;hpb=ac5acfb5b6792da4df2080ac55e18a734d2b5fc7;p=inkscape.git diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index 8e9bf45da..dfe47bee8 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -76,6 +76,7 @@ #include "helper/units.h" #include "sp-item.h" #include "box3d.h" +#include "persp3d.h" #include "unit-constants.h" #include "xml/simple-document.h" #include "sp-filter-reference.h" @@ -88,9 +89,7 @@ // For clippath editing #include "tools-switch.h" -#include "shape-editor.h" -#include "node-context.h" -#include "nodepath.h" +#include "ui/tool/node-tool.h" #include "ui/clipboard.h" @@ -730,7 +729,9 @@ sp_selection_raise(SPDesktop *desktop) } sp_document_done(sp_desktop_document(desktop), SP_VERB_SELECTION_RAISE, - //TRANSLATORS: Only put the word "Raise" in the translation. Means "to raise an object" in the undo history + //TRANSLATORS: only translate "string" in "context|string". + // For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS + // "Raise" means "to raise an object" in the undo history Q_("undo_action|Raise")); } @@ -1169,18 +1170,40 @@ selection_contains_both_clone_and_original(Inkscape::Selection *selection) return clone_with_original; } - /** Apply matrix to the selection. \a set_i2d is normally true, which means objects are in the original transform, synced with their reprs, and need to jump to the new transform in one go. A value of set_i2d==false is only used by seltrans when it's dragging objects live (not outlines); in that case, items are already in the new position, but the repr is in the old, and this function then simply updates the repr from item->transform. */ -void sp_selection_apply_affine(Inkscape::Selection *selection, Geom::Matrix const &affine, bool set_i2d) +void sp_selection_apply_affine(Inkscape::Selection *selection, Geom::Matrix const &affine, bool set_i2d, bool compensate) { if (selection->isEmpty()) return; + // For each perspective with a box in selection, check whether all boxes are selected and + // unlink all non-selected boxes. + Persp3D *persp; + Persp3D *transf_persp; + std::list plist = selection->perspList(); + for (std::list::iterator i = plist.begin(); i != plist.end(); ++i) { + persp = (Persp3D *) (*i); + + if (!persp3d_has_all_boxes_in_selection (persp, selection)) { + std::list selboxes = selection->box3DList(persp); + + // create a new perspective as a copy of the current one and link the selected boxes to it + transf_persp = persp3d_create_xml_element (SP_OBJECT_DOCUMENT(persp), persp->perspective_impl); + + for (std::list::iterator b = selboxes.begin(); b != selboxes.end(); ++b) + box3d_switch_perspectives(*b, persp, transf_persp); + } else { + transf_persp = persp; + } + + persp3d_apply_affine_transformation(transf_persp, affine); + } + for (GSList const *l = selection->itemList(); l != NULL; l = l->next) { SPItem *item = SP_ITEM(l->data); @@ -1240,7 +1263,7 @@ void sp_selection_apply_affine(Inkscape::Selection *selection, Geom::Matrix cons continue; for (SPObject *use = region->firstChild() ; use ; use = SP_OBJECT_NEXT(use)) { if (!SP_IS_USE(use)) continue; - sp_item_write_transform(SP_USE(use), SP_OBJECT_REPR(use), item->transform.inverse(), NULL); + sp_item_write_transform(SP_USE(use), SP_OBJECT_REPR(use), item->transform.inverse(), NULL, compensate); } } } else if (transform_clone_with_original) { @@ -1266,30 +1289,30 @@ void sp_selection_apply_affine(Inkscape::Selection *selection, Geom::Matrix cons if (prefs_parallel) { Geom::Matrix move = result * clone_move * t_inv; - sp_item_write_transform(item, SP_OBJECT_REPR(item), move, &move); + sp_item_write_transform(item, SP_OBJECT_REPR(item), move, &move, compensate); } else if (prefs_unmoved) { //if (SP_IS_USE(sp_use_get_original(SP_USE(item)))) // clone_move = Geom::identity(); Geom::Matrix move = result * clone_move; - sp_item_write_transform(item, SP_OBJECT_REPR(item), move, &t); + sp_item_write_transform(item, SP_OBJECT_REPR(item), move, &t, compensate); } } else { // just apply the result - sp_item_write_transform(item, SP_OBJECT_REPR(item), result, &t); + sp_item_write_transform(item, SP_OBJECT_REPR(item), result, &t, compensate); } } else { if (set_i2d) { sp_item_set_i2d_affine(item, sp_item_i2d_affine(item) * (Geom::Matrix)affine); } - sp_item_write_transform(item, SP_OBJECT_REPR(item), item->transform, NULL); + sp_item_write_transform(item, SP_OBJECT_REPR(item), item->transform, NULL, compensate); } // if we're moving the actual object, not just updating the repr, we can transform the // center by the same matrix (only necessary for non-translations) - if (set_i2d && item->isCenterSet() && !affine.isTranslation()) { + if (set_i2d && item->isCenterSet() && !(affine.isTranslation() || affine.isIdentity())) { item->setCenter(old_center * affine); SP_OBJECT(item)->updateRepr(); } @@ -1384,9 +1407,9 @@ sp_selection_skew_relative(Inkscape::Selection *selection, Geom::Point const &al sp_selection_apply_affine(selection, final); } -void sp_selection_move_relative(Inkscape::Selection *selection, Geom::Point const &move) +void sp_selection_move_relative(Inkscape::Selection *selection, Geom::Point const &move, bool compensate) { - sp_selection_apply_affine(selection, Geom::Matrix(Geom::Translate(move))); + sp_selection_apply_affine(selection, Geom::Matrix(Geom::Translate(move)), true, compensate); } void sp_selection_move_relative(Inkscape::Selection *selection, double dx, double dy) @@ -1714,53 +1737,52 @@ void sp_selection_next_patheffect_param(SPDesktop * dt) } } -void sp_selection_edit_clip_or_mask(SPDesktop * dt, bool clip) +/*bool has_path_recursive(SPObject *obj) { - if (!dt) return; - - Inkscape::Selection *selection = sp_desktop_selection(dt); - if ( selection && !selection->isEmpty() ) { - SPItem *item = selection->singleItem(); - if ( item ) { - SPObject *obj = NULL; - if (clip) - obj = item->clip_ref ? SP_OBJECT(item->clip_ref->getObject()) : NULL; - else - obj = item->mask_ref ? SP_OBJECT(item->mask_ref->getObject()) : NULL; - - if (obj) { - // obj is a group object, the children are the actual clippers - for ( SPObject *child = obj->children ; child ; child = child->next ) { - if ( SP_IS_ITEM(child) ) { - // If not already in nodecontext, goto it! - if (!tools_isactive(dt, TOOLS_NODES)) { - tools_switch(dt, TOOLS_NODES); - } - - ShapeEditor * shape_editor = dt->event_context->shape_editor; - // TODO: should we set the item for nodepath or knotholder or both? seems to work with both. - shape_editor->set_item(SP_ITEM(child), SH_NODEPATH); - shape_editor->set_item(SP_ITEM(child), SH_KNOTHOLDER); - Inkscape::NodePath::Path *np = shape_editor->get_nodepath(); - if (np) { - // take colors from prefs (same as used in outline mode) - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - np->helperpath_rgba = clip ? - prefs->getInt("/options/wireframecolors/clips", 0x00ff00ff) : - prefs->getInt("/options/wireframecolors/masks", 0x0000ffff); - np->helperpath_width = 1.0; - sp_nodepath_show_helperpath(np, true); - } - break; // break out of for loop after 1st encountered item - } - } - } else if (clip) { - dt->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("The selection has no applied clip path.")); - } else { - dt->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("The selection has no applied mask.")); - } + if (!obj) return false; + if (SP_IS_PATH(obj)) { + return true; + } + if (SP_IS_GROUP(obj) || SP_IS_OBJECTGROUP(obj)) { + for (SPObject *c = obj->children; c; c = c->next) { + if (has_path_recursive(c)) return true; } } + return false; +}*/ + +void sp_selection_edit_clip_or_mask(SPDesktop * /*dt*/, bool /*clip*/) +{ + return; + /*if (!dt) return; + using namespace Inkscape::UI; + + Inkscape::Selection *selection = sp_desktop_selection(dt); + if (!selection || selection->isEmpty()) return; + + GSList const *items = selection->itemList(); + bool has_path = false; + for (GSList *i = const_cast(items); i; i= i->next) { + SPItem *item = SP_ITEM(i->data); + SPObject *search = clip + ? SP_OBJECT(item->clip_ref ? item->clip_ref->getObject() : NULL) + : SP_OBJECT(item->mask_ref ? item->mask_ref->getObject() : NULL); + has_path |= has_path_recursive(search); + if (has_path) break; + } + if (has_path) { + if (!tools_isactive(dt, TOOLS_NODES)) { + tools_switch(dt, TOOLS_NODES); + } + ink_node_tool_set_mode(INK_NODE_TOOL(dt->event_context), + clip ? NODE_TOOL_EDIT_CLIPPING_PATHS : NODE_TOOL_EDIT_MASKS); + } else if (clip) { + dt->messageStack()->flash(Inkscape::WARNING_MESSAGE, + _("The selection has no applied clip path.")); + } else { + dt->messageStack()->flash(Inkscape::WARNING_MESSAGE, + _("The selection has no applied mask.")); + }*/ } @@ -2907,10 +2929,12 @@ void sp_selection_unset_mask(SPDesktop *desktop, bool apply_clip_path) { } /** - * Returns true if an undoable change should be recorded. + * \param with_margins margins defined in the xml under + * "fit-margin-..." attributes. See SPDocument::fitToRect. + * \return true if an undoable change should be recorded. */ bool -fit_canvas_to_selection(SPDesktop *desktop) +fit_canvas_to_selection(SPDesktop *desktop, bool with_margins) { g_return_val_if_fail(desktop != NULL, false); SPDocument *doc = sp_desktop_document(desktop); @@ -2924,7 +2948,7 @@ fit_canvas_to_selection(SPDesktop *desktop) } Geom::OptRect const bbox(desktop->selection->bounds()); if (bbox) { - doc->fitToRect(*bbox); + doc->fitToRect(*bbox, with_margins); return true; } else { return false; @@ -2943,8 +2967,12 @@ verb_fit_canvas_to_selection(SPDesktop *const desktop) } } +/** + * \param with_margins margins defined in the xml under + * "fit-margin-..." attributes. See SPDocument::fitToRect. + */ bool -fit_canvas_to_drawing(SPDocument *doc) +fit_canvas_to_drawing(SPDocument *doc, bool with_margins) { g_return_val_if_fail(doc != NULL, false); @@ -2952,7 +2980,7 @@ fit_canvas_to_drawing(SPDocument *doc) SPItem const *const root = SP_ITEM(doc->root); Geom::OptRect const bbox(root->getBounds(sp_item_i2d_affine(root))); if (bbox) { - doc->fitToRect(*bbox); + doc->fitToRect(*bbox, with_margins); return true; } else { return false; @@ -2968,6 +2996,11 @@ verb_fit_canvas_to_drawing(SPDesktop *desktop) } } +/** + * Fits canvas to selection or drawing with margins from + * "fit-margin-..." attributes. See SPDocument::fitToRect and + * ui/dialog/page-sizer. + */ void fit_canvas_to_selection_or_drawing(SPDesktop *desktop) { g_return_if_fail(desktop != NULL); SPDocument *doc = sp_desktop_document(desktop); @@ -2976,8 +3009,8 @@ void fit_canvas_to_selection_or_drawing(SPDesktop *desktop) { g_return_if_fail(desktop->selection != NULL); bool const changed = ( desktop->selection->isEmpty() - ? fit_canvas_to_drawing(doc) - : fit_canvas_to_selection(desktop) ); + ? fit_canvas_to_drawing(doc, true) + : fit_canvas_to_selection(desktop, true) ); if (changed) { sp_document_done(sp_desktop_document(desktop), SP_VERB_FIT_CANVAS_TO_SELECTION_OR_DRAWING, _("Fit Page to Selection or Drawing"));