Merge lp:~inkscape+alexander/inkscape/clones into lp:~inkscape.dev/inkscape/trunk
- clones
- Merge into trunk
Status: | Superseded |
---|---|
Proposed branch: | lp:~inkscape+alexander/inkscape/clones |
Merge into: | lp:~inkscape.dev/inkscape/trunk |
Diff against target: |
670 lines (+171/-101) 5 files modified
src/menus-skeleton.h (+1/-0) src/object-set.h (+14/-2) src/selection-chemistry.cpp (+150/-99) src/verbs.cpp (+5/-0) src/verbs.h (+1/-0) |
To merge this branch: | bzr merge lp:~inkscape+alexander/inkscape/clones |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Martin Owens | Pending | ||
Mc | code, refactor | Pending | |
Review via email: mp+309506@code.launchpad.net |
This proposal supersedes a proposal from 2016-10-20.
This proposal has been superseded by a proposal from 2016-11-04.
Commit message
Description of the change
I added "Edit->
This is one of the features from this branch: https:/
Mc (mc...) wrote : Posted in a previous version of this proposal | # |
Mc (mc...) wrote : Posted in a previous version of this proposal | # |
Ok, so with the small change I did to the codebase, here's what I think should be done:
-> add a "bool skip_undo" flag to ::setMask(), ::unsetMask(), and ::unlink() similar to what's done in other methods in the file. (Also add it to your recursive method).
-> make a ObjectSet with no SPDesktop (just the SPDocument) containing the selection, so that it does not flash recursively.
-> make all the calls with the skip_undo flag on your ObjectSet.
Alexander Brock (brock-alexander) wrote : Posted in a previous version of this proposal | # |
> Ok, so with the small change I did to the codebase, here's what I think should
> be done:
>
> -> add a "bool skip_undo" flag to ::setMask(), ::unsetMask(), and ::unlink()
> similar to what's done in other methods in the file. (Also add it to your
> recursive method).
>
> -> make a ObjectSet with no SPDesktop (just the SPDocument) containing the
> selection, so that it does not flash recursively.
>
> -> make all the calls with the skip_undo flag on your ObjectSet.
I tried to merge your changes with my branch, failed and restarted from scratch.
I added an unlinkRecursive method to ObjectSet, added the bool skip_undo where I needed it and force-pushed the code to the old location (lp:~inkscape+alexander/inkscape/clones).
- 15194. By Jordi Mas
-
[Bug #1636086] Update Catalan translation for Inkscape 0.92.
- 15195. By Mc
-
allows for denser screens in zoom correction factors
- 15196. By FirasH
-
[Bug #1574561] Italian translation update.
- 15197. By Jabiertxof
-
Close the bounding box path LPE
- 15198. By Jabiertxof
-
Fix fill between many LPE to start up with current path
- 15199. By Jabiertxof
-
Update branding folder
- 15200. By Jabiertxof
-
Fix bug:1013141 crash deleting LPE
- 15201. By houz
-
fix none color in palettes with scrollbars
- 15202. By houz
-
fix prefs icon
- 15203. By Mc
-
Add some unit tests for object-set cppification
- 15204. By Mc
-
Revert two changes from r15177
Mc (mc...) wrote : | # |
Good !
I did a merge proposal to your branch to propose a simpler version of the recursive function, though it can be improved and further simplified by putting the unclip/reclip business in the unlink() function where it probably belongs.
If you find the courage, you can also propose unit tests to test the function (see testfiles/
- 15205. By Alexander Brock <email address hidden>
-
Add "Edit->
Clone-> Unlink Clones recursively" function (ObjectSet: :unlinkRecursiv e) - 15206. By Alexander Brock <email address hidden>
-
Preserve clips when unlinking clones
- 15207. By Alexander Brock <email address hidden>
-
Make ObjectSet::unlink() work for clones which are both clipped and masked
- 15208. By Alexander Brock <email address hidden>
-
Remove duplicate code from unlinkRecursive() and fix issue with clones of groups
- 15209. By Alexander Brock <email address hidden>
-
Fix selection issue with ObjectSet:
:unlinkRecursiv e() and add tests for it.
Unmerged revisions
Preview Diff
1 | === modified file 'src/menus-skeleton.h' | |||
2 | --- src/menus-skeleton.h 2016-04-15 14:39:49 +0000 | |||
3 | +++ src/menus-skeleton.h 2016-11-04 12:38:02 +0000 | |||
4 | @@ -66,6 +66,7 @@ | |||
5 | 66 | " <verb verb-id=\"EditClone\" />\n" | 66 | " <verb verb-id=\"EditClone\" />\n" |
6 | 67 | " <verb verb-id=\"DialogClonetiler\" />\n" | 67 | " <verb verb-id=\"DialogClonetiler\" />\n" |
7 | 68 | " <verb verb-id=\"EditUnlinkClone\" />\n" | 68 | " <verb verb-id=\"EditUnlinkClone\" />\n" |
8 | 69 | " <verb verb-id=\"EditUnlinkCloneRecursive\" />\n" | ||
9 | 69 | " <verb verb-id=\"EditRelinkClone\" />\n" | 70 | " <verb verb-id=\"EditRelinkClone\" />\n" |
10 | 70 | " <verb verb-id=\"EditCloneSelectOriginal\" />\n" | 71 | " <verb verb-id=\"EditCloneSelectOriginal\" />\n" |
11 | 71 | " <verb verb-id=\"EditCloneOriginalPathLPE\" />\n" | 72 | " <verb verb-id=\"EditCloneOriginalPathLPE\" />\n" |
12 | 72 | 73 | ||
13 | === modified file 'src/object-set.h' | |||
14 | --- src/object-set.h 2016-11-03 23:28:50 +0000 | |||
15 | +++ src/object-set.h 2016-11-04 12:38:02 +0000 | |||
16 | @@ -330,7 +330,19 @@ | |||
17 | 330 | void deleteItems(); | 330 | void deleteItems(); |
18 | 331 | void duplicate(bool suppressDone = false, bool duplicateLayer = false); | 331 | void duplicate(bool suppressDone = false, bool duplicateLayer = false); |
19 | 332 | void clone(); | 332 | void clone(); |
21 | 333 | void unlink(); | 333 | |
22 | 334 | /** | ||
23 | 335 | * @brief Unlink all directly selected clones. | ||
24 | 336 | * @param skip_undo If this is set to true the call to DocumentUndo::done is omitted. | ||
25 | 337 | * @return True if anything was unlinked, otherwise false. | ||
26 | 338 | */ | ||
27 | 339 | bool unlink(bool skip_undo = false); | ||
28 | 340 | /** | ||
29 | 341 | * @brief Recursively unlink any clones present in the current selection, | ||
30 | 342 | * including clones which are used to clip other objects, groups of clones etc. | ||
31 | 343 | * @return true if anything was unlinked, otherwise false. | ||
32 | 344 | */ | ||
33 | 345 | bool unlinkRecursive(const bool skip_undo = false); | ||
34 | 334 | void relink(); | 346 | void relink(); |
35 | 335 | void cloneOriginal(); | 347 | void cloneOriginal(); |
36 | 336 | void cloneOriginalPathLPE(); | 348 | void cloneOriginalPathLPE(); |
37 | @@ -376,7 +388,7 @@ | |||
38 | 376 | void createBitmapCopy(); | 388 | void createBitmapCopy(); |
39 | 377 | void setMask(bool apply_clip_path, bool apply_to_layer = false, bool skip_undo = false); | 389 | void setMask(bool apply_clip_path, bool apply_to_layer = false, bool skip_undo = false); |
40 | 378 | void editMask(bool clip); | 390 | void editMask(bool clip); |
42 | 379 | void unsetMask(bool apply_clip_path); | 391 | void unsetMask(const bool apply_clip_path, const bool skip_undo = false); |
43 | 380 | void setClipGroup(); | 392 | void setClipGroup(); |
44 | 381 | 393 | ||
45 | 382 | // moves | 394 | // moves |
46 | 383 | 395 | ||
47 | === modified file 'src/selection-chemistry.cpp' | |||
48 | --- src/selection-chemistry.cpp 2016-11-02 23:08:41 +0000 | |||
49 | +++ src/selection-chemistry.cpp 2016-11-04 12:38:02 +0000 | |||
50 | @@ -124,8 +124,8 @@ | |||
51 | 124 | desktop->messageStack()->flash(msgType, msg); | 124 | desktop->messageStack()->flash(msgType, msg); |
52 | 125 | } else { | 125 | } else { |
53 | 126 | if (msgType == Inkscape::IMMEDIATE_MESSAGE || | 126 | if (msgType == Inkscape::IMMEDIATE_MESSAGE || |
56 | 127 | msgType == Inkscape::WARNING_MESSAGE || | 127 | msgType == Inkscape::WARNING_MESSAGE || |
57 | 128 | msgType == Inkscape::ERROR_MESSAGE) { | 128 | msgType == Inkscape::ERROR_MESSAGE) { |
58 | 129 | g_printerr("%s\n", msg.c_str()); | 129 | g_printerr("%s\n", msg.c_str()); |
59 | 130 | } | 130 | } |
60 | 131 | } | 131 | } |
61 | @@ -273,8 +273,8 @@ | |||
62 | 273 | for(auto i = boost::rbegin(selList); i != boost::rend(selList); ++i) { | 273 | for(auto i = boost::rbegin(selList); i != boost::rend(selList); ++i) { |
63 | 274 | SPItem *item = *i; | 274 | SPItem *item = *i; |
64 | 275 | if( item && | 275 | if( item && |
67 | 276 | !dt->isLayer(item) && | 276 | !dt->isLayer(item) && |
68 | 277 | (!item->isLocked())) | 277 | (!item->isLocked())) |
69 | 278 | { | 278 | { |
70 | 279 | items.push_back(item); | 279 | items.push_back(item); |
71 | 280 | } | 280 | } |
72 | @@ -378,19 +378,19 @@ | |||
73 | 378 | void ObjectSet::deleteItems() | 378 | void ObjectSet::deleteItems() |
74 | 379 | { | 379 | { |
75 | 380 | if(desktop() && tools_isactive(desktop(), TOOLS_TEXT)){ | 380 | if(desktop() && tools_isactive(desktop(), TOOLS_TEXT)){ |
77 | 381 | if (Inkscape::UI::Tools::sp_text_delete_selection(desktop()->event_context)) { | 381 | if (Inkscape::UI::Tools::sp_text_delete_selection(desktop()->event_context)) { |
78 | 382 | DocumentUndo::done(desktop()->getDocument(), SP_VERB_CONTEXT_TEXT, | 382 | DocumentUndo::done(desktop()->getDocument(), SP_VERB_CONTEXT_TEXT, |
79 | 383 | _("Delete text")); | 383 | _("Delete text")); |
80 | 384 | return; | 384 | return; |
82 | 385 | } | 385 | } |
83 | 386 | } | 386 | } |
84 | 387 | 387 | ||
87 | 388 | if (isEmpty()) { | 388 | if (isEmpty()) { |
88 | 389 | selection_display_message(desktop(),Inkscape::WARNING_MESSAGE, _("<b>Nothing</b> was deleted.")); | 389 | selection_display_message(desktop(),Inkscape::WARNING_MESSAGE, _("<b>Nothing</b> was deleted.")); |
89 | 390 | return; | 390 | return; |
90 | 391 | } | 391 | } |
91 | 392 | std::vector<SPItem*> selected(items().begin(), items().end()); | 392 | std::vector<SPItem*> selected(items().begin(), items().end()); |
93 | 393 | clear(); | 393 | clear(); |
94 | 394 | sp_selection_delete_impl(selected); | 394 | sp_selection_delete_impl(selected); |
95 | 395 | if(SPDesktop *d = desktop()){ | 395 | if(SPDesktop *d = desktop()){ |
96 | 396 | d->currentLayer()->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); | 396 | d->currentLayer()->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); |
97 | @@ -404,7 +404,7 @@ | |||
98 | 404 | tools_switch( d, tools_active( d ) ); | 404 | tools_switch( d, tools_active( d ) ); |
99 | 405 | } | 405 | } |
100 | 406 | if(document()) | 406 | if(document()) |
102 | 407 | DocumentUndo::done(document(), SP_VERB_EDIT_DELETE, | 407 | DocumentUndo::done(document(), SP_VERB_EDIT_DELETE, |
103 | 408 | _("Delete")); | 408 | _("Delete")); |
104 | 409 | 409 | ||
105 | 410 | } | 410 | } |
106 | @@ -430,7 +430,7 @@ | |||
107 | 430 | //TODO: understand why layer management is tied to desktop and not to document. | 430 | //TODO: understand why layer management is tied to desktop and not to document. |
108 | 431 | return; | 431 | return; |
109 | 432 | } | 432 | } |
111 | 433 | 433 | ||
112 | 434 | SPDocument *doc = document(); | 434 | SPDocument *doc = document(); |
113 | 435 | 435 | ||
114 | 436 | if(!doc) | 436 | if(!doc) |
115 | @@ -586,11 +586,11 @@ | |||
116 | 586 | for (auto& child: from->children) { | 586 | for (auto& child: from->children) { |
117 | 587 | SPItem *item = dynamic_cast<SPItem *>(&child); | 587 | SPItem *item = dynamic_cast<SPItem *>(&child); |
118 | 588 | if (item && | 588 | if (item && |
124 | 589 | !desktop->isLayer(item) && | 589 | !desktop->isLayer(item) && |
125 | 590 | (!onlysensitive || !item->isLocked()) && | 590 | (!onlysensitive || !item->isLocked()) && |
126 | 591 | (!onlyvisible || !desktop->itemIsHidden(item)) && | 591 | (!onlyvisible || !desktop->itemIsHidden(item)) && |
127 | 592 | (exclude.empty() || exclude.end() == std::find(exclude.begin(), exclude.end(), &child)) | 592 | (exclude.empty() || exclude.end() == std::find(exclude.begin(), exclude.end(), &child)) |
128 | 593 | ) | 593 | ) |
129 | 594 | { | 594 | { |
130 | 595 | list.insert(list.begin(),item); | 595 | list.insert(list.begin(),item); |
131 | 596 | } | 596 | } |
132 | @@ -628,10 +628,10 @@ | |||
133 | 628 | inlayer = PREFS_SELECTION_ALL; | 628 | inlayer = PREFS_SELECTION_ALL; |
134 | 629 | 629 | ||
135 | 630 | switch (inlayer) { | 630 | switch (inlayer) { |
137 | 631 | case PREFS_SELECTION_LAYER: { | 631 | case PREFS_SELECTION_LAYER: { |
138 | 632 | if ( (onlysensitive && dynamic_cast<SPItem *>(dt->currentLayer())->isLocked()) || | 632 | if ( (onlysensitive && dynamic_cast<SPItem *>(dt->currentLayer())->isLocked()) || |
139 | 633 | (onlyvisible && dt->itemIsHidden(dynamic_cast<SPItem *>(dt->currentLayer()))) ) | 633 | (onlyvisible && dt->itemIsHidden(dynamic_cast<SPItem *>(dt->currentLayer()))) ) |
141 | 634 | return; | 634 | return; |
142 | 635 | 635 | ||
143 | 636 | std::vector<SPItem*> all_items = sp_item_group_item_list(dynamic_cast<SPGroup *>(dt->currentLayer())); | 636 | std::vector<SPItem*> all_items = sp_item_group_item_list(dynamic_cast<SPGroup *>(dt->currentLayer())); |
144 | 637 | 637 | ||
145 | @@ -649,17 +649,17 @@ | |||
146 | 649 | } | 649 | } |
147 | 650 | } | 650 | } |
148 | 651 | 651 | ||
160 | 652 | break; | 652 | break; |
161 | 653 | } | 653 | } |
162 | 654 | case PREFS_SELECTION_LAYER_RECURSIVE: { | 654 | case PREFS_SELECTION_LAYER_RECURSIVE: { |
163 | 655 | std::vector<SPItem*> x; | 655 | std::vector<SPItem*> x; |
164 | 656 | items = get_all_items(x, dt->currentLayer(), dt, onlyvisible, onlysensitive, FALSE, exclude); | 656 | items = get_all_items(x, dt->currentLayer(), dt, onlyvisible, onlysensitive, FALSE, exclude); |
165 | 657 | break; | 657 | break; |
166 | 658 | } | 658 | } |
167 | 659 | default: { | 659 | default: { |
168 | 660 | std::vector<SPItem*> x; | 660 | std::vector<SPItem*> x; |
169 | 661 | items = get_all_items(x, dt->currentRoot(), dt, onlyvisible, onlysensitive, FALSE, exclude); | 661 | items = get_all_items(x, dt->currentRoot(), dt, onlyvisible, onlysensitive, FALSE, exclude); |
170 | 662 | break; | 662 | break; |
171 | 663 | } | 663 | } |
172 | 664 | } | 664 | } |
173 | 665 | 665 | ||
174 | @@ -787,7 +787,7 @@ | |||
175 | 787 | } | 787 | } |
176 | 788 | 788 | ||
177 | 789 | auto item = items().begin(); // leaving this because it will be useful for | 789 | auto item = items().begin(); // leaving this because it will be useful for |
179 | 790 | // future implementation of complex pop ungrouping | 790 | // future implementation of complex pop ungrouping |
180 | 791 | SPItem *obj = *item; | 791 | SPItem *obj = *item; |
181 | 792 | SPItem *parent_group = static_cast<SPItem*>(obj->parent); | 792 | SPItem *parent_group = static_cast<SPItem*>(obj->parent); |
182 | 793 | if (!SP_IS_GROUP(parent_group) || SP_IS_LAYER(parent_group)) { | 793 | if (!SP_IS_GROUP(parent_group) || SP_IS_LAYER(parent_group)) { |
183 | @@ -806,7 +806,7 @@ | |||
184 | 806 | 806 | ||
185 | 807 | if(document()) | 807 | if(document()) |
186 | 808 | DocumentUndo::done(document(), SP_VERB_SELECTION_UNGROUP_POP_SELECTION, | 808 | DocumentUndo::done(document(), SP_VERB_SELECTION_UNGROUP_POP_SELECTION, |
188 | 809 | _("Pop selection from group")); | 809 | _("Pop selection from group")); |
189 | 810 | 810 | ||
190 | 811 | } | 811 | } |
191 | 812 | 812 | ||
192 | @@ -883,7 +883,7 @@ | |||
193 | 883 | ungroup_impl(this); | 883 | ungroup_impl(this); |
194 | 884 | if(document()) | 884 | if(document()) |
195 | 885 | DocumentUndo::done(document(), SP_VERB_SELECTION_UNGROUP, | 885 | DocumentUndo::done(document(), SP_VERB_SELECTION_UNGROUP, |
197 | 886 | _("Ungroup")); | 886 | _("Ungroup")); |
198 | 887 | } | 887 | } |
199 | 888 | 888 | ||
200 | 889 | // TODO replace it with ObjectSet::degroup_list | 889 | // TODO replace it with ObjectSet::degroup_list |
201 | @@ -964,7 +964,7 @@ | |||
202 | 964 | bool sp_item_repr_compare_position_bool(SPObject const *first, SPObject const *second) | 964 | bool sp_item_repr_compare_position_bool(SPObject const *first, SPObject const *second) |
203 | 965 | { | 965 | { |
204 | 966 | return sp_repr_compare_position(((SPItem*)first)->getRepr(), | 966 | return sp_repr_compare_position(((SPItem*)first)->getRepr(), |
206 | 967 | ((SPItem*)second)->getRepr())<0; | 967 | ((SPItem*)second)->getRepr())<0; |
207 | 968 | } | 968 | } |
208 | 969 | 969 | ||
209 | 970 | void ObjectSet::raise(bool skip_undo){ | 970 | void ObjectSet::raise(bool skip_undo){ |
210 | @@ -1015,8 +1015,8 @@ | |||
211 | 1015 | } | 1015 | } |
212 | 1016 | if(document() && !skip_undo) | 1016 | if(document() && !skip_undo) |
213 | 1017 | DocumentUndo::done(document(), SP_VERB_SELECTION_RAISE, | 1017 | DocumentUndo::done(document(), SP_VERB_SELECTION_RAISE, |
216 | 1018 | //TRANSLATORS: "Raise" means "to raise an object" in the undo history | 1018 | //TRANSLATORS: "Raise" means "to raise an object" in the undo history |
217 | 1019 | C_("Undo action", "Raise")); | 1019 | C_("Undo action", "Raise")); |
218 | 1020 | } | 1020 | } |
219 | 1021 | 1021 | ||
220 | 1022 | 1022 | ||
221 | @@ -1042,7 +1042,7 @@ | |||
222 | 1042 | } | 1042 | } |
223 | 1043 | if (document() && !skip_undo) { | 1043 | if (document() && !skip_undo) { |
224 | 1044 | DocumentUndo::done(document(), SP_VERB_SELECTION_TO_FRONT, | 1044 | DocumentUndo::done(document(), SP_VERB_SELECTION_TO_FRONT, |
226 | 1045 | _("Raise to top")); | 1045 | _("Raise to top")); |
227 | 1046 | } | 1046 | } |
228 | 1047 | } | 1047 | } |
229 | 1048 | 1048 | ||
230 | @@ -1096,8 +1096,8 @@ | |||
231 | 1096 | } | 1096 | } |
232 | 1097 | if(document() && !skip_undo) | 1097 | if(document() && !skip_undo) |
233 | 1098 | DocumentUndo::done(document(), SP_VERB_SELECTION_LOWER, | 1098 | DocumentUndo::done(document(), SP_VERB_SELECTION_LOWER, |
236 | 1099 | //TRANSLATORS: "Lower" means "to lower an object" in the undo history | 1099 | //TRANSLATORS: "Lower" means "to lower an object" in the undo history |
237 | 1100 | C_("Undo action", "Lower")); | 1100 | C_("Undo action", "Lower")); |
238 | 1101 | } | 1101 | } |
239 | 1102 | 1102 | ||
240 | 1103 | 1103 | ||
241 | @@ -1183,7 +1183,7 @@ | |||
242 | 1183 | return NULL; | 1183 | return NULL; |
243 | 1184 | 1184 | ||
244 | 1185 | if ((dynamic_cast<SPGroup *>(object) && object->firstChild()) || | 1185 | if ((dynamic_cast<SPGroup *>(object) && object->firstChild()) || |
246 | 1186 | (dynamic_cast<SPText *>(object) && object->firstChild() && object->firstChild()->getNext() == NULL)) { | 1186 | (dynamic_cast<SPText *>(object) && object->firstChild() && object->firstChild()->getNext() == NULL)) { |
247 | 1187 | // if this is a text with exactly one tspan child, merge the style of that tspan as well | 1187 | // if this is a text with exactly one tspan child, merge the style of that tspan as well |
248 | 1188 | // If this is a group, merge the style of its topmost (last) child with style | 1188 | // If this is a group, merge the style of its topmost (last) child with style |
249 | 1189 | auto list = object->children | boost::adaptors::reversed; | 1189 | auto list = object->children | boost::adaptors::reversed; |
250 | @@ -1268,7 +1268,7 @@ | |||
251 | 1268 | // check if something is selected | 1268 | // check if something is selected |
252 | 1269 | if (isEmpty()) { | 1269 | if (isEmpty()) { |
253 | 1270 | if(desktop()) | 1270 | if(desktop()) |
255 | 1271 | desktop()->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>object(s)</b> to remove live path effects from.")); | 1271 | desktop()->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>object(s)</b> to remove live path effects from.")); |
256 | 1272 | return; | 1272 | return; |
257 | 1273 | } | 1273 | } |
258 | 1274 | auto list= items(); | 1274 | auto list= items(); |
259 | @@ -1281,7 +1281,7 @@ | |||
260 | 1281 | 1281 | ||
261 | 1282 | if(document()) | 1282 | if(document()) |
262 | 1283 | DocumentUndo::done(document(), SP_VERB_EDIT_REMOVE_LIVEPATHEFFECT, | 1283 | DocumentUndo::done(document(), SP_VERB_EDIT_REMOVE_LIVEPATHEFFECT, |
264 | 1284 | _("Remove live path effect")); | 1284 | _("Remove live path effect")); |
265 | 1285 | } | 1285 | } |
266 | 1286 | 1286 | ||
267 | 1287 | void ObjectSet::removeFilter() | 1287 | void ObjectSet::removeFilter() |
268 | @@ -1300,7 +1300,7 @@ | |||
269 | 1300 | sp_repr_css_attr_unref(css); | 1300 | sp_repr_css_attr_unref(css); |
270 | 1301 | if(document()) | 1301 | if(document()) |
271 | 1302 | DocumentUndo::done(document(), SP_VERB_EDIT_REMOVE_FILTER, | 1302 | DocumentUndo::done(document(), SP_VERB_EDIT_REMOVE_FILTER, |
273 | 1303 | _("Remove filter")); | 1303 | _("Remove filter")); |
274 | 1304 | } | 1304 | } |
275 | 1305 | 1305 | ||
276 | 1306 | 1306 | ||
277 | @@ -1334,8 +1334,8 @@ | |||
278 | 1334 | SPItem *oldparent = dynamic_cast<SPItem *>(item->parent); | 1334 | SPItem *oldparent = dynamic_cast<SPItem *>(item->parent); |
279 | 1335 | SPItem *newparent = dynamic_cast<SPItem *>(where); | 1335 | SPItem *newparent = dynamic_cast<SPItem *>(where); |
280 | 1336 | sp_item_group_ungroup_handle_clones(item, | 1336 | sp_item_group_ungroup_handle_clones(item, |
283 | 1337 | (oldparent->i2doc_affine()) | 1337 | (oldparent->i2doc_affine()) |
284 | 1338 | *((newparent->i2doc_affine()).inverse())); | 1338 | *((newparent->i2doc_affine()).inverse())); |
285 | 1339 | } | 1339 | } |
286 | 1340 | } | 1340 | } |
287 | 1341 | } | 1341 | } |
288 | @@ -1345,7 +1345,7 @@ | |||
289 | 1345 | if(!desktop()) | 1345 | if(!desktop()) |
290 | 1346 | return; | 1346 | return; |
291 | 1347 | SPDesktop *dt=desktop(); //TODO make it desktop-independent | 1347 | SPDesktop *dt=desktop(); //TODO make it desktop-independent |
293 | 1348 | 1348 | ||
294 | 1349 | // check if something is selected | 1349 | // check if something is selected |
295 | 1350 | if (isEmpty()) { | 1350 | if (isEmpty()) { |
296 | 1351 | dt->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>object(s)</b> to move to the layer above.")); | 1351 | dt->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>object(s)</b> to move to the layer above.")); |
297 | @@ -1515,7 +1515,7 @@ | |||
298 | 1515 | */ | 1515 | */ |
299 | 1516 | 1516 | ||
300 | 1517 | void ObjectSet::applyAffine(Geom::Affine const &affine, bool set_i2d, bool compensate, | 1517 | void ObjectSet::applyAffine(Geom::Affine const &affine, bool set_i2d, bool compensate, |
302 | 1518 | bool adjust_transf_center) | 1518 | bool adjust_transf_center) |
303 | 1519 | { | 1519 | { |
304 | 1520 | if (isEmpty()) | 1520 | if (isEmpty()) |
305 | 1521 | return; | 1521 | return; |
306 | @@ -1559,7 +1559,7 @@ | |||
307 | 1559 | old_center = item->getCenter(); | 1559 | old_center = item->getCenter(); |
308 | 1560 | 1560 | ||
309 | 1561 | #if 0 /* Re-enable this once persistent guides have a graphical indication. | 1561 | #if 0 /* Re-enable this once persistent guides have a graphical indication. |
311 | 1562 | At the time of writing, this is the only place to re-enable. */ | 1562 | At the time of writing, this is the only place to re-enable. */ |
312 | 1563 | sp_item_update_cns(*item, desktop()); | 1563 | sp_item_update_cns(*item, desktop()); |
313 | 1564 | #endif | 1564 | #endif |
314 | 1565 | 1565 | ||
315 | @@ -1716,7 +1716,7 @@ | |||
316 | 1716 | 1716 | ||
317 | 1717 | if(document()) | 1717 | if(document()) |
318 | 1718 | DocumentUndo::done(document(), SP_VERB_OBJECT_FLATTEN, | 1718 | DocumentUndo::done(document(), SP_VERB_OBJECT_FLATTEN, |
320 | 1719 | _("Remove transform")); | 1719 | _("Remove transform")); |
321 | 1720 | } | 1720 | } |
322 | 1721 | 1721 | ||
323 | 1722 | void ObjectSet::setScaleAbsolute(double x0, double x1,double y0, double y1) | 1722 | void ObjectSet::setScaleAbsolute(double x0, double x1,double y0, double y1) |
324 | @@ -1955,20 +1955,20 @@ | |||
325 | 1955 | SPIPaint *iter_paint = (type == SP_FILL_COLOR) ? &(iter->style->fill) : &(iter->style->stroke); | 1955 | SPIPaint *iter_paint = (type == SP_FILL_COLOR) ? &(iter->style->fill) : &(iter->style->stroke); |
326 | 1956 | match = false; | 1956 | match = false; |
327 | 1957 | if (sel_paint->isColor() && iter_paint->isColor() // color == color comparision doesnt seem to work here. | 1957 | if (sel_paint->isColor() && iter_paint->isColor() // color == color comparision doesnt seem to work here. |
329 | 1958 | && (sel_paint->value.color.toRGBA32(1.0) == iter_paint->value.color.toRGBA32(1.0))) { | 1958 | && (sel_paint->value.color.toRGBA32(1.0) == iter_paint->value.color.toRGBA32(1.0))) { |
330 | 1959 | match = true; | 1959 | match = true; |
331 | 1960 | } else if (sel_paint->isPaintserver() && iter_paint->isPaintserver()) { | 1960 | } else if (sel_paint->isPaintserver() && iter_paint->isPaintserver()) { |
332 | 1961 | 1961 | ||
333 | 1962 | SPPaintServer *sel_server = | 1962 | SPPaintServer *sel_server = |
335 | 1963 | (type == SP_FILL_COLOR) ? sel->style->getFillPaintServer() : sel->style->getStrokePaintServer(); | 1963 | (type == SP_FILL_COLOR) ? sel->style->getFillPaintServer() : sel->style->getStrokePaintServer(); |
336 | 1964 | SPPaintServer *iter_server = | 1964 | SPPaintServer *iter_server = |
338 | 1965 | (type == SP_FILL_COLOR) ? iter->style->getFillPaintServer() : iter->style->getStrokePaintServer(); | 1965 | (type == SP_FILL_COLOR) ? iter->style->getFillPaintServer() : iter->style->getStrokePaintServer(); |
339 | 1966 | 1966 | ||
340 | 1967 | if ((dynamic_cast<SPLinearGradient *>(sel_server) || dynamic_cast<SPRadialGradient *>(sel_server) || | 1967 | if ((dynamic_cast<SPLinearGradient *>(sel_server) || dynamic_cast<SPRadialGradient *>(sel_server) || |
341 | 1968 | (dynamic_cast<SPGradient *>(sel_server) && dynamic_cast<SPGradient *>(sel_server)->getVector()->isSwatch())) | 1968 | (dynamic_cast<SPGradient *>(sel_server) && dynamic_cast<SPGradient *>(sel_server)->getVector()->isSwatch())) |
345 | 1969 | && | 1969 | && |
346 | 1970 | (dynamic_cast<SPLinearGradient *>(iter_server) || dynamic_cast<SPRadialGradient *>(iter_server) || | 1970 | (dynamic_cast<SPLinearGradient *>(iter_server) || dynamic_cast<SPRadialGradient *>(iter_server) || |
347 | 1971 | (dynamic_cast<SPGradient *>(iter_server) && dynamic_cast<SPGradient *>(iter_server)->getVector()->isSwatch()))) { | 1971 | (dynamic_cast<SPGradient *>(iter_server) && dynamic_cast<SPGradient *>(iter_server)->getVector()->isSwatch()))) { |
348 | 1972 | SPGradient *sel_vector = dynamic_cast<SPGradient *>(sel_server)->getVector(); | 1972 | SPGradient *sel_vector = dynamic_cast<SPGradient *>(sel_server)->getVector(); |
349 | 1973 | SPGradient *iter_vector = dynamic_cast<SPGradient *>(iter_server)->getVector(); | 1973 | SPGradient *iter_vector = dynamic_cast<SPGradient *>(iter_server)->getVector(); |
350 | 1974 | if (sel_vector == iter_vector) { | 1974 | if (sel_vector == iter_vector) { |
351 | @@ -2119,7 +2119,7 @@ | |||
352 | 2119 | for (int i = 0; i < len; i++) { | 2119 | for (int i = 0; i < len; i++) { |
353 | 2120 | match = (sel_style->marker_ptrs[i]->set == iter_style->marker_ptrs[i]->set); | 2120 | match = (sel_style->marker_ptrs[i]->set == iter_style->marker_ptrs[i]->set); |
354 | 2121 | if (sel_style->marker_ptrs[i]->set && iter_style->marker_ptrs[i]->set && | 2121 | if (sel_style->marker_ptrs[i]->set && iter_style->marker_ptrs[i]->set && |
356 | 2122 | (strcmp(sel_style->marker_ptrs[i]->value, iter_style->marker_ptrs[i]->value))) { | 2122 | (strcmp(sel_style->marker_ptrs[i]->value, iter_style->marker_ptrs[i]->value))) { |
357 | 2123 | match = false; | 2123 | match = false; |
358 | 2124 | break; | 2124 | break; |
359 | 2125 | } | 2125 | } |
360 | @@ -2652,13 +2652,59 @@ | |||
361 | 2652 | } | 2652 | } |
362 | 2653 | } | 2653 | } |
363 | 2654 | 2654 | ||
366 | 2655 | 2655 | bool ObjectSet::unlinkRecursive(const bool skip_undo) { | |
367 | 2656 | void ObjectSet::unlink() | 2656 | if(isEmpty()){ |
368 | 2657 | if(desktop()) | ||
369 | 2658 | desktop()->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>clones</b> to unlink.")); | ||
370 | 2659 | return false; | ||
371 | 2660 | } | ||
372 | 2661 | bool unlinked = false; | ||
373 | 2662 | ObjectSet tmp_set(document()); | ||
374 | 2663 | std::vector<SPItem*> items_(items().begin(), items().end()); | ||
375 | 2664 | for (auto& it:items_){ | ||
376 | 2665 | if (SP_IS_GROUP(it)) { | ||
377 | 2666 | std::vector<SPObject*> c = it->childList(false); | ||
378 | 2667 | tmp_set.setList(c); | ||
379 | 2668 | unlinked = tmp_set.unlinkRecursive(true) || unlinked; | ||
380 | 2669 | } | ||
381 | 2670 | tmp_set.set(it); | ||
382 | 2671 | bool has_clip = false; | ||
383 | 2672 | bool has_mask = false; | ||
384 | 2673 | Inkscape::URIReference *clip = it->clip_ref; | ||
385 | 2674 | Inkscape::URIReference *mask = it->mask_ref; | ||
386 | 2675 | if ((NULL != clip) && (NULL != clip->getObject())) { | ||
387 | 2676 | tmp_set.unsetMask(true,true); | ||
388 | 2677 | has_clip = true; | ||
389 | 2678 | } | ||
390 | 2679 | if ((NULL != mask) && (NULL != mask->getObject())) { | ||
391 | 2680 | tmp_set.unsetMask(false,true); | ||
392 | 2681 | has_mask = true; | ||
393 | 2682 | } | ||
394 | 2683 | unlinked = tmp_set.unlink(true) || unlinked; | ||
395 | 2684 | if (has_mask) | ||
396 | 2685 | tmp_set.setMask(false,false,true); | ||
397 | 2686 | if (has_clip) | ||
398 | 2687 | tmp_set.setMask(true,false,true); | ||
399 | 2688 | } | ||
400 | 2689 | if (!unlinked) { | ||
401 | 2690 | if(desktop()) | ||
402 | 2691 | desktop()->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("<b>No clones to unlink</b> in the selection.")); | ||
403 | 2692 | } | ||
404 | 2693 | if (!skip_undo) { | ||
405 | 2694 | DocumentUndo::done(document(), SP_VERB_EDIT_UNLINK_CLONE_RECURSIVE, | ||
406 | 2695 | _("Unlink clone recursively")); | ||
407 | 2696 | } | ||
408 | 2697 | return unlinked; | ||
409 | 2698 | } | ||
410 | 2699 | |||
411 | 2700 | |||
412 | 2701 | |||
413 | 2702 | bool ObjectSet::unlink(bool skip_undo) | ||
414 | 2657 | { | 2703 | { |
415 | 2658 | if (isEmpty()) { | 2704 | if (isEmpty()) { |
416 | 2659 | if(desktop()) | 2705 | if(desktop()) |
417 | 2660 | desktop()->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>clones</b> to unlink.")); | 2706 | desktop()->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>clones</b> to unlink.")); |
419 | 2661 | return; | 2707 | return false; |
420 | 2662 | } | 2708 | } |
421 | 2663 | 2709 | ||
422 | 2664 | // Get a copy of current selection. | 2710 | // Get a copy of current selection. |
423 | @@ -2715,8 +2761,11 @@ | |||
424 | 2715 | desktop()->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("<b>No clones to unlink</b> in the selection.")); | 2761 | desktop()->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("<b>No clones to unlink</b> in the selection.")); |
425 | 2716 | } | 2762 | } |
426 | 2717 | 2763 | ||
429 | 2718 | DocumentUndo::done(document(), SP_VERB_EDIT_UNLINK_CLONE, | 2764 | if (!skip_undo) { |
430 | 2719 | _("Unlink clone")); | 2765 | DocumentUndo::done(document(), SP_VERB_EDIT_UNLINK_CLONE, |
431 | 2766 | _("Unlink clone")); | ||
432 | 2767 | } | ||
433 | 2768 | return unlinked; | ||
434 | 2720 | } | 2769 | } |
435 | 2721 | 2770 | ||
436 | 2722 | void ObjectSet::cloneOriginal() | 2771 | void ObjectSet::cloneOriginal() |
437 | @@ -2876,8 +2925,8 @@ | |||
438 | 2876 | void ObjectSet::toMarker(bool apply) | 2925 | void ObjectSet::toMarker(bool apply) |
439 | 2877 | { | 2926 | { |
440 | 2878 | // sp_selection_tile has similar code | 2927 | // sp_selection_tile has similar code |
443 | 2879 | if (desktop() == NULL) { // TODO: We should not need desktop for that. | 2928 | if (desktop() == NULL) { // TODO: We should not need desktop for that. |
444 | 2880 | // Someone get rid of the dt2doc() call. | 2929 | // Someone get rid of the dt2doc() call. |
445 | 2881 | return; | 2930 | return; |
446 | 2882 | } | 2931 | } |
447 | 2883 | 2932 | ||
448 | @@ -2901,7 +2950,7 @@ | |||
449 | 2901 | Geom::Point doc_height( 0, doc->getHeight().value("px")); | 2950 | Geom::Point doc_height( 0, doc->getHeight().value("px")); |
450 | 2902 | 2951 | ||
451 | 2903 | // calculate the transform to be applied to objects to move them to 0,0 | 2952 | // calculate the transform to be applied to objects to move them to 0,0 |
453 | 2904 | Geom::Point corner( r->min()[Geom::X], r->max()[Geom::Y] ); // FIXME: Inverted Y coodinate | 2953 | Geom::Point corner( r->min()[Geom::X], r->max()[Geom::Y] ); // FIXME: Inverted Y coodinate |
454 | 2905 | Geom::Point move_p = doc_height - corner; | 2954 | Geom::Point move_p = doc_height - corner; |
455 | 2906 | move_p[Geom::Y] = -move_p[Geom::Y]; | 2955 | move_p[Geom::Y] = -move_p[Geom::Y]; |
456 | 2907 | Geom::Affine move = Geom::Affine(Geom::Translate(move_p)); | 2956 | Geom::Affine move = Geom::Affine(Geom::Translate(move_p)); |
457 | @@ -3007,7 +3056,7 @@ | |||
458 | 3007 | 3056 | ||
459 | 3008 | /* | 3057 | /* |
460 | 3009 | * Convert objects to <symbol>. How that happens depends on what is selected: | 3058 | * Convert objects to <symbol>. How that happens depends on what is selected: |
462 | 3010 | * | 3059 | * |
463 | 3011 | * 1) A random selection of objects will be embedded into a single <symbol> element. | 3060 | * 1) A random selection of objects will be embedded into a single <symbol> element. |
464 | 3012 | * | 3061 | * |
465 | 3013 | * 2) Except, a single <g> will have its content directly embedded into a <symbol>; the 'id' and | 3062 | * 2) Except, a single <g> will have its content directly embedded into a <symbol>; the 'id' and |
466 | @@ -3033,9 +3082,9 @@ | |||
467 | 3033 | 3082 | ||
468 | 3034 | // Check if something is selected. | 3083 | // Check if something is selected. |
469 | 3035 | if (isEmpty()) { | 3084 | if (isEmpty()) { |
473 | 3036 | if (desktop()) | 3085 | if (desktop()) |
474 | 3037 | desktop()->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>objects</b> to convert to symbol.")); | 3086 | desktop()->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>objects</b> to convert to symbol.")); |
475 | 3038 | return; | 3087 | return; |
476 | 3039 | } | 3088 | } |
477 | 3040 | 3089 | ||
478 | 3041 | doc->ensureUpToDate(); | 3090 | doc->ensureUpToDate(); |
479 | @@ -3108,9 +3157,9 @@ | |||
480 | 3108 | 3157 | ||
481 | 3109 | // Move selected items to new <symbol> | 3158 | // Move selected items to new <symbol> |
482 | 3110 | for (std::vector<SPObject*>::const_reverse_iterator i=items_.rbegin();i!=items_.rend();++i){ | 3159 | for (std::vector<SPObject*>::const_reverse_iterator i=items_.rbegin();i!=items_.rend();++i){ |
486 | 3111 | Inkscape::XML::Node *repr = (*i)->getRepr(); | 3160 | Inkscape::XML::Node *repr = (*i)->getRepr(); |
487 | 3112 | repr->parent()->removeChild(repr); | 3161 | repr->parent()->removeChild(repr); |
488 | 3113 | symbol_repr->addChild(repr,NULL); | 3162 | symbol_repr->addChild(repr,NULL); |
489 | 3114 | } | 3163 | } |
490 | 3115 | 3164 | ||
491 | 3116 | if( single_group && transform.isTranslation() ) { | 3165 | if( single_group && transform.isTranslation() ) { |
492 | @@ -3154,7 +3203,7 @@ | |||
493 | 3154 | } | 3203 | } |
494 | 3155 | 3204 | ||
495 | 3156 | SPObject* symbol = single(); | 3205 | SPObject* symbol = single(); |
497 | 3157 | 3206 | ||
498 | 3158 | // Make sure we have only one object in selection. | 3207 | // Make sure we have only one object in selection. |
499 | 3159 | // Require that we really have a <symbol>. | 3208 | // Require that we really have a <symbol>. |
500 | 3160 | if( symbol == NULL || !dynamic_cast<SPSymbol *>( symbol )) { | 3209 | if( symbol == NULL || !dynamic_cast<SPSymbol *>( symbol )) { |
501 | @@ -3179,14 +3228,14 @@ | |||
502 | 3179 | SPObject *object = children[0]; | 3228 | SPObject *object = children[0]; |
503 | 3180 | if ( dynamic_cast<SPGroup *>( object ) ) { | 3229 | if ( dynamic_cast<SPGroup *>( object ) ) { |
504 | 3181 | if( object->getAttribute("style") == NULL || | 3230 | if( object->getAttribute("style") == NULL || |
506 | 3182 | object->getAttribute("class") == NULL ) { | 3231 | object->getAttribute("class") == NULL ) { |
507 | 3183 | 3232 | ||
508 | 3184 | group->setAttribute("transform", object->getAttribute("transform")); | 3233 | group->setAttribute("transform", object->getAttribute("transform")); |
509 | 3185 | children = object->childList(false); | 3234 | children = object->childList(false); |
510 | 3186 | } | 3235 | } |
511 | 3187 | } | 3236 | } |
512 | 3188 | } | 3237 | } |
514 | 3189 | 3238 | ||
515 | 3190 | for (std::vector<SPObject*>::const_reverse_iterator i=children.rbegin();i!=children.rend();++i){ | 3239 | for (std::vector<SPObject*>::const_reverse_iterator i=children.rbegin();i!=children.rend();++i){ |
516 | 3191 | Inkscape::XML::Node *repr = (*i)->getRepr(); | 3240 | Inkscape::XML::Node *repr = (*i)->getRepr(); |
517 | 3192 | repr->parent()->removeChild(repr); | 3241 | repr->parent()->removeChild(repr); |
518 | @@ -3291,10 +3340,10 @@ | |||
519 | 3291 | prefs->setInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED); | 3340 | prefs->setInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED); |
520 | 3292 | 3341 | ||
521 | 3293 | gchar const *pat_id = SPPattern::produce(repr_copies, bbox, doc, | 3342 | gchar const *pat_id = SPPattern::produce(repr_copies, bbox, doc, |
526 | 3294 | ( Geom::Affine(Geom::Translate(desktop()->dt2doc(Geom::Point(r->min()[Geom::X], | 3343 | ( Geom::Affine(Geom::Translate(desktop()->dt2doc(Geom::Point(r->min()[Geom::X], |
527 | 3295 | r->max()[Geom::Y])))) | 3344 | r->max()[Geom::Y])))) |
528 | 3296 | * parent_transform.inverse() ), | 3345 | * parent_transform.inverse() ), |
529 | 3297 | parent_transform * move); | 3346 | parent_transform * move); |
530 | 3298 | 3347 | ||
531 | 3299 | // restore compensation setting | 3348 | // restore compensation setting |
532 | 3300 | prefs->setInt("/options/clonecompensation/value", saved_compensation); | 3349 | prefs->setInt("/options/clonecompensation/value", saved_compensation); |
533 | @@ -3374,8 +3423,8 @@ | |||
534 | 3374 | Inkscape::XML::Node *copy = child.getRepr()->duplicate(xml_doc); | 3423 | Inkscape::XML::Node *copy = child.getRepr()->duplicate(xml_doc); |
535 | 3375 | SPItem *i = dynamic_cast<SPItem *>(item->parent->appendChildRepr(copy)); | 3424 | SPItem *i = dynamic_cast<SPItem *>(item->parent->appendChildRepr(copy)); |
536 | 3376 | 3425 | ||
539 | 3377 | // FIXME: relink clones to the new canvas objects | 3426 | // FIXME: relink clones to the new canvas objects |
540 | 3378 | // use SPObject::setid when mental finishes it to steal ids of | 3427 | // use SPObject::setid when mental finishes it to steal ids of |
541 | 3379 | 3428 | ||
542 | 3380 | // this is needed to make sure the new item has curve (simply requestDisplayUpdate does not work) | 3429 | // this is needed to make sure the new item has curve (simply requestDisplayUpdate does not work) |
543 | 3381 | doc->ensureUpToDate(); | 3430 | doc->ensureUpToDate(); |
544 | @@ -3517,7 +3566,7 @@ | |||
545 | 3517 | gchar *const basename = g_strdup_printf("%s-%s-%u.png", | 3566 | gchar *const basename = g_strdup_printf("%s-%s-%u.png", |
546 | 3518 | doc->getName(), | 3567 | doc->getName(), |
547 | 3519 | items_[0]->getRepr()->attribute("id"), | 3568 | items_[0]->getRepr()->attribute("id"), |
549 | 3520 | current); | 3569 | current); |
550 | 3521 | // Imagemagick is known not to handle spaces in filenames, so we replace anything but letters, | 3570 | // Imagemagick is known not to handle spaces in filenames, so we replace anything but letters, |
551 | 3522 | // digits, and a few other chars, with "_" | 3571 | // digits, and a few other chars, with "_" |
552 | 3523 | g_strcanon(basename, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.=+~$#@^&!?", '_'); | 3572 | g_strcanon(basename, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.=+~$#@^&!?", '_'); |
553 | @@ -3622,12 +3671,12 @@ | |||
554 | 3622 | // Do the export | 3671 | // Do the export |
555 | 3623 | sp_export_png_file(doc, filepath, | 3672 | sp_export_png_file(doc, filepath, |
556 | 3624 | bbox->min()[Geom::X], bbox->min()[Geom::Y], | 3673 | bbox->min()[Geom::X], bbox->min()[Geom::Y], |
563 | 3625 | bbox->max()[Geom::X], bbox->max()[Geom::Y], | 3674 | bbox->max()[Geom::X], bbox->max()[Geom::Y], |
564 | 3626 | width, height, res, res, | 3675 | width, height, res, res, |
565 | 3627 | (guint32) 0xffffff00, | 3676 | (guint32) 0xffffff00, |
566 | 3628 | NULL, NULL, | 3677 | NULL, NULL, |
567 | 3629 | true, /*bool force_overwrite,*/ | 3678 | true, /*bool force_overwrite,*/ |
568 | 3630 | items_); | 3679 | items_); |
569 | 3631 | 3680 | ||
570 | 3632 | // Run filter, if any | 3681 | // Run filter, if any |
571 | 3633 | if (run) { | 3682 | if (run) { |
572 | @@ -3699,7 +3748,7 @@ | |||
573 | 3699 | desktop()->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>object(s)</b> to create clippath or mask from.")); | 3748 | desktop()->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>object(s)</b> to create clippath or mask from.")); |
574 | 3700 | return; | 3749 | return; |
575 | 3701 | } | 3750 | } |
577 | 3702 | 3751 | ||
578 | 3703 | std::vector<Inkscape::XML::Node*> p(xmlNodes().begin(), xmlNodes().end()); | 3752 | std::vector<Inkscape::XML::Node*> p(xmlNodes().begin(), xmlNodes().end()); |
579 | 3704 | 3753 | ||
580 | 3705 | sort(p.begin(),p.end(),sp_repr_compare_position_bool); | 3754 | sort(p.begin(),p.end(),sp_repr_compare_position_bool); |
581 | @@ -3794,7 +3843,7 @@ | |||
582 | 3794 | * If \a apply_clip_path parameter is true, clipPath is created, otherwise mask | 3843 | * If \a apply_clip_path parameter is true, clipPath is created, otherwise mask |
583 | 3795 | * | 3844 | * |
584 | 3796 | */ | 3845 | */ |
586 | 3797 | void ObjectSet::setMask(bool apply_clip_path, bool apply_to_layer, bool skip_undo) | 3846 | void ObjectSet::setMask(bool apply_clip_path, bool apply_to_layer, bool skip_undo) |
587 | 3798 | { | 3847 | { |
588 | 3799 | if(!desktop() && apply_to_layer) | 3848 | if(!desktop() && apply_to_layer) |
589 | 3800 | return; | 3849 | return; |
590 | @@ -3960,7 +4009,7 @@ | |||
591 | 3960 | } | 4009 | } |
592 | 3961 | } | 4010 | } |
593 | 3962 | 4011 | ||
595 | 3963 | void ObjectSet::unsetMask(bool apply_clip_path) { | 4012 | void ObjectSet::unsetMask(const bool apply_clip_path, const bool skip_undo) { |
596 | 3964 | SPDocument *doc = document(); | 4013 | SPDocument *doc = document(); |
597 | 3965 | Inkscape::XML::Document *xml_doc = doc->getReprDoc(); | 4014 | Inkscape::XML::Document *xml_doc = doc->getReprDoc(); |
598 | 3966 | 4015 | ||
599 | @@ -4010,13 +4059,13 @@ | |||
600 | 4010 | 4059 | ||
601 | 4011 | SPGroup *group = dynamic_cast<SPGroup *>(*i); | 4060 | SPGroup *group = dynamic_cast<SPGroup *>(*i); |
602 | 4012 | if (ungroup_masked && group) { | 4061 | if (ungroup_masked && group) { |
605 | 4013 | // if we had previously enclosed masked object in group, | 4062 | // if we had previously enclosed masked object in group, |
606 | 4014 | // add it to list so we can ungroup it later | 4063 | // add it to list so we can ungroup it later |
607 | 4015 | 4064 | ||
612 | 4016 | // ungroup only groups we created when setting clip/mask | 4065 | // ungroup only groups we created when setting clip/mask |
613 | 4017 | if (group->layerMode() == SPGroup::MASK_HELPER) { | 4066 | if (group->layerMode() == SPGroup::MASK_HELPER) { |
614 | 4018 | items_to_ungroup = g_slist_prepend(items_to_ungroup, group); | 4067 | items_to_ungroup = g_slist_prepend(items_to_ungroup, group); |
615 | 4019 | } | 4068 | } |
616 | 4020 | 4069 | ||
617 | 4021 | } | 4070 | } |
618 | 4022 | } | 4071 | } |
619 | @@ -4082,10 +4131,12 @@ | |||
620 | 4082 | // rebuild selection | 4131 | // rebuild selection |
621 | 4083 | addList(items_to_select); | 4132 | addList(items_to_select); |
622 | 4084 | 4133 | ||
627 | 4085 | if (apply_clip_path) { | 4134 | if (!skip_undo) { |
628 | 4086 | DocumentUndo::done(doc, SP_VERB_OBJECT_UNSET_CLIPPATH, _("Release clipping path")); | 4135 | if (apply_clip_path) { |
629 | 4087 | } else { | 4136 | DocumentUndo::done(doc, SP_VERB_OBJECT_UNSET_CLIPPATH, _("Release clipping path")); |
630 | 4088 | DocumentUndo::done(doc, SP_VERB_OBJECT_UNSET_MASK, _("Release mask")); | 4137 | } else { |
631 | 4138 | DocumentUndo::done(doc, SP_VERB_OBJECT_UNSET_MASK, _("Release mask")); | ||
632 | 4139 | } | ||
633 | 4089 | } | 4140 | } |
634 | 4090 | } | 4141 | } |
635 | 4091 | 4142 | ||
636 | 4092 | 4143 | ||
637 | === modified file 'src/verbs.cpp' | |||
638 | --- src/verbs.cpp 2016-11-02 22:42:43 +0000 | |||
639 | +++ src/verbs.cpp 2016-11-04 12:38:02 +0000 | |||
640 | @@ -1009,6 +1009,9 @@ | |||
641 | 1009 | case SP_VERB_EDIT_UNLINK_CLONE: | 1009 | case SP_VERB_EDIT_UNLINK_CLONE: |
642 | 1010 | dt->selection->unlink(); | 1010 | dt->selection->unlink(); |
643 | 1011 | break; | 1011 | break; |
644 | 1012 | case SP_VERB_EDIT_UNLINK_CLONE_RECURSIVE: | ||
645 | 1013 | dt->selection->unlinkRecursive(); | ||
646 | 1014 | break; | ||
647 | 1012 | case SP_VERB_EDIT_RELINK_CLONE: | 1015 | case SP_VERB_EDIT_RELINK_CLONE: |
648 | 1013 | dt->selection->relink(); | 1016 | dt->selection->relink(); |
649 | 1014 | break; | 1017 | break; |
650 | @@ -2530,6 +2533,8 @@ | |||
651 | 2530 | N_("Create a clone (a copy linked to the original) of selected object"), INKSCAPE_ICON("edit-clone")), | 2533 | N_("Create a clone (a copy linked to the original) of selected object"), INKSCAPE_ICON("edit-clone")), |
652 | 2531 | new EditVerb(SP_VERB_EDIT_UNLINK_CLONE, "EditUnlinkClone", N_("Unlin_k Clone"), | 2534 | new EditVerb(SP_VERB_EDIT_UNLINK_CLONE, "EditUnlinkClone", N_("Unlin_k Clone"), |
653 | 2532 | N_("Cut the selected clones' links to the originals, turning them into standalone objects"), INKSCAPE_ICON("edit-clone-unlink")), | 2535 | N_("Cut the selected clones' links to the originals, turning them into standalone objects"), INKSCAPE_ICON("edit-clone-unlink")), |
654 | 2536 | new EditVerb(SP_VERB_EDIT_UNLINK_CLONE_RECURSIVE, "EditUnlinkCloneRecursive", N_("Unlink Clones _recursively"), | ||
655 | 2537 | N_("Unlink all clones in the selection, even if they are in groups."), INKSCAPE_ICON("edit-clone-unlink")), | ||
656 | 2533 | new EditVerb(SP_VERB_EDIT_RELINK_CLONE, "EditRelinkClone", N_("Relink to Copied"), | 2538 | new EditVerb(SP_VERB_EDIT_RELINK_CLONE, "EditRelinkClone", N_("Relink to Copied"), |
657 | 2534 | N_("Relink the selected clones to the object currently on the clipboard"), NULL), | 2539 | N_("Relink the selected clones to the object currently on the clipboard"), NULL), |
658 | 2535 | new EditVerb(SP_VERB_EDIT_CLONE_SELECT_ORIGINAL, "EditCloneSelectOriginal", N_("Select _Original"), | 2540 | new EditVerb(SP_VERB_EDIT_CLONE_SELECT_ORIGINAL, "EditCloneSelectOriginal", N_("Select _Original"), |
659 | 2536 | 2541 | ||
660 | === modified file 'src/verbs.h' | |||
661 | --- src/verbs.h 2016-10-08 06:16:53 +0000 | |||
662 | +++ src/verbs.h 2016-11-04 12:38:02 +0000 | |||
663 | @@ -83,6 +83,7 @@ | |||
664 | 83 | SP_VERB_EDIT_DUPLICATE, | 83 | SP_VERB_EDIT_DUPLICATE, |
665 | 84 | SP_VERB_EDIT_CLONE, | 84 | SP_VERB_EDIT_CLONE, |
666 | 85 | SP_VERB_EDIT_UNLINK_CLONE, | 85 | SP_VERB_EDIT_UNLINK_CLONE, |
667 | 86 | SP_VERB_EDIT_UNLINK_CLONE_RECURSIVE, | ||
668 | 86 | SP_VERB_EDIT_RELINK_CLONE, | 87 | SP_VERB_EDIT_RELINK_CLONE, |
669 | 87 | SP_VERB_EDIT_CLONE_SELECT_ORIGINAL, | 88 | SP_VERB_EDIT_CLONE_SELECT_ORIGINAL, |
670 | 88 | SP_VERB_EDIT_CLONE_ORIGINAL_PATH_LPE, | 89 | SP_VERB_EDIT_CLONE_ORIGINAL_PATH_LPE, |
Looks mostly fine, but I'm not a big fan of the _functions which seems to duplicate the code a bit and double number of functions. I'd prefer a ", bool flash = true" or something like that in the already present function and "if(doflash) desktop- >messageStack( )->flash( whatever) "
I'll re-read the main new function during the week-end and extensively test it.