summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: bbc1c8d)
raw | patch | inline | side by side (parent: bbc1c8d)
author | Josh Andler <scislac@gmail.com> | |
Sat, 20 Mar 2010 19:15:35 +0000 (12:15 -0700) | ||
committer | Josh Andler <scislac@gmail.com> | |
Sat, 20 Mar 2010 19:15:35 +0000 (12:15 -0700) |
src/selection-chemistry.cpp | patch | blob | history |
index 17875075e0d5d2d8008152d012db00d762c05c91..730467ee548bd90479e73f974addfe32c101eb49 100644 (file)
* bulia byak <buliabyak@users.sf.net>
* Andrius R. <knutux@gmail.com>
* Jon A. Cruz <jon@joncruz.org>
+ * Martin Sucha <martin.sucha-inkscape@jts-sro.sk>
*
* Copyright (C) 1999-2010 authors
* Copyright (C) 2001-2002 Ximian, Inc.
sp_edit_select_all_full(desktop, true, true);
}
-void sp_selection_group_impl(GSList const *reprs_to_group, Inkscape::XML::Node *group, Inkscape::XML::Document *xml_doc, SPDocument *doc) {
- GSList *p = g_slist_copy((GSList *) reprs_to_group);
-
+void sp_selection_group_impl(GSList *p, Inkscape::XML::Node *group, Inkscape::XML::Document *xml_doc, SPDocument *doc) {
+
p = g_slist_sort(p, (GCompareFunc) sp_repr_compare_position);
// Remember the position and parent of the topmost object.
}
GSList const *l = (GSList *) selection->reprList();
-
+
+ GSList *p = g_slist_copy((GSList *) l);
+
+ selection->clear();
Inkscape::XML::Node *group = xml_doc->createElement("svg:g");
- sp_selection_group_impl(l, group, xml_doc, doc);
+ sp_selection_group_impl(p, group, xml_doc, doc);
sp_document_done(sp_desktop_document(desktop), SP_VERB_SELECTION_GROUP,
_("Group"));
- selection->clear();
selection->set(group);
Inkscape::GC::release(group);
}
/* We do not allow ungrouping <svg> etc. (lauris) */
if (strcmp(SP_OBJECT_REPR(group)->name(), "svg:g") && strcmp(SP_OBJECT_REPR(group)->name(), "svg:switch")) {
// keep the non-group item in the new selection
- selection->add(group);
+ new_select = g_slist_append(new_select, group);
continue;
}
@@ -2858,11 +2860,16 @@ sp_selection_set_mask(SPDesktop *desktop, bool apply_clip_path, bool apply_to_la
GSList *items = g_slist_copy((GSList *) selection->itemList());
items = g_slist_sort(items, (GCompareFunc) sp_object_compare_position);
+
+ // See lp bug #542004
+ selection->clear();
// create a list of duplicates
GSList *mask_items = NULL;
GSList *apply_to_items = NULL;
GSList *items_to_delete = NULL;
+ GSList *items_to_select = NULL;
+
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
bool topmost = prefs->getBool("/options/maskobject/topmost", true);
bool remove_original = prefs->getBool("/options/maskobject/remove", true);
@@ -2871,15 +2878,18 @@ sp_selection_set_mask(SPDesktop *desktop, bool apply_clip_path, bool apply_to_la
if (apply_to_layer) {
// all selected items are used for mask, which is applied to a layer
apply_to_items = g_slist_prepend(apply_to_items, desktop->currentLayer());
-
+
for (GSList *i = items; i != NULL; i = i->next) {
Inkscape::XML::Node *dup = (SP_OBJECT_REPR(i->data))->duplicate(xml_doc);
mask_items = g_slist_prepend(mask_items, dup);
- if (remove_original) {
- SPObject *item = SP_OBJECT(i->data);
+ SPObject *item = SP_OBJECT(i->data);
+ if (remove_original) {
items_to_delete = g_slist_prepend(items_to_delete, item);
}
+ else {
+ items_to_select = g_slist_prepend(items_to_select, item);
+ }
}
} else if (!topmost) {
// topmost item is used as a mask, which is applied to other items in a selection
@@ -2894,11 +2904,13 @@ sp_selection_set_mask(SPDesktop *desktop, bool apply_clip_path, bool apply_to_la
for (i = i->next; i != NULL; i = i->next) {
apply_to_items = g_slist_prepend(apply_to_items, i->data);
+ items_to_select = g_slist_prepend(items_to_select, i->data);
}
} else {
GSList *i = NULL;
for (i = items; NULL != i->next; i = i->next) {
apply_to_items = g_slist_prepend(apply_to_items, i->data);
+ items_to_select = g_slist_prepend(items_to_select, i->data);
}
Inkscape::XML::Node *dup = (SP_OBJECT_REPR(i->data))->duplicate(xml_doc);
@@ -2925,20 +2937,20 @@ sp_selection_set_mask(SPDesktop *desktop, bool apply_clip_path, bool apply_to_la
for (GSList *i = apply_to_items ; NULL != i ; i = i->next) {
reprs_to_group = g_slist_prepend(reprs_to_group, SP_OBJECT_REPR(i->data));
- selection->remove(SP_OBJECT(i->data));
+ items_to_select = g_slist_remove(items_to_select, i->data);
}
reprs_to_group = g_slist_reverse(reprs_to_group);
sp_selection_group_impl(reprs_to_group, group, xml_doc, doc);
-
- g_slist_free(reprs_to_group);
+
+ reprs_to_group = NULL;
// apply clip/mask only to newly created group
g_slist_free(apply_to_items);
apply_to_items = NULL;
apply_to_items = g_slist_prepend(apply_to_items, doc->getObjectByRepr(group));
- selection->add(group);
+ items_to_select = g_slist_prepend(items_to_select, doc->getObjectByRepr(group));
Inkscape::GC::release(group);
}
@@ -2978,7 +2990,7 @@ sp_selection_set_mask(SPDesktop *desktop, bool apply_clip_path, bool apply_to_la
Inkscape::XML::Node *spnew = current->duplicate(xml_doc);
gint position = current->position();
- selection->remove(current);
+ items_to_select = g_slist_remove(items_to_select, item);
current->parent()->appendChild(group);
sp_repr_unparent(current);
group->appendChild(spnew);
@@ -2987,7 +2999,7 @@ sp_selection_set_mask(SPDesktop *desktop, bool apply_clip_path, bool apply_to_la
// Apply clip/mask to group instead
apply_mask_to = group;
- selection->add(group);
+ items_to_select = g_slist_prepend(items_to_select, doc->getObjectByRepr(group));
Inkscape::GC::release(spnew);
Inkscape::GC::release(group);
}
@@ -3002,8 +3014,14 @@ sp_selection_set_mask(SPDesktop *desktop, bool apply_clip_path, bool apply_to_la
for (GSList *i = items_to_delete; NULL != i; i = i->next) {
SPObject *item = SP_OBJECT(i->data);
item->deleteObject(false);
+ items_to_select = g_slist_remove(items_to_select, item);
}
g_slist_free(items_to_delete);
+
+ items_to_select = g_slist_reverse(items_to_select);
+
+ selection->addList(items_to_select);
+ g_slist_free(items_to_select);
if (apply_clip_path)
sp_document_done(doc, SP_VERB_OBJECT_SET_CLIPPATH, _("Set clipping path"));
gchar const *attributeName = apply_clip_path ? "clip-path" : "mask";
std::map<SPObject*,SPItem*> referenced_objects;
+ GSList *items = g_slist_copy((GSList *) selection->itemList());
+ selection->clear();
+
GSList *items_to_ungroup = NULL;
+ GSList *items_to_select = g_slist_copy(items);
+ items_to_select = g_slist_reverse(items_to_select);
+
// SPObject* refers to a group containing the clipped path or mask itself,
// whereas SPItem* refers to the item being clipped or masked
- for (GSList const *i = selection->itemList(); NULL != i; i = i->next) {
+ for (GSList const *i = items; NULL != i; i = i->next) {
if (remove_original) {
// remember referenced mask/clippath, so orphaned masks can be moved back to document
SPItem *item = reinterpret_cast<SPItem *>(i->data);
}
}
+ g_slist_free(items);
// restore mask objects into a document
for ( std::map<SPObject*,SPItem*>::iterator it = referenced_objects.begin() ; it != referenced_objects.end() ; ++it) {
repr->setPosition((pos + 1) > 0 ? (pos + 1) : 0);
SPItem *mask_item = (SPItem *) sp_desktop_document(desktop)->getObjectByRepr(repr);
- selection->add(repr);
+ items_to_select = g_slist_prepend(items_to_select, mask_item);
// transform mask, so it is moved the same spot where mask was applied
Geom::Matrix transform(mask_item->transform);
// ungroup marked groups added when setting mask
for (GSList *i = items_to_ungroup ; NULL != i ; i = i->next) {
- selection->remove(SP_GROUP(i->data));
+ items_to_select = g_slist_remove(items_to_select, SP_GROUP(i->data));
GSList *children = NULL;
sp_item_group_ungroup(SP_GROUP(i->data), &children, false);
- selection->addList(children);
- g_slist_free(children);
+ items_to_select = g_slist_concat(children, items_to_select);
}
g_slist_free(items_to_ungroup);
+
+ // rebuild selection
+ items_to_select = g_slist_reverse(items_to_select);
+ selection->addList(items_to_select);
+ g_slist_free(items_to_select);
if (apply_clip_path)
sp_document_done(doc, SP_VERB_OBJECT_UNSET_CLIPPATH, _("Release clipping path"));