diff options
| author | Adrian Boguszewski <adrbogus1@student.pg.gda.pl> | 2016-08-09 09:58:51 +0000 |
|---|---|---|
| committer | Adrian Boguszewski <adrbogus1@student.pg.gda.pl> | 2016-08-09 09:58:51 +0000 |
| commit | e5143d65bb57d4ce623e6220585b099e6d2ee453 (patch) | |
| tree | 4ff78f6fa8f0c1b740fd43b0ade2b91dbf9226d0 /src | |
| parent | Remove deprecated Autotools and btool files. Please use CMake instead (diff) | |
| parent | Merged trunk (diff) | |
| download | inkscape-e5143d65bb57d4ce623e6220585b099e6d2ee453.tar.gz inkscape-e5143d65bb57d4ce623e6220585b099e6d2ee453.zip | |
Merged gsoc work. Created better data structure for selections, replaced SPObject children list, improved spray tool, split tests to separate executables
(bzr r15047)
Diffstat (limited to 'src')
150 files changed, 2590 insertions, 2369 deletions
diff --git a/src/2geom/sbasis-geometric.cpp b/src/2geom/sbasis-geometric.cpp index 3fe27748e..19eccc451 100644 --- a/src/2geom/sbasis-geometric.cpp +++ b/src/2geom/sbasis-geometric.cpp @@ -227,7 +227,7 @@ Geom::unitVector(D2<SBasis> const &V_in, double tol, unsigned order){ // -This approach is numerically bad. Find a stable way to rescale V_in to have non vanishing ends. // -This done, unitVector will have jumps at zeros: fill the gaps with arcs of circles. D2<SBasis> V = RescaleForNonVanishingEnds(V_in); - if (V[0].isZero(tol) && V[1].isZero(tol)) + if (V[0].isZero(0) && V[1].isZero(0)) return Piecewise<D2<SBasis> >(D2<SBasis>(Linear(1),SBasis())); SBasis x = V[0], y = V[1]; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ed46cbe3c..4ba738635 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -228,6 +228,7 @@ set(inkscape_SRC message-stack.cpp mod360.cpp object-hierarchy.cpp + object-set.cpp object-snapper.cpp path-chemistry.cpp persp3d-reference.cpp @@ -352,6 +353,7 @@ set(inkscape_SRC mod360.h number-opt-number.h object-hierarchy.h + object-set.h object-snapper.h object-test.h path-chemistry.h diff --git a/src/box3d.cpp b/src/box3d.cpp index e50cc4afb..dfc4d06e7 100644 --- a/src/box3d.cpp +++ b/src/box3d.cpp @@ -253,8 +253,8 @@ void box3d_position_set(SPBox3D *box) { /* This draws the curve and calls requestDisplayUpdate() for each side (the latter is done in box3d_side_position_set() to avoid update conflicts with the parent box) */ - for ( SPObject *obj = box->firstChild(); obj; obj = obj->getNext() ) { - Box3DSide *side = dynamic_cast<Box3DSide *>(obj); + for (auto& obj: box->children) { + Box3DSide *side = dynamic_cast<Box3DSide *>(&obj); if (side) { box3d_side_position_set(side); } @@ -269,8 +269,8 @@ Geom::Affine SPBox3D::set_transform(Geom::Affine const &xform) { gdouble const sw = hypot(ret[0], ret[1]); gdouble const sh = hypot(ret[2], ret[3]); - for ( SPObject *child = firstChild(); child; child = child->getNext() ) { - SPItem *childitem = dynamic_cast<SPItem *>(child); + for (auto& child: children) { + SPItem *childitem = dynamic_cast<SPItem *>(&child); if (childitem) { // Adjust stroke width childitem->adjust_stroke(sqrt(fabs(sw * sh))); @@ -1068,8 +1068,8 @@ box3d_recompute_z_orders (SPBox3D *box) { static std::map<int, Box3DSide *> box3d_get_sides(SPBox3D *box) { std::map<int, Box3DSide *> sides; - for ( SPObject *obj = box->firstChild(); obj; obj = obj->getNext() ) { - Box3DSide *side = dynamic_cast<Box3DSide *>(obj); + for (auto& obj: box->children) { + Box3DSide *side = dynamic_cast<Box3DSide *>(&obj); if (side) { sides[Box3D::face_to_int(side->getFaceId())] = side; } @@ -1211,8 +1211,8 @@ static void box3d_extract_boxes_rec(SPObject *obj, std::list<SPBox3D *> &boxes) if (box) { boxes.push_back(box); } else if (dynamic_cast<SPGroup *>(obj)) { - for ( SPObject *child = obj->firstChild(); child; child = child->getNext() ) { - box3d_extract_boxes_rec(child, boxes); + for (auto& child: obj->children) { + box3d_extract_boxes_rec(&child, boxes); } } } @@ -1270,8 +1270,8 @@ SPGroup *box3d_convert_to_group(SPBox3D *box) // create a new group and add the sides (converted to ordinary paths) as its children Inkscape::XML::Node *grepr = xml_doc->createElement("svg:g"); - for ( SPObject *obj = box->firstChild(); obj; obj = obj->getNext() ) { - Box3DSide *side = dynamic_cast<Box3DSide *>(obj); + for (auto& obj: box->children) { + Box3DSide *side = dynamic_cast<Box3DSide *>(&obj); if (side) { Inkscape::XML::Node *repr = box3d_side_convert_to_path(side); grepr->appendChild(repr); diff --git a/src/conn-avoid-ref.cpp b/src/conn-avoid-ref.cpp index e4c8ce7b5..71743fda5 100644 --- a/src/conn-avoid-ref.cpp +++ b/src/conn-avoid-ref.cpp @@ -328,19 +328,19 @@ static Avoid::Polygon avoid_item_poly(SPItem const *item) std::vector<SPItem *> get_avoided_items(std::vector<SPItem *> &list, SPObject *from, SPDesktop *desktop, bool initialised) { - for (SPObject *child = from->firstChild() ; child != NULL; child = child->next ) { - if (SP_IS_ITEM(child) && - !desktop->isLayer(SP_ITEM(child)) && - !SP_ITEM(child)->isLocked() && - !desktop->itemIsHidden(SP_ITEM(child)) && - (!initialised || SP_ITEM(child)->avoidRef->shapeRef) + for (auto& child: from->children) { + if (SP_IS_ITEM(&child) && + !desktop->isLayer(SP_ITEM(&child)) && + !SP_ITEM(&child)->isLocked() && + !desktop->itemIsHidden(SP_ITEM(&child)) && + (!initialised || SP_ITEM(&child)->avoidRef->shapeRef) ) { - list.push_back(SP_ITEM(child)); + list.push_back(SP_ITEM(&child)); } - if (SP_IS_ITEM(child) && desktop->isLayer(SP_ITEM(child))) { - list = get_avoided_items(list, child, desktop, initialised); + if (SP_IS_ITEM(&child) && desktop->isLayer(SP_ITEM(&child))) { + list = get_avoided_items(list, &child, desktop, initialised); } } diff --git a/src/desktop-style.cpp b/src/desktop-style.cpp index 393e0caa7..81aa95b48 100644 --- a/src/desktop-style.cpp +++ b/src/desktop-style.cpp @@ -156,17 +156,17 @@ sp_desktop_apply_css_recursive(SPObject *o, SPCSSAttr *css, bool skip_lines) return; } - for ( SPObject *child = o->firstChild() ; child ; child = child->getNext() ) { + for (auto& child: o->children) { if (sp_repr_css_property(css, "opacity", NULL) != NULL) { // Unset properties which are accumulating and thus should not be set recursively. // For example, setting opacity 0.5 on a group recursively would result in the visible opacity of 0.25 for an item in the group. SPCSSAttr *css_recurse = sp_repr_css_attr_new(); sp_repr_css_merge(css_recurse, css); sp_repr_css_set_property(css_recurse, "opacity", NULL); - sp_desktop_apply_css_recursive(child, css_recurse, skip_lines); + sp_desktop_apply_css_recursive(&child, css_recurse, skip_lines); sp_repr_css_attr_unref(css_recurse); } else { - sp_desktop_apply_css_recursive(child, css, skip_lines); + sp_desktop_apply_css_recursive(&child, css, skip_lines); } } } @@ -187,8 +187,8 @@ sp_desktop_set_style(SPDesktop *desktop, SPCSSAttr *css, bool change, bool write sp_repr_css_merge(css_write, css); sp_css_attr_unset_uris(css_write); prefs->mergeStyle("/desktop/style", css_write); - std::vector<SPItem*> const itemlist = desktop->selection->itemList(); - for (std::vector<SPItem*>::const_iterator i = itemlist.begin(); i!= itemlist.end(); ++i) { + auto itemlist = desktop->selection->items(); + for (auto i = itemlist.begin(); i!= itemlist.end(); ++i) { /* last used styles for 3D box faces are stored separately */ SPObject *obj = *i; Box3DSide *side = dynamic_cast<Box3DSide *>(obj); @@ -227,8 +227,8 @@ sp_desktop_set_style(SPDesktop *desktop, SPCSSAttr *css, bool change, bool write sp_repr_css_merge(css_no_text, css); css_no_text = sp_css_attr_unset_text(css_no_text); - std::vector<SPItem*> const itemlist = desktop->selection->itemList(); - for (std::vector<SPItem*>::const_iterator i = itemlist.begin(); i!= itemlist.end(); ++i) { + auto itemlist = desktop->selection->items(); + for (auto i = itemlist.begin(); i!= itemlist.end(); ++i) { SPItem *item = *i; // If not text, don't apply text attributes (can a group have text attributes? Yes! FIXME) @@ -1707,10 +1707,11 @@ objects_query_blend (const std::vector<SPItem*> &objects, SPStyle *style_res) int blendcount = 0; // determine whether filter is simple (blend and/or blur) or complex - for(SPObject *primitive_obj = style->getFilter()->children; - primitive_obj && dynamic_cast<SPFilterPrimitive *>(primitive_obj); - primitive_obj = primitive_obj->next) { - SPFilterPrimitive *primitive = dynamic_cast<SPFilterPrimitive *>(primitive_obj); + for(auto& primitive_obj: style->getFilter()->children) { + SPFilterPrimitive *primitive = dynamic_cast<SPFilterPrimitive *>(&primitive_obj); + if (!primitive) { + break; + } if (dynamic_cast<SPFeBlend *>(primitive)) { ++blendcount; } else if (dynamic_cast<SPGaussianBlur *>(primitive)) { @@ -1723,10 +1724,12 @@ objects_query_blend (const std::vector<SPItem*> &objects, SPStyle *style_res) // simple filter if(blurcount == 1 || blendcount == 1) { - for(SPObject *primitive_obj = style->getFilter()->children; - primitive_obj && dynamic_cast<SPFilterPrimitive *>(primitive_obj); - primitive_obj = primitive_obj->next) { - SPFeBlend *spblend = dynamic_cast<SPFeBlend *>(primitive_obj); + for(auto& primitive_obj: style->getFilter()->children) { + SPFilterPrimitive *primitive = dynamic_cast<SPFilterPrimitive *>(&primitive_obj); + if (!primitive) { + break; + } + SPFeBlend *spblend = dynamic_cast<SPFeBlend *>(&primitive_obj); if (spblend) { blend = spblend->blend_mode; } @@ -1800,9 +1803,8 @@ objects_query_blur (const std::vector<SPItem*> &objects, SPStyle *style_res) //if object has a filter if (style->filter.set && style->getFilter()) { //cycle through filter primitives - SPObject *primitive_obj = style->getFilter()->children; - while (primitive_obj) { - SPFilterPrimitive *primitive = dynamic_cast<SPFilterPrimitive *>(primitive_obj); + for(auto& primitive_obj: style->getFilter()->children) { + SPFilterPrimitive *primitive = dynamic_cast<SPFilterPrimitive *>(&primitive_obj); if (primitive) { //if primitive is gaussianblur @@ -1820,7 +1822,6 @@ objects_query_blur (const std::vector<SPItem*> &objects, SPStyle *style_res) } } } - primitive_obj = primitive_obj->next; } } } @@ -1910,7 +1911,8 @@ sp_desktop_query_style(SPDesktop *desktop, SPStyle *style, int property) // otherwise, do querying and averaging over selection if (desktop->selection != NULL) { - return sp_desktop_query_style_from_list (desktop->selection->itemList(), style, property); + std::vector<SPItem *> vec(desktop->selection->items().begin(), desktop->selection->items().end()); + return sp_desktop_query_style_from_list (vec, style, property); } return QUERY_STYLE_NOTHING; diff --git a/src/display/nr-svgfonts.cpp b/src/display/nr-svgfonts.cpp index 011f51977..53a5cba49 100644 --- a/src/display/nr-svgfonts.cpp +++ b/src/display/nr-svgfonts.cpp @@ -203,14 +203,19 @@ SvgFont::scaled_font_text_to_glyphs (cairo_scaled_font_t */*scaled_font*/, //check whether is there a glyph declared on the SVG document // that matches with the text string in its current position if ( (len = size_of_substring(this->glyphs[i]->unicode.c_str(), _utf8)) ){ - for(SPObject* node = this->font->children;previous_unicode && node;node=node->next){ + for(auto& node: font->children) { + if (!previous_unicode) { + break; + } //apply glyph kerning if appropriate - SPHkern *hkern = dynamic_cast<SPHkern *>(node); - if (hkern && is_horizontal_text && MatchHKerningRule(hkern, this->glyphs[i], previous_unicode, previous_glyph_name) ){ + SPHkern *hkern = dynamic_cast<SPHkern *>(&node); + if (hkern && is_horizontal_text && + MatchHKerningRule(hkern, this->glyphs[i], previous_unicode, previous_glyph_name)) { x -= (hkern->k / 1000.0);//TODO: use here the height of the font } - SPVkern *vkern = dynamic_cast<SPVkern *>(node); - if (vkern && !is_horizontal_text && MatchVKerningRule(vkern, this->glyphs[i], previous_unicode, previous_glyph_name) ){ + SPVkern *vkern = dynamic_cast<SPVkern *>(&node); + if (vkern && !is_horizontal_text && + MatchVKerningRule(vkern, this->glyphs[i], previous_unicode, previous_glyph_name)) { y -= (vkern->k / 1000.0);//TODO: use here the "height" of the font } } @@ -271,10 +276,10 @@ SvgFont::glyph_modified(SPObject* /* blah */, unsigned int /* bleh */){ Geom::PathVector SvgFont::flip_coordinate_system(SPFont* spfont, Geom::PathVector pathv){ double units_per_em = 1000; - for (SPObject *obj = spfont->children; obj; obj = obj->next){ - if (dynamic_cast<SPFontFace *>(obj)) { + for(auto& obj: spfont->children) { + if (dynamic_cast<SPFontFace *>(&obj)) { //XML Tree being directly used here while it shouldn't be. - sp_repr_get_double(obj->getRepr(), "units_per_em", &units_per_em); + sp_repr_get_double(obj.getRepr(), "units_per_em", &units_per_em); } } @@ -339,19 +344,19 @@ SvgFont::scaled_font_render_glyph (cairo_scaled_font_t */*scaled_font*/, if (node->hasChildren()){ //render the SVG described on this glyph's child nodes. - for(node = node->children; node; node=node->next){ + for(auto& child: node->children) { { - SPPath *path = dynamic_cast<SPPath *>(node); + SPPath *path = dynamic_cast<SPPath *>(&child); if (path) { pathv = path->_curve->get_pathvector(); pathv = flip_coordinate_system(spfont, pathv); render_glyph_path(cr, &pathv); } } - if (dynamic_cast<SPObjectGroup *>(node)) { + if (dynamic_cast<SPObjectGroup *>(&child)) { g_warning("TODO: svgfonts: render OBJECTGROUP"); } - SPUse *use = dynamic_cast<SPUse *>(node); + SPUse *use = dynamic_cast<SPUse *>(&child); if (use) { SPItem* item = use->ref->getObject(); SPPath *path = dynamic_cast<SPPath *>(item); @@ -374,12 +379,12 @@ SvgFont::scaled_font_render_glyph (cairo_scaled_font_t */*scaled_font*/, cairo_font_face_t* SvgFont::get_font_face(){ if (!this->userfont) { - for(SPObject* node = this->font->children;node;node=node->next){ - SPGlyph *glyph = dynamic_cast<SPGlyph *>(node); + for(auto& node: font->children) { + SPGlyph *glyph = dynamic_cast<SPGlyph *>(&node); if (glyph) { glyphs.push_back(glyph); } - SPMissingGlyph *missing = dynamic_cast<SPMissingGlyph *>(node); + SPMissingGlyph *missing = dynamic_cast<SPMissingGlyph *>(&node); if (missing) { missingglyph = missing; } diff --git a/src/document.cpp b/src/document.cpp index 0ff01b587..920e47cb8 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -250,9 +250,9 @@ void SPDocument::setCurrentPersp3D(Persp3D * const persp) { void SPDocument::getPerspectivesInDefs(std::vector<Persp3D*> &list) const { - for (SPObject *i = root->defs->firstChild(); i; i = i->getNext() ) { - if (SP_IS_PERSP3D(i)) { - list.push_back(SP_PERSP3D(i)); + for (auto& i: root->defs->children) { + if (SP_IS_PERSP3D(&i)) { + list.push_back(SP_PERSP3D(&i)); } } } @@ -1252,12 +1252,12 @@ static std::vector<SPItem*> &find_items_in_area(std::vector<SPItem*> &s, SPGroup { g_return_val_if_fail(SP_IS_GROUP(group), s); - for ( SPObject *o = group->firstChild() ; o ; o = o->getNext() ) { - if ( SP_IS_ITEM(o) ) { - if (SP_IS_GROUP(o) && (SP_GROUP(o)->effectiveLayerMode(dkey) == SPGroup::LAYER || into_groups)) { - s = find_items_in_area(s, SP_GROUP(o), dkey, area, test, take_insensitive, into_groups); + for (auto& o: group->children) { + if ( SP_IS_ITEM(&o) ) { + if (SP_IS_GROUP(&o) && (SP_GROUP(&o)->effectiveLayerMode(dkey) == SPGroup::LAYER || into_groups)) { + s = find_items_in_area(s, SP_GROUP(&o), dkey, area, test, take_insensitive, into_groups); } else { - SPItem *child = SP_ITEM(o); + SPItem *child = SP_ITEM(&o); Geom::OptRect box = child->desktopVisualBounds(); if ( box && test(area, *box) && (take_insensitive || child->isVisibleAndUnlocked(dkey))) { s.push_back(child); @@ -1274,17 +1274,16 @@ Returns true if an item is among the descendants of group (recursively). */ static bool item_is_in_group(SPItem *item, SPGroup *group) { - bool inGroup = false; - for ( SPObject *o = group->firstChild() ; o && !inGroup; o = o->getNext() ) { - if ( SP_IS_ITEM(o) ) { - if (SP_ITEM(o) == item) { - inGroup = true; - } else if ( SP_IS_GROUP(o) ) { - inGroup = item_is_in_group(item, SP_GROUP(o)); + for (auto& o: group->children) { + if ( SP_IS_ITEM(&o) ) { + if (SP_ITEM(&o) == item) { + return true; + } else if (SP_IS_GROUP(&o) && item_is_in_group(item, SP_GROUP(&o))) { + return true; } } } - return inGroup; + return false; } SPItem *SPDocument::getItemFromListAtPointBottom(unsigned int dkey, SPGroup *group, std::vector<SPItem*> const &list,Geom::Point const &p, bool take_insensitive) @@ -1295,21 +1294,24 @@ SPItem *SPDocument::getItemFromListAtPointBottom(unsigned int dkey, SPGroup *gro Inkscape::Preferences *prefs = Inkscape::Preferences::get(); gdouble delta = prefs->getDouble("/options/cursortolerance/value", 1.0); - for ( SPObject *o = group->firstChild() ; o && !bottomMost; o = o->getNext() ) { - if ( SP_IS_ITEM(o) ) { - SPItem *item = SP_ITEM(o); + for (auto& o: group->children) { + if (bottomMost) { + break; + } + if (SP_IS_ITEM(&o)) { + SPItem *item = SP_ITEM(&o); Inkscape::DrawingItem *arenaitem = item->get_arenaitem(dkey); arenaitem->drawing().update(); if (arenaitem && arenaitem->pick(p, delta, 1) != NULL && (take_insensitive || item->isVisibleAndUnlocked(dkey))) { - if (find(list.begin(),list.end(),item)!=list.end() ) { + if (find(list.begin(), list.end(), item) != list.end()) { bottomMost = item; } } - if ( !bottomMost && SP_IS_GROUP(o) ) { + if (!bottomMost && SP_IS_GROUP(&o)) { // return null if not found: - bottomMost = getItemFromListAtPointBottom(dkey, SP_GROUP(o), list, p, take_insensitive); + bottomMost = getItemFromListAtPointBottom(dkey, SP_GROUP(&o), list, p, take_insensitive); } } } @@ -1322,15 +1324,15 @@ The list can be persisted, which improves "find at multiple points" speed. */ void SPDocument::build_flat_item_list(unsigned int dkey, SPGroup *group, gboolean into_groups) const { - for ( SPObject *o = group->firstChild() ; o ; o = o->getNext() ) { - if (!SP_IS_ITEM(o)) { + for (auto& o: group->children) { + if (!SP_IS_ITEM(&o)) { continue; } - if (SP_IS_GROUP(o) && (SP_GROUP(o)->effectiveLayerMode(dkey) == SPGroup::LAYER || into_groups)) { - build_flat_item_list(dkey, SP_GROUP(o), into_groups); + if (SP_IS_GROUP(&o) && (SP_GROUP(&o)->effectiveLayerMode(dkey) == SPGroup::LAYER || into_groups)) { + build_flat_item_list(dkey, SP_GROUP(&o), into_groups); } else { - SPItem *child = SP_ITEM(o); + SPItem *child = SP_ITEM(&o); if (child->isVisibleAndUnlocked(dkey)) { _node_cache.push_front(child); @@ -1386,18 +1388,18 @@ static SPItem *find_group_at_point(unsigned int dkey, SPGroup *group, Geom::Poin Inkscape::Preferences *prefs = Inkscape::Preferences::get(); gdouble delta = prefs->getDouble("/options/cursortolerance/value", 1.0); - for ( SPObject *o = group->firstChild() ; o ; o = o->getNext() ) { - if (!SP_IS_ITEM(o)) { + for (auto& o: group->children) { + if (!SP_IS_ITEM(&o)) { continue; } - if (SP_IS_GROUP(o) && SP_GROUP(o)->effectiveLayerMode(dkey) == SPGroup::LAYER) { - SPItem *newseen = find_group_at_point(dkey, SP_GROUP(o), p); + if (SP_IS_GROUP(&o) && SP_GROUP(&o)->effectiveLayerMode(dkey) == SPGroup::LAYER) { + SPItem *newseen = find_group_at_point(dkey, SP_GROUP(&o), p); if (newseen) { seen = newseen; } } - if (SP_IS_GROUP(o) && SP_GROUP(o)->effectiveLayerMode(dkey) != SPGroup::LAYER ) { - SPItem *child = SP_ITEM(o); + if (SP_IS_GROUP(&o) && SP_GROUP(&o)->effectiveLayerMode(dkey) != SPGroup::LAYER ) { + SPItem *child = SP_ITEM(&o); Inkscape::DrawingItem *arenaitem = child->get_arenaitem(dkey); arenaitem->drawing().update(); @@ -1591,8 +1593,8 @@ static unsigned int count_objects_recursive(SPObject *obj, unsigned int count) { count++; // obj itself - for ( SPObject *i = obj->firstChild(); i; i = i->getNext() ) { - count = count_objects_recursive(i, count); + for (auto& i: obj->children) { + count = count_objects_recursive(&i, count); } return count; @@ -1617,13 +1619,13 @@ static unsigned int objects_in_document(SPDocument *document) static void vacuum_document_recursive(SPObject *obj) { if (SP_IS_DEFS(obj)) { - for ( SPObject *def = obj->firstChild(); def; def = def->getNext()) { + for (auto& def: obj->children) { // fixme: some inkscape-internal nodes in the future might not be collectable - def->requestOrphanCollection(); + def.requestOrphanCollection(); } } else { - for ( SPObject *i = obj->firstChild(); i; i = i->getNext() ) { - vacuum_document_recursive(i); + for (auto& i: obj->children) { + vacuum_document_recursive(&i); } } } @@ -1751,14 +1753,14 @@ void SPDocument::importDefsNode(SPDocument *source, Inkscape::XML::Node *defs, I // Prevent duplicates of solid swatches by checking if equivalent swatch already exists if (src && SP_IS_GRADIENT(src)) { SPGradient *s_gr = SP_GRADIENT(src); - for (SPObject *trg = this->getDefs()->firstChild() ; trg ; trg = trg->getNext()) { - if (trg && (src != trg) && SP_IS_GRADIENT(trg)) { - SPGradient *t_gr = SP_GRADIENT(trg); + for (auto& trg: getDefs()->children) { + if (&trg && (src != &trg) && SP_IS_GRADIENT(&trg)) { + SPGradient *t_gr = SP_GRADIENT(&trg); if (t_gr && s_gr->isEquivalent(t_gr)) { // Change object references to the existing equivalent gradient - Glib::ustring newid = trg->getId(); + Glib::ustring newid = trg.getId(); if(newid != defid){ // id could be the same if it is a second paste into the same document - change_def_references(src, trg); + change_def_references(src, &trg); } gchar *longid = g_strdup_printf("%s_%9.9d", DuplicateDefString.c_str(), stagger++); def->setAttribute("id", longid ); @@ -1822,9 +1824,9 @@ void SPDocument::importDefsNode(SPDocument *source, Inkscape::XML::Node *defs, I id.erase( pos ); // Check that it really is a duplicate - for (SPObject *trg = this->getDefs()->firstChild() ; trg ; trg = trg->getNext()) { - if( trg && SP_IS_SYMBOL(trg) && src != trg ) { - std::string id2 = trg->getRepr()->attribute("id"); + for (auto& trg: getDefs()->children) { + if(&trg && SP_IS_SYMBOL(&trg) && src != &trg ) { + std::string id2 = trg.getRepr()->attribute("id"); if( !id.compare( id2 ) ) { duplicate = true; diff --git a/src/extension/dbus/document-interface.cpp b/src/extension/dbus/document-interface.cpp index d0a2e81aa..5a8fb0918 100644 --- a/src/extension/dbus/document-interface.cpp +++ b/src/extension/dbus/document-interface.cpp @@ -189,7 +189,7 @@ selection_get_center_y (Inkscape::Selection *sel){ std::vector<SPObject*> selection_swap(Inkscape::Selection *sel, gchar *name, GError **error) { - std::vector<SPObject*> oldsel = sel->list(); + std::vector<SPObject*> oldsel = std::vector<SPObject*>(sel->objects().begin(), sel->objects().end()); sel->set(get_object_by_name(sel->layers()->getDocument(), name, error)); return oldsel; @@ -1087,14 +1087,14 @@ void document_interface_update(DocumentInterface *doc_interface, GError ** error gboolean document_interface_selection_get(DocumentInterface *doc_interface, char ***out, GError ** /*error*/) { Inkscape::Selection * sel = doc_interface->target.getSelection(); - std::vector<SPObject*> oldsel = sel->list(); + auto oldsel = sel->objects(); int size = oldsel.size(); *out = g_new0 (char *, size + 1); int i = 0; - for (std::vector<SPObject*>::iterator iter = oldsel.begin(), e = oldsel.end(); iter != e; ++iter) { + for (auto iter = oldsel.begin(); iter != oldsel.end(); ++iter) { (*out)[i] = g_strdup((*iter)->getId()); i++; } @@ -1252,7 +1252,7 @@ gboolean document_interface_selection_move_to(DocumentInterface *doc_interface, Geom::OptRect sel_bbox = sel->visualBounds(); if (sel_bbox) { Geom::Point m( x - selection_get_center_x(sel) , 0 - (y - selection_get_center_y(sel)) ); - sp_selection_move_relative(sel, m, true); + sp_object_set_move_relative(sel, m, true); } return TRUE; } diff --git a/src/extension/execution-env.cpp b/src/extension/execution-env.cpp index 569e2c762..624813863 100644 --- a/src/extension/execution-env.cpp +++ b/src/extension/execution-env.cpp @@ -55,8 +55,8 @@ ExecutionEnv::ExecutionEnv (Effect * effect, Inkscape::UI::View::View * doc, Imp sp_namedview_document_from_window(desktop); if (desktop != NULL) { - std::vector<SPItem*> selected = desktop->getSelection()->itemList(); - for(std::vector<SPItem*>::const_iterator x = selected.begin(); x != selected.end(); ++x){ + auto selected = desktop->getSelection()->items(); + for(auto x = selected.begin(); x != selected.end(); ++x){ Glib::ustring selected_id; selected_id = (*x)->getId(); _selected.insert(_selected.end(), selected_id); diff --git a/src/extension/implementation/implementation.cpp b/src/extension/implementation/implementation.cpp index 995d3d9ad..6e6100d2b 100644 --- a/src/extension/implementation/implementation.cpp +++ b/src/extension/implementation/implementation.cpp @@ -45,10 +45,10 @@ Gtk::Widget *Implementation::prefs_effect(Inkscape::Extension::Effect *module, I SPDocument * current_document = view->doc(); - std::vector<SPItem*> selected = ((SPDesktop *)view)->getSelection()->itemList(); + auto selected = ((SPDesktop *) view)->getSelection()->items(); Inkscape::XML::Node const* first_select = NULL; if (!selected.empty()) { - const SPItem * item = selected[0]; + const SPItem * item = selected.front(); first_select = item->getRepr(); } diff --git a/src/extension/implementation/script.cpp b/src/extension/implementation/script.cpp index 72a189c3f..d2319c2e0 100644 --- a/src/extension/implementation/script.cpp +++ b/src/extension/implementation/script.cpp @@ -689,9 +689,9 @@ void Script::effect(Inkscape::Extension::Effect *module, return; } - std::vector<SPItem*> selected = - desktop->getSelection()->itemList(); //desktop should not be NULL since doc was checked and desktop is a casted pointer - for(std::vector<SPItem*>::const_iterator x = selected.begin(); x != selected.end(); ++x){ + auto selected = + desktop->getSelection()->items(); //desktop should not be NULL since doc was checked and desktop is a casted pointer + for(auto x = selected.begin(); x != selected.end(); ++x){ Glib::ustring selected_id; selected_id += "--id="; selected_id += (*x)->getId(); diff --git a/src/extension/internal/bitmap/imagemagick.cpp b/src/extension/internal/bitmap/imagemagick.cpp index a235dcb0f..472c2db91 100644 --- a/src/extension/internal/bitmap/imagemagick.cpp +++ b/src/extension/internal/bitmap/imagemagick.cpp @@ -65,8 +65,8 @@ ImageMagickDocCache::ImageMagickDocCache(Inkscape::UI::View::View * view) : _imageItems(NULL) { SPDesktop *desktop = (SPDesktop*)view; - const std::vector<SPItem*> selectedItemList = desktop->selection->itemList(); - int selectCount = selectedItemList.size(); + auto selectedItemList = desktop->selection->items(); + int selectCount = (int) boost::distance(selectedItemList); // Init the data-holders _nodes = new Inkscape::XML::Node*[selectCount]; @@ -78,7 +78,7 @@ ImageMagickDocCache::ImageMagickDocCache(Inkscape::UI::View::View * view) : _imageItems = new SPItem*[selectCount]; // Loop through selected items - for (std::vector<SPItem*>::const_iterator i = selectedItemList.begin(); i != selectedItemList.end(); ++i) { + for (auto i = selectedItemList.begin(); i != selectedItemList.end(); ++i) { SPItem *item = *i; Inkscape::XML::Node *node = reinterpret_cast<Inkscape::XML::Node *>(item->getRepr()); if (!strcmp(node->name(), "image") || !strcmp(node->name(), "svg:image")) @@ -235,7 +235,7 @@ ImageMagick::prefs_effect(Inkscape::Extension::Effect *module, Inkscape::UI::Vie { SPDocument * current_document = view->doc(); - std::vector<SPItem*> selected = ((SPDesktop *)view)->getSelection()->itemList(); + auto selected = ((SPDesktop *) view)->getSelection()->items(); Inkscape::XML::Node * first_select = NULL; if (!selected.empty()) { first_select = (selected.front())->getRepr(); diff --git a/src/extension/internal/bluredge.cpp b/src/extension/internal/bluredge.cpp index 4a04e3c33..4f66b39fc 100644 --- a/src/extension/internal/bluredge.cpp +++ b/src/extension/internal/bluredge.cpp @@ -62,7 +62,7 @@ BlurEdge::effect (Inkscape::Extension::Effect *module, Inkscape::UI::View::View double old_offset = prefs->getDouble("/options/defaultoffsetwidth/value", 1.0, "px"); // TODO need to properly refcount the items, at least - std::vector<SPItem*> items(selection->itemList()); + std::vector<SPItem*> items(selection->items().begin(), selection->items().end()); selection->clear(); for(std::vector<SPItem*>::iterator item = items.begin(); diff --git a/src/extension/internal/cairo-render-context.cpp b/src/extension/internal/cairo-render-context.cpp index 5d8b0e076..1310bb343 100644 --- a/src/extension/internal/cairo-render-context.cpp +++ b/src/extension/internal/cairo-render-context.cpp @@ -986,13 +986,12 @@ void CairoRenderContext::popState(void) static bool pattern_hasItemChildren(SPPattern *pat) { - bool hasItems = false; - for ( SPObject *child = pat->firstChild() ; child && !hasItems; child = child->getNext() ) { - if (SP_IS_ITEM (child)) { - hasItems = true; + for (auto& child: pat->children) { + if (SP_IS_ITEM (&child)) { + return true; } } - return hasItems; + return false; } cairo_pattern_t* @@ -1087,10 +1086,10 @@ CairoRenderContext::_createPatternPainter(SPPaintServer const *const paintserver // show items and render them for (SPPattern *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { if (pat_i && SP_IS_OBJECT(pat_i) && pattern_hasItemChildren(pat_i)) { // find the first one with item children - for ( SPObject *child = pat_i->firstChild() ; child; child = child->getNext() ) { - if (SP_IS_ITEM(child)) { - SP_ITEM(child)->invoke_show(drawing, dkey, SP_ITEM_REFERENCE_FLAGS); - _renderer->renderItem(pattern_ctx, SP_ITEM(child)); + for (auto& child: pat_i->children) { + if (SP_IS_ITEM(&child)) { + SP_ITEM(&child)->invoke_show(drawing, dkey, SP_ITEM_REFERENCE_FLAGS); + _renderer->renderItem(pattern_ctx, SP_ITEM(&child)); } } break; // do not go further up the chain if children are found @@ -1116,9 +1115,9 @@ CairoRenderContext::_createPatternPainter(SPPaintServer const *const paintserver // hide all items for (SPPattern *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { if (pat_i && SP_IS_OBJECT(pat_i) && pattern_hasItemChildren(pat_i)) { // find the first one with item children - for ( SPObject *child = pat_i->firstChild() ; child; child = child->getNext() ) { - if (SP_IS_ITEM(child)) { - SP_ITEM(child)->invoke_hide(dkey); + for (auto& child: pat_i->children) { + if (SP_IS_ITEM(&child)) { + SP_ITEM(&child)->invoke_hide(dkey); } } break; // do not go further up the chain if children are found diff --git a/src/extension/internal/cairo-renderer.cpp b/src/extension/internal/cairo-renderer.cpp index 5dc20ab06..cd96a7f58 100644 --- a/src/extension/internal/cairo-renderer.cpp +++ b/src/extension/internal/cairo-renderer.cpp @@ -741,8 +741,8 @@ CairoRenderer::applyClipPath(CairoRenderContext *ctx, SPClipPath const *cp) TRACE(("BEGIN clip\n")); SPObject const *co = cp; - for ( SPObject const *child = co->firstChild() ; child; child = child->getNext() ) { - SPItem const *item = dynamic_cast<SPItem const *>(child); + for (auto& child: co->children) { + SPItem const *item = dynamic_cast<SPItem const *>(&child); if (item) { // combine transform of the item in clippath and the item using clippath: @@ -800,8 +800,8 @@ CairoRenderer::applyMask(CairoRenderContext *ctx, SPMask const *mask) TRACE(("BEGIN mask\n")); SPObject const *co = mask; - for ( SPObject const *child = co->firstChild() ; child; child = child->getNext() ) { - SPItem const *item = dynamic_cast<SPItem const *>(child); + for (auto& child: co->children) { + SPItem const *item = dynamic_cast<SPItem const *>(&child); if (item) { // TODO fix const correctness: renderItem(ctx, const_cast<SPItem*>(item)); diff --git a/src/extension/internal/emf-print.cpp b/src/extension/internal/emf-print.cpp index 9f3b5475f..d4c5d95a3 100644 --- a/src/extension/internal/emf-print.cpp +++ b/src/extension/internal/emf-print.cpp @@ -1042,8 +1042,12 @@ void PrintEmf::do_clip_if_present(SPStyle const *style){ /* find the clipping path */ Geom::PathVector combined_pathvector; Geom::Affine tfc; // clipping transform, generally not the same as item transform - for(item = SP_ITEM(scp->firstChild()); item; item=SP_ITEM(item->getNext())){ - if (SP_IS_GROUP(item)) { // not implemented + for (auto& child: scp->children) { + item = SP_ITEM(&child); + if (!item) { + break; + } + if (SP_IS_GROUP(item)) { // not implemented // return sp_group_render(item); combined_pathvector = merge_PathVector_with_group(combined_pathvector, item, tfc); } else if (SP_IS_SHAPE(item)) { @@ -1081,7 +1085,11 @@ Geom::PathVector PrintEmf::merge_PathVector_with_group(Geom::PathVector const &c new_combined_pathvector = combined_pathvector; SPGroup *group = SP_GROUP(item); Geom::Affine tfc = item->transform * transform; - for(SPItem *item = SP_ITEM(group->firstChild()); item; item=SP_ITEM(item->getNext())){ + for (auto& child: group->children) { + item = SP_ITEM(&child); + if (!item) { + break; + } if (SP_IS_GROUP(item)) { new_combined_pathvector = merge_PathVector_with_group(new_combined_pathvector, item, tfc); // could be endlessly recursive on a badly formed SVG } else if (SP_IS_SHAPE(item)) { diff --git a/src/extension/internal/filter/filter.cpp b/src/extension/internal/filter/filter.cpp index 25e89bbf3..0907845f8 100644 --- a/src/extension/internal/filter/filter.cpp +++ b/src/extension/internal/filter/filter.cpp @@ -125,7 +125,7 @@ void Filter::effect(Inkscape::Extension::Effect *module, Inkscape::UI::View::Vie Inkscape::Selection * selection = ((SPDesktop *)document)->selection; // TODO need to properly refcount the items, at least - std::vector<SPItem*> items(selection->itemList()); + std::vector<SPItem*> items(selection->items().begin(), selection->items().end()); Inkscape::XML::Document * xmldoc = document->doc()->getReprDoc(); Inkscape::XML::Node * defsrepr = document->doc()->getDefs()->getRepr(); diff --git a/src/extension/internal/grid.cpp b/src/extension/internal/grid.cpp index c766bd828..9e730f5e5 100644 --- a/src/extension/internal/grid.cpp +++ b/src/extension/internal/grid.cpp @@ -180,10 +180,10 @@ Grid::prefs_effect(Inkscape::Extension::Effect *module, Inkscape::UI::View::View { SPDocument * current_document = view->doc(); - std::vector<SPItem*> selected = ((SPDesktop *)view)->getSelection()->itemList(); + auto selected = ((SPDesktop *) view)->getSelection()->items(); Inkscape::XML::Node * first_select = NULL; if (!selected.empty()) { - first_select = selected[0]->getRepr(); + first_select = selected.front()->getRepr(); } return module->autogui(current_document, first_select, changeSignal); diff --git a/src/extension/internal/javafx-out.cpp b/src/extension/internal/javafx-out.cpp index 386bde1d6..d7ad7e6f7 100644 --- a/src/extension/internal/javafx-out.cpp +++ b/src/extension/internal/javafx-out.cpp @@ -732,9 +732,9 @@ bool JavaFXOutput::doTreeRecursive(SPDocument *doc, SPObject *obj) /** * Descend into children */ - for (SPObject *child = obj->firstChild() ; child ; child = child->next) + for (auto &child: obj->children) { - if (!doTreeRecursive(doc, child)) { + if (!doTreeRecursive(doc, &child)) { return false; } } @@ -804,9 +804,9 @@ bool JavaFXOutput::doBody(SPDocument *doc, SPObject *obj) /** * Descend into children */ - for (SPObject *child = obj->firstChild() ; child ; child = child->next) + for (auto &child: obj->children) { - if (!doBody(doc, child)) { + if (!doBody(doc, &child)) { return false; } } diff --git a/src/extension/internal/metafile-print.cpp b/src/extension/internal/metafile-print.cpp index 47ba5971c..061eb634d 100644 --- a/src/extension/internal/metafile-print.cpp +++ b/src/extension/internal/metafile-print.cpp @@ -293,20 +293,22 @@ void PrintMetafile::brush_classify(SPObject *parent, int depth, Inkscape::Pixbuf } // still looking? Look at this pattern's children, if there are any - SPObject *child = pat_i->firstChild(); - while (child && !(*epixbuf) && (*hatchType == -1)) { - brush_classify(child, depth, epixbuf, hatchType, hatchColor, bkColor); - child = child->getNext(); + for (auto& child: pat_i->children) { + if (*epixbuf || *hatchType != -1) { + break; + } + brush_classify(&child, depth, epixbuf, hatchType, hatchColor, bkColor); } } } else if (SP_IS_IMAGE(parent)) { *epixbuf = ((SPImage *)parent)->pixbuf; return; } else { // some inkscape rearrangements pass through nodes between pattern and image which are not classified as either. - SPObject *child = parent->firstChild(); - while (child && !(*epixbuf) && (*hatchType == -1)) { - brush_classify(child, depth, epixbuf, hatchType, hatchColor, bkColor); - child = child->getNext(); + for (auto& child: parent->children) { + if (*epixbuf || *hatchType != -1) { + break; + } + brush_classify(&child, depth, epixbuf, hatchType, hatchColor, bkColor); } } } diff --git a/src/extension/internal/pov-out.cpp b/src/extension/internal/pov-out.cpp index bd2168b68..8df883069 100644 --- a/src/extension/internal/pov-out.cpp +++ b/src/extension/internal/pov-out.cpp @@ -479,9 +479,9 @@ bool PovOutput::doTreeRecursive(SPDocument *doc, SPObject *obj) /** * Descend into children */ - for (SPObject *child = obj->firstChild() ; child ; child = child->next) + for (auto &child: obj->children) { - if (!doTreeRecursive(doc, child)) + if (!doTreeRecursive(doc, &child)) return false; } diff --git a/src/extension/param/bool.cpp b/src/extension/param/bool.cpp index e67d3e3f5..ca61d8c51 100644 --- a/src/extension/param/bool.cpp +++ b/src/extension/param/bool.cpp @@ -14,6 +14,7 @@ #include <gtkmm/box.h> #include <gtkmm/spinbutton.h> #include <gtkmm/checkbutton.h> +#include <glib/gi18n.h> #include "xml/node.h" #include "../extension.h" @@ -132,7 +133,7 @@ Gtk::Widget *ParamBool::get_widget(SPDocument * doc, Inkscape::XML::Node * node, auto hbox = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_HORIZONTAL, 4)); hbox->set_homogeneous(false); - Gtk::Label * label = Gtk::manage(new Gtk::Label(_text, Gtk::ALIGN_START)); + Gtk::Label * label = Gtk::manage(new Gtk::Label(_(_text), Gtk::ALIGN_START)); label->show(); hbox->pack_end(*label, true, true); diff --git a/src/extension/param/enum.cpp b/src/extension/param/enum.cpp index 4e7420807..8bc0fbda7 100644 --- a/src/extension/param/enum.cpp +++ b/src/extension/param/enum.cpp @@ -251,7 +251,7 @@ Gtk::Widget *ParamComboBox::get_widget(SPDocument * doc, Inkscape::XML::Node * n } Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox(false, 4)); - Gtk::Label * label = Gtk::manage(new Gtk::Label(_text, Gtk::ALIGN_START)); + Gtk::Label * label = Gtk::manage(new Gtk::Label(_(_text), Gtk::ALIGN_START)); label->show(); hbox->pack_start(*label, false, false, _indent); diff --git a/src/extension/param/float.cpp b/src/extension/param/float.cpp index d4c33ec94..23a03ea8f 100644 --- a/src/extension/param/float.cpp +++ b/src/extension/param/float.cpp @@ -15,6 +15,7 @@ #include <gtkmm/scale.h> #include "ui/widget/spinbutton.h" #include "ui/widget/spin-scale.h" +#include <glib/gi18n.h> #include "xml/node.h" #include "extension/extension.h" @@ -181,7 +182,7 @@ Gtk::Widget * ParamFloat::get_widget(SPDocument * doc, Inkscape::XML::Node * nod if (_mode == FULL) { - UI::Widget::SpinScale *scale = new UI::Widget::SpinScale(_text, fadjust, _precision); + UI::Widget::SpinScale *scale = new UI::Widget::SpinScale(_(_text), fadjust, _precision); scale->set_size_request(400, -1); scale->show(); hbox->pack_start(*scale, false, false); @@ -189,7 +190,7 @@ Gtk::Widget * ParamFloat::get_widget(SPDocument * doc, Inkscape::XML::Node * nod } else if (_mode == MINIMAL) { - Gtk::Label * label = Gtk::manage(new Gtk::Label(_text, Gtk::ALIGN_START)); + Gtk::Label * label = Gtk::manage(new Gtk::Label(_(_text), Gtk::ALIGN_START)); label->show(); hbox->pack_start(*label, true, true, _indent); diff --git a/src/extension/param/int.cpp b/src/extension/param/int.cpp index 533ee3886..222d4f243 100644 --- a/src/extension/param/int.cpp +++ b/src/extension/param/int.cpp @@ -15,6 +15,7 @@ #include <gtkmm/scale.h> #include "ui/widget/spinbutton.h" #include "ui/widget/spin-scale.h" +#include <glib/gi18n.h> #include "xml/node.h" #include "extension/extension.h" @@ -162,14 +163,14 @@ ParamInt::get_widget (SPDocument * doc, Inkscape::XML::Node * node, sigc::signal if (_mode == FULL) { - UI::Widget::SpinScale *scale = new UI::Widget::SpinScale(_text, fadjust, 0); + UI::Widget::SpinScale *scale = new UI::Widget::SpinScale(_(_text), fadjust, 0); scale->set_size_request(400, -1); scale->show(); hbox->pack_start(*scale, false, false); } else if (_mode == MINIMAL) { - Gtk::Label * label = Gtk::manage(new Gtk::Label(_text, Gtk::ALIGN_START)); + Gtk::Label * label = Gtk::manage(new Gtk::Label(_(_text), Gtk::ALIGN_START)); label->show(); hbox->pack_start(*label, true, true, _indent); diff --git a/src/extension/param/parameter.cpp b/src/extension/param/parameter.cpp index e4a614667..a5632a39a 100644 --- a/src/extension/param/parameter.cpp +++ b/src/extension/param/parameter.cpp @@ -58,16 +58,6 @@ Parameter *Parameter::make(Inkscape::XML::Node *in_repr, Inkscape::Extension::Ex const char *guitext = in_repr->attribute("gui-text"); if (guitext == NULL) { guitext = in_repr->attribute("_gui-text"); - if (guitext == NULL) { - // guitext = ""; // propably better to require devs to explicitly set an empty gui-text if this is what they want - } else { - const char *context = in_repr->attribute("msgctxt"); - if (context != NULL) { - guitext = g_dpgettext2(NULL, context, guitext); - } else { - guitext = _(guitext); - } - } } const char *gui_tip = in_repr->attribute("gui-tip"); if (gui_tip == NULL) { diff --git a/src/extension/param/radiobutton.cpp b/src/extension/param/radiobutton.cpp index ed28c0d75..c54cc0ec3 100644 --- a/src/extension/param/radiobutton.cpp +++ b/src/extension/param/radiobutton.cpp @@ -308,7 +308,7 @@ Gtk::Widget * ParamRadioButton::get_widget(SPDocument * doc, Inkscape::XML::Node auto vbox = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_VERTICAL, 0)); vbox->set_homogeneous(false); - Gtk::Label * label = Gtk::manage(new Gtk::Label(_text, Gtk::ALIGN_START, Gtk::ALIGN_START)); + Gtk::Label * label = Gtk::manage(new Gtk::Label(_(_text), Gtk::ALIGN_START, Gtk::ALIGN_START)); label->show(); hbox->pack_start(*label, false, false, _indent); diff --git a/src/extension/param/string.cpp b/src/extension/param/string.cpp index 6b082b133..1d9205502 100644 --- a/src/extension/param/string.cpp +++ b/src/extension/param/string.cpp @@ -166,7 +166,7 @@ Gtk::Widget * ParamString::get_widget(SPDocument * doc, Inkscape::XML::Node * no } Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox(false, 4)); - Gtk::Label * label = Gtk::manage(new Gtk::Label(_text, Gtk::ALIGN_START)); + Gtk::Label * label = Gtk::manage(new Gtk::Label(_(_text), Gtk::ALIGN_START)); label->show(); hbox->pack_start(*label, false, false, _indent); diff --git a/src/extension/plugins/grid2/grid.cpp b/src/extension/plugins/grid2/grid.cpp index 6880c574d..233d4e522 100644 --- a/src/extension/plugins/grid2/grid.cpp +++ b/src/extension/plugins/grid2/grid.cpp @@ -186,10 +186,10 @@ Grid::prefs_effect(Inkscape::Extension::Effect *module, Inkscape::UI::View::View { SPDocument * current_document = view->doc(); - std::vector<SPItem*> selected = ((SPDesktop *)view)->getSelection()->itemList(); + auto selected = ((SPDesktop *) view)->getSelection()->items(); Inkscape::XML::Node * first_select = NULL; if (!selected.empty()) { - first_select = selected[0]->getRepr(); + first_select = selected.front()->getRepr(); } return module->autogui(current_document, first_select, changeSignal); diff --git a/src/file.cpp b/src/file.cpp index 56fdffb3c..7c17a6158 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -1118,14 +1118,14 @@ void sp_import_document(SPDesktop *desktop, SPDocument *clipdoc, bool in_place) Inkscape::Selection *selection = desktop->getSelection(); selection->setReprList(pasted_objects_not); Geom::Affine doc2parent = SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse(); - sp_selection_apply_affine(selection, desktop->dt2doc() * doc2parent * desktop->doc2dt(), true, false, false); + sp_object_set_apply_affine(selection, desktop->dt2doc() * doc2parent * desktop->doc2dt(), true, false, false); sp_selection_delete(desktop); // Change the selection to the freshly pasted objects selection->setReprList(pasted_objects); // Apply inverse of parent transform - sp_selection_apply_affine(selection, desktop->dt2doc() * doc2parent * desktop->doc2dt(), true, false, false); + sp_object_set_apply_affine(selection, desktop->dt2doc() * doc2parent * desktop->doc2dt(), true, false, false); // Update (among other things) all curves in paths, for bounds() to work target_document->ensureUpToDate(); @@ -1155,7 +1155,7 @@ void sp_import_document(SPDesktop *desktop, SPDocument *clipdoc, bool in_place) m.unSetup(); } - sp_selection_move_relative(selection, offset); + sp_object_set_move_relative(selection, offset); } } @@ -1193,8 +1193,8 @@ file_import(SPDocument *in_doc, const Glib::ustring &uri, // Count the number of top-level items in the imported document. guint items_count = 0; - for ( SPObject *child = doc->getRoot()->firstChild(); child; child = child->getNext()) { - if (SP_IS_ITEM(child)) { + for (auto& child: doc->getRoot()->children) { + if (SP_IS_ITEM(&child)) { items_count++; } } @@ -1223,9 +1223,9 @@ file_import(SPDocument *in_doc, const Glib::ustring &uri, // Construct a new object representing the imported image, // and insert it into the current document. SPObject *new_obj = NULL; - for ( SPObject *child = doc->getRoot()->firstChild(); child; child = child->getNext() ) { - if (SP_IS_ITEM(child)) { - Inkscape::XML::Node *newitem = child->getRepr()->duplicate(xml_in_doc); + for (auto& child: doc->getRoot()->children) { + if (SP_IS_ITEM(&child)) { + Inkscape::XML::Node *newitem = child.getRepr()->duplicate(xml_in_doc); // convert layers to groups, and make sure they are unlocked // FIXME: add "preserve layers" mode where each layer from @@ -1238,10 +1238,10 @@ file_import(SPDocument *in_doc, const Glib::ustring &uri, } // don't lose top-level defs or style elements - else if (child->getRepr()->type() == Inkscape::XML::ELEMENT_NODE) { - const gchar *tag = child->getRepr()->name(); + else if (child.getRepr()->type() == Inkscape::XML::ELEMENT_NODE) { + const gchar *tag = child.getRepr()->name(); if (!strcmp(tag, "svg:style")) { - in_doc->getRoot()->appendChildRepr(child->getRepr()->duplicate(xml_in_doc)); + in_doc->getRoot()->appendChildRepr(child.getRepr()->duplicate(xml_in_doc)); } } } @@ -1260,7 +1260,7 @@ file_import(SPDocument *in_doc, const Glib::ustring &uri, // c2p is identity matrix at this point unless ensureUpToDate is called doc->ensureUpToDate(); Geom::Affine affine = doc->getRoot()->c2p * SP_ITEM(place_to_insert)->i2doc_affine().inverse(); - sp_selection_apply_affine(selection, desktop->dt2doc() * affine * desktop->doc2dt(), true, false, false); + sp_object_set_apply_affine(selection, desktop->dt2doc() * affine * desktop->doc2dt(), true, false, false); // move to mouse pointer { @@ -1268,7 +1268,7 @@ file_import(SPDocument *in_doc, const Glib::ustring &uri, Geom::OptRect sel_bbox = selection->visualBounds(); if (sel_bbox) { Geom::Point m( desktop->point() - sel_bbox->midpoint() ); - sp_selection_move_relative(selection, m, false); + sp_object_set_move_relative(selection, m, false); } } } diff --git a/src/filter-chemistry.cpp b/src/filter-chemistry.cpp index 3618b2642..560e73322 100644 --- a/src/filter-chemistry.cpp +++ b/src/filter-chemistry.cpp @@ -46,8 +46,8 @@ static guint count_filter_hrefs(SPObject *o, SPFilter *filter) i ++; } - for ( SPObject *child = o->firstChild(); child; child = child->getNext() ) { - i += count_filter_hrefs(child, filter); + for (auto& child: o->children) { + i += count_filter_hrefs(&child, filter); } return i; @@ -486,16 +486,14 @@ void remove_filter_gaussian_blur (SPObject *item) bool filter_is_single_gaussian_blur(SPFilter *filter) { - return (filter->firstChild() && - (filter->firstChild() == filter->lastChild()) && - SP_IS_GAUSSIANBLUR(filter->firstChild())); + return (filter->children.size() == 1 && + SP_IS_GAUSSIANBLUR(&filter->children.front())); } double get_single_gaussian_blur_radius(SPFilter *filter) { - if (filter->firstChild() && - (filter->firstChild() == filter->lastChild()) && - SP_IS_GAUSSIANBLUR(filter->firstChild())) { + if (filter->children.size() == 1 && + SP_IS_GAUSSIANBLUR(&filter->children.front())) { SPGaussianBlur *gb = SP_GAUSSIANBLUR(filter->firstChild()); double x = gb->stdDeviation.getNumber(); diff --git a/src/filters/blend.cpp b/src/filters/blend.cpp index b3767632f..0c7f87542 100644 --- a/src/filters/blend.cpp +++ b/src/filters/blend.cpp @@ -195,11 +195,11 @@ Inkscape::XML::Node* SPFeBlend::write(Inkscape::XML::Document *doc, Inkscape::XM if( !in2_name ) { // This code is very similar to sp_filter_primtive_name_previous_out() - SPObject *i = parent->children; + SPObject *i = parent->firstChild(); // Find previous filter primitive - while (i && i->next != this) { - i = i->next; + while (i && i->getNext() != this) { + i = i->getNext(); } if( i ) { diff --git a/src/filters/componenttransfer.cpp b/src/filters/componenttransfer.cpp index 47e570fa4..19843eebd 100644 --- a/src/filters/componenttransfer.cpp +++ b/src/filters/componenttransfer.cpp @@ -45,11 +45,10 @@ static void sp_feComponentTransfer_children_modified(SPFeComponentTransfer *sp_c { if (sp_componenttransfer->renderer) { bool set[4] = {false, false, false, false}; - SPObject* node = sp_componenttransfer->children; - for(;node;node=node->next){ + for(auto& node: sp_componenttransfer->children) { int i = 4; - SPFeFuncNode *funcNode = SP_FEFUNCNODE(node); + SPFeFuncNode *funcNode = SP_FEFUNCNODE(&node); switch (funcNode->channel) { case SPFeFuncNode::R: @@ -70,13 +69,13 @@ static void sp_feComponentTransfer_children_modified(SPFeComponentTransfer *sp_c g_warning("Unrecognized channel for component transfer."); break; } - sp_componenttransfer->renderer->type[i] = ((SPFeFuncNode *) node)->type; - sp_componenttransfer->renderer->tableValues[i] = ((SPFeFuncNode *) node)->tableValues; - sp_componenttransfer->renderer->slope[i] = ((SPFeFuncNode *) node)->slope; - sp_componenttransfer->renderer->intercept[i] = ((SPFeFuncNode *) node)->intercept; - sp_componenttransfer->renderer->amplitude[i] = ((SPFeFuncNode *) node)->amplitude; - sp_componenttransfer->renderer->exponent[i] = ((SPFeFuncNode *) node)->exponent; - sp_componenttransfer->renderer->offset[i] = ((SPFeFuncNode *) node)->offset; + sp_componenttransfer->renderer->type[i] = ((SPFeFuncNode *) &node)->type; + sp_componenttransfer->renderer->tableValues[i] = ((SPFeFuncNode *) &node)->tableValues; + sp_componenttransfer->renderer->slope[i] = ((SPFeFuncNode *) &node)->slope; + sp_componenttransfer->renderer->intercept[i] = ((SPFeFuncNode *) &node)->intercept; + sp_componenttransfer->renderer->amplitude[i] = ((SPFeFuncNode *) &node)->amplitude; + sp_componenttransfer->renderer->exponent[i] = ((SPFeFuncNode *) &node)->exponent; + sp_componenttransfer->renderer->offset[i] = ((SPFeFuncNode *) &node)->offset; set[i] = true; } // Set any types not explicitly set to the identity transform diff --git a/src/filters/composite.cpp b/src/filters/composite.cpp index 3e651a778..42f06915f 100644 --- a/src/filters/composite.cpp +++ b/src/filters/composite.cpp @@ -221,11 +221,11 @@ Inkscape::XML::Node* SPFeComposite::write(Inkscape::XML::Document *doc, Inkscape if( !in2_name ) { // This code is very similar to sp_filter_primitive_name_previous_out() - SPObject *i = parent->children; + SPObject *i = parent->firstChild(); // Find previous filter primitive - while (i && i->next != this) { - i = i->next; + while (i && i->getNext() != this) { + i = i->getNext(); } if( i ) { diff --git a/src/filters/diffuselighting.cpp b/src/filters/diffuselighting.cpp index 120c058d2..a46b367ec 100644 --- a/src/filters/diffuselighting.cpp +++ b/src/filters/diffuselighting.cpp @@ -258,17 +258,17 @@ static void sp_feDiffuseLighting_children_modified(SPFeDiffuseLighting *sp_diffu { if (sp_diffuselighting->renderer) { sp_diffuselighting->renderer->light_type = Inkscape::Filters::NO_LIGHT; - if (SP_IS_FEDISTANTLIGHT(sp_diffuselighting->children)) { + if (SP_IS_FEDISTANTLIGHT(sp_diffuselighting->firstChild())) { sp_diffuselighting->renderer->light_type = Inkscape::Filters::DISTANT_LIGHT; - sp_diffuselighting->renderer->light.distant = SP_FEDISTANTLIGHT(sp_diffuselighting->children); + sp_diffuselighting->renderer->light.distant = SP_FEDISTANTLIGHT(sp_diffuselighting->firstChild()); } - if (SP_IS_FEPOINTLIGHT(sp_diffuselighting->children)) { + if (SP_IS_FEPOINTLIGHT(sp_diffuselighting->firstChild())) { sp_diffuselighting->renderer->light_type = Inkscape::Filters::POINT_LIGHT; - sp_diffuselighting->renderer->light.point = SP_FEPOINTLIGHT(sp_diffuselighting->children); + sp_diffuselighting->renderer->light.point = SP_FEPOINTLIGHT(sp_diffuselighting->firstChild()); } - if (SP_IS_FESPOTLIGHT(sp_diffuselighting->children)) { + if (SP_IS_FESPOTLIGHT(sp_diffuselighting->firstChild())) { sp_diffuselighting->renderer->light_type = Inkscape::Filters::SPOT_LIGHT; - sp_diffuselighting->renderer->light.spot = SP_FESPOTLIGHT(sp_diffuselighting->children); + sp_diffuselighting->renderer->light.spot = SP_FESPOTLIGHT(sp_diffuselighting->firstChild()); } } } @@ -293,19 +293,19 @@ void SPFeDiffuseLighting::build_renderer(Inkscape::Filters::Filter* filter) { //We assume there is at most one child nr_diffuselighting->light_type = Inkscape::Filters::NO_LIGHT; - if (SP_IS_FEDISTANTLIGHT(this->children)) { + if (SP_IS_FEDISTANTLIGHT(this->firstChild())) { nr_diffuselighting->light_type = Inkscape::Filters::DISTANT_LIGHT; - nr_diffuselighting->light.distant = SP_FEDISTANTLIGHT(this->children); + nr_diffuselighting->light.distant = SP_FEDISTANTLIGHT(this->firstChild()); } - if (SP_IS_FEPOINTLIGHT(this->children)) { + if (SP_IS_FEPOINTLIGHT(this->firstChild())) { nr_diffuselighting->light_type = Inkscape::Filters::POINT_LIGHT; - nr_diffuselighting->light.point = SP_FEPOINTLIGHT(this->children); + nr_diffuselighting->light.point = SP_FEPOINTLIGHT(this->firstChild()); } - if (SP_IS_FESPOTLIGHT(this->children)) { + if (SP_IS_FESPOTLIGHT(this->firstChild())) { nr_diffuselighting->light_type = Inkscape::Filters::SPOT_LIGHT; - nr_diffuselighting->light.spot = SP_FESPOTLIGHT(this->children); + nr_diffuselighting->light.spot = SP_FESPOTLIGHT(this->firstChild()); } //nr_offset->set_dx(sp_offset->dx); diff --git a/src/filters/displacementmap.cpp b/src/filters/displacementmap.cpp index 1dbea67ff..f0ca36079 100644 --- a/src/filters/displacementmap.cpp +++ b/src/filters/displacementmap.cpp @@ -193,11 +193,11 @@ Inkscape::XML::Node* SPFeDisplacementMap::write(Inkscape::XML::Document *doc, In if( !in2_name ) { // This code is very similar to sp_filter_primtive_name_previous_out() - SPObject *i = parent->children; + SPObject *i = parent->firstChild(); // Find previous filter primitive - while (i && i->next != this) { - i = i->next; + while (i && i->getNext() != this) { + i = i->getNext(); } if( i ) { diff --git a/src/filters/merge.cpp b/src/filters/merge.cpp index 68f671b11..8ec40cb46 100644 --- a/src/filters/merge.cpp +++ b/src/filters/merge.cpp @@ -92,17 +92,14 @@ void SPFeMerge::build_renderer(Inkscape::Filters::Filter* filter) { sp_filter_primitive_renderer_common(this, nr_primitive); - SPObject *input = this->children; int in_nr = 0; - while (input) { - if (SP_IS_FEMERGENODE(input)) { - SPFeMergeNode *node = SP_FEMERGENODE(input); + for(auto& input: children) { + if (SP_IS_FEMERGENODE(&input)) { + SPFeMergeNode *node = SP_FEMERGENODE(&input); nr_merge->set_input(in_nr, node->input); in_nr++; } - - input = input->next; } } diff --git a/src/filters/specularlighting.cpp b/src/filters/specularlighting.cpp index bda1a0f30..ac7253ad9 100644 --- a/src/filters/specularlighting.cpp +++ b/src/filters/specularlighting.cpp @@ -266,19 +266,19 @@ static void sp_feSpecularLighting_children_modified(SPFeSpecularLighting *sp_spe if (sp_specularlighting->renderer) { sp_specularlighting->renderer->light_type = Inkscape::Filters::NO_LIGHT; - if (SP_IS_FEDISTANTLIGHT(sp_specularlighting->children)) { + if (SP_IS_FEDISTANTLIGHT(sp_specularlighting->firstChild())) { sp_specularlighting->renderer->light_type = Inkscape::Filters::DISTANT_LIGHT; - sp_specularlighting->renderer->light.distant = SP_FEDISTANTLIGHT(sp_specularlighting->children); + sp_specularlighting->renderer->light.distant = SP_FEDISTANTLIGHT(sp_specularlighting->firstChild()); } - if (SP_IS_FEPOINTLIGHT(sp_specularlighting->children)) { + if (SP_IS_FEPOINTLIGHT(sp_specularlighting->firstChild())) { sp_specularlighting->renderer->light_type = Inkscape::Filters::POINT_LIGHT; - sp_specularlighting->renderer->light.point = SP_FEPOINTLIGHT(sp_specularlighting->children); + sp_specularlighting->renderer->light.point = SP_FEPOINTLIGHT(sp_specularlighting->firstChild()); } - if (SP_IS_FESPOTLIGHT(sp_specularlighting->children)) { + if (SP_IS_FESPOTLIGHT(sp_specularlighting->firstChild())) { sp_specularlighting->renderer->light_type = Inkscape::Filters::SPOT_LIGHT; - sp_specularlighting->renderer->light.spot = SP_FESPOTLIGHT(sp_specularlighting->children); + sp_specularlighting->renderer->light.spot = SP_FESPOTLIGHT(sp_specularlighting->firstChild()); } } } @@ -304,19 +304,19 @@ void SPFeSpecularLighting::build_renderer(Inkscape::Filters::Filter* filter) { //We assume there is at most one child nr_specularlighting->light_type = Inkscape::Filters::NO_LIGHT; - if (SP_IS_FEDISTANTLIGHT(this->children)) { + if (SP_IS_FEDISTANTLIGHT(this->firstChild())) { nr_specularlighting->light_type = Inkscape::Filters::DISTANT_LIGHT; - nr_specularlighting->light.distant = SP_FEDISTANTLIGHT(this->children); + nr_specularlighting->light.distant = SP_FEDISTANTLIGHT(this->firstChild()); } - if (SP_IS_FEPOINTLIGHT(this->children)) { + if (SP_IS_FEPOINTLIGHT(this->firstChild())) { nr_specularlighting->light_type = Inkscape::Filters::POINT_LIGHT; - nr_specularlighting->light.point = SP_FEPOINTLIGHT(this->children); + nr_specularlighting->light.point = SP_FEPOINTLIGHT(this->firstChild()); } - if (SP_IS_FESPOTLIGHT(this->children)) { + if (SP_IS_FESPOTLIGHT(this->firstChild())) { nr_specularlighting->light_type = Inkscape::Filters::SPOT_LIGHT; - nr_specularlighting->light.spot = SP_FESPOTLIGHT(this->children); + nr_specularlighting->light.spot = SP_FESPOTLIGHT(this->firstChild()); } //nr_offset->set_dx(sp_offset->dx); diff --git a/src/gradient-chemistry.cpp b/src/gradient-chemistry.cpp index ae82499de..4521d72fd 100644 --- a/src/gradient-chemistry.cpp +++ b/src/gradient-chemistry.cpp @@ -195,8 +195,8 @@ static guint count_gradient_hrefs(SPObject *o, SPGradient *gr) i ++; } - for ( SPObject *child = o->firstChild(); child; child = child->getNext() ) { - i += count_gradient_hrefs(child, gr); + for (auto& child: o->children) { + i += count_gradient_hrefs(&child, gr); } return i; @@ -922,11 +922,11 @@ void sp_item_gradient_reverse_vector(SPItem *item, Inkscape::PaintTarget fill_or GSList *child_objects = NULL; std::vector<double> offsets; double offset; - for ( SPObject *child = vector->firstChild(); child; child = child->getNext()) { - child_reprs = g_slist_prepend (child_reprs, child->getRepr()); - child_objects = g_slist_prepend (child_objects, child); + for (auto& child: vector->children) { + child_reprs = g_slist_prepend (child_reprs, child.getRepr()); + child_objects = g_slist_prepend (child_objects, &child); offset=0; - sp_repr_get_double(child->getRepr(), "offset", &offset); + sp_repr_get_double(child.getRepr(), "offset", &offset); offsets.push_back(offset); } @@ -975,9 +975,9 @@ void sp_item_gradient_invert_vector_color(SPItem *item, Inkscape::PaintTarget fi sp_gradient_repr_set_link(gradient->getRepr(), vector); } - for ( SPObject *child = vector->firstChild(); child; child = child->getNext()) { - if (SP_IS_STOP(child)) { - guint32 color = SP_STOP(child)->get_rgba32(); + for (auto& child: vector->children) { + if (SP_IS_STOP(&child)) { + guint32 color = SP_STOP(&child)->get_rgba32(); //g_message("Stop color %d", color); gchar c[64]; sp_svg_write_color (c, sizeof(c), @@ -990,7 +990,7 @@ void sp_item_gradient_invert_vector_color(SPItem *item, Inkscape::PaintTarget fi ); SPCSSAttr *css = sp_repr_css_attr_new (); sp_repr_css_set_property (css, "stop-color", c); - sp_repr_css_change(child->getRepr(), css, "style"); + sp_repr_css_change(child.getRepr(), css, "style"); sp_repr_css_attr_unref (css); } } @@ -1566,8 +1566,8 @@ void sp_gradient_invert_selected_gradients(SPDesktop *desktop, Inkscape::PaintTa { Inkscape::Selection *selection = desktop->getSelection(); - const std::vector<SPItem*> list=selection->itemList(); - for (std::vector<SPItem*>::const_iterator i = list.begin(); i != list.end(); ++i) { + auto list= selection->items(); + for (auto i = list.begin(); i != list.end(); ++i) { sp_item_gradient_invert_vector_color(*i, fill_or_stroke); } @@ -1591,8 +1591,8 @@ void sp_gradient_reverse_selected_gradients(SPDesktop *desktop) if (drag && !drag->selected.empty()) { drag->selected_reverse_vector(); } else { // If no drag or no dragger selected, act on selection (both fill and stroke gradients) - const std::vector<SPItem*> list=selection->itemList(); - for (std::vector<SPItem*>::const_iterator i = list.begin(); i != list.end(); ++i) { + auto list= selection->items(); + for (auto i = list.begin(); i != list.end(); ++i) { sp_item_gradient_reverse_vector(*i, Inkscape::FOR_FILL); sp_item_gradient_reverse_vector(*i, Inkscape::FOR_STROKE); } diff --git a/src/gradient-drag.cpp b/src/gradient-drag.cpp index aa4da7fcc..5b91bdc9f 100644 --- a/src/gradient-drag.cpp +++ b/src/gradient-drag.cpp @@ -2065,8 +2065,8 @@ void GrDrag::updateDraggers() this->draggers.clear(); g_return_if_fail(this->selection != NULL); - std::vector<SPItem*> list = this->selection->itemList(); - for (std::vector<SPItem*>::const_iterator i = list.begin(); i != list.end(); ++i) { + auto list = this->selection->items(); + for (auto i = list.begin(); i != list.end(); ++i) { SPItem *item = *i; SPStyle *style = item->style; @@ -2133,8 +2133,8 @@ void GrDrag::updateLines() g_return_if_fail(this->selection != NULL); - std::vector<SPItem*> list = this->selection->itemList(); - for (std::vector<SPItem*>::const_iterator i = list.begin(); i != list.end(); ++i) { + auto list = this->selection->items(); + for (auto i = list.begin(); i != list.end(); ++i) { SPItem *item = *i; SPStyle *style = item->style; @@ -2277,8 +2277,8 @@ void GrDrag::updateLevels() g_return_if_fail (this->selection != NULL); - std::vector<SPItem*> list = this->selection->itemList(); - for (std::vector<SPItem*>::const_iterator i = list.begin(); i != list.end(); ++i) { + auto list = this->selection->items(); + for (auto i = list.begin(); i != list.end(); ++i) { SPItem *item = *i; Geom::OptRect rect = item->desktopVisualBounds(); if (rect) { @@ -2534,9 +2534,9 @@ void GrDrag::deleteSelected(bool just_one) // cannot use vector->vector.stops.size() because the vector might be invalidated by deletion of a midstop // manually count the children, don't know if there already exists a function for this... int len = 0; - for ( SPObject *child = (stopinfo->vector)->firstChild() ; child ; child = child->getNext() ) + for (auto& child: stopinfo->vector->children) { - if ( SP_IS_STOP(child) ) { + if ( SP_IS_STOP(&child) ) { len ++; } } diff --git a/src/helper/pixbuf-ops.cpp b/src/helper/pixbuf-ops.cpp index 8a363d736..bab998fdb 100644 --- a/src/helper/pixbuf-ops.cpp +++ b/src/helper/pixbuf-ops.cpp @@ -49,8 +49,8 @@ static void hide_other_items_recursively(SPObject *o, GSList *list, unsigned dke // recurse if (!g_slist_find(list, o)) { - for ( SPObject *child = o->firstChild() ; child; child = child->getNext() ) { - hide_other_items_recursively(child, list, dkey); + for (auto& child: o->children) { + hide_other_items_recursively(&child, list, dkey); } } } diff --git a/src/helper/png-write.cpp b/src/helper/png-write.cpp index e2b7e5b8c..682aee9b2 100644 --- a/src/helper/png-write.cpp +++ b/src/helper/png-write.cpp @@ -372,8 +372,8 @@ static void hide_other_items_recursively(SPObject *o, const std::vector<SPItem*> // recurse if (list.end()==find(list.begin(),list.end(),o)) { - for ( SPObject *child = o->firstChild() ; child; child = child->getNext() ) { - hide_other_items_recursively(child, list, dkey); + for (auto& child: o->children) { + hide_other_items_recursively(&child, list, dkey); } } } diff --git a/src/helper/stock-items.cpp b/src/helper/stock-items.cpp index 5a56b89ff..647e42916 100644 --- a/src/helper/stock-items.cpp +++ b/src/helper/stock-items.cpp @@ -204,37 +204,37 @@ SPObject *get_stock_item(gchar const *urn, gboolean stock) } SPObject *object = NULL; if (!strcmp(base, "marker") && !stock) { - for ( SPObject *child = defs->firstChild(); child; child = child->getNext() ) + for (auto& child: defs->children) { - if (child->getRepr()->attribute("inkscape:stockid") && - !strcmp(name_p, child->getRepr()->attribute("inkscape:stockid")) && - SP_IS_MARKER(child)) + if (child.getRepr()->attribute("inkscape:stockid") && + !strcmp(name_p, child.getRepr()->attribute("inkscape:stockid")) && + SP_IS_MARKER(&child)) { - object = child; + object = &child; } } } else if (!strcmp(base,"pattern") && !stock) { - for ( SPObject *child = defs->firstChild() ; child; child = child->getNext() ) + for (auto& child: defs->children) { - if (child->getRepr()->attribute("inkscape:stockid") && - !strcmp(name_p, child->getRepr()->attribute("inkscape:stockid")) && - SP_IS_PATTERN(child)) + if (child.getRepr()->attribute("inkscape:stockid") && + !strcmp(name_p, child.getRepr()->attribute("inkscape:stockid")) && + SP_IS_PATTERN(&child)) { - object = child; + object = &child; } } } else if (!strcmp(base,"gradient") && !stock) { - for ( SPObject *child = defs->firstChild(); child; child = child->getNext() ) + for (auto& child: defs->children) { - if (child->getRepr()->attribute("inkscape:stockid") && - !strcmp(name_p, child->getRepr()->attribute("inkscape:stockid")) && - SP_IS_GRADIENT(child)) + if (child.getRepr()->attribute("inkscape:stockid") && + !strcmp(name_p, child.getRepr()->attribute("inkscape:stockid")) && + SP_IS_GRADIENT(&child)) { - object = child; + object = &child; } } diff --git a/src/id-clash.cpp b/src/id-clash.cpp index b14526e79..c284843b8 100644 --- a/src/id-clash.cpp +++ b/src/id-clash.cpp @@ -185,9 +185,9 @@ find_references(SPObject *elem, refmap_type &refmap) } // recurse - for (SPObject *child = elem->firstChild(); child; child = child->getNext() ) + for (auto& child: elem->children) { - find_references(child, refmap); + find_references(&child, refmap); } } @@ -240,9 +240,9 @@ change_clashing_ids(SPDocument *imported_doc, SPDocument *current_doc, // recurse - for (SPObject *child = elem->firstChild(); child; child = child->getNext() ) + for (auto& child: elem->children) { - change_clashing_ids(imported_doc, current_doc, child, refmap, id_changes); + change_clashing_ids(imported_doc, current_doc, &child, refmap, id_changes); } } diff --git a/src/layer-fns.cpp b/src/layer-fns.cpp index 3e794a0a4..030ebc07e 100644 --- a/src/layer-fns.cpp +++ b/src/layer-fns.cpp @@ -36,11 +36,9 @@ bool is_layer(SPObject &object) { * @returns NULL if there are no further layers under a parent */ SPObject *next_sibling_layer(SPObject *layer) { - using std::find_if; - - return find_if<SPObject::SiblingIterator>( - layer->getNext(), NULL, &is_layer - ); + SPObject::ChildrenList &list = layer->parent->children; + auto l = std::find_if(++list.iterator_to(*layer), list.end(), &is_layer); + return l != list.end() ? &*l : nullptr; } /** Finds the previous sibling layer for a \a layer @@ -50,11 +48,9 @@ SPObject *next_sibling_layer(SPObject *layer) { SPObject *previous_sibling_layer(SPObject *layer) { using Inkscape::Algorithms::find_last_if; - SPObject *sibling(find_last_if<SPObject::SiblingIterator>( - layer->parent->firstChild(), layer, &is_layer - )); - - return ( sibling != layer ) ? sibling : NULL; + SPObject::ChildrenList &list = layer->parent->children; + auto l = find_last_if(list.begin(), list.iterator_to(*layer), &is_layer); + return l != list.iterator_to(*layer) ? &*(l) : nullptr; } /** Finds the first child of a \a layer @@ -62,16 +58,15 @@ SPObject *previous_sibling_layer(SPObject *layer) { * @returns NULL if layer has no sublayers */ SPObject *first_descendant_layer(SPObject *layer) { - using std::find_if; - - SPObject *first_descendant=NULL; - while (layer) { - layer = find_if<SPObject::SiblingIterator>( - layer->firstChild(), NULL, &is_layer - ); - if (layer) { + SPObject *first_descendant = nullptr; + while (true) { + auto tmp = std::find_if(layer->children.begin(), layer->children.end(), &is_layer); + if (tmp != layer->children.end()) { first_descendant = layer; + } else { + break; } + layer = &*tmp; } return first_descendant; @@ -84,9 +79,8 @@ SPObject *first_descendant_layer(SPObject *layer) { SPObject *last_child_layer(SPObject *layer) { using Inkscape::Algorithms::find_last_if; - return find_last_if<SPObject::SiblingIterator>( - layer->firstChild(), NULL, &is_layer - ); + auto l = find_last_if(layer->children.begin(), layer->children.end(), &is_layer); + return l != layer->children.end() ? &*l : nullptr; } SPObject *last_elder_layer(SPObject *root, SPObject *layer) { diff --git a/src/libnrtype/font-lister.cpp b/src/libnrtype/font-lister.cpp index 568a7c8cc..4deae821a 100644 --- a/src/libnrtype/font-lister.cpp +++ b/src/libnrtype/font-lister.cpp @@ -298,8 +298,8 @@ void FontLister::update_font_list_recursive(SPObject *r, std::list<Glib::ustring l->push_back(Glib::ustring(font_family)); } - for (SPObject *child = r->firstChild(); child; child = child->getNext()) { - update_font_list_recursive(child, l); + for (auto& child: r->children) { + update_font_list_recursive(&child, l); } } diff --git a/src/live_effects/lpe-perspective_path.cpp b/src/live_effects/lpe-perspective_path.cpp index 6857d4363..cb4e43d87 100644 --- a/src/live_effects/lpe-perspective_path.cpp +++ b/src/live_effects/lpe-perspective_path.cpp @@ -102,12 +102,12 @@ void LPEPerspectivePath::refresh(Gtk::Entry* perspective) { perspectiveID = perspective->get_text(); Persp3D *first = 0; Persp3D *persp = 0; - for ( SPObject *child = this->lpeobj->document->getDefs()->firstChild(); child && !persp; child = child->getNext() ) { - if (SP_IS_PERSP3D(child) && first == 0) { - first = SP_PERSP3D(child); + for (auto& child: lpeobj->document->getDefs()->children) { + if (SP_IS_PERSP3D(&child) && first == 0) { + first = SP_PERSP3D(&child); } - if (SP_IS_PERSP3D(child) && strcmp(child->getId(), const_cast<const gchar *>(perspectiveID.c_str())) == 0) { - persp = SP_PERSP3D(child); + if (SP_IS_PERSP3D(&child) && strcmp(child.getId(), const_cast<const gchar *>(perspectiveID.c_str())) == 0) { + persp = SP_PERSP3D(&child); break; } } diff --git a/src/main-cmdlineact.cpp b/src/main-cmdlineact.cpp index d22b513d6..c1b756ad5 100644 --- a/src/main-cmdlineact.cpp +++ b/src/main-cmdlineact.cpp @@ -61,7 +61,7 @@ CmdLineAction::doIt (ActionContext const & context) { } Inkscape::Selection * selection = context.getSelection(); - selection->add(obj, false); + selection->add(obj); } return; } diff --git a/src/main.cpp b/src/main.cpp index 990909701..28bdf8359 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1209,8 +1209,8 @@ static int sp_process_file_list(GSList *fl) std::vector<SPItem*> items; SPRoot *root = doc->getRoot(); doc->ensureUpToDate(); - for ( SPObject *iter = root->firstChild(); iter ; iter = iter->getNext()) { - SPItem* item = (SPItem*) iter; + for (auto& iter: root->children) { + SPItem* item = (SPItem*) &iter; if (! (SP_IS_TEXT(item) || SP_IS_FLOWTEXT(item) || SP_IS_GROUP(item))) { continue; } @@ -1464,10 +1464,8 @@ do_query_all_recurse (SPObject *o) } } - SPObject *child = o->children; - while (child) { - do_query_all_recurse (child); - child = child->next; + for(auto& child: o->children) { + do_query_all_recurse (&child); } } diff --git a/src/object-set.cpp b/src/object-set.cpp new file mode 100644 index 000000000..92bcf6b07 --- /dev/null +++ b/src/object-set.cpp @@ -0,0 +1,370 @@ +/* + * Multiindex container for selection + * + * Authors: + * Adrian Boguszewski + * + * Copyright (C) 2016 Adrian Boguszewski + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include <sigc++/sigc++.h> +#include <glib.h> +#include "object-set.h" +#include "box3d.h" +#include "persp3d.h" +#include "preferences.h" +#include <boost/range/adaptor/filtered.hpp> +#include <boost/range/adaptor/transformed.hpp> + +namespace Inkscape { + +bool ObjectSet::add(SPObject* object) { + g_return_val_if_fail(object != NULL, false); + g_return_val_if_fail(SP_IS_OBJECT(object), false); + + // any ancestor is in the set - do nothing + if (_anyAncestorIsInSet(object)) { + return false; + } + + // very nice function, but changes selection behavior (probably needs new selection option to deal with it) + // check if there is mutual ancestor for some elements, which can replace all of them in the set +// object = _getMutualAncestor(object); + + // remove all descendants from the set + _removeDescendantsFromSet(object); + + _add(object); + _emitSignals(); + return true; +} + +bool ObjectSet::remove(SPObject* object) { + g_return_val_if_fail(object != NULL, false); + g_return_val_if_fail(SP_IS_OBJECT(object), false); + + // object is the top of subtree + if (includes(object)) { + _remove(object); + _emitSignals(); + return true; + } + + // any ancestor of object is in the set + if (_anyAncestorIsInSet(object)) { + _removeAncestorsFromSet(object); + _emitSignals(); + return true; + } + + // no object nor any parent in the set + return false; +} + +bool ObjectSet::includes(SPObject *object) { + g_return_val_if_fail(object != NULL, false); + g_return_val_if_fail(SP_IS_OBJECT(object), false); + + return _container.get<hashed>().find(object) != _container.get<hashed>().end(); +} + +void ObjectSet::clear() { + _clear(); + _emitSignals(); +} + +int ObjectSet::size() { + return _container.size(); +} + +bool ObjectSet::_anyAncestorIsInSet(SPObject *object) { + SPObject* o = object; + while (o != nullptr) { + if (includes(o)) { + return true; + } + o = o->parent; + } + + return false; +} + +void ObjectSet::_removeDescendantsFromSet(SPObject *object) { + for (auto& child: object->children) { + if (includes(&child)) { + _remove(&child); + // there is certainly no children of this child in the set + continue; + } + + _removeDescendantsFromSet(&child); + } +} + +void ObjectSet::_remove(SPObject *object) { + _releaseConnections[object].disconnect(); + _releaseConnections.erase(object); + _container.get<hashed>().erase(object); + _remove3DBoxesRecursively(object); + _releaseSignals(object); +} + +void ObjectSet::_add(SPObject *object) { + _releaseConnections[object] = object->connectRelease(sigc::hide_return(sigc::mem_fun(*this, &ObjectSet::remove))); + _container.push_back(object); + _add3DBoxesRecursively(object); + _connectSignals(object); +} + +void ObjectSet::_clear() { + for (auto object: _container) { + _remove(object); + } +} + +SPObject *ObjectSet::_getMutualAncestor(SPObject *object) { + SPObject *o = object; + + bool flag = true; + while (o->parent != nullptr) { + for (auto &child: o->parent->children) { + if(&child != o && !includes(&child)) { + flag = false; + break; + } + } + if (!flag) { + break; + } + o = o->parent; + } + return o; +} + +void ObjectSet::_removeAncestorsFromSet(SPObject *object) { + SPObject* o = object; + while (o->parent != nullptr) { + for (auto &child: o->parent->children) { + if (&child != o) { + _add(&child); + } + } + if (includes(o->parent)) { + _remove(o->parent); + break; + } + o = o->parent; + } +} + +ObjectSet::~ObjectSet() { + _clear(); +} + +void ObjectSet::toggle(SPObject *obj) { + if (includes(obj)) { + remove(obj); + } else { + add(obj); + } +} + +bool ObjectSet::isEmpty() { + return _container.size() == 0; +} + +SPObject *ObjectSet::single() { + return _container.size() == 1 ? *_container.begin() : nullptr; +} + +SPItem *ObjectSet::singleItem() { + if (_container.size() == 1) { + SPObject* obj = *_container.begin(); + if (SP_IS_ITEM(obj)) { + return SP_ITEM(obj); + } + } + + return nullptr; +} + +SPItem *ObjectSet::smallestItem(CompareSize compare) { + return _sizeistItem(true, compare); +} + +SPItem *ObjectSet::largestItem(CompareSize compare) { + return _sizeistItem(false, compare); +} + +SPItem *ObjectSet::_sizeistItem(bool sml, CompareSize compare) { + auto items = this->items(); + gdouble max = sml ? 1e18 : 0; + SPItem *ist = NULL; + + for (auto i = items.begin(); i != items.end(); ++i) { + Geom::OptRect obox = SP_ITEM(*i)->desktopPreferredBounds(); + if (!obox || obox.empty()) { + continue; + } + + Geom::Rect bbox = *obox; + + gdouble size = compare == AREA ? bbox.area() : + (compare == VERTICAL ? bbox.width() : bbox.height()); + size = sml ? size : size * -1; + if (size < max) { + max = size; + ist = SP_ITEM(*i); + } + } + + return ist; +} + +SPObjectRange ObjectSet::objects() { + return SPObjectRange(_container.get<random_access>().begin(), _container.get<random_access>().end()); +} + +Inkscape::XML::Node *ObjectSet::singleRepr() { + SPObject *obj = single(); + return obj ? obj->getRepr() : nullptr; +} + +void ObjectSet::set(SPObject *object) { + _clear(); + _add(object); + // can't emit signal here due to boolean argument in Selection +// _emitSignals(); +} + +Geom::OptRect ObjectSet::bounds(SPItem::BBoxType type) const +{ + return (type == SPItem::GEOMETRIC_BBOX) ? + geometricBounds() : visualBounds(); +} + +Geom::OptRect ObjectSet::geometricBounds() const +{ + auto items = const_cast<ObjectSet *>(this)->items(); + + Geom::OptRect bbox; + for (auto iter = items.begin(); iter != items.end(); ++iter) { + bbox.unionWith(SP_ITEM(*iter)->desktopGeometricBounds()); + } + return bbox; +} + +Geom::OptRect ObjectSet::visualBounds() const +{ + auto items = const_cast<ObjectSet *>(this)->items(); + + Geom::OptRect bbox; + for (auto iter = items.begin(); iter != items.end(); ++iter) { + bbox.unionWith(SP_ITEM(*iter)->desktopVisualBounds()); + } + return bbox; +} + +Geom::OptRect ObjectSet::preferredBounds() const +{ + if (Inkscape::Preferences::get()->getInt("/tools/bounding_box") == 0) { + return bounds(SPItem::VISUAL_BBOX); + } else { + return bounds(SPItem::GEOMETRIC_BBOX); + } +} + +Geom::OptRect ObjectSet::documentBounds(SPItem::BBoxType type) const +{ + Geom::OptRect bbox; + auto items = const_cast<ObjectSet *>(this)->items(); + if (items.empty()) return bbox; + + for (auto iter = items.begin(); iter != items.end(); ++iter) { + SPItem *item = SP_ITEM(*iter); + bbox |= item->documentBounds(type); + } + + return bbox; +} + +// If we have a selection of multiple items, then the center of the first item +// will be returned; this is also the case in SelTrans::centerRequest() +boost::optional<Geom::Point> ObjectSet::center() const { + auto items = const_cast<ObjectSet *>(this)->items(); + if (!items.empty()) { + SPItem *first = items.back(); // from the first item in selection + if (first->isCenterSet()) { // only if set explicitly + return first->getCenter(); + } + } + Geom::OptRect bbox = preferredBounds(); + if (bbox) { + return bbox->midpoint(); + } else { + return boost::optional<Geom::Point>(); + } +} + +std::list<Persp3D *> const ObjectSet::perspList() { + std::list<Persp3D *> pl; + for (std::list<SPBox3D *>::iterator i = _3dboxes.begin(); i != _3dboxes.end(); ++i) { + Persp3D *persp = box3d_get_perspective(*i); + if (std::find(pl.begin(), pl.end(), persp) == pl.end()) + pl.push_back(persp); + } + return pl; +} + +std::list<SPBox3D *> const ObjectSet::box3DList(Persp3D *persp) { + std::list<SPBox3D *> boxes; + if (persp) { + for (std::list<SPBox3D *>::iterator i = _3dboxes.begin(); i != _3dboxes.end(); ++i) { + SPBox3D *box = *i; + if (persp == box3d_get_perspective(box)) { + boxes.push_back(box); + } + } + } else { + boxes = _3dboxes; + } + return boxes; +} + +void ObjectSet::_add3DBoxesRecursively(SPObject *obj) { + std::list<SPBox3D *> boxes = box3d_extract_boxes(obj); + + for (std::list<SPBox3D *>::iterator i = boxes.begin(); i != boxes.end(); ++i) { + SPBox3D *box = *i; + _3dboxes.push_back(box); + } +} + +void ObjectSet::_remove3DBoxesRecursively(SPObject *obj) { + std::list<SPBox3D *> boxes = box3d_extract_boxes(obj); + + for (std::list<SPBox3D *>::iterator i = boxes.begin(); i != boxes.end(); ++i) { + SPBox3D *box = *i; + std::list<SPBox3D *>::iterator b = std::find(_3dboxes.begin(), _3dboxes.end(), box); + if (b == _3dboxes.end()) { + g_print ("Warning! Trying to remove unselected box from selection.\n"); + return; + } + _3dboxes.erase(b); + } +} + +} // namespace Inkscape + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/object-set.h b/src/object-set.h new file mode 100644 index 000000000..fae365f70 --- /dev/null +++ b/src/object-set.h @@ -0,0 +1,329 @@ +/* + * Multiindex container for selection + * + * Authors: + * Adrian Boguszewski + * + * Copyright (C) 2016 Adrian Boguszewski + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef INKSCAPE_PROTOTYPE_OBJECTSET_H +#define INKSCAPE_PROTOTYPE_OBJECTSET_H + +#include <string> +#include <unordered_map> +#include <boost/multi_index_container.hpp> +#include <boost/multi_index/identity.hpp> +#include <boost/multi_index/sequenced_index.hpp> +#include <boost/multi_index/hashed_index.hpp> +#include <boost/multi_index/random_access_index.hpp> +#include <boost/range/adaptor/filtered.hpp> +#include <boost/range/adaptor/transformed.hpp> +#include <boost/range/sub_range.hpp> +#include <boost/range/any_range.hpp> +#include <boost/type_traits.hpp> +#include <boost/utility/enable_if.hpp> +#include <sigc++/connection.h> +#include <inkgc/gc-soft-ptr.h> +#include "sp-object.h" +#include "sp-item.h" +#include "sp-item-group.h" + +class SPBox3D; +class Persp3D; +class SPDesktop; + +namespace Inkscape { + +namespace XML { +class Node; +} + +struct hashed{}; +struct random_access{}; + +struct is_item { + bool operator()(SPObject* obj) { + return SP_IS_ITEM(obj); + } +}; + +struct is_group { + bool operator()(SPObject* obj) { + return SP_IS_GROUP(obj); + } +}; + +struct object_to_item { + typedef SPItem* result_type; + SPItem* operator()(SPObject* obj) const { + return SP_ITEM(obj); + } +}; + +struct object_to_node { + typedef XML::Node* result_type; + XML::Node* operator()(SPObject* obj) const { + return obj->getRepr(); + } +}; + +struct object_to_group { + typedef SPGroup* result_type; + SPGroup* operator()(SPObject* obj) const { + return SP_GROUP(obj); + } +}; + +typedef boost::multi_index_container< + SPObject*, + boost::multi_index::indexed_by< + boost::multi_index::sequenced<>, + boost::multi_index::random_access< + boost::multi_index::tag<random_access>>, + boost::multi_index::hashed_unique< + boost::multi_index::tag<hashed>, + boost::multi_index::identity<SPObject*>> + >> MultiIndexContainer; + +typedef boost::any_range< + SPObject*, + boost::random_access_traversal_tag, + SPObject* const&, + std::ptrdiff_t> SPObjectRange; + +class ObjectSet { +public: + enum CompareSize {HORIZONTAL, VERTICAL, AREA}; + typedef decltype(MultiIndexContainer().get<random_access>() | boost::adaptors::filtered(is_item()) | boost::adaptors::transformed(object_to_item())) SPItemRange; + typedef decltype(MultiIndexContainer().get<random_access>() | boost::adaptors::filtered(is_group()) | boost::adaptors::transformed(object_to_group())) SPGroupRange; + typedef decltype(MultiIndexContainer().get<random_access>() | boost::adaptors::filtered(is_item()) | boost::adaptors::transformed(object_to_node())) XMLNodeRange; + + ObjectSet(SPDesktop* desktop): _desktop(desktop) {}; + ObjectSet(): _desktop(nullptr) {}; + virtual ~ObjectSet(); + + /** + * Add an SPObject to the set of selected objects. + * + * @param obj the SPObject to add + */ + bool add(SPObject* object); + + /** Add items from an STL iterator range to the selection. + * \param from the begin iterator + * \param to the end iterator + */ + template <typename InputIterator> + void add(InputIterator from, InputIterator to) { + for(auto it = from; it != to; ++it) { + _add(*it); + } + _emitSignals(); + } + + /** + * Removes an item from the set of selected objects. + * + * It is ok to call this method for an unselected item. + * + * @param item the item to unselect + * + * @return is success + */ + bool remove(SPObject* object); + + /** + * Returns true if the given object is selected. + */ + bool includes(SPObject *object); + + /** + * Set the selection to a single specific object. + * + * @param obj the object to select + */ + void set(SPObject *object); + + /** + * Unselects all selected objects. + */ + void clear(); + + /** + * Returns size of the selection. + */ + int size(); + + /** + * Returns true if no items are selected. + */ + bool isEmpty(); + + /** + * Removes an item if selected, adds otherwise. + * + * @param item the item to unselect + */ + void toggle(SPObject *obj); + + /** + * Returns a single selected object. + * + * @return NULL unless exactly one object is selected + */ + SPObject *single(); + + /** + * Returns a single selected item. + * + * @return NULL unless exactly one object is selected + */ + SPItem *singleItem(); + + /** + * Returns the smallest item from this selection. + */ + SPItem *smallestItem(CompareSize compare); + + /** + * Returns the largest item from this selection. + */ + SPItem *largestItem(CompareSize compare); + + /** Returns the list of selected objects. */ + SPObjectRange objects(); + + /** Returns a range of selected SPItems. */ + SPItemRange items() { + return SPItemRange(_container.get<random_access>() + | boost::adaptors::filtered(is_item()) + | boost::adaptors::transformed(object_to_item())); + }; + + /** Returns a range of selected groups. */ + SPGroupRange groups() { + return SPGroupRange (_container.get<random_access>() + | boost::adaptors::filtered(is_group()) + | boost::adaptors::transformed(object_to_group())); + } + + /** Returns a range of the xml nodes of all selected objects. */ + XMLNodeRange xmlNodes() { + return XMLNodeRange(_container.get<random_access>() + | boost::adaptors::filtered(is_item()) + | boost::adaptors::transformed(object_to_node())); + } + + /** + * Returns a single selected object's xml node. + * + * @return NULL unless exactly one object is selected + */ + XML::Node *singleRepr(); + + /** + * Selects exactly the specified objects. + * + * @param objs the objects to select + */ + template <class T> + typename boost::enable_if<boost::is_base_of<SPObject, T>, void>::type + setList(const std::vector<T*> &objs) { + _clear(); + addList(objs); + } + + /** + * Adds the specified objects to selection, without deselecting first. + * + * @param objs the objects to select + */ + template <class T> + typename boost::enable_if<boost::is_base_of<SPObject, T>, void>::type + addList(const std::vector<T*> &objs) { + for (auto obj: objs) { + if (!includes(obj)) { + add(obj); + } + } + } + + /** Returns the bounding rectangle of the selection. */ + Geom::OptRect bounds(SPItem::BBoxType type) const; + Geom::OptRect visualBounds() const; + Geom::OptRect geometricBounds() const; + + /** + * Returns either the visual or geometric bounding rectangle of the selection, based on the + * preferences specified for the selector tool + */ + Geom::OptRect preferredBounds() const; + + /* Returns the bounding rectangle of the selectionin document coordinates.*/ + Geom::OptRect documentBounds(SPItem::BBoxType type) const; + + /** + * Returns the rotation/skew center of the selection. + */ + boost::optional<Geom::Point> center() const; + + /** Returns a list of all perspectives which have a 3D box in the current selection. + (these may also be nested in groups) */ + std::list<Persp3D *> const perspList(); + + /** + * Returns a list of all 3D boxes in the current selection which are associated to @c + * persp. If @c pers is @c NULL, return all selected boxes. + */ + std::list<SPBox3D *> const box3DList(Persp3D *persp = NULL); + + /** + * Returns the desktop the selection is bound to + * + * @return the desktop the selection is bound to, or NULL if in console mode + */ + SPDesktop *desktop() { return _desktop; } + +protected: + virtual void _connectSignals(SPObject* object) {}; + virtual void _releaseSignals(SPObject* object) {}; + virtual void _emitSignals() {}; + void _add(SPObject* object); + void _clear(); + void _remove(SPObject* object); + bool _anyAncestorIsInSet(SPObject *object); + void _removeDescendantsFromSet(SPObject *object); + void _removeAncestorsFromSet(SPObject *object); + SPItem *_sizeistItem(bool sml, CompareSize compare); + SPObject *_getMutualAncestor(SPObject *object); + virtual void _add3DBoxesRecursively(SPObject *obj); + virtual void _remove3DBoxesRecursively(SPObject *obj); + + MultiIndexContainer _container; + GC::soft_ptr<SPDesktop> _desktop; + std::list<SPBox3D *> _3dboxes; + std::unordered_map<SPObject*, sigc::connection> _releaseConnections; + +}; + +typedef ObjectSet::SPItemRange SPItemRange; +typedef ObjectSet::SPGroupRange SPGroupRange; +typedef ObjectSet::XMLNodeRange XMLNodeRange; + +} // namespace Inkscape + +#endif //INKSCAPE_PROTOTYPE_OBJECTSET_H + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/object-snapper.cpp b/src/object-snapper.cpp index af33415a1..b4f4024cc 100644 --- a/src/object-snapper.cpp +++ b/src/object-snapper.cpp @@ -84,9 +84,9 @@ void Inkscape::ObjectSnapper::_findCandidates(SPObject* parent, Geom::Rect bbox_to_snap_incl = bbox_to_snap; // _incl means: will include the snapper tolerance bbox_to_snap_incl.expandBy(getSnapperTolerance()); // see? - for ( SPObject *o = parent->firstChild(); o; o = o->getNext() ) { + for (auto& o: parent->children) { g_assert(dt != NULL); - SPItem *item = dynamic_cast<SPItem *>(o); + SPItem *item = dynamic_cast<SPItem *>(&o); if (item && !(dt->itemIsHidden(item) && !clip_or_mask)) { // Snapping to items in a locked layer is allowed // Don't snap to hidden objects, unless they're a clipped path or a mask @@ -94,7 +94,7 @@ void Inkscape::ObjectSnapper::_findCandidates(SPObject* parent, std::vector<SPItem const *>::const_iterator i; if (it != NULL) { i = it->begin(); - while (i != it->end() && *i != o) { + while (i != it->end() && *i != &o) { ++i; } } @@ -116,7 +116,7 @@ void Inkscape::ObjectSnapper::_findCandidates(SPObject* parent, } if (dynamic_cast<SPGroup *>(item)) { - _findCandidates(o, it, false, bbox_to_snap, clip_or_mask, additional_affine); + _findCandidates(&o, it, false, bbox_to_snap, clip_or_mask, additional_affine); } else { Geom::OptRect bbox_of_item; Preferences *prefs = Preferences::get(); diff --git a/src/object-test.h b/src/object-test.h index 4f0be3251..0af823684 100644 --- a/src/object-test.h +++ b/src/object-test.h @@ -115,7 +115,6 @@ public: prev = next; next = next->getNext(); } - TS_ASSERT(child->lastChild() == next); // Test hrefcount TS_ASSERT(path->isReferenced()); diff --git a/src/path-chemistry.cpp b/src/path-chemistry.cpp index 79a15f509..5295b7a70 100644 --- a/src/path-chemistry.cpp +++ b/src/path-chemistry.cpp @@ -54,7 +54,7 @@ sp_selected_path_combine(SPDesktop *desktop, bool skip_undo) Inkscape::Selection *selection = desktop->getSelection(); SPDocument *doc = desktop->getDocument(); - std::vector<SPItem*> items(selection->itemList()); + std::vector<SPItem*> items(selection->items().begin(), selection->items().end()); if (items.size() < 1) { desktop->getMessageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>object(s)</b> to combine.")); @@ -200,7 +200,7 @@ sp_selected_path_break_apart(SPDesktop *desktop, bool skip_undo) bool did = false; - std::vector<SPItem*> itemlist(selection->itemList()); + std::vector<SPItem*> itemlist(selection->items().begin(), selection->items().end()); for (std::vector<SPItem*>::const_iterator i = itemlist.begin(); i != itemlist.end(); ++i){ SPItem *item = *i; @@ -300,7 +300,7 @@ sp_selected_path_to_curves(Inkscape::Selection *selection, SPDesktop *desktop, b desktop->setWaitingCursor(); } - std::vector<SPItem*> selected(selection->itemList()); + std::vector<SPItem*> selected(selection->items().begin(), selection->items().end()); std::vector<Inkscape::XML::Node*> to_select; selection->clear(); std::vector<SPItem*> items(selected); @@ -331,7 +331,7 @@ void sp_selected_to_lpeitems(SPDesktop *desktop) return; } - std::vector<SPItem*> selected(selection->itemList()); + std::vector<SPItem*> selected(selection->items().begin(), selection->items().end()); std::vector<Inkscape::XML::Node*> to_select; selection->clear(); std::vector<SPItem*> items(selected); @@ -600,7 +600,7 @@ void sp_selected_path_reverse(SPDesktop *desktop) { Inkscape::Selection *selection = desktop->getSelection(); - std::vector<SPItem*> items = selection->itemList(); + auto items = selection->items(); if (items.empty()) { desktop->getMessageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>path(s)</b> to reverse.")); @@ -614,7 +614,7 @@ sp_selected_path_reverse(SPDesktop *desktop) bool did = false; desktop->messageStack()->flash(Inkscape::IMMEDIATE_MESSAGE, _("Reversing paths...")); - for (std::vector<SPItem*>::const_iterator i = items.begin(); i != items.end(); ++i){ + for (auto i = items.begin(); i != items.end(); ++i){ SPPath *path = dynamic_cast<SPPath *>(*i); if (!path) { diff --git a/src/persp3d.cpp b/src/persp3d.cpp index 809242ed8..ff00f9441 100644 --- a/src/persp3d.cpp +++ b/src/persp3d.cpp @@ -213,9 +213,10 @@ Persp3D *persp3d_create_xml_element(SPDocument *document, Persp3DImpl *dup) {// Persp3D *persp3d_document_first_persp(SPDocument *document) { Persp3D *first = 0; - for ( SPObject *child = document->getDefs()->firstChild(); child && !first; child = child->getNext() ) { - if (SP_IS_PERSP3D(child)) { - first = SP_PERSP3D(child); + for (auto& child: document->getDefs()->children) { + if (SP_IS_PERSP3D(&child)) { + first = SP_PERSP3D(&child); + break; } } return first; @@ -491,10 +492,10 @@ persp3d_on_repr_attr_changed ( Inkscape::XML::Node * /*repr*/, /* checks whether all boxes linked to this perspective are currently selected */ bool -persp3d_has_all_boxes_in_selection (Persp3D *persp, Inkscape::Selection *selection) { +persp3d_has_all_boxes_in_selection (Persp3D *persp, Inkscape::ObjectSet *set) { Persp3DImpl *persp_impl = persp->perspective_impl; - std::list<SPBox3D *> selboxes = selection->box3DList(); + std::list<SPBox3D *> selboxes = set->box3DList(); for (std::vector<SPBox3D *>::iterator i = persp_impl->boxes.begin(); i != persp_impl->boxes.end(); ++i) { if (std::find(selboxes.begin(), selboxes.end(), *i) == selboxes.end()) { @@ -531,9 +532,9 @@ persp3d_print_debugging_info (Persp3D *persp) { void persp3d_print_debugging_info_all(SPDocument *document) { - for ( SPObject *child = document->getDefs()->firstChild(); child; child = child->getNext() ) { - if (SP_IS_PERSP3D(child)) { - persp3d_print_debugging_info(SP_PERSP3D(child)); + for (auto& child: document->getDefs()->children) { + if (SP_IS_PERSP3D(&child)) { + persp3d_print_debugging_info(SP_PERSP3D(&child)); } } persp3d_print_all_selected(); diff --git a/src/persp3d.h b/src/persp3d.h index be5680bcb..ce0e3c120 100644 --- a/src/persp3d.h +++ b/src/persp3d.h @@ -107,7 +107,7 @@ void persp3d_absorb(Persp3D *persp1, Persp3D *persp2); Persp3D * persp3d_create_xml_element (SPDocument *document, Persp3DImpl *dup = NULL); Persp3D * persp3d_document_first_persp (SPDocument *document); -bool persp3d_has_all_boxes_in_selection (Persp3D *persp, Inkscape::Selection *selection); +bool persp3d_has_all_boxes_in_selection (Persp3D *persp, Inkscape::ObjectSet *set); void persp3d_print_debugging_info (Persp3D *persp); void persp3d_print_debugging_info_all(SPDocument *doc); diff --git a/src/selcue.cpp b/src/selcue.cpp index 3d9f3c619..13600231a 100644 --- a/src/selcue.cpp +++ b/src/selcue.cpp @@ -93,15 +93,15 @@ void Inkscape::SelCue::_updateItemBboxes(Inkscape::Preferences *prefs) void Inkscape::SelCue::_updateItemBboxes(gint mode, int prefs_bbox) { - const std::vector<SPItem*> items = _selection->itemList(); - if (_item_bboxes.size() != items.size()) { + auto items = _selection->items(); + if (_item_bboxes.size() != boost::distance(items)) { _newItemBboxes(); return; } int bcount = 0; - std::vector<SPItem*> ll=_selection->itemList(); - for (std::vector<SPItem*>::const_iterator l = ll.begin(); l != ll.end(); ++l) { + auto ll= _selection->items(); + for (auto l = ll.begin(); l != ll.end(); ++l) { SPItem *item = *l; SPCanvasItem* box = _item_bboxes[bcount ++]; @@ -143,8 +143,8 @@ void Inkscape::SelCue::_newItemBboxes() int prefs_bbox = prefs->getBool("/tools/bounding_box"); - std::vector<SPItem*> ll=_selection->itemList(); - for (std::vector<SPItem*>::const_iterator l = ll.begin(); l != ll.end(); ++l) { + auto ll= _selection->items(); + for (auto l = ll.begin(); l != ll.end(); ++l) { SPItem *item = *l; Geom::OptRect const b = (prefs_bbox == 0) ? @@ -198,8 +198,8 @@ void Inkscape::SelCue::_newTextBaselines() } _text_baselines.clear(); - std::vector<SPItem*> ll = _selection->itemList(); - for (std::vector<SPItem*>::const_iterator l=ll.begin();l!=ll.end();++l) { + auto ll = _selection->items(); + for (auto l=ll.begin();l!=ll.end();++l) { SPItem *item = *l; SPCanvasItem* baseline_point = NULL; diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index f6923d1ea..37a0e42e1 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -12,8 +12,9 @@ * Abhishek Sharma * Kris De Gussem <Kris.DeGussem@gmail.com> * Tavmjong Bah <tavmjong@free.fr> (Symbol additions) + * Adrian Boguszewski * - * Copyright (C) 1999-2010,2012 authors + * Copyright (C) 1999-2016 authors * Copyright (C) 2001-2002 Ximian, Inc. * * Released under GNU GPL, read the file 'COPYING' for more information @@ -78,6 +79,11 @@ SPCycleType SP_CYCLING = SP_CYCLE_FOCUS; #include "helper/png-write.h" #include "layer-fns.h" #include "context-fns.h" +#include <map> +#include <cstring> +#include <string> +#include <boost/range/adaptor/reversed.hpp> +#include "sp-item.h" #include "box3d.h" #include "persp3d.h" #include "xml/simple-document.h" @@ -89,6 +95,7 @@ SPCycleType SP_CYCLING = SP_CYCLE_FOCUS; #include "live_effects/effect.h" #include "live_effects/parameter/originalpath.h" #include "layer-manager.h" +#include "object-set.h" // For clippath editing #include "ui/tools/node-tool.h" @@ -100,6 +107,7 @@ using Inkscape::DocumentUndo; using Geom::X; using Geom::Y; using Inkscape::UI::Tools::NodeTool; +using namespace Inkscape; /* The clipboard handling is in ui/clipboard.cpp now. There are some legacy functions left here, because the layer manipulation code uses them. It should be rewritten specifically @@ -259,9 +267,9 @@ void SelectionHelper::fixSelection(SPDesktop *dt) std::vector<SPItem*> items ; - std::vector<SPItem*> const selList = selection->itemList(); + auto selList = selection->items(); - for( std::vector<SPItem*>::const_reverse_iterator i = selList.rbegin(); i != selList.rend(); ++i ) { + for(auto i = boost::rbegin(selList); i != boost::rend(selList); ++i) { SPItem *item = *i; if( item && !dt->isLayer(item) && @@ -386,7 +394,7 @@ void sp_selection_delete(SPDesktop *desktop) desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("<b>Nothing</b> was deleted.")); return; } - std::vector<SPItem*> selected(selection->itemList()); + std::vector<SPItem*> selected(selection->items().begin(), selection->items().end()); selection->clear(); sp_selection_delete_impl(selected); desktop->currentLayer()->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); @@ -409,8 +417,8 @@ static void add_ids_recursive(std::vector<const gchar *> &ids, SPObject *obj) ids.push_back(obj->getId()); if (dynamic_cast<SPGroup *>(obj)) { - for (SPObject *child = obj->firstChild() ; child; child = child->getNext() ) { - add_ids_recursive(ids, child); + for (auto& child: obj->children) { + add_ids_recursive(ids, &child); } } } @@ -431,7 +439,7 @@ void sp_selection_duplicate(SPDesktop *desktop, bool suppressDone, bool duplicat desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>object(s)</b> to duplicate.")); return; } - std::vector<Inkscape::XML::Node*> reprs(selection->reprList()); + std::vector<Inkscape::XML::Node*> reprs(selection->xmlNodes().begin(), selection->xmlNodes().end()); if(duplicateLayer){ reprs.clear(); @@ -563,20 +571,20 @@ void sp_edit_clear_all(Inkscape::Selection *selection) */ std::vector<SPItem*> &get_all_items(std::vector<SPItem*> &list, SPObject *from, SPDesktop *desktop, bool onlyvisible, bool onlysensitive, bool ingroups, std::vector<SPItem*> const &exclude) { - for ( SPObject *child = from->firstChild() ; child; child = child->getNext() ) { - SPItem *item = dynamic_cast<SPItem *>(child); + for (auto& child: from->children) { + SPItem *item = dynamic_cast<SPItem *>(&child); if (item && !desktop->isLayer(item) && (!onlysensitive || !item->isLocked()) && (!onlyvisible || !desktop->itemIsHidden(item)) && - (exclude.empty() || exclude.end() == std::find(exclude.begin(),exclude.end(),child)) + (exclude.empty() || exclude.end() == std::find(exclude.begin(), exclude.end(), &child)) ) { list.insert(list.begin(),item); } if (ingroups || (item && desktop->isLayer(item))) { - list = get_all_items(list, child, desktop, onlyvisible, onlysensitive, ingroups, exclude); + list = get_all_items(list, &child, desktop, onlyvisible, onlysensitive, ingroups, exclude); } } @@ -601,7 +609,7 @@ static void sp_edit_select_all_full(SPDesktop *dt, bool force_all_layers, bool i std::vector<SPItem*> exclude; if (invert) { - exclude = selection->itemList(); + exclude.insert(exclude.end(), selection->items().begin(), selection->items().end()); } if (force_all_layers) @@ -667,9 +675,13 @@ void sp_edit_invert_in_all_layers(SPDesktop *desktop) sp_edit_select_all_full(desktop, true, true); } -static void sp_selection_group_impl(std::vector<Inkscape::XML::Node*> p, Inkscape::XML::Node *group, Inkscape::XML::Document *xml_doc, SPDocument *doc) { +static Inkscape::XML::Node* sp_object_set_group(ObjectSet *set) { + SPDocument *doc = set->desktop()->getDocument(); + Inkscape::XML::Document *xml_doc = doc->getReprDoc(); + Inkscape::XML::Node *group = xml_doc->createElement("svg:g"); - sort(p.begin(),p.end(),sp_repr_compare_position_bool); + std::vector<Inkscape::XML::Node*> p(set->xmlNodes().begin(), set->xmlNodes().end()); + std::sort(p.begin(), p.end(), sp_repr_compare_position_bool); // Remember the position and parent of the topmost object. gint topmost = p.back()->position(); @@ -727,31 +739,24 @@ static void sp_selection_group_impl(std::vector<Inkscape::XML::Node*> p, Inkscap // Move to the position of the topmost, reduced by the number of items deleted from topmost_parent group->setPosition(topmost + 1); + + set->set(doc->getObjectByRepr(group)); + + return group; } void sp_selection_group(Inkscape::Selection *selection, SPDesktop *desktop) { - SPDocument *doc = selection->layers()->getDocument(); - Inkscape::XML::Document *xml_doc = doc->getReprDoc(); - // Check if something is selected. if (selection->isEmpty()) { selection_display_message(desktop, Inkscape::WARNING_MESSAGE, _("Select <b>some objects</b> to group.")); return; } + Inkscape::XML::Node* group = sp_object_set_group(selection); - std::vector<Inkscape::XML::Node*> p (selection->reprList()); - - selection->clear(); - - Inkscape::XML::Node *group = xml_doc->createElement("svg:g"); - - sp_selection_group_impl(p, group, xml_doc, doc); - - DocumentUndo::done(doc, SP_VERB_SELECTION_GROUP, + DocumentUndo::done(selection->layers()->getDocument(), SP_VERB_SELECTION_GROUP, C_("Verb", "Group")); - selection->set(group); Inkscape::GC::release(group); } @@ -775,9 +780,8 @@ void sp_selection_ungroup_pop_selection(Inkscape::Selection *selection, SPDeskto selection_display_message(desktop, Inkscape::WARNING_MESSAGE, _("<b>No objects selected</b> to pop out of group.")); return; } - std::vector<SPItem*> selection_list = selection->itemList(); - std::vector<SPItem*>::const_iterator item = selection_list.begin(); // leaving this because it will be useful for + auto item = selection->items().begin(); // leaving this because it will be useful for // future implementation of complex pop ungrouping SPItem *obj = *item; SPItem *parent_group = static_cast<SPItem*>(obj->parent); @@ -800,32 +804,16 @@ void sp_selection_ungroup_pop_selection(Inkscape::Selection *selection, SPDeskto } - -void sp_selection_ungroup(Inkscape::Selection *selection, SPDesktop *desktop) +static void sp_object_set_ungroup(ObjectSet *set) { - if (selection->isEmpty()) { - selection_display_message(desktop, Inkscape::WARNING_MESSAGE, _("Select a <b>group</b> to ungroup.")); - } - - // first check whether there is anything to ungroup - std::vector<SPItem*> old_select = selection->itemList(); - std::vector<SPItem*> new_select; GSList *groups = NULL; - for (std::vector<SPItem*>::const_iterator item = old_select.begin(); item!=old_select.end(); ++item) { - SPItem *obj = *item; - if (dynamic_cast<SPGroup *>(obj)) { - groups = g_slist_prepend(groups, obj); - } + for (auto g: set->groups()) { + groups = g_slist_prepend(groups, g); } - if (groups == NULL) { - selection_display_message(desktop, Inkscape::ERROR_MESSAGE, _("<b>No groups</b> to ungroup in the selection.")); - g_slist_free(groups); - return; - } - - std::vector<SPItem*> items(old_select); - selection->clear(); + std::vector<SPItem*> new_select; + auto old_select = set->items(); + std::vector<SPItem*> items(old_select.begin(), old_select.end()); // If any of the clones refer to the groups, unlink them and replace them with successors // in the items list. @@ -872,7 +860,21 @@ void sp_selection_ungroup(Inkscape::Selection *selection, SPDesktop *desktop) } } - selection->addList(new_select); + set->setList(new_select); +} + +void sp_selection_ungroup(Inkscape::Selection *selection, SPDesktop *desktop) +{ + if (selection->isEmpty()) { + selection_display_message(desktop, Inkscape::WARNING_MESSAGE, _("Select a <b>group</b> to ungroup.")); + } + + if (boost::distance(selection->groups()) == 0) { + selection_display_message(desktop, Inkscape::ERROR_MESSAGE, _("<b>No groups</b> to ungroup in the selection.")); + return; + } + + sp_object_set_ungroup(selection); DocumentUndo::done(selection->layers()->getDocument(), SP_VERB_SELECTION_UNGROUP, _("Ungroup")); @@ -908,18 +910,18 @@ sp_degroup_list(std::vector<SPItem*> &items) /** If items in the list have a common parent, return it, otherwise return NULL */ static SPGroup * -sp_item_list_common_parent_group(std::vector<SPItem*> const &items) +sp_item_list_common_parent_group(const SPItemRange &items) { if (items.empty()) { return NULL; } - SPObject *parent = items[0]->parent; + SPObject *parent = items.front()->parent; // Strictly speaking this CAN happen, if user selects <svg> from Inkscape::XML editor if (!dynamic_cast<SPGroup *>(parent)) { return NULL; } - for (std::vector<SPItem*>::const_iterator item=items.begin();item!=items.end();++item) { - if((*item)==items[0])continue; + for (auto item=items.begin();item!=items.end();++item) { + if((*item)==items.front())continue; if ((*item)->parent != parent) { return NULL; } @@ -957,22 +959,9 @@ bool sp_item_repr_compare_position_bool(SPObject const *first, SPObject const *s ((SPItem*)second)->getRepr())<0; } -void -sp_selection_raise(Inkscape::Selection *selection, SPDesktop *desktop) -{ - std::vector<SPItem*> items= selection->itemList(); - if (items.empty()) { - selection_display_message(desktop, Inkscape::WARNING_MESSAGE, _("Select <b>object(s)</b> to raise.")); - return; - } - - SPGroup const *group = sp_item_list_common_parent_group(items); - if (!group) { - selection_display_message(desktop, Inkscape::ERROR_MESSAGE, _("You cannot raise/lower objects from <b>different groups</b> or <b>layers</b>.")); - return; - } - - Inkscape::XML::Node *grepr = const_cast<Inkscape::XML::Node *>(group->getRepr()); +void sp_object_set_raise(ObjectSet *set) { + std::vector<SPItem*> items(set->items().begin(), set->items().end()); + Inkscape::XML::Node *grepr = const_cast<Inkscape::XML::Node *>(items.front()->parent->getRepr()); /* Construct reverse-ordered list of selected children. */ std::vector<SPItem*> rev(items); @@ -986,7 +975,7 @@ sp_selection_raise(Inkscape::Selection *selection, SPDesktop *desktop) for (std::vector<SPItem*>::const_iterator item=rev.begin();item!=rev.end();++item) { SPObject *child = *item; // for each selected object, find the next sibling - for (SPObject *newref = child->next; newref; newref = newref->next) { + for (SPObject *newref = child->getNext(); newref; newref = newref->getNext()) { // if the sibling is an item AND overlaps our selection, SPItem *newItem = dynamic_cast<SPItem *>(newref); if (newItem) { @@ -1003,55 +992,61 @@ sp_selection_raise(Inkscape::Selection *selection, SPDesktop *desktop) } } } - DocumentUndo::done(selection->layers()->getDocument(), SP_VERB_SELECTION_RAISE, - //TRANSLATORS: "Raise" means "to raise an object" in the undo history - C_("Undo action", "Raise")); } -void sp_selection_raise_to_top(Inkscape::Selection *selection, SPDesktop *desktop) +void sp_selection_raise(Inkscape::Selection *selection, SPDesktop *desktop) { - SPDocument *document = selection->layers()->getDocument(); - - if (selection->isEmpty()) { - selection_display_message(desktop, Inkscape::WARNING_MESSAGE, _("Select <b>object(s)</b> to raise to top.")); + if (selection->items().empty()) { + selection_display_message(desktop, Inkscape::WARNING_MESSAGE, _("Select <b>object(s)</b> to raise.")); return; } - std::vector<SPItem*> items = selection->itemList(); - - SPGroup const *group = sp_item_list_common_parent_group(items); + SPGroup const *group = sp_item_list_common_parent_group(selection->items()); if (!group) { selection_display_message(desktop, Inkscape::ERROR_MESSAGE, _("You cannot raise/lower objects from <b>different groups</b> or <b>layers</b>.")); return; } + sp_object_set_raise(selection); - std::vector<Inkscape::XML::Node*> rl(selection->reprList()); + DocumentUndo::done(selection->layers()->getDocument(), SP_VERB_SELECTION_RAISE, + //TRANSLATORS: "Raise" means "to raise an object" in the undo history + C_("Undo action", "Raise")); +} + +void sp_object_set_raise_to_top(ObjectSet *set) { + std::vector<Inkscape::XML::Node*> rl(set->xmlNodes().begin(), set->xmlNodes().end()); sort(rl.begin(),rl.end(),sp_repr_compare_position_bool); for (std::vector<Inkscape::XML::Node*>::const_iterator l=rl.begin(); l!=rl.end();++l) { Inkscape::XML::Node *repr =(*l); repr->setPosition(-1); } - - DocumentUndo::done(document, SP_VERB_SELECTION_TO_FRONT, - _("Raise to top")); } -void sp_selection_lower(Inkscape::Selection *selection, SPDesktop *desktop) +void sp_selection_raise_to_top(Inkscape::Selection *selection, SPDesktop *desktop) { - std::vector<SPItem*> items = selection->itemList(); - if (items.empty()) { - selection_display_message(desktop, Inkscape::WARNING_MESSAGE, _("Select <b>object(s)</b> to lower.")); + SPDocument *document = selection->layers()->getDocument(); + + if (selection->isEmpty()) { + selection_display_message(desktop, Inkscape::WARNING_MESSAGE, _("Select <b>object(s)</b> to raise to top.")); return; } - SPGroup const *group = sp_item_list_common_parent_group(items); + SPGroup const *group = sp_item_list_common_parent_group(selection->items()); if (!group) { selection_display_message(desktop, Inkscape::ERROR_MESSAGE, _("You cannot raise/lower objects from <b>different groups</b> or <b>layers</b>.")); return; } - Inkscape::XML::Node *grepr = const_cast<Inkscape::XML::Node *>(group->getRepr()); + sp_object_set_raise_to_top(selection); + + DocumentUndo::done(document, SP_VERB_SELECTION_TO_FRONT, + _("Raise to top")); +} + +void sp_object_set_lower(ObjectSet *set) { + std::vector<SPItem*> items(set->items().begin(), set->items().end()); + Inkscape::XML::Node *grepr = const_cast<Inkscape::XML::Node *>(items.front()->parent->getRepr()); // Determine the common bbox of the selected items. Geom::OptRect selected = enclose_items(items); @@ -1086,48 +1081,65 @@ void sp_selection_lower(Inkscape::Selection *selection, SPDesktop *desktop) } } } - - DocumentUndo::done(selection->layers()->getDocument(), SP_VERB_SELECTION_LOWER, - //TRANSLATORS: "Lower" means "to lower an object" in the undo history - C_("Undo action", "Lower")); } -void sp_selection_lower_to_bottom(Inkscape::Selection *selection, SPDesktop *desktop) +void sp_selection_lower(Inkscape::Selection *selection, SPDesktop *desktop) { - SPDocument *document = selection->layers()->getDocument(); - - if (selection->isEmpty()) { - selection_display_message(desktop, Inkscape::WARNING_MESSAGE, _("Select <b>object(s)</b> to lower to bottom.")); + if (selection->items().empty()) { + selection_display_message(desktop, Inkscape::WARNING_MESSAGE, _("Select <b>object(s)</b> to lower.")); return; } - std::vector<SPItem*> items =selection->itemList(); - - SPGroup const *group = sp_item_list_common_parent_group(items); + SPGroup const *group = sp_item_list_common_parent_group(selection->items()); if (!group) { selection_display_message(desktop, Inkscape::ERROR_MESSAGE, _("You cannot raise/lower objects from <b>different groups</b> or <b>layers</b>.")); return; } - std::vector<Inkscape::XML::Node*> rl(selection->reprList()); + sp_object_set_lower(selection); + + DocumentUndo::done(selection->layers()->getDocument(), SP_VERB_SELECTION_LOWER, + //TRANSLATORS: "Lower" means "to lower an object" in the undo history + C_("Undo action", "Lower")); +} + +void sp_object_set_lower_to_bottom(ObjectSet *set) { + std::vector<Inkscape::XML::Node*> rl(set->xmlNodes().begin(), set->xmlNodes().end()); sort(rl.begin(),rl.end(),sp_repr_compare_position_bool); for (std::vector<Inkscape::XML::Node*>::const_reverse_iterator l=rl.rbegin();l!=rl.rend();++l) { gint minpos; - SPObject *pp, *pc; + SPObject *pp; Inkscape::XML::Node *repr = (*l); - pp = document->getObjectByRepr(repr->parent()); + pp = set->desktop()->getDocument()->getObjectByRepr(repr->parent()); minpos = 0; g_assert(dynamic_cast<SPGroup *>(pp)); - pc = pp->firstChild(); - while (!dynamic_cast<SPItem *>(pc)) { + for (auto& pc: pp->children) { + if(dynamic_cast<SPItem *>(&pc)) { + break; + } minpos += 1; - pc = pc->next; } repr->setPosition(minpos); } +} + +void sp_selection_lower_to_bottom(Inkscape::Selection *selection, SPDesktop *desktop) +{ + if (selection->isEmpty()) { + selection_display_message(desktop, Inkscape::WARNING_MESSAGE, _("Select <b>object(s)</b> to lower to bottom.")); + return; + } + + SPGroup const *group = sp_item_list_common_parent_group(selection->items()); + if (!group) { + selection_display_message(desktop, Inkscape::ERROR_MESSAGE, _("You cannot raise/lower objects from <b>different groups</b> or <b>layers</b>.")); + return; + } - DocumentUndo::done(document, SP_VERB_SELECTION_TO_BACK, + sp_object_set_lower_to_bottom(selection); + + DocumentUndo::done(selection->layers()->getDocument(), SP_VERB_SELECTION_TO_BACK, _("Lower to bottom")); } @@ -1173,13 +1185,14 @@ take_style_from_item(SPObject *object) if (css == NULL) return NULL; - if ((dynamic_cast<SPGroup *>(object) && object->children) || - (dynamic_cast<SPText *>(object) && object->children && object->children->next == NULL)) { + if ((dynamic_cast<SPGroup *>(object) && object->firstChild()) || + (dynamic_cast<SPText *>(object) && object->firstChild() && object->firstChild()->getNext() == NULL)) { // if this is a text with exactly one tspan child, merge the style of that tspan as well // If this is a group, merge the style of its topmost (last) child with style - for (SPObject *last_element = object->lastChild(); last_element != NULL; last_element = last_element->getPrev()) { - if ( last_element->style ) { - SPCSSAttr *temp = sp_css_attr_from_object(last_element, SP_STYLE_FLAG_IFSET); + auto list = object->children | boost::adaptors::reversed; + for (auto& element: list) { + if (element.style ) { + SPCSSAttr *temp = sp_css_attr_from_object(&element, SP_STYLE_FLAG_IFSET); if (temp) { sp_repr_css_merge(css, temp); sp_repr_css_attr_unref(temp); @@ -1264,8 +1277,8 @@ void sp_selection_remove_livepatheffect(SPDesktop *desktop) desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>object(s)</b> to remove live path effects from.")); return; } - std::vector<SPItem*> list=selection->itemList(); - for ( std::vector<SPItem*>::const_iterator itemlist=list.begin();itemlist!=list.end();++itemlist) { + auto list= selection->items(); + for (auto itemlist=list.begin();itemlist!=list.end();++itemlist) { SPItem *item = *itemlist; sp_selection_remove_livepatheffect_impl(item); @@ -1345,7 +1358,7 @@ void sp_selection_to_next_layer(SPDesktop *dt, bool suppressDone) return; } - std::vector<SPItem*> items(selection->itemList()); + std::vector<SPItem*> items(selection->items().begin(), selection->items().end()); bool no_more = false; // Set to true, if no more layers above SPObject *next=Inkscape::next_layer(dt->currentRoot(), dt->currentLayer()); @@ -1389,7 +1402,7 @@ void sp_selection_to_prev_layer(SPDesktop *dt, bool suppressDone) return; } - const std::vector<SPItem*> items(selection->itemList()); + std::vector<SPItem*> items(selection->items().begin(), selection->items().end()); bool no_more = false; // Set to true, if no more layers below SPObject *next=Inkscape::previous_layer(dt->currentRoot(), dt->currentLayer()); @@ -1432,7 +1445,7 @@ void sp_selection_to_layer(SPDesktop *dt, SPObject *moveto, bool suppressDone) return; } - std::vector<SPItem*> items(selection->itemList()); + std::vector<SPItem*> items(selection->items().begin(), selection->items().end()); if (moveto) { selection->clear(); @@ -1452,7 +1465,7 @@ void sp_selection_to_layer(SPDesktop *dt, SPObject *moveto, bool suppressDone) } static bool -selection_contains_original(SPItem *item, Inkscape::Selection *selection) +object_set_contains_original(SPItem *item, ObjectSet *set) { bool contains_original = false; @@ -1463,7 +1476,7 @@ selection_contains_original(SPItem *item, Inkscape::Selection *selection) { item_use = use->get_original(); use = dynamic_cast<SPUse *>(item_use); - contains_original |= selection->includes(item_use); + contains_original |= set->includes(item_use); if (item_use == item_use_first) break; } @@ -1472,7 +1485,7 @@ selection_contains_original(SPItem *item, Inkscape::Selection *selection) // data is part of the selection SPTRef *tref = dynamic_cast<SPTRef *>(item); if (!contains_original && tref) { - contains_original = selection->includes(tref->getObjectReferredTo()); + contains_original = set->includes(tref->getObjectReferredTo()); } return contains_original; @@ -1480,14 +1493,14 @@ selection_contains_original(SPItem *item, Inkscape::Selection *selection) static bool -selection_contains_both_clone_and_original(Inkscape::Selection *selection) +object_set_contains_both_clone_and_original(ObjectSet *set) { bool clone_with_original = false; - std::vector<SPItem*> items = selection->itemList(); - for (std::vector<SPItem*>::const_iterator l=items.begin();l!=items.end() ;++l) { + auto items = set->items(); + for (auto l=items.begin();l!=items.end() ;++l) { SPItem *item = *l; if (item) { - clone_with_original |= selection_contains_original(item, selection); + clone_with_original |= object_set_contains_original(item, set); if (clone_with_original) break; } @@ -1501,21 +1514,22 @@ value of set_i2d==false is only used by seltrans when it's dragging objects live 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::Affine const &affine, bool set_i2d, bool compensate, bool adjust_transf_center) +void sp_object_set_apply_affine(ObjectSet *set, Geom::Affine const &affine, bool set_i2d, bool compensate, + bool adjust_transf_center) { - if (selection->isEmpty()) + if (set->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<Persp3D *> plist = selection->perspList(); + std::list<Persp3D *> plist = set->perspList(); for (std::list<Persp3D *>::iterator i = plist.begin(); i != plist.end(); ++i) { persp = (Persp3D *) (*i); - if (!persp3d_has_all_boxes_in_selection (persp, selection)) { - std::list<SPBox3D *> selboxes = selection->box3DList(persp); + if (!persp3d_has_all_boxes_in_selection (persp, set)) { + std::list<SPBox3D *> selboxes = set->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 (persp->document, persp->perspective_impl); @@ -1528,14 +1542,14 @@ void sp_selection_apply_affine(Inkscape::Selection *selection, Geom::Affine cons persp3d_apply_affine_transformation(transf_persp, affine); } - std::vector<SPItem*> items = selection->itemList(); - for (std::vector<SPItem*>::const_iterator l=items.begin();l!=items.end() ;++l) { + auto items = set->items(); + for (auto l=items.begin();l!=items.end() ;++l) { SPItem *item = *l; if( dynamic_cast<SPRoot *>(item) ) { // An SVG element cannot have a transform. We could change 'x' and 'y' in response // to a translation... but leave that for another day. - selection->desktop()->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Cannot transform an embedded SVG.")); + set->desktop()->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Cannot transform an embedded SVG.")); break; } @@ -1549,17 +1563,17 @@ void sp_selection_apply_affine(Inkscape::Selection *selection, Geom::Affine cons #endif // we're moving both a clone and its original or any ancestor in clone chain? - bool transform_clone_with_original = selection_contains_original(item, selection); + bool transform_clone_with_original = object_set_contains_original(item, set); // ...both a text-on-path and its path? bool transform_textpath_with_path = ((dynamic_cast<SPText *>(item) && item->firstChild() && dynamic_cast<SPTextPath *>(item->firstChild())) - && selection->includes( sp_textpath_get_path_item(dynamic_cast<SPTextPath *>(item->firstChild())) )); + && set->includes( sp_textpath_get_path_item(dynamic_cast<SPTextPath *>(item->firstChild())) )); // ...both a flowtext and its frame? - bool transform_flowtext_with_frame = (dynamic_cast<SPFlowtext *>(item) && selection->includes( dynamic_cast<SPFlowtext *>(item)->get_frame(NULL))); // (only the first frame is checked so far) + bool transform_flowtext_with_frame = (dynamic_cast<SPFlowtext *>(item) && set->includes( dynamic_cast<SPFlowtext *>(item)->get_frame(NULL))); // (only the first frame is checked so far) // ...both an offset and its source? - bool transform_offset_with_source = (dynamic_cast<SPOffset *>(item) && dynamic_cast<SPOffset *>(item)->sourceHref) && selection->includes( sp_offset_get_source(dynamic_cast<SPOffset *>(item)) ); + bool transform_offset_with_source = (dynamic_cast<SPOffset *>(item) && dynamic_cast<SPOffset *>(item)->sourceHref) && set->includes( sp_offset_get_source(dynamic_cast<SPOffset *>(item)) ); // If we're moving a connector, we want to detach it // from shapes that aren't part of the selection, but @@ -1570,7 +1584,7 @@ void sp_selection_apply_affine(Inkscape::Selection *selection, Geom::Affine cons SPItem *attItem[2] = {0, 0}; path->connEndPair.getAttachedItems(attItem); for (int n = 0; n < 2; ++n) { - if (!selection->includes(attItem[n])) { + if (!set->includes(attItem[n])) { sp_conn_end_detach(item, n); } } @@ -1598,10 +1612,10 @@ void sp_selection_apply_affine(Inkscape::Selection *selection, Geom::Affine cons } else if (transform_flowtext_with_frame) { // apply the inverse of the region's transform to the <use> so that the flow remains // the same (even though the output itself gets transformed) - for ( SPObject *region = item->firstChild() ; region ; region = region->getNext() ) { - if (dynamic_cast<SPFlowregion *>(region) || dynamic_cast<SPFlowregionExclude *>(region)) { - for ( SPObject *item = region->firstChild() ; item ; item = item->getNext() ) { - SPUse *use = dynamic_cast<SPUse *>(item); + for (auto& region: item->children) { + if (dynamic_cast<SPFlowregion *>(®ion) || dynamic_cast<SPFlowregionExclude *>(®ion)) { + for (auto& itm: region.children) { + SPUse *use = dynamic_cast<SPUse *>(&itm); if ( use ) { use->doWriteTransform(use->getRepr(), use->transform.inverse(), NULL, compensate); } @@ -1692,15 +1706,15 @@ void sp_selection_apply_affine(Inkscape::Selection *selection, Geom::Affine cons } } -void sp_selection_remove_transform(SPDesktop *desktop) +void sp_object_set_remove_transform(SPDesktop *desktop) { if (desktop == NULL) return; Inkscape::Selection *selection = desktop->getSelection(); - std::vector<Inkscape::XML::Node*> items = selection->reprList(); - for (std::vector<Inkscape::XML::Node*>::const_iterator l=items.begin();l!=items.end() ;++l) { + auto items = selection->xmlNodes(); + for (auto l=items.begin();l!=items.end() ;++l) { (*l)->setAttribute("transform", NULL, false); } @@ -1709,14 +1723,14 @@ void sp_selection_remove_transform(SPDesktop *desktop) } void -sp_selection_scale_absolute(Inkscape::Selection *selection, - double const x0, double const x1, - double const y0, double const y1) +sp_object_set_scale_absolute(ObjectSet *set, + double x0, double x1, + double y0, double y1) { - if (selection->isEmpty()) + if (set->isEmpty()) return; - Geom::OptRect bbox = selection->visualBounds(); + Geom::OptRect bbox = set->visualBounds(); if ( !bbox ) { return; } @@ -1729,16 +1743,16 @@ sp_selection_scale_absolute(Inkscape::Selection *selection, Geom::Translate const o2n(x0, y0); Geom::Affine const final( p2o * scale * o2n ); - sp_selection_apply_affine(selection, final); + sp_object_set_apply_affine(set, final); } -void sp_selection_scale_relative(Inkscape::Selection *selection, Geom::Point const &align, Geom::Scale const &scale) +void sp_object_set_scale_relative(ObjectSet *set, Geom::Point const &align, Geom::Scale const &scale) { - if (selection->isEmpty()) + if (set->isEmpty()) return; - Geom::OptRect bbox = selection->visualBounds(); + Geom::OptRect bbox = set->visualBounds(); if ( !bbox ) { return; @@ -1754,21 +1768,21 @@ void sp_selection_scale_relative(Inkscape::Selection *selection, Geom::Point con Geom::Translate const n2d(-align); Geom::Translate const d2n(align); Geom::Affine const final( n2d * scale * d2n ); - sp_selection_apply_affine(selection, final); + sp_object_set_apply_affine(set, final); } void -sp_selection_rotate_relative(Inkscape::Selection *selection, Geom::Point const ¢er, gdouble const angle_degrees) +sp_object_set_rotate_relative(ObjectSet *set, Geom::Point const ¢er, double angle_degrees) { Geom::Translate const d2n(center); Geom::Translate const n2d(-center); Geom::Rotate const rotate(Geom::Rotate::from_degrees(angle_degrees)); Geom::Affine const final( Geom::Affine(n2d) * rotate * d2n ); - sp_selection_apply_affine(selection, final); + sp_object_set_apply_affine(set, final); } void -sp_selection_skew_relative(Inkscape::Selection *selection, Geom::Point const &align, double dx, double dy) +sp_object_set_skew_relative(ObjectSet *set, Geom::Point const &align, double dx, double dy) { Geom::Translate const d2n(align); Geom::Translate const n2d(-align); @@ -1776,17 +1790,17 @@ sp_selection_skew_relative(Inkscape::Selection *selection, Geom::Point const &al dx, 1, 0, 0); Geom::Affine const final( n2d * skew * d2n ); - sp_selection_apply_affine(selection, final); + sp_object_set_apply_affine(set, final); } -void sp_selection_move_relative(Inkscape::Selection *selection, Geom::Point const &move, bool compensate) +void sp_object_set_move_relative(ObjectSet *set, Geom::Point const &move, bool compensate) { - sp_selection_apply_affine(selection, Geom::Affine(Geom::Translate(move)), true, compensate); + sp_object_set_apply_affine(set, Geom::Affine(Geom::Translate(move)), true, compensate); } -void sp_selection_move_relative(Inkscape::Selection *selection, double dx, double dy) +void sp_object_set_move_relative(ObjectSet *set, double dx, double dy) { - sp_selection_apply_affine(selection, Geom::Affine(Geom::Translate(dx, dy))); + sp_object_set_apply_affine(set, Geom::Affine(Geom::Translate(dx, dy))); } /** @@ -1799,9 +1813,9 @@ void sp_selection_rotate_90(SPDesktop *desktop, bool ccw) if (selection->isEmpty()) return; - std::vector<SPItem*> items = selection->itemList(); + auto items = selection->items(); Geom::Rotate const rot_90(Geom::Point(0, ccw ? 1 : -1)); // pos. or neg. rotation, depending on the value of ccw - for (std::vector<SPItem*>::const_iterator l=items.begin();l!=items.end() ;++l) { + for (auto l=items.begin();l!=items.end() ;++l) { SPItem *item = *l; if (item) { sp_item_rotate_rel(item, rot_90); @@ -1826,7 +1840,7 @@ sp_selection_rotate(Inkscape::Selection *selection, gdouble const angle_degrees) return; } - sp_selection_rotate_relative(selection, *center, angle_degrees); + sp_object_set_rotate_relative(selection, *center, angle_degrees); DocumentUndo::maybeDone(selection->desktop()->getDocument(), ( ( angle_degrees > 0 ) @@ -1863,7 +1877,7 @@ void sp_select_same_fill_stroke_style(SPDesktop *desktop, gboolean fill, gboolea std::vector<SPItem*> all_matches; Inkscape::Selection *selection = desktop->getSelection(); - std::vector<SPItem*> items = selection->itemList(); + auto items = selection->items(); std::vector<SPItem*> tmp; for (std::vector<SPItem*>::const_iterator iter=all_list.begin();iter!=all_list.end();++iter) { @@ -1873,7 +1887,7 @@ void sp_select_same_fill_stroke_style(SPDesktop *desktop, gboolean fill, gboolea } all_list=tmp; - for (std::vector<SPItem*>::const_iterator sel_iter=items.begin();sel_iter!=items.end();++sel_iter) { + for (auto sel_iter=items.begin();sel_iter!=items.end();++sel_iter) { SPItem *sel = *sel_iter; std::vector<SPItem*> matches = all_list; if (fill && stroke && style) { @@ -1920,8 +1934,8 @@ void sp_select_same_object_type(SPDesktop *desktop) Inkscape::Selection *selection = desktop->getSelection(); - std::vector<SPItem*> items=selection->itemList(); - for (std::vector<SPItem*>::const_iterator sel_iter=items.begin();sel_iter!=items.end();++sel_iter) { + auto items= selection->items(); + for (auto sel_iter=items.begin();sel_iter!=items.end();++sel_iter) { SPItem *sel = *sel_iter; if (sel) { matches = sp_get_same_object_type(sel, matches); @@ -2175,7 +2189,7 @@ sp_selection_rotate_screen(Inkscape::Selection *selection, gdouble angle) gdouble const zangle = 180 * atan2(zmove, r) / M_PI; - sp_selection_rotate_relative(selection, *center, zangle); + sp_object_set_rotate_relative(selection, *center, zangle); DocumentUndo::maybeDone(selection->desktop()->getDocument(), ( (angle > 0) @@ -2205,7 +2219,7 @@ sp_selection_scale(Inkscape::Selection *selection, gdouble grow) } double const times = 1.0 + grow / max_len; - sp_selection_scale_relative(selection, center, Geom::Scale(times, times)); + sp_object_set_scale_relative(selection, center, Geom::Scale(times, times)); DocumentUndo::maybeDone(selection->desktop()->getDocument(), ( (grow > 0) @@ -2218,8 +2232,7 @@ sp_selection_scale(Inkscape::Selection *selection, gdouble grow) void sp_selection_scale_screen(Inkscape::Selection *selection, gdouble grow_pixels) { - sp_selection_scale(selection, - grow_pixels / selection->desktop()->current_zoom()); + sp_selection_scale(selection, grow_pixels / selection->desktop()->current_zoom()); } void @@ -2235,7 +2248,7 @@ sp_selection_scale_times(Inkscape::Selection *selection, gdouble times) } Geom::Point const center(sel_bbox->midpoint()); - sp_selection_scale_relative(selection, center, Geom::Scale(times, times)); + sp_object_set_scale_relative(selection, center, Geom::Scale(times, times)); DocumentUndo::done(selection->desktop()->getDocument(), SP_VERB_CONTEXT_SELECT, _("Scale by whole factor")); } @@ -2247,7 +2260,7 @@ sp_selection_move(Inkscape::Selection *selection, gdouble dx, gdouble dy) return; } - sp_selection_move_relative(selection, dx, dy); + sp_object_set_move_relative(selection, dx, dy); SPDocument *doc = selection->layers()->getDocument(); if (dx == 0) { @@ -2273,7 +2286,7 @@ sp_selection_move_screen(Inkscape::Selection *selection, gdouble dx, gdouble dy) gdouble const zoom = selection->desktop()->current_zoom(); gdouble const zdx = dx / zoom; gdouble const zdy = dy / zoom; - sp_selection_move_relative(selection, zdx, zdy); + sp_object_set_move_relative(selection, zdx, zdy); SPDocument *doc = selection->layers()->getDocument(); if (dx == 0) { @@ -2305,10 +2318,10 @@ typedef struct ListReverse { typedef GSList *Iterator; static Iterator children(SPObject *o) { - return make_list(o->firstChild(), NULL); + return make_list(o, NULL); } static Iterator siblings_after(SPObject *o) { - return make_list(o->parent->firstChild(), o); + return make_list(o->parent, o); } static void dispose(Iterator i) { g_slist_free(i); @@ -2322,13 +2335,12 @@ typedef struct ListReverse { private: static GSList *make_list(SPObject *object, SPObject *limit) { GSList *list = NULL; - while ( object != limit ) { - if (!object) { // TODO check if this happens in practice - g_warning("Unexpected list overrun"); + for (auto &child: object->children) { + if (&child == limit) { break; } - list = g_slist_prepend(list, object); - object = object->getNext(); + list = g_slist_prepend(list, &child); + } return list; } @@ -2433,7 +2445,8 @@ sp_selection_item_next(SPDesktop *desktop) root = desktop->currentRoot(); } - SPItem *item=next_item_from_list<Forward>(desktop, selection->itemList(), root, SP_CYCLING == SP_CYCLE_VISIBLE, inlayer, onlyvisible, onlysensitive); + std::vector<SPItem *> vec(selection->items().begin(), selection->items().end()); + SPItem *item=next_item_from_list<Forward>(desktop, vec, root, SP_CYCLING == SP_CYCLE_VISIBLE, inlayer, onlyvisible, onlysensitive); if (item) { selection->set(item, PREFS_SELECTION_LAYER_RECURSIVE == inlayer); @@ -2463,7 +2476,8 @@ sp_selection_item_prev(SPDesktop *desktop) root = desktop->currentRoot(); } - SPItem *item=next_item_from_list<ListReverse>(desktop, selection->itemList(), root, SP_CYCLING == SP_CYCLE_VISIBLE, inlayer, onlyvisible, onlysensitive); + std::vector<SPItem *> vec(selection->items().begin(), selection->items().end()); + SPItem *item=next_item_from_list<ListReverse>(desktop, vec, root, SP_CYCLING == SP_CYCLE_VISIBLE, inlayer, onlyvisible, onlysensitive); if (item) { selection->set(item, PREFS_SELECTION_LAYER_RECURSIVE == inlayer); @@ -2580,7 +2594,7 @@ void sp_selection_clone(SPDesktop *desktop) return; } - std::vector<Inkscape::XML::Node*> reprs (selection->reprList()); + std::vector<Inkscape::XML::Node*> reprs(selection->xmlNodes().begin(), selection->xmlNodes().end()); selection->clear(); @@ -2639,8 +2653,8 @@ sp_selection_relink(SPDesktop *desktop) // Get a copy of current selection. bool relinked = false; - std::vector<SPItem*> items=selection->itemList(); - for (std::vector<SPItem*>::const_iterator i=items.begin();i!=items.end();++i){ + auto items= selection->items(); + for (auto i=items.begin();i!=items.end();++i){ SPItem *item = *i; if (dynamic_cast<SPUse *>(item)) { @@ -2677,8 +2691,9 @@ sp_selection_unlink(SPDesktop *desktop) // Get a copy of current selection. std::vector<SPItem*> new_select; bool unlinked = false; - std::vector<SPItem*> items=selection->itemList(); - for (std::vector<SPItem*>::const_reverse_iterator i=items.rbegin();i!=items.rend();++i){ + std::vector<SPItem *> items(selection->items().begin(), selection->items().end()); + + for (auto i=items.rbegin();i!=items.rend();++i){ SPItem *item = *i; if (dynamic_cast<SPText *>(item)) { @@ -2744,8 +2759,8 @@ sp_select_clone_original(SPDesktop *desktop) // Check if other than two objects are selected - std::vector<SPItem*> items=selection->itemList(); - if (items.size() != 1 || !item) { + auto items= selection->items(); + if (boost::distance(items) != 1 || !item) { desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, error); return; } @@ -2842,8 +2857,8 @@ void sp_selection_clone_original_path_lpe(SPDesktop *desktop) Inkscape::SVGOStringStream os; SPObject * firstItem = NULL; - std::vector<SPItem*> items=selection->itemList(); - for (std::vector<SPItem*>::const_iterator i=items.begin();i!=items.end();++i){ + auto items= selection->items(); + for (auto i=items.begin();i!=items.end();++i){ if (SP_IS_SHAPE(*i) || SP_IS_TEXT(*i)) { if (firstItem) { os << "|"; @@ -2927,12 +2942,12 @@ void sp_selection_to_marker(SPDesktop *desktop, bool apply) Geom::Point center( *c - corner ); // As defined by rotation center center[Geom::Y] = -center[Geom::Y]; - std::vector<SPItem*> items(selection->itemList()); + std::vector<SPItem*> items(selection->items().begin(), selection->items().end()); //items = g_slist_sort(items, (GCompareFunc) sp_object_compare_position); // Why needed? // bottommost object, after sorting - SPObject *parent = items[0]->parent; + SPObject *parent = items.front()->parent; Geom::Affine parent_transform; { @@ -3001,7 +3016,7 @@ void sp_selection_to_guides(SPDesktop *desktop) SPDocument *doc = desktop->getDocument(); Inkscape::Selection *selection = desktop->getSelection(); // we need to copy the list because it gets reset when objects are deleted - std::vector<SPItem*> items(selection->itemList()); + std::vector<SPItem*> items(selection->items().begin(), selection->items().end()); if (items.empty()) { desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>object(s)</b> to convert to guides.")); @@ -3067,7 +3082,7 @@ void sp_selection_symbol(SPDesktop *desktop, bool /*apply*/ ) doc->ensureUpToDate(); - std::vector<SPObject*> items(selection->list()); + std::vector<SPObject*> items(selection->objects().begin(), selection->objects().end()); sort(items.begin(),items.end(),sp_object_compare_position_bool); // Keep track of parent, this is where <use> will be inserted. @@ -3279,7 +3294,7 @@ sp_selection_tile(SPDesktop *desktop, bool apply) move_p[Geom::Y] = -move_p[Geom::Y]; Geom::Affine move = Geom::Affine(Geom::Translate(move_p)); - std::vector<SPItem*> items (selection->itemList()); + std::vector<SPItem*> items(selection->items().begin(), selection->items().end()); sort(items.begin(),items.end(),sp_object_compare_position_bool); @@ -3384,7 +3399,7 @@ void sp_selection_untile(SPDesktop *desktop) bool did = false; - std::vector<SPItem*> items(selection->itemList()); + std::vector<SPItem*> items(selection->items().begin(), selection->items().end()); for (std::vector<SPItem*>::const_reverse_iterator i=items.rbegin();i!=items.rend();++i){ SPItem *item = *i; @@ -3407,9 +3422,9 @@ void sp_selection_untile(SPDesktop *desktop) Geom::Affine pat_transform = basePat->getTransform(); pat_transform *= item->transform; - for (SPObject *child = pattern->firstChild() ; child != NULL; child = child->next ) { - if (dynamic_cast<SPItem *>(child)) { - Inkscape::XML::Node *copy = child->getRepr()->duplicate(xml_doc); + for (auto& child: pattern->children) { + if (dynamic_cast<SPItem *>(&child)) { + Inkscape::XML::Node *copy = child.getRepr()->duplicate(xml_doc); SPItem *i = dynamic_cast<SPItem *>(desktop->currentLayer()->appendChildRepr(copy)); // FIXME: relink clones to the new canvas objects @@ -3443,18 +3458,18 @@ void sp_selection_untile(SPDesktop *desktop) } } -void sp_selection_get_export_hints(Inkscape::Selection *selection, Glib::ustring &filename, float *xdpi, float *ydpi) +void sp_object_set_get_export_hints(ObjectSet *set, Glib::ustring &filename, float *xdpi, float *ydpi) { - if (selection->isEmpty()) { + if (set->isEmpty()) { return; } - std::vector<Inkscape::XML::Node*> const reprlst = selection->reprList(); + auto reprlst = set->xmlNodes(); bool filename_search = TRUE; bool xdpi_search = TRUE; bool ydpi_search = TRUE; - for (std::vector<Inkscape::XML::Node*>::const_iterator i=reprlst.begin();filename_search&&xdpi_search&&ydpi_search&&i!=reprlst.end();++i){ + for (auto i=reprlst.begin();filename_search&&xdpi_search&&ydpi_search&&i!=reprlst.end();++i){ gchar const *dpi_string; Inkscape::XML::Node *repr = *i; @@ -3541,7 +3556,7 @@ void sp_selection_create_bitmap_copy(SPDesktop *desktop) } // List of the items to show; all others will be hidden - std::vector<SPItem*> items(selection->itemList()); + std::vector<SPItem*> items(selection->items().begin(), selection->items().end()); // Sort items so that the topmost comes last sort(items.begin(),items.end(),sp_item_repr_compare_position_bool); @@ -3594,7 +3609,7 @@ void sp_selection_create_bitmap_copy(SPDesktop *desktop) float hint_xdpi = 0, hint_ydpi = 0; Glib::ustring hint_filename; // take resolution hint from the selected objects - sp_selection_get_export_hints(selection, hint_filename, &hint_xdpi, &hint_ydpi); + sp_object_set_get_export_hints(selection, hint_filename, &hint_xdpi, &hint_ydpi); if (hint_xdpi != 0) { res = hint_xdpi; } else { @@ -3742,7 +3757,7 @@ void sp_selection_set_clipgroup(SPDesktop *desktop) return; } - std::vector<Inkscape::XML::Node*> p(selection->reprList()); + std::vector<Inkscape::XML::Node*> p(selection->xmlNodes().begin(), selection->xmlNodes().end()); sort(p.begin(),p.end(),sp_repr_compare_position_bool); @@ -3852,14 +3867,14 @@ void sp_selection_set_mask(SPDesktop *desktop, bool apply_clip_path, bool apply_ if ( apply_to_layer && is_empty) { desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>object(s)</b> to create clippath or mask from.")); return; - } else if (!apply_to_layer && ( is_empty || selection->itemList().size()==1 )) { + } else if (!apply_to_layer && ( is_empty || boost::distance(selection->items())==1 )) { desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select mask object and <b>object(s)</b> to apply clippath or mask to.")); return; } // FIXME: temporary patch to prevent crash! // Remove this when bboxes are fixed to not blow up on an item clipped/masked with its own clone - bool clone_with_original = selection_contains_both_clone_and_original(selection); + bool clone_with_original = object_set_contains_both_clone_and_original(selection); if (clone_with_original) { return; // in this version, you cannot clip/mask an object with its own clone } @@ -3867,7 +3882,7 @@ void sp_selection_set_mask(SPDesktop *desktop, bool apply_clip_path, bool apply_ doc->ensureUpToDate(); - std::vector<SPItem*> items(selection->itemList()); + std::vector<SPItem*> items(selection->items().begin(), selection->items().end()); sort(items.begin(),items.end(),sp_object_compare_position_bool); @@ -3919,18 +3934,13 @@ void sp_selection_set_mask(SPDesktop *desktop, bool apply_clip_path, bool apply_ if (grouping == PREFS_MASKOBJECT_GROUPING_ALL) { // group all those objects into one group // and apply mask to that - Inkscape::XML::Node *group = xml_doc->createElement("svg:g"); + ObjectSet* set = new ObjectSet(selection->desktop()); + set->add(apply_to_items.begin(), apply_to_items.end()); - // make a note we should ungroup this when unsetting mask - group->setAttribute("inkscape:groupmode", "maskhelper"); - - std::vector<Inkscape::XML::Node*> reprs_to_group; - for (std::vector<SPItem*>::const_iterator i = apply_to_items.begin(); i != apply_to_items.end(); ++i) { - reprs_to_group.push_back(static_cast<SPObject*>(*i)->getRepr()); - } items_to_select.clear(); - sp_selection_group_impl(reprs_to_group, group, xml_doc, doc); + Inkscape::XML::Node *group = sp_object_set_group(set); + group->setAttribute("inkscape:groupmode", "maskhelper"); // apply clip/mask only to newly created group apply_to_items.clear(); @@ -3938,6 +3948,7 @@ void sp_selection_set_mask(SPDesktop *desktop, bool apply_clip_path, bool apply_ items_to_select.push_back((SPItem*)(doc->getObjectByRepr(group))); + delete set; Inkscape::GC::release(group); } if (grouping == PREFS_MASKOBJECT_GROUPING_SEPARATE) { @@ -4029,7 +4040,7 @@ void sp_selection_unset_mask(SPDesktop *desktop, bool apply_clip_path) { gchar const *attributeName = apply_clip_path ? "clip-path" : "mask"; std::map<SPObject*,SPItem*> referenced_objects; - std::vector<SPItem*> items(selection->itemList()); + std::vector<SPItem*> items(selection->items().begin(), selection->items().end()); selection->clear(); GSList *items_to_ungroup = NULL; @@ -4075,9 +4086,9 @@ void sp_selection_unset_mask(SPDesktop *desktop, bool apply_clip_path) { for ( std::map<SPObject*,SPItem*>::iterator it = referenced_objects.begin() ; it != referenced_objects.end() ; ++it) { SPObject *obj = (*it).first; // Group containing the clipped paths or masks GSList *items_to_move = NULL; - for ( SPObject *child = obj->firstChild() ; child; child = child->getNext() ) { + for (auto& child: obj->children) { // Collect all clipped paths and masks within a single group - Inkscape::XML::Node *copy = child->getRepr()->duplicate(xml_doc); + Inkscape::XML::Node *copy = child.getRepr()->duplicate(xml_doc); if(copy->attribute("inkscape:original-d") && copy->attribute("inkscape:path-effect")) { copy->setAttribute("d", copy->attribute("inkscape:original-d")); @@ -4236,11 +4247,11 @@ static void itemtree_map(void (*f)(SPItem *, SPDesktop *), SPObject *root, SPDes f(item, desktop); } } - for ( SPObject::SiblingIterator iter = root->firstChild() ; iter ; ++iter ) { + for (auto& child: root->children) { //don't recurse into locked layers - SPItem *item = dynamic_cast<SPItem *>(&*iter); + SPItem *item = dynamic_cast<SPItem *>(&child); if (!(item && desktop->isLayer(item) && item->isLocked())) { - itemtree_map(f, iter, desktop); + itemtree_map(f, &child, desktop); } } } diff --git a/src/selection-chemistry.h b/src/selection-chemistry.h index 82b91c617..ca9062320 100644 --- a/src/selection-chemistry.h +++ b/src/selection-chemistry.h @@ -26,6 +26,7 @@ class SPDesktop; namespace Inkscape { class Selection; +class ObjectSet; namespace LivePathEffect { class PathParam; @@ -78,6 +79,11 @@ void sp_selection_group(Inkscape::Selection *selection, SPDesktop *desktop); void sp_selection_ungroup(Inkscape::Selection *selection, SPDesktop *desktop); void sp_selection_ungroup_pop_selection(Inkscape::Selection *selection, SPDesktop *desktop); +void sp_object_set_raise(Inkscape::ObjectSet *set); +void sp_object_set_raise_to_top(Inkscape::ObjectSet *set); +void sp_object_set_lower(Inkscape::ObjectSet *set); +void sp_object_set_lower_to_bottom(Inkscape::ObjectSet *set); + void sp_selection_raise(Inkscape::Selection *selection, SPDesktop *desktop); void sp_selection_raise_to_top(Inkscape::Selection *selection, SPDesktop *desktop); void sp_selection_lower(Inkscape::Selection *selection, SPDesktop *desktop); @@ -103,14 +109,15 @@ void sp_selection_to_next_layer( SPDesktop *desktop, bool suppressDone = false ) void sp_selection_to_prev_layer( SPDesktop *desktop, bool suppressDone = false ); void sp_selection_to_layer( SPDesktop *desktop, SPObject *layer, bool suppressDone = false ); -void sp_selection_apply_affine(Inkscape::Selection *selection, Geom::Affine const &affine, bool set_i2d = true, bool compensate = true, bool adjust_transf_center = true); -void sp_selection_remove_transform (SPDesktop *desktop); -void sp_selection_scale_absolute (Inkscape::Selection *selection, double x0, double x1, double y0, double y1); -void sp_selection_scale_relative(Inkscape::Selection *selection, Geom::Point const &align, Geom::Scale const &scale); -void sp_selection_rotate_relative (Inkscape::Selection *selection, Geom::Point const ¢er, double angle); -void sp_selection_skew_relative (Inkscape::Selection *selection, Geom::Point const &align, double dx, double dy); -void sp_selection_move_relative (Inkscape::Selection *selection, Geom::Point const &move, bool compensate = true); -void sp_selection_move_relative (Inkscape::Selection *selection, double dx, double dy); +void sp_object_set_apply_affine(Inkscape::ObjectSet *set, Geom::Affine const &affine, bool set_i2d = true, + bool compensate = true, bool adjust_transf_center = true); +void sp_object_set_remove_transform(SPDesktop *desktop); +void sp_object_set_scale_absolute(Inkscape::ObjectSet *set, double x0, double x1, double y0, double y1); +void sp_object_set_scale_relative(Inkscape::ObjectSet *set, Geom::Point const &align, Geom::Scale const &scale); +void sp_object_set_rotate_relative(Inkscape::ObjectSet *set, Geom::Point const ¢er, double angle); +void sp_object_set_skew_relative(Inkscape::ObjectSet *set, Geom::Point const &align, double dx, double dy); +void sp_object_set_move_relative(Inkscape::ObjectSet *set, Geom::Point const &move, bool compensate = true); +void sp_object_set_move_relative(Inkscape::ObjectSet *set, double dx, double dy); void sp_selection_rotate_90 (SPDesktop *desktop, bool ccw); void sp_selection_rotate (Inkscape::Selection *selection, double angle); @@ -151,7 +158,7 @@ void scroll_to_show_item(SPDesktop *desktop, SPItem *item); void sp_undo (SPDesktop *desktop, SPDocument *doc); void sp_redo (SPDesktop *desktop, SPDocument *doc); -void sp_selection_get_export_hints (Inkscape::Selection *selection, Glib::ustring &filename, float *xdpi, float *ydpi); +void sp_object_set_get_export_hints(Inkscape::ObjectSet *set, Glib::ustring &filename, float *xdpi, float *ydpi); void sp_document_get_export_hints (SPDocument * doc, Glib::ustring &filename, float *xdpi, float *ydpi); void sp_selection_create_bitmap_copy (SPDesktop *desktop); diff --git a/src/selection-describer.cpp b/src/selection-describer.cpp index 584510756..43fe1311d 100644 --- a/src/selection-describer.cpp +++ b/src/selection-describer.cpp @@ -113,7 +113,7 @@ void SelectionDescriber::_selectionModified(Inkscape::Selection *selection, guin } void SelectionDescriber::_updateMessageFromSelection(Inkscape::Selection *selection) { - std::vector<SPItem*> const items = selection->itemList(); + std::vector<SPItem*> items(selection->items().begin(), selection->items().end()); if (items.empty()) { // no items _context.set(Inkscape::NORMAL_MESSAGE, _when_nothing); diff --git a/src/selection.cpp b/src/selection.cpp index 05ab68550..bdd4f0dc7 100644 --- a/src/selection.cpp +++ b/src/selection.cpp @@ -7,8 +7,10 @@ * bulia byak <buliabyak@users.sf.net> * Andrius R. <knutux@gmail.com> * Abhishek Sharma + * Adrian Boguszewski * - * Copyright (C) 2006 Andrius R. + * Copyright (C) 2016 Adrian Boguszewski + * Copyright (C) 2006 Andrius R. * Copyright (C) 2004-2005 MenTaLguY * Copyright (C) 1999-2002 Lauris Kaplinski * Copyright (C) 2001-2002 Ximian, Inc. @@ -17,32 +19,24 @@ */ #ifdef HAVE_CONFIG_H -#include <config.h> #endif #include "inkscape.h" -#include "document.h" #include "xml/repr.h" #include "preferences.h" #include "sp-shape.h" #include "sp-path.h" -#include "sp-item-group.h" -#include "box3d.h" -#include "persp3d.h" +#include "desktop.h" +#include "document.h" #define SP_SELECTION_UPDATE_PRIORITY (G_PRIORITY_HIGH_IDLE + 1) namespace Inkscape { -Selection::Selection(LayerModel *layers, SPDesktop *desktop) : - _objs(std::list<SPObject*>()), - _objs_vector(std::vector<SPObject*>()), - _objs_set(std::set<SPObject*>()), - _reprs(std::vector<XML::Node*>()), - _items(std::vector<SPItem*>()), +Selection::Selection(LayerModel *layers, SPDesktop *desktop): + ObjectSet(desktop), _layers(layers), - _desktop(desktop), _selection_context(NULL), _flags(0), _idle(0) @@ -50,7 +44,6 @@ Selection::Selection(LayerModel *layers, SPDesktop *desktop) : } Selection::~Selection() { - _clear(); _layers = NULL; if (_idle) { g_source_remove(_idle); @@ -70,8 +63,7 @@ void Selection::_schedule_modified(SPObject */*obj*/, guint flags) { this->_flags |= flags; } -gboolean -Selection::_emit_modified(Selection *selection) +gboolean Selection::_emit_modified(Selection *selection) { /* force new handler to be created if requested before we return */ selection->_idle = 0; @@ -104,8 +96,7 @@ void Selection::_emitChanged(bool persist_selection_context/* = false */) { _changed_signal.emit(this); } -void -Selection::_releaseContext(SPObject *obj) +void Selection::_releaseContext(SPObject *obj) { if (NULL == _selection_context || _selection_context != obj) return; @@ -116,354 +107,38 @@ Selection::_releaseContext(SPObject *obj) _selection_context = NULL; } -void Selection::_invalidateCachedLists() { - _items.clear(); - _reprs.clear(); - _objs_vector.clear(); -} - -void Selection::_clear() { - _invalidateCachedLists(); - while (!_objs.empty()) { - SPObject *obj=_objs.front(); - _remove(obj); - } -} - SPObject *Selection::activeContext() { if (NULL != _selection_context) return _selection_context; return _layers->currentLayer(); - } - -bool Selection::includes(SPObject *obj) const { - if (obj == NULL) - return FALSE; - - g_return_val_if_fail(SP_IS_OBJECT(obj), FALSE); - - return ( _objs_set.find(obj)!=_objs_set.end() ); -} - -void Selection::add(SPObject *obj, bool persist_selection_context/* = false */) { - g_return_if_fail(obj != NULL); - g_return_if_fail(SP_IS_OBJECT(obj)); - g_return_if_fail(obj->document != NULL); - - if (includes(obj)) { - return; - } - - _invalidateCachedLists(); - _add(obj); - _emitChanged(persist_selection_context); -} - -void Selection::add_3D_boxes_recursively(SPObject *obj) { - std::list<SPBox3D *> boxes = box3d_extract_boxes(obj); - - for (std::list<SPBox3D *>::iterator i = boxes.begin(); i != boxes.end(); ++i) { - SPBox3D *box = *i; - _3dboxes.push_back(box); - } -} - -void Selection::_add(SPObject *obj) { - // unselect any of the item's ancestors and descendants which may be selected - // (to prevent double-selection) - _removeObjectDescendants(obj); - _removeObjectAncestors(obj); - g_return_if_fail(SP_IS_OBJECT(obj)); - - _objs.push_front(obj); - _objs_set.insert(obj); - - add_3D_boxes_recursively(obj); - - _release_connections[obj] = obj->connectRelease(sigc::mem_fun(*this, (void (Selection::*)(SPObject *))&Selection::remove)); - _modified_connections[obj] = obj->connectModified(sigc::mem_fun(*this, &Selection::_schedule_modified)); } void Selection::set(SPObject *object, bool persist_selection_context) { - _clear(); - add(object, persist_selection_context); -} - -void Selection::toggle(SPObject *obj) { - if (includes (obj)) { - remove (obj); - } else { - add(obj); - } -} - -void Selection::remove(SPObject *obj) { - g_return_if_fail(obj != NULL); - g_return_if_fail(SP_IS_OBJECT(obj)); - g_return_if_fail(includes(obj)); - - _invalidateCachedLists(); - _remove(obj); - _emitChanged(); -} - -void Selection::remove_3D_boxes_recursively(SPObject *obj) { - std::list<SPBox3D *> boxes = box3d_extract_boxes(obj); - - for (std::list<SPBox3D *>::iterator i = boxes.begin(); i != boxes.end(); ++i) { - SPBox3D *box = *i; - std::list<SPBox3D *>::iterator b = std::find(_3dboxes.begin(), _3dboxes.end(), box); - if (b == _3dboxes.end()) { - g_print ("Warning! Trying to remove unselected box from selection.\n"); - return; - } - _3dboxes.erase(b); - } -} - -void Selection::_remove(SPObject *obj) { - _modified_connections[obj].disconnect(); - _modified_connections.erase(obj); - - _release_connections[obj].disconnect(); - _release_connections.erase(obj); - - remove_3D_boxes_recursively(obj); - - _objs.remove(obj); - _objs_set.erase(obj); -} - -void Selection::setList(std::vector<SPItem*> const &list) { - // Clear and add, or just clear with emit. - if (!list.empty()) { - _clear(); - addList(list); - } else clear(); -} - -void Selection::addList(std::vector<SPItem*> const &list) { - - if (list.empty()) - return; - - _invalidateCachedLists(); - - for ( std::vector<SPItem*>::const_iterator iter=list.begin();iter!=list.end(); ++iter) { - SPObject *obj = *iter; - if (includes(obj)) continue; - _add (obj); - } - - _emitChanged(); + ObjectSet::set(object); + _emitChanged(persist_selection_context); } void Selection::setReprList(std::vector<XML::Node*> const &list) { - _clear(); + clear(); - for ( std::vector<XML::Node*>::const_reverse_iterator iter=list.rbegin();iter!=list.rend(); ++iter) { - SPObject *obj=_objectForXMLNode(*iter); + for (std::vector<XML::Node*>::const_reverse_iterator iter = list.rbegin(); iter != list.rend(); ++iter) { + SPObject *obj = _objectForXMLNode(*iter); if (obj) { - _add(obj); + add(obj); } } _emitChanged(); } -void Selection::clear() { - _clear(); - _emitChanged(); -} - -std::vector<SPObject*> const &Selection::list() { - if(!_objs_vector.empty()) - return _objs_vector; - - for ( std::list<SPObject*>::const_iterator iter=_objs.begin();iter!=_objs.end(); ++iter) { - _objs_vector.push_back(*iter); - } - return _objs_vector; - -} - -std::vector<SPItem*> const &Selection::itemList() { - if (!_items.empty()) { - return _items; - } - - for ( std::list<SPObject*>::const_iterator iter=_objs.begin();iter!=_objs.end(); ++iter) { - SPObject *obj=*iter; - if (SP_IS_ITEM(obj)) { - _items.push_back(SP_ITEM(obj)); - } - } - return _items; -} - -std::vector<XML::Node*> const &Selection::reprList() { - if (!_reprs.empty()) { return _reprs; } - std::vector<SPItem*> list = itemList(); - for ( std::vector<SPItem*>::const_iterator iter=list.begin();iter!=list.end(); ++iter) { - SPObject *obj = *iter; - _reprs.push_back(obj->getRepr()); - } - return _reprs; -} - -std::list<Persp3D *> const Selection::perspList() { - std::list<Persp3D *> pl; - for (std::list<SPBox3D *>::iterator i = _3dboxes.begin(); i != _3dboxes.end(); ++i) { - Persp3D *persp = box3d_get_perspective(*i); - if (std::find(pl.begin(), pl.end(), persp) == pl.end()) - pl.push_back(persp); - } - return pl; -} - -std::list<SPBox3D *> const Selection::box3DList(Persp3D *persp) { - std::list<SPBox3D *> boxes; - if (persp) { - for (std::list<SPBox3D *>::iterator i = _3dboxes.begin(); i != _3dboxes.end(); ++i) { - SPBox3D *box = *i; - if (persp == box3d_get_perspective(box)) { - boxes.push_back(box); - } - } - } else { - boxes = _3dboxes; - } - return boxes; -} - -SPObject *Selection::single() { - if ( _objs.size() == 1 ) { - return _objs.front(); - } else { - return NULL; - } -} - -SPItem *Selection::singleItem() { - std::vector<SPItem*> const items=itemList(); - if ( items.size()==1) { - return items[0]; - } else { - return NULL; - } -} - -SPItem *Selection::smallestItem(Selection::CompareSize compare) { - return _sizeistItem(true, compare); -} - -SPItem *Selection::largestItem(Selection::CompareSize compare) { - return _sizeistItem(false, compare); -} - -SPItem *Selection::_sizeistItem(bool sml, Selection::CompareSize compare) { - std::vector<SPItem*> const items = const_cast<Selection *>(this)->itemList(); - gdouble max = sml ? 1e18 : 0; - SPItem *ist = NULL; - - for ( std::vector<SPItem*>::const_iterator i=items.begin();i!=items.end(); ++i) { - Geom::OptRect obox = SP_ITEM(*i)->desktopPreferredBounds(); - if (!obox || obox.empty()) continue; - Geom::Rect bbox = *obox; - - gdouble size = compare == 2 ? bbox.area() : - (compare == 1 ? bbox.width() : bbox.height()); - size = sml ? size : size * -1; - if (size < max) { - max = size; - ist = SP_ITEM(*i); - } - } - return ist; -} - -Inkscape::XML::Node *Selection::singleRepr() { - SPObject *obj=single(); - return obj ? obj->getRepr() : NULL; -} - -Geom::OptRect Selection::bounds(SPItem::BBoxType type) const -{ - return (type == SPItem::GEOMETRIC_BBOX) ? - geometricBounds() : visualBounds(); -} - -Geom::OptRect Selection::geometricBounds() const -{ - std::vector<SPItem*> const items = const_cast<Selection *>(this)->itemList(); - - Geom::OptRect bbox; - for ( std::vector<SPItem*>::const_iterator iter=items.begin();iter!=items.end(); ++iter) { - bbox.unionWith(SP_ITEM(*iter)->desktopGeometricBounds()); - } - return bbox; -} - -Geom::OptRect Selection::visualBounds() const -{ - std::vector<SPItem*> const items = const_cast<Selection *>(this)->itemList(); - - Geom::OptRect bbox; - for ( std::vector<SPItem*>::const_iterator iter=items.begin();iter!=items.end(); ++iter) { - bbox.unionWith(SP_ITEM(*iter)->desktopVisualBounds()); - } - return bbox; -} - -Geom::OptRect Selection::preferredBounds() const -{ - if (Inkscape::Preferences::get()->getInt("/tools/bounding_box") == 0) { - return bounds(SPItem::VISUAL_BBOX); - } else { - return bounds(SPItem::GEOMETRIC_BBOX); - } -} - -Geom::OptRect Selection::documentBounds(SPItem::BBoxType type) const -{ - Geom::OptRect bbox; - std::vector<SPItem*> const items = const_cast<Selection *>(this)->itemList(); - if (items.empty()) return bbox; - - for ( std::vector<SPItem*>::const_iterator iter=items.begin();iter!=items.end(); ++iter) { - SPItem *item = SP_ITEM(*iter); - bbox |= item->documentBounds(type); - } - - return bbox; -} - -// If we have a selection of multiple items, then the center of the first item -// will be returned; this is also the case in SelTrans::centerRequest() -boost::optional<Geom::Point> Selection::center() const { - std::vector<SPItem*> const items = const_cast<Selection *>(this)->itemList(); - if (!items.empty()) { - SPItem *first = items.back(); // from the first item in selection - if (first->isCenterSet()) { // only if set explicitly - return first->getCenter(); - } - } - Geom::OptRect bbox = preferredBounds(); - if (bbox) { - return bbox->midpoint(); - } else { - return boost::optional<Geom::Point>(); - } -} - std::vector<Inkscape::SnapCandidatePoint> Selection::getSnapPoints(SnapPreferences const *snapprefs) const { std::vector<Inkscape::SnapCandidatePoint> p; if (snapprefs != NULL){ SnapPreferences snapprefs_dummy = *snapprefs; // create a local copy of the snapping prefs snapprefs_dummy.setTargetSnappable(Inkscape::SNAPTARGET_ROTATION_CENTER, false); // locally disable snapping to the item center - std::vector<SPItem*> const items = const_cast<Selection *>(this)->itemList(); - for ( std::vector<SPItem*>::const_iterator iter=items.begin();iter!=items.end(); ++iter) { + auto items = const_cast<Selection *>(this)->items(); + for (auto iter = items.begin(); iter != items.end(); ++iter) { SPItem *this_item = *iter; this_item->getSnappoints(p, &snapprefs_dummy); @@ -478,34 +153,6 @@ std::vector<Inkscape::SnapCandidatePoint> Selection::getSnapPoints(SnapPreferenc return p; } -void Selection::_removeObjectDescendants(SPObject *obj) { - std::vector<SPObject*> toremove; - for ( std::list<SPObject*>::const_iterator iter=_objs.begin();iter!=_objs.end(); ++iter) { - SPObject *sel_obj= dynamic_cast<SPObject*>(*iter); - SPObject *parent = sel_obj->parent; - while (parent) { - if ( parent == obj ) { - toremove.push_back(sel_obj); - break; - } - parent = parent->parent; - } - } - for ( std::vector<SPObject*>::const_iterator iter=toremove.begin();iter!=toremove.end(); ++iter) { - _remove(*iter); - } -} - -void Selection::_removeObjectAncestors(SPObject *obj) { - SPObject *parent = obj->parent; - while (parent) { - if (includes(parent)) { - _remove(parent); - } - parent = parent->parent; - } -} - SPObject *Selection::_objectForXMLNode(Inkscape::XML::Node *repr) const { g_return_val_if_fail(repr != NULL, NULL); gchar const *id = repr->attribute("id"); @@ -516,25 +163,39 @@ SPObject *Selection::_objectForXMLNode(Inkscape::XML::Node *repr) const { } size_t Selection::numberOfLayers() { - std::vector<SPItem*> const items = const_cast<Selection *>(this)->itemList(); + auto items = this->items(); std::set<SPObject*> layers; - for ( std::vector<SPItem*>::const_iterator iter=items.begin();iter!=items.end(); ++iter) { + for (auto iter = items.begin(); iter != items.end(); ++iter) { SPObject *layer = _layers->layerForObject(*iter); layers.insert(layer); } + return layers.size(); } size_t Selection::numberOfParents() { - std::vector<SPItem*> const items = const_cast<Selection *>(this)->itemList(); + auto items = this->items(); std::set<SPObject*> parents; - for ( std::vector<SPItem*>::const_iterator iter=items.begin();iter!=items.end(); ++iter) { + for (auto iter = items.begin(); iter != items.end(); ++iter) { SPObject *parent = (*iter)->parent; parents.insert(parent); } return parents.size(); } +void Selection::_emitSignals() { + _emitChanged(); +} + +void Selection::_connectSignals(SPObject *object) { + _modified_connections[object] = object->connectModified(sigc::mem_fun(*this, &Selection::_schedule_modified)); +} + +void Selection::_releaseSignals(SPObject *object) { + _modified_connections[object].disconnect(); + _modified_connections.erase(object); +} + } /* diff --git a/src/selection.h b/src/selection.h index 04bcca402..4ea70c38d 100644 --- a/src/selection.h +++ b/src/selection.h @@ -5,7 +5,9 @@ * Lauris Kaplinski <lauris@kaplinski.com> * MenTaLguY <mental@rydia.net> * bulia byak <buliabyak@users.sf.net> + * Adrian Boguszewski * + * Copyright (C) 2016 Adrian Boguszewski * Copyright (C) 2004-2005 MenTaLguY * Copyright (C) 1999-2002 Lauris Kaplinski * Copyright (C) 2001-2002 Ximian, Inc. @@ -15,21 +17,16 @@ #include <vector> #include <map> -#include <list> -#include <set> #include <stddef.h> #include <sigc++/sigc++.h> #include "inkgc/gc-managed.h" #include "gc-finalized.h" #include "gc-anchored.h" -#include "inkgc/gc-soft-ptr.h" #include "sp-item.h" +#include "object-set.h" -class SPDesktop; class SPItem; -class SPBox3D; -class Persp3D; namespace Inkscape { class LayerModel; @@ -38,7 +35,6 @@ class Node; } } - namespace Inkscape { /** @@ -60,10 +56,10 @@ namespace Inkscape { */ class Selection : public Inkscape::GC::Managed<>, public Inkscape::GC::Finalized, - public Inkscape::GC::Anchored + public Inkscape::GC::Anchored, + public ObjectSet { public: - enum CompareSize { HORIZONTAL, VERTICAL, AREA }; /** * Constructs an selection object, bound to a particular * layer model @@ -82,12 +78,7 @@ public: */ LayerModel *layers() { return _layers; } - /** - * Returns the desktop the selection is bound to - * - * @return the desktop the selection is bound to, or NULL if in console mode - */ - SPDesktop *desktop() { return _desktop; } + /** * Returns active layer for selection (currentLayer or its parent). @@ -96,19 +87,16 @@ public: */ SPObject *activeContext(); - /** - * Add an SPObject to the set of selected objects. - * - * @param obj the SPObject to add - */ - void add(SPObject *obj, bool persist_selection_context = false); + using ObjectSet::add; /** * Add an XML node's SPObject to the set of selected objects. * * @param the xml node of the item to add */ - void add(XML::Node *repr) { add(_objectForXMLNode(repr)); } + void add(XML::Node *repr) { + add(_objectForXMLNode(repr)); + } /** * Set the selection to a single specific object. @@ -122,23 +110,11 @@ public: * * @param repr the xml node of the item to select */ - void set(XML::Node *repr) { set(_objectForXMLNode(repr)); } - - /** - * Removes an item from the set of selected objects. - * - * It is ok to call this method for an unselected item. - * - * @param item the item to unselect - */ - void remove(SPObject *obj); + void set(XML::Node *repr) { + set(_objectForXMLNode(repr)); + } - /** - * Removes an item if selected, adds otherwise. - * - * @param item the item to unselect - */ - void toggle(SPObject *obj); + using ObjectSet::remove; /** * Removes an item from the set of selected objects. @@ -147,21 +123,9 @@ public: * * @param repr the xml node of the item to remove */ - void remove(XML::Node *repr) { remove(_objectForXMLNode(repr)); } - - /** - * Selects exactly the specified objects. - * - * @param objs the objects to select - */ - void setList(std::vector<SPItem*> const &objs); - - /** - * Adds the specified objects to selection, without deselecting first. - * - * @param objs the objects to select - */ - void addList(std::vector<SPItem*> const &objs); + void remove(XML::Node *repr) { + remove(_objectForXMLNode(repr)); + } /** * Clears the selection and selects the specified objects. @@ -170,117 +134,21 @@ public: */ void setReprList(std::vector<XML::Node*> const &reprs); - /** Add items from an STL iterator range to the selection. - * \param from the begin iterator - * \param to the end iterator - */ - template <typename InputIterator> - void add(InputIterator from, InputIterator to) { - _invalidateCachedLists(); - while ( from != to ) { - _add(*from); - ++from; - } - _emitChanged(); - } - - /** - * Unselects all selected objects.. - */ - void clear(); - - /** - * Returns true if no items are selected. - */ - bool isEmpty() const { return _objs.empty(); } - - /** - * Returns true if the given object is selected. - */ - bool includes(SPObject *obj) const; + using ObjectSet::includes; /** * Returns true if the given item is selected. */ - bool includes(XML::Node *repr) const { + bool includes(XML::Node *repr) { return includes(_objectForXMLNode(repr)); } - /** - * Returns a single selected object. - * - * @return NULL unless exactly one object is selected - */ - SPObject *single(); - - /** - * Returns a single selected item. - * - * @return NULL unless exactly one object is selected - */ - SPItem *singleItem(); - - /** - * Returns the smallest item from this selection. - */ - SPItem *smallestItem(CompareSize compare); - - /** - * Returns the largest item from this selection. - */ - SPItem *largestItem(CompareSize compare); - - /** - * Returns a single selected object's xml node. - * - * @return NULL unless exactly one object is selected - */ - XML::Node *singleRepr(); - - /** Returns the list of selected objects. */ - std::vector<SPObject*> const &list(); - /** Returns the list of selected SPItems. */ - std::vector<SPItem*> const &itemList(); - /** Returns a list of the xml nodes of all selected objects. */ - /// \todo only returns reprs of SPItems currently; need a separate - /// method for that - std::vector<XML::Node*> const &reprList(); - - /** Returns a list of all perspectives which have a 3D box in the current selection. - (these may also be nested in groups) */ - std::list<Persp3D *> const perspList(); - - /** - * Returns a list of all 3D boxes in the current selection which are associated to @c - * persp. If @c pers is @c NULL, return all selected boxes. - */ - std::list<SPBox3D *> const box3DList(Persp3D *persp = NULL); - /** Returns the number of layers in which there are selected objects. */ size_t numberOfLayers(); /** Returns the number of parents to which the selected objects belong. */ size_t numberOfParents(); - /** Returns the bounding rectangle of the selection. */ - Geom::OptRect bounds(SPItem::BBoxType type) const; - Geom::OptRect visualBounds() const; - Geom::OptRect geometricBounds() const; - - /** - * Returns either the visual or geometric bounding rectangle of the selection, based on the - * preferences specified for the selector tool - */ - Geom::OptRect preferredBounds() const; - - /// Returns the bounding rectangle of the selectionin document coordinates. - Geom::OptRect documentBounds(SPItem::BBoxType type) const; - - /** - * Returns the rotation/skew center of the selection. - */ - boost::optional<Geom::Point> center() const; - /** * Compute the list of points in the selection that are to be considered for snapping from. * @@ -327,6 +195,11 @@ public: return _modified_signal.slots().insert(_modified_signal.slots().begin(), slot); } +protected: + void _emitSignals(); + void _connectSignals(SPObject* object); + void _releaseSignals(SPObject* object); + private: /** no copy. */ Selection(Selection const &); @@ -342,46 +215,17 @@ private: void _emitModified(unsigned int flags); /** Issues changed selection signal. */ void _emitChanged(bool persist_selection_context = false); - - void _invalidateCachedLists(); - - /** unselect all descendants of the given item. */ - void _removeObjectDescendants(SPObject *obj); - /** unselect all ancestors of the given item. */ - void _removeObjectAncestors(SPObject *obj); - /** clears the selection (without issuing a notification). */ - void _clear(); - /** adds an object (without issuing a notification). */ - void _add(SPObject *obj); - /** removes an object (without issuing a notification). */ - void _remove(SPObject *obj); /** returns the SPObject corresponding to an xml node (if any). */ SPObject *_objectForXMLNode(XML::Node *repr) const; /** Releases an active layer object that is being removed. */ void _releaseContext(SPObject *obj); - mutable std::list<SPObject*> _objs; //to more efficiently remove arbitrary elements - mutable std::vector<SPObject*> _objs_vector; // to be returned by list(); - mutable std::set<SPObject*> _objs_set; //to efficiently test if object is selected - mutable std::vector<XML::Node*> _reprs; - mutable std::vector<SPItem*> _items; - - void add_box_perspective(SPBox3D *box); - void add_3D_boxes_recursively(SPObject *obj); - void remove_box_perspective(SPBox3D *box); - void remove_3D_boxes_recursively(SPObject *obj); - SPItem *_sizeistItem(bool sml, CompareSize compare); - - std::list<SPBox3D *> _3dboxes; - LayerModel *_layers; - GC::soft_ptr<SPDesktop> _desktop; SPObject* _selection_context; unsigned int _flags; unsigned int _idle; std::map<SPObject *, sigc::connection> _modified_connections; - std::map<SPObject *, sigc::connection> _release_connections; sigc::connection _context_release_connection; sigc::signal<void, Selection *> _changed_signal; diff --git a/src/seltrans.cpp b/src/seltrans.cpp index c1fb652be..7b17a294a 100644 --- a/src/seltrans.cpp +++ b/src/seltrans.cpp @@ -234,8 +234,8 @@ void Inkscape::SelTrans::setCenter(Geom::Point const &p) _center_is_set = true; // Write the new center position into all selected items - std::vector<SPItem*> items=_desktop->selection->itemList(); - for ( std::vector<SPItem*>::const_iterator iter=items.begin();iter!=items.end(); ++iter) { + auto items= _desktop->selection->items(); + for (auto iter=items.begin();iter!=items.end(); ++iter) { SPItem *it = SP_ITEM(*iter); it->setCenter(p); // only set the value; updating repr and document_done will be done once, on ungrab @@ -264,8 +264,8 @@ void Inkscape::SelTrans::grab(Geom::Point const &p, gdouble x, gdouble y, bool s return; } - std::vector<SPItem*> items=_desktop->selection->itemList(); - for ( std::vector<SPItem*>::const_iterator iter=items.begin();iter!=items.end(); ++iter) { + auto items= _desktop->selection->items(); + for (auto iter=items.begin();iter!=items.end(); ++iter) { SPItem *it = static_cast<SPItem*>(sp_object_ref(*iter, NULL)); _items.push_back(it); _items_const.push_back(it); @@ -439,7 +439,7 @@ void Inkscape::SelTrans::ungrab() if (!_current_relative_affine.isIdentity()) { // we can have a identity affine // when trying to stretch a perfectly vertical line in horizontal direction, which will not be allowed by the handles; - sp_selection_apply_affine(selection, _current_relative_affine, (_show == SHOW_OUTLINE)? true : false); + sp_object_set_apply_affine(selection, _current_relative_affine, (_show == SHOW_OUTLINE) ? true : false); if (_center) { *_center *= _current_relative_affine; _center_is_set = true; @@ -486,8 +486,8 @@ void Inkscape::SelTrans::ungrab() if (_center_is_set) { // we were dragging center; update reprs and commit undoable action - std::vector<SPItem*> items=_desktop->selection->itemList(); - for ( std::vector<SPItem*>::const_iterator iter=items.begin();iter!=items.end(); ++iter) { + auto items= _desktop->selection->items(); + for (auto iter=items.begin();iter!=items.end(); ++iter) { SPItem *it = *iter; it->updateRepr(); } @@ -523,8 +523,8 @@ void Inkscape::SelTrans::stamp() l = _stamp_cache; } else { /* Build cache */ - l = selection->itemList(); - sort(l.begin(),l.end(),sp_object_compare_position_bool); + l.insert(l.end(), selection->items().begin(), selection->items().end()); + sort(l.begin(), l.end(), sp_object_compare_position_bool); _stamp_cache = l; } @@ -615,7 +615,8 @@ void Inkscape::SelTrans::_updateVolatileState() return; } - _strokewidth = stroke_average_width (selection->itemList()); + std::vector<SPItem *> vec(selection->items().begin(), selection->items().end()); + _strokewidth = stroke_average_width(vec); } void Inkscape::SelTrans::_showHandles(SPSelTransType type) @@ -705,8 +706,8 @@ void Inkscape::SelTrans::handleClick(SPKnot */*knot*/, guint state, SPSelTransHa case HANDLE_CENTER: if (state & GDK_SHIFT_MASK) { // Unset the center position for all selected items - std::vector<SPItem*> items=_desktop->selection->itemList(); - for ( std::vector<SPItem*>::const_iterator iter=items.begin();iter!=items.end(); ++iter) { + auto items = _desktop->selection->items(); + for (auto iter=items.begin();iter!=items.end(); ++iter) { SPItem *it = *iter; it->unsetCenter(); it->updateRepr(); @@ -1281,7 +1282,7 @@ gboolean Inkscape::SelTrans::centerRequest(Geom::Point &pt, guint state) // items will share a single center. While dragging that single center, it should never snap to the // centers of any of the selected objects. Therefore we will have to pass the list of selected items // to the snapper, to avoid self-snapping of the rotation center - std::vector<SPItem*> items = const_cast<Selection *>(_selection)->itemList(); + std::vector<SPItem *> items(_selection->items().begin(), _selection->items().end()); SnapManager &m = _desktop->namedview->snap_manager; m.setup(_desktop); m.setRotationCenterSource(items); diff --git a/src/snap.cpp b/src/snap.cpp index 50f40a9a1..c84da0491 100644 --- a/src/snap.cpp +++ b/src/snap.cpp @@ -702,8 +702,8 @@ void SnapManager::setupIgnoreSelection(SPDesktop const *desktop, _items_to_ignore.clear(); Inkscape::Selection *sel = _desktop->selection; - std::vector<SPItem*> const items = sel->itemList(); - for (std::vector<SPItem*>::const_iterator i=items.begin();i!=items.end();++i) { + auto items = sel->items(); + for (auto i=items.begin();i!=items.end();++i) { _items_to_ignore.push_back(*i); } } diff --git a/src/sp-clippath.cpp b/src/sp-clippath.cpp index 915c57e45..b371e15b2 100644 --- a/src/sp-clippath.cpp +++ b/src/sp-clippath.cpp @@ -127,9 +127,9 @@ void SPClipPath::update(SPCtx* ctx, unsigned int flags) { flags &= SP_OBJECT_MODIFIED_CASCADE; GSList *l = NULL; - for ( SPObject *child = this->firstChild(); child; child = child->getNext()) { - sp_object_ref(child); - l = g_slist_prepend(l, child); + for (auto& child: children) { + sp_object_ref(&child); + l = g_slist_prepend(l, &child); } l = g_slist_reverse(l); @@ -166,9 +166,9 @@ void SPClipPath::modified(unsigned int flags) { flags &= SP_OBJECT_MODIFIED_CASCADE; GSList *l = NULL; - for (SPObject *child = this->firstChild(); child; child = child->getNext()) { - sp_object_ref(child); - l = g_slist_prepend(l, child); + for (auto& child: children) { + sp_object_ref(&child); + l = g_slist_prepend(l, &child); } l = g_slist_reverse(l); @@ -199,9 +199,9 @@ Inkscape::DrawingItem *SPClipPath::show(Inkscape::Drawing &drawing, unsigned int Inkscape::DrawingGroup *ai = new Inkscape::DrawingGroup(drawing); display = sp_clippath_view_new_prepend(display, key, ai); - for ( SPObject *child = firstChild() ; child ; child = child->getNext() ) { - if (SP_IS_ITEM(child)) { - Inkscape::DrawingItem *ac = SP_ITEM(child)->invoke_show(drawing, key, SP_ITEM_REFERENCE_FLAGS); + for (auto& child: children) { + if (SP_IS_ITEM(&child)) { + Inkscape::DrawingItem *ac = SP_ITEM(&child)->invoke_show(drawing, key, SP_ITEM_REFERENCE_FLAGS); if (ac) { /* The order is not important in clippath */ @@ -222,9 +222,9 @@ Inkscape::DrawingItem *SPClipPath::show(Inkscape::Drawing &drawing, unsigned int } void SPClipPath::hide(unsigned int key) { - for ( SPObject *child = firstChild() ; child; child = child->getNext() ) { - if (SP_IS_ITEM(child)) { - SP_ITEM(child)->invoke_hide(key); + for (auto& child: children) { + if (SP_IS_ITEM(&child)) { + SP_ITEM(&child)->invoke_hide(key); } } @@ -251,9 +251,9 @@ void SPClipPath::setBBox(unsigned int key, Geom::OptRect const &bbox) { Geom::OptRect SPClipPath::geometricBounds(Geom::Affine const &transform) { Geom::OptRect bbox; - for (SPObject *i = firstChild(); i; i = i->getNext()) { - if (SP_IS_ITEM(i)) { - Geom::OptRect tmp = SP_ITEM(i)->geometricBounds(Geom::Affine(SP_ITEM(i)->transform) * transform); + for (auto& i: children) { + if (SP_IS_ITEM(&i)) { + Geom::OptRect tmp = SP_ITEM(&i)->geometricBounds(Geom::Affine(SP_ITEM(&i)->transform) * transform); bbox.unionWith(tmp); } } diff --git a/src/sp-defs.cpp b/src/sp-defs.cpp index dd779c0da..865c6891e 100644 --- a/src/sp-defs.cpp +++ b/src/sp-defs.cpp @@ -54,9 +54,9 @@ void SPDefs::modified(unsigned int flags) { flags &= SP_OBJECT_MODIFIED_CASCADE; GSList *l = NULL; - for ( SPObject *child = this->firstChild() ; child; child = child->getNext() ) { - sp_object_ref(child); - l = g_slist_prepend(l, child); + for (auto& child: children) { + sp_object_ref(&child); + l = g_slist_prepend(l, &child); } l = g_slist_reverse(l); @@ -79,8 +79,8 @@ Inkscape::XML::Node* SPDefs::write(Inkscape::XML::Document *xml_doc, Inkscape::X } GSList *l = NULL; - for ( SPObject *child = this->firstChild() ; child; child = child->getNext() ) { - Inkscape::XML::Node *crepr = child->updateRepr(xml_doc, NULL, flags); + for (auto& child: children) { + Inkscape::XML::Node *crepr = child.updateRepr(xml_doc, NULL, flags); if (crepr) { l = g_slist_prepend(l, crepr); } @@ -93,8 +93,8 @@ Inkscape::XML::Node* SPDefs::write(Inkscape::XML::Document *xml_doc, Inkscape::X } } else { - for ( SPObject *child = this->firstChild() ; child; child = child->getNext() ) { - child->updateRepr(flags); + for (auto& child: children) { + child.updateRepr(flags); } } diff --git a/src/sp-filter-primitive.cpp b/src/sp-filter-primitive.cpp index 2e6e06caf..0fbeed15b 100644 --- a/src/sp-filter-primitive.cpp +++ b/src/sp-filter-primitive.cpp @@ -242,8 +242,10 @@ int sp_filter_primitive_read_result(SPFilterPrimitive *prim, gchar const *name) */ int sp_filter_primitive_name_previous_out(SPFilterPrimitive *prim) { SPFilter *parent = SP_FILTER(prim->parent); - SPObject *i = parent->children; - while (i && i->next != prim) i = i->next; + SPObject *i = parent->firstChild(); + while (i && i->getNext() != prim) { + i = i->getNext(); + } if (i) { SPFilterPrimitive *i_prim = SP_FILTER_PRIMITIVE(i); if (i_prim->image_out < 0) { diff --git a/src/sp-filter.cpp b/src/sp-filter.cpp index 64a972ff4..26ea03c6c 100644 --- a/src/sp-filter.cpp +++ b/src/sp-filter.cpp @@ -264,8 +264,8 @@ Inkscape::XML::Node* SPFilter::write(Inkscape::XML::Document *doc, Inkscape::XML } GSList *l = NULL; - for ( SPObject *child = this->firstChild(); child; child = child->getNext() ) { - Inkscape::XML::Node *crepr = child->updateRepr(doc, NULL, flags); + for (auto& child: children) { + Inkscape::XML::Node *crepr = child.updateRepr(doc, NULL, flags); if (crepr) { l = g_slist_prepend (l, crepr); @@ -278,8 +278,8 @@ Inkscape::XML::Node* SPFilter::write(Inkscape::XML::Document *doc, Inkscape::XML l = g_slist_remove (l, l->data); } } else { - for ( SPObject *child = this->firstChild() ; child; child = child->getNext() ) { - child->updateRepr(flags); + for (auto& child: children) { + child.updateRepr(flags); } } @@ -416,10 +416,9 @@ void sp_filter_build_renderer(SPFilter *sp_filter, Inkscape::Filters::Filter *nr } nr_filter->clear_primitives(); - SPObject *primitive_obj = sp_filter->children; - while (primitive_obj) { - if (SP_IS_FILTER_PRIMITIVE(primitive_obj)) { - SPFilterPrimitive *primitive = SP_FILTER_PRIMITIVE(primitive_obj); + for(auto& primitive_obj: sp_filter->children) { + if (SP_IS_FILTER_PRIMITIVE(&primitive_obj)) { + SPFilterPrimitive *primitive = SP_FILTER_PRIMITIVE(&primitive_obj); g_assert(primitive != NULL); // if (((SPFilterPrimitiveClass*) G_OBJECT_GET_CLASS(primitive))->build_renderer) { @@ -429,7 +428,6 @@ void sp_filter_build_renderer(SPFilter *sp_filter, Inkscape::Filters::Filter *nr // } // CPPIFY: => FilterPrimitive should be abstract. primitive->build_renderer(nr_filter); } - primitive_obj = primitive_obj->next; } } @@ -437,11 +435,12 @@ int sp_filter_primitive_count(SPFilter *filter) { g_assert(filter != NULL); int count = 0; - SPObject *primitive_obj = filter->children; - while (primitive_obj) { - if (SP_IS_FILTER_PRIMITIVE(primitive_obj)) count++; - primitive_obj = primitive_obj->next; + for(auto& primitive_obj: filter->children) { + if (SP_IS_FILTER_PRIMITIVE(&primitive_obj)) { + count++; + } } + return count; } @@ -509,10 +508,9 @@ Glib::ustring sp_filter_get_new_result_name(SPFilter *filter) { g_assert(filter != NULL); int largest = 0; - SPObject *primitive_obj = filter->children; - while (primitive_obj) { - if (SP_IS_FILTER_PRIMITIVE(primitive_obj)) { - Inkscape::XML::Node *repr = primitive_obj->getRepr(); + for(auto& primitive_obj: filter->children) { + if (SP_IS_FILTER_PRIMITIVE(&primitive_obj)) { + Inkscape::XML::Node *repr = primitive_obj.getRepr(); char const *result = repr->attribute("result"); int index; if (result) @@ -526,7 +524,6 @@ Glib::ustring sp_filter_get_new_result_name(SPFilter *filter) { } } } - primitive_obj = primitive_obj->next; } return "result" + Glib::Ascii::dtostr(largest + 1); diff --git a/src/sp-flowdiv.cpp b/src/sp-flowdiv.cpp index 8d9c51ab8..17b841e37 100644 --- a/src/sp-flowdiv.cpp +++ b/src/sp-flowdiv.cpp @@ -27,9 +27,9 @@ void SPFlowdiv::update(SPCtx *ctx, unsigned int flags) { childflags &= SP_OBJECT_MODIFIED_CASCADE; GSList* l = NULL; - for (SPObject *child = this->firstChild() ; child ; child = child->getNext() ) { - sp_object_ref(child); - l = g_slist_prepend(l, child); + for (auto& child: children) { + sp_object_ref(&child); + l = g_slist_prepend(l, &child); } l = g_slist_reverse(l); @@ -65,9 +65,9 @@ void SPFlowdiv::modified(unsigned int flags) { flags &= SP_OBJECT_MODIFIED_CASCADE; GSList *l = NULL; - for ( SPObject *child = this->firstChild() ; child ; child = child->getNext() ) { - sp_object_ref(child); - l = g_slist_prepend(l, child); + for (auto& child: children) { + sp_object_ref(&child); + l = g_slist_prepend(l, &child); } l = g_slist_reverse (l); @@ -104,15 +104,15 @@ Inkscape::XML::Node* SPFlowdiv::write(Inkscape::XML::Document *xml_doc, Inkscape GSList *l = NULL; - for (SPObject* child = this->firstChild() ; child ; child = child->getNext() ) { + for (auto& child: children) { Inkscape::XML::Node* c_repr = NULL; - if ( SP_IS_FLOWTSPAN (child) ) { - c_repr = child->updateRepr(xml_doc, NULL, flags); - } else if ( SP_IS_FLOWPARA(child) ) { - c_repr = child->updateRepr(xml_doc, NULL, flags); - } else if ( SP_IS_STRING(child) ) { - c_repr = xml_doc->createTextNode(SP_STRING(child)->string.c_str()); + if ( SP_IS_FLOWTSPAN (&child) ) { + c_repr = child.updateRepr(xml_doc, NULL, flags); + } else if ( SP_IS_FLOWPARA(&child) ) { + c_repr = child.updateRepr(xml_doc, NULL, flags); + } else if ( SP_IS_STRING(&child) ) { + c_repr = xml_doc->createTextNode(SP_STRING(&child)->string.c_str()); } if ( c_repr ) { @@ -126,13 +126,13 @@ Inkscape::XML::Node* SPFlowdiv::write(Inkscape::XML::Document *xml_doc, Inkscape l = g_slist_remove(l, l->data); } } else { - for ( SPObject* child = this->firstChild() ; child ; child = child->getNext() ) { - if ( SP_IS_FLOWTSPAN (child) ) { - child->updateRepr(flags); - } else if ( SP_IS_FLOWPARA(child) ) { - child->updateRepr(flags); - } else if ( SP_IS_STRING(child) ) { - child->getRepr()->setContent(SP_STRING(child)->string.c_str()); + for (auto& child: children) { + if ( SP_IS_FLOWTSPAN (&child) ) { + child.updateRepr(flags); + } else if ( SP_IS_FLOWPARA(&child) ) { + child.updateRepr(flags); + } else if ( SP_IS_STRING(&child) ) { + child.getRepr()->setContent(SP_STRING(&child)->string.c_str()); } } } @@ -168,9 +168,9 @@ void SPFlowtspan::update(SPCtx *ctx, unsigned int flags) { childflags &= SP_OBJECT_MODIFIED_CASCADE; GSList* l = NULL; - for ( SPObject *child = this->firstChild() ; child ; child = child->getNext() ) { - sp_object_ref(child); - l = g_slist_prepend(l, child); + for (auto& child: children) { + sp_object_ref(&child); + l = g_slist_prepend(l, &child); } l = g_slist_reverse (l); @@ -206,9 +206,9 @@ void SPFlowtspan::modified(unsigned int flags) { flags &= SP_OBJECT_MODIFIED_CASCADE; GSList *l = NULL; - for ( SPObject *child = this->firstChild() ; child ; child = child->getNext() ) { - sp_object_ref(child); - l = g_slist_prepend(l, child); + for (auto& child: children) { + sp_object_ref(&child); + l = g_slist_prepend(l, &child); } l = g_slist_reverse (l); @@ -242,15 +242,15 @@ Inkscape::XML::Node *SPFlowtspan::write(Inkscape::XML::Document *xml_doc, Inksca GSList *l = NULL; - for ( SPObject* child = this->firstChild() ; child ; child = child->getNext() ) { + for (auto& child: children) { Inkscape::XML::Node* c_repr = NULL; - if ( SP_IS_FLOWTSPAN(child) ) { - c_repr = child->updateRepr(xml_doc, NULL, flags); - } else if ( SP_IS_FLOWPARA(child) ) { - c_repr = child->updateRepr(xml_doc, NULL, flags); - } else if ( SP_IS_STRING(child) ) { - c_repr = xml_doc->createTextNode(SP_STRING(child)->string.c_str()); + if ( SP_IS_FLOWTSPAN(&child) ) { + c_repr = child.updateRepr(xml_doc, NULL, flags); + } else if ( SP_IS_FLOWPARA(&child) ) { + c_repr = child.updateRepr(xml_doc, NULL, flags); + } else if ( SP_IS_STRING(&child) ) { + c_repr = xml_doc->createTextNode(SP_STRING(&child)->string.c_str()); } if ( c_repr ) { @@ -264,13 +264,13 @@ Inkscape::XML::Node *SPFlowtspan::write(Inkscape::XML::Document *xml_doc, Inksca l = g_slist_remove(l, l->data); } } else { - for ( SPObject* child = this->firstChild() ; child ; child = child->getNext() ) { - if ( SP_IS_FLOWTSPAN(child) ) { - child->updateRepr(flags); - } else if ( SP_IS_FLOWPARA(child) ) { - child->updateRepr(flags); - } else if ( SP_IS_STRING(child) ) { - child->getRepr()->setContent(SP_STRING(child)->string.c_str()); + for (auto& child: children) { + if ( SP_IS_FLOWTSPAN(&child) ) { + child.updateRepr(flags); + } else if ( SP_IS_FLOWPARA(&child) ) { + child.updateRepr(flags); + } else if ( SP_IS_STRING(&child) ) { + child.getRepr()->setContent(SP_STRING(&child)->string.c_str()); } } } @@ -307,9 +307,9 @@ void SPFlowpara::update(SPCtx *ctx, unsigned int flags) { flags &= SP_OBJECT_MODIFIED_CASCADE; GSList* l = NULL; - for ( SPObject *child = this->firstChild() ; child ; child = child->getNext() ) { - sp_object_ref(child); - l = g_slist_prepend(l, child); + for (auto& child: children) { + sp_object_ref(&child); + l = g_slist_prepend(l, &child); } l = g_slist_reverse (l); @@ -343,9 +343,9 @@ void SPFlowpara::modified(unsigned int flags) { flags &= SP_OBJECT_MODIFIED_CASCADE; GSList *l = NULL; - for ( SPObject *child = this->firstChild() ; child ; child = child->getNext() ) { - sp_object_ref(child); - l = g_slist_prepend(l, child); + for (auto& child: children) { + sp_object_ref(&child); + l = g_slist_prepend(l, &child); } l = g_slist_reverse (l); @@ -379,15 +379,15 @@ Inkscape::XML::Node *SPFlowpara::write(Inkscape::XML::Document *xml_doc, Inkscap GSList *l = NULL; - for ( SPObject* child = this->firstChild() ; child ; child = child->getNext() ) { + for (auto& child: children) { Inkscape::XML::Node* c_repr = NULL; - if ( SP_IS_FLOWTSPAN(child) ) { - c_repr = child->updateRepr(xml_doc, NULL, flags); - } else if ( SP_IS_FLOWPARA(child) ) { - c_repr = child->updateRepr(xml_doc, NULL, flags); - } else if ( SP_IS_STRING(child) ) { - c_repr = xml_doc->createTextNode(SP_STRING(child)->string.c_str()); + if ( SP_IS_FLOWTSPAN(&child) ) { + c_repr = child.updateRepr(xml_doc, NULL, flags); + } else if ( SP_IS_FLOWPARA(&child) ) { + c_repr = child.updateRepr(xml_doc, NULL, flags); + } else if ( SP_IS_STRING(&child) ) { + c_repr = xml_doc->createTextNode(SP_STRING(&child)->string.c_str()); } if ( c_repr ) { @@ -401,13 +401,13 @@ Inkscape::XML::Node *SPFlowpara::write(Inkscape::XML::Document *xml_doc, Inkscap l = g_slist_remove(l, l->data); } } else { - for ( SPObject* child = this->firstChild() ; child ; child = child->getNext() ) { - if ( SP_IS_FLOWTSPAN(child) ) { - child->updateRepr(flags); - } else if ( SP_IS_FLOWPARA(child) ) { - child->updateRepr(flags); - } else if ( SP_IS_STRING(child) ) { - child->getRepr()->setContent(SP_STRING(child)->string.c_str()); + for (auto& child: children) { + if ( SP_IS_FLOWTSPAN(&child) ) { + child.updateRepr(flags); + } else if ( SP_IS_FLOWPARA(&child) ) { + child.updateRepr(flags); + } else if ( SP_IS_STRING(&child) ) { + child.getRepr()->setContent(SP_STRING(&child)->string.c_str()); } } } diff --git a/src/sp-flowregion.cpp b/src/sp-flowregion.cpp index 3dc02c3ca..4064c12f1 100644 --- a/src/sp-flowregion.cpp +++ b/src/sp-flowregion.cpp @@ -61,9 +61,9 @@ void SPFlowregion::update(SPCtx *ctx, unsigned int flags) { GSList *l = NULL; - for ( SPObject *child = this->firstChild() ; child ; child = child->getNext() ) { - sp_object_ref(child); - l = g_slist_prepend(l, child); + for (auto& child: children) { + sp_object_ref(&child); + l = g_slist_prepend(l, &child); } l = g_slist_reverse(l); @@ -100,9 +100,9 @@ void SPFlowregion::UpdateComputed(void) } computed.clear(); - for (SPObject* child = firstChild() ; child ; child = child->getNext() ) { + for (auto& child: children) { Shape *shape = 0; - GetDest(child, &shape); + GetDest(&child, &shape); computed.push_back(shape); } } @@ -116,9 +116,9 @@ void SPFlowregion::modified(guint flags) { GSList *l = NULL; - for ( SPObject *child = this->firstChild() ; child ; child = child->getNext() ) { - sp_object_ref(child); - l = g_slist_prepend(l, child); + for (auto& child: children) { + sp_object_ref(&child); + l = g_slist_prepend(l, &child); } l = g_slist_reverse(l); @@ -143,9 +143,9 @@ Inkscape::XML::Node *SPFlowregion::write(Inkscape::XML::Document *xml_doc, Inksc } GSList *l = NULL; - for ( SPObject *child = this->firstChild() ; child; child = child->getNext() ) { - if ( !dynamic_cast<SPTitle *>(child) && !dynamic_cast<SPDesc *>(child) ) { - Inkscape::XML::Node *crepr = child->updateRepr(xml_doc, NULL, flags); + for (auto& child: children) { + if ( !dynamic_cast<SPTitle *>(&child) && !dynamic_cast<SPDesc *>(&child) ) { + Inkscape::XML::Node *crepr = child.updateRepr(xml_doc, NULL, flags); if (crepr) { l = g_slist_prepend(l, crepr); @@ -159,10 +159,9 @@ Inkscape::XML::Node *SPFlowregion::write(Inkscape::XML::Document *xml_doc, Inksc l = g_slist_remove(l, l->data); } - } else { - for ( SPObject *child = this->firstChild() ; child; child = child->getNext() ) { - if ( !dynamic_cast<SPTitle *>(child) && !dynamic_cast<SPDesc *>(child) ) { - child->updateRepr(flags); + for (auto& child: children) { + if ( !dynamic_cast<SPTitle *>(&child) && !dynamic_cast<SPDesc *>(&child) ) { + child.updateRepr(flags); } } } @@ -219,9 +218,9 @@ void SPFlowregionExclude::update(SPCtx *ctx, unsigned int flags) { GSList *l = NULL; - for ( SPObject *child = this->firstChild() ; child ; child = child->getNext() ) { - sp_object_ref(child); - l = g_slist_prepend(l, child); + for (auto& child: children) { + sp_object_ref(&child); + l = g_slist_prepend(l, &child); } l = g_slist_reverse (l); @@ -257,8 +256,8 @@ void SPFlowregionExclude::UpdateComputed(void) computed = NULL; } - for ( SPObject* child = firstChild() ; child ; child = child->getNext() ) { - GetDest(child, &computed); + for (auto& child: children) { + GetDest(&child, &computed); } } @@ -271,9 +270,9 @@ void SPFlowregionExclude::modified(guint flags) { GSList *l = NULL; - for ( SPObject *child = this->firstChild() ; child ; child = child->getNext() ) { - sp_object_ref(child); - l = g_slist_prepend(l, child); + for (auto& child: children) { + sp_object_ref(&child); + l = g_slist_prepend(l, &child); } l = g_slist_reverse (l); @@ -299,8 +298,8 @@ Inkscape::XML::Node *SPFlowregionExclude::write(Inkscape::XML::Document *xml_doc GSList *l = NULL; - for ( SPObject *child = this->firstChild() ; child; child = child->getNext() ) { - Inkscape::XML::Node *crepr = child->updateRepr(xml_doc, NULL, flags); + for (auto& child: children) { + Inkscape::XML::Node *crepr = child.updateRepr(xml_doc, NULL, flags); if (crepr) { l = g_slist_prepend(l, crepr); @@ -314,8 +313,8 @@ Inkscape::XML::Node *SPFlowregionExclude::write(Inkscape::XML::Document *xml_doc } } else { - for ( SPObject *child = this->firstChild() ; child; child = child->getNext() ) { - child->updateRepr(flags); + for (auto& child: children) { + child.updateRepr(flags); } } diff --git a/src/sp-flowtext.cpp b/src/sp-flowtext.cpp index d89de33bf..264558014 100644 --- a/src/sp-flowtext.cpp +++ b/src/sp-flowtext.cpp @@ -67,9 +67,9 @@ void SPFlowtext::update(SPCtx* ctx, unsigned int flags) { GSList *l = NULL; - for (SPObject *child = this->firstChild() ; child ; child = child->getNext() ) { - sp_object_ref(child); - l = g_slist_prepend(l, child); + for (auto& child: children) { + sp_object_ref(&child); + l = g_slist_prepend(l, &child); } l = g_slist_reverse(l); @@ -130,9 +130,9 @@ void SPFlowtext::modified(unsigned int flags) { } } - for ( SPObject *o = this->firstChild() ; o ; o = o->getNext() ) { - if (dynamic_cast<SPFlowregion *>(o)) { - region = o; + for (auto& o: children) { + if (dynamic_cast<SPFlowregion *>(&o)) { + region = &o; break; } } @@ -218,11 +218,11 @@ Inkscape::XML::Node* SPFlowtext::write(Inkscape::XML::Document* doc, Inkscape::X GSList *l = NULL; - for (SPObject *child = this->firstChild() ; child ; child = child->getNext() ) { + for (auto& child: children) { Inkscape::XML::Node *c_repr = NULL; - if ( dynamic_cast<SPFlowdiv *>(child) || dynamic_cast<SPFlowpara *>(child) || dynamic_cast<SPFlowregion *>(child) || dynamic_cast<SPFlowregionExclude *>(child)) { - c_repr = child->updateRepr(doc, NULL, flags); + if ( dynamic_cast<SPFlowdiv *>(&child) || dynamic_cast<SPFlowpara *>(&child) || dynamic_cast<SPFlowregion *>(&child) || dynamic_cast<SPFlowregionExclude *>(&child)) { + c_repr = child.updateRepr(doc, NULL, flags); } if ( c_repr ) { @@ -236,9 +236,9 @@ Inkscape::XML::Node* SPFlowtext::write(Inkscape::XML::Document* doc, Inkscape::X l = g_slist_remove(l, l->data); } } else { - for (SPObject *child = this->firstChild() ; child ; child = child->getNext() ) { - if ( dynamic_cast<SPFlowdiv *>(child) || dynamic_cast<SPFlowpara *>(child) || dynamic_cast<SPFlowregion *>(child) || dynamic_cast<SPFlowregionExclude *>(child)) { - child->updateRepr(flags); + for (auto& child: children) { + if ( dynamic_cast<SPFlowdiv *>(&child) || dynamic_cast<SPFlowpara *>(&child) || dynamic_cast<SPFlowregion *>(&child) || dynamic_cast<SPFlowregionExclude *>(&child)) { + child.updateRepr(flags); } } } @@ -385,8 +385,8 @@ void SPFlowtext::_buildLayoutInput(SPObject *root, Shape const *exclusion_shape, *pending_line_break_object = NULL; } - for (SPObject *child = root->firstChild() ; child ; child = child->getNext() ) { - SPString *str = dynamic_cast<SPString *>(child); + for (auto& child: root->children) { + SPString *str = dynamic_cast<SPString *>(&child); if (str) { if (*pending_line_break_object) { if (dynamic_cast<SPFlowregionbreak *>(*pending_line_break_object)) @@ -397,12 +397,12 @@ void SPFlowtext::_buildLayoutInput(SPObject *root, Shape const *exclusion_shape, *pending_line_break_object = NULL; } if (with_indent) { - layout.appendText(str->string, root->style, child, &pi); + layout.appendText(str->string, root->style, &child, &pi); } else { - layout.appendText(str->string, root->style, child); + layout.appendText(str->string, root->style, &child); } } else { - SPFlowregion *region = dynamic_cast<SPFlowregion *>(child); + SPFlowregion *region = dynamic_cast<SPFlowregion *>(&child); if (region) { std::vector<Shape*> const &computed = region->computed; for (std::vector<Shape*>::const_iterator it = computed.begin() ; it != computed.end() ; ++it) { @@ -416,8 +416,8 @@ void SPFlowtext::_buildLayoutInput(SPObject *root, Shape const *exclusion_shape, } } //Xml Tree is being directly used while it shouldn't be. - else if (!dynamic_cast<SPFlowregionExclude *>(child) && !sp_repr_is_meta_element(child->getRepr())) { - _buildLayoutInput(child, exclusion_shape, shapes, pending_line_break_object); + else if (!dynamic_cast<SPFlowregionExclude *>(&child) && !sp_repr_is_meta_element(child.getRepr())) { + _buildLayoutInput(&child, exclusion_shape, shapes, pending_line_break_object); } } } @@ -435,9 +435,9 @@ Shape* SPFlowtext::_buildExclusionShape() const Shape *shape = new Shape(); Shape *shape_temp = new Shape(); - for (SPObject *child = children ; child ; child = child->getNext() ) { + for (auto& child: children) { // RH: is it right that this shouldn't be recursive? - SPFlowregionExclude *c_child = dynamic_cast<SPFlowregionExclude *>(child); + SPFlowregionExclude *c_child = dynamic_cast<SPFlowregionExclude *>(const_cast<SPObject*>(&child)); if ( c_child && c_child->computed && c_child->computed->hasEdges() ) { if (shape->hasEdges()) { shape_temp->Booleen(shape, c_child->computed, bool_op_union); @@ -588,9 +588,9 @@ SPItem *SPFlowtext::get_frame(SPItem const *after) SPItem *frame = 0; SPObject *region = 0; - for (SPObject *o = firstChild() ; o ; o = o->getNext() ) { - if (dynamic_cast<SPFlowregion *>(o)) { - region = o; + for (auto& o: children) { + if (dynamic_cast<SPFlowregion *>(&o)) { + region = &o; break; } } @@ -598,8 +598,8 @@ SPItem *SPFlowtext::get_frame(SPItem const *after) if (region) { bool past = false; - for (SPObject *o = region->firstChild() ; o ; o = o->getNext() ) { - SPItem *item = dynamic_cast<SPItem *>(o); + for (auto& o: region->children) { + SPItem *item = dynamic_cast<SPItem *>(&o); if (item) { if ( (after == NULL) || past ) { frame = item; @@ -702,9 +702,9 @@ Geom::Affine SPFlowtext::set_transform (Geom::Affine const &xform) } SPObject *region = NULL; - for ( SPObject *o = this->firstChild() ; o ; o = o->getNext() ) { - if (dynamic_cast<SPFlowregion *>(o)) { - region = o; + for (auto& o: children) { + if (dynamic_cast<SPFlowregion *>(&o)) { + region = &o; break; } } diff --git a/src/sp-flowtext.h b/src/sp-flowtext.h index 9ee676893..d0b0a19a4 100644 --- a/src/sp-flowtext.h +++ b/src/sp-flowtext.h @@ -8,6 +8,7 @@ #include "libnrtype/Layout-TNG.h" #include "sp-item.h" +#include "desktop.h" #define SP_FLOWTEXT(obj) (dynamic_cast<SPFlowtext*>((SPObject*)obj)) #define SP_IS_FLOWTEXT(obj) (dynamic_cast<const SPFlowtext*>((SPObject*)obj) != NULL) diff --git a/src/sp-gradient.cpp b/src/sp-gradient.cpp index 49143bda4..f24e25ab1 100644 --- a/src/sp-gradient.cpp +++ b/src/sp-gradient.cpp @@ -269,8 +269,8 @@ void SPGradient::build(SPDocument *document, Inkscape::XML::Node *repr) SPPaintServer::build(document, repr); - for ( SPObject *ochild = this->firstChild() ; ochild ; ochild = ochild->getNext() ) { - if (SP_IS_STOP(ochild)) { + for (auto& ochild: children) { + if (SP_IS_STOP(&ochild)) { this->has_stops = TRUE; break; } @@ -474,8 +474,8 @@ void SPGradient::remove_child(Inkscape::XML::Node *child) SPPaintServer::remove_child(child); this->has_stops = FALSE; - for ( SPObject *ochild = this->firstChild() ; ochild ; ochild = ochild->getNext() ) { - if (SP_IS_STOP(ochild)) { + for (auto& ochild: children) { + if (SP_IS_STOP(&ochild)) { this->has_stops = TRUE; break; } @@ -529,9 +529,9 @@ void SPGradient::modified(guint flags) // FIXME: climb up the ladder of hrefs GSList *l = NULL; - for (SPObject *child = this->firstChild() ; child; child = child->getNext() ) { - sp_object_ref(child); - l = g_slist_prepend(l, child); + for (auto& child: children) { + sp_object_ref(&child); + l = g_slist_prepend(l, &child); } l = g_slist_reverse(l); @@ -550,10 +550,11 @@ void SPGradient::modified(guint flags) SPStop* SPGradient::getFirstStop() { - SPStop* first = 0; - for (SPObject *ochild = firstChild(); ochild && !first; ochild = ochild->getNext()) { - if (SP_IS_STOP(ochild)) { - first = SP_STOP(ochild); + SPStop* first = nullptr; + for (auto& ochild: children) { + if (SP_IS_STOP(&ochild)) { + first = SP_STOP(&ochild); + break; } } return first; @@ -580,8 +581,8 @@ Inkscape::XML::Node *SPGradient::write(Inkscape::XML::Document *xml_doc, Inkscap if (flags & SP_OBJECT_WRITE_BUILD) { GSList *l = NULL; - for (SPObject *child = this->firstChild(); child; child = child->getNext()) { - Inkscape::XML::Node *crepr = child->updateRepr(xml_doc, NULL, flags); + for (auto& child: children) { + Inkscape::XML::Node *crepr = child.updateRepr(xml_doc, NULL, flags); if (crepr) { l = g_slist_prepend(l, crepr); @@ -908,8 +909,8 @@ bool SPGradient::invalidateArray() void SPGradient::rebuildVector() { gint len = 0; - for ( SPObject *child = firstChild() ; child ; child = child->getNext() ) { - if (SP_IS_STOP(child)) { + for (auto& child: children) { + if (SP_IS_STOP(&child)) { len ++; } } @@ -930,9 +931,9 @@ void SPGradient::rebuildVector() } } - for ( SPObject *child = firstChild(); child; child = child->getNext() ) { - if (SP_IS_STOP(child)) { - SPStop *stop = SP_STOP(child); + for (auto& child: children) { + if (SP_IS_STOP(&child)) { + SPStop *stop = SP_STOP(&child); SPGradientStop gstop; if (!vector.stops.empty()) { @@ -1015,8 +1016,8 @@ void SPGradient::rebuildArray() array.read( SP_MESH( this ) ); has_patches = false; - for ( SPObject *ro = firstChild() ; ro ; ro = ro->getNext() ) { - if (SP_IS_MESHROW(ro)) { + for (auto& ro: children) { + if (SP_IS_MESHROW(&ro)) { has_patches = true; // std::cout << " Has Patches" << std::endl; break; diff --git a/src/sp-hatch.cpp b/src/sp-hatch.cpp index a17a555b8..02d95c75c 100644 --- a/src/sp-hatch.cpp +++ b/src/sp-hatch.cpp @@ -230,14 +230,13 @@ void SPHatch::set(unsigned int key, const gchar* value) bool SPHatch::_hasHatchPatchChildren(SPHatch const *hatch) { - bool matched = false; - for (SPObject const *child = hatch->firstChild(); child && !matched; child = child->getNext() ) { - SPHatchPath const *hatchPath = dynamic_cast<SPHatchPath const *>(child); + for (auto& child: hatch->children) { + SPHatchPath const *hatchPath = dynamic_cast<SPHatchPath const *>(&child); if (hatchPath) { - matched = true; + return true; } } - return matched; + return false; } std::vector<SPHatchPath*> SPHatch::hatchPaths() @@ -246,8 +245,8 @@ std::vector<SPHatchPath*> SPHatch::hatchPaths() SPHatch *src = chase_hrefs<SPHatch>(this, sigc::ptr_fun(&_hasHatchPatchChildren)); if (src) { - for (SPObject *child = src->firstChild(); child; child = child->getNext()) { - SPHatchPath *hatchPath = dynamic_cast<SPHatchPath *>(child); + for (auto& child: src->children) { + SPHatchPath *hatchPath = dynamic_cast<SPHatchPath *>(&child); if (hatchPath) { list.push_back(hatchPath); } @@ -262,8 +261,8 @@ std::vector<SPHatchPath const*> SPHatch::hatchPaths() const SPHatch const *src = chase_hrefs<SPHatch const>(this, sigc::ptr_fun(&_hasHatchPatchChildren)); if (src) { - for (SPObject const *child = src->firstChild(); child; child = child->getNext()) { - SPHatchPath const *hatchPath = dynamic_cast<SPHatchPath const*>(child); + for (auto& child: src->children) { + SPHatchPath const *hatchPath = dynamic_cast<SPHatchPath const*>(&child); if (hatchPath) { list.push_back(hatchPath); } diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp index f5c8f348e..097026057 100644 --- a/src/sp-item-group.cpp +++ b/src/sp-item-group.cpp @@ -230,9 +230,9 @@ Inkscape::XML::Node* SPGroup::write(Inkscape::XML::Document *xml_doc, Inkscape:: l = NULL; - for (SPObject *child = firstChild(); child; child = child->getNext() ) { - if ( !dynamic_cast<SPTitle *>(child) && !dynamic_cast<SPDesc *>(child) ) { - Inkscape::XML::Node *crepr = child->updateRepr(xml_doc, NULL, flags); + for (auto& child: children) { + if ( !dynamic_cast<SPTitle *>(&child) && !dynamic_cast<SPDesc *>(&child) ) { + Inkscape::XML::Node *crepr = child.updateRepr(xml_doc, NULL, flags); if (crepr) { l = g_slist_prepend (l, crepr); @@ -246,9 +246,9 @@ Inkscape::XML::Node* SPGroup::write(Inkscape::XML::Document *xml_doc, Inkscape:: l = g_slist_remove (l, l->data); } } else { - for (SPObject *child = firstChild() ; child ; child = child->getNext() ) { - if ( !dynamic_cast<SPTitle *>(child) && !dynamic_cast<SPDesc *>(child) ) { - child->updateRepr(flags); + for (auto& child: children) { + if ( !dynamic_cast<SPTitle *>(&child) && !dynamic_cast<SPDesc *>(&child) ) { + child.updateRepr(flags); } } } @@ -292,9 +292,8 @@ Geom::OptRect SPGroup::bbox(Geom::Affine const &transform, SPItem::BBoxType bbox } void SPGroup::print(SPPrintContext *ctx) { - std::vector<SPObject*> l=this->childList(false); - for(std::vector<SPObject*>::const_iterator i=l.begin();i!=l.end();++i){ - SPObject *o = *i; + for(auto& child: children){ + SPObject *o = &child; SPItem *item = dynamic_cast<SPItem *>(o); if (item) { item->invoke_print(ctx); @@ -361,9 +360,9 @@ void SPGroup::hide (unsigned int key) { void SPGroup::snappoints(std::vector<Inkscape::SnapCandidatePoint> &p, Inkscape::SnapPreferences const *snapprefs) const { - for ( SPObject const *o = this->firstChild(); o; o = o->getNext() ) + for (auto& o: children) { - SPItem const *item = dynamic_cast<SPItem const *>(o); + SPItem const *item = dynamic_cast<SPItem const *>(&o); if (item) { item->getSnappoints(p, snapprefs); } @@ -507,20 +506,21 @@ sp_item_group_ungroup (SPGroup *group, std::vector<SPItem*> &children, bool do_d GSList *objects = NULL; Geom::Affine const g(group->transform); - for (SPObject *child = group->firstChild() ; child; child = child->getNext() ) - if (SPItem *citem = dynamic_cast<SPItem *>(child)) - sp_item_group_ungroup_handle_clones(citem,g); - + for (auto& child: group->children) { + if (SPItem *citem = dynamic_cast<SPItem *>(&child)) { + sp_item_group_ungroup_handle_clones(citem, g); + } + } - for (SPObject *child = group->firstChild() ; child; child = child->getNext() ) { - SPItem *citem = dynamic_cast<SPItem *>(child); + for (auto& child: group->children) { + SPItem *citem = dynamic_cast<SPItem *>(&child); if (citem) { /* Merging of style */ // this converts the gradient/pattern fill/stroke, if any, to userSpaceOnUse; we need to do // it here _before_ the new transform is set, so as to use the pre-transform bbox citem->adjust_paint_recursive (Geom::identity(), Geom::identity(), false); - child->style->merge( group->style ); + child.style->merge( group->style ); /* * fixme: We currently make no allowance for the case where child is cloned * and the group has any style settings. @@ -542,9 +542,9 @@ sp_item_group_ungroup (SPGroup *group, std::vector<SPItem*> &children, bool do_d * extra complication & maintenance burden and this case is rare. */ - child->updateRepr(); + child.updateRepr(); - Inkscape::XML::Node *nrepr = child->getRepr()->duplicate(prepr->document()); + Inkscape::XML::Node *nrepr = child.getRepr()->duplicate(prepr->document()); // Merging transform Geom::Affine ctrans = citem->transform * g; @@ -578,7 +578,7 @@ sp_item_group_ungroup (SPGroup *group, std::vector<SPItem*> &children, bool do_d if (text) { //this causes a change in text-on-path appearance when there is a non-conformal transform, see bug #1594565 double scale = (ctrans.expansionX() + ctrans.expansionY()) / 2.0; - SPTextPath * text_path = dynamic_cast<SPTextPath *>(text->children); + SPTextPath * text_path = dynamic_cast<SPTextPath *>(text->firstChild()); if (!text_path) { nrepr->setAttribute("transform", affinestr); } else { @@ -595,7 +595,7 @@ sp_item_group_ungroup (SPGroup *group, std::vector<SPItem*> &children, bool do_d items = g_slist_prepend (items, nrepr); } else { - Inkscape::XML::Node *nrepr = child->getRepr()->duplicate(prepr->document()); + Inkscape::XML::Node *nrepr = child.getRepr()->duplicate(prepr->document()); objects = g_slist_prepend (objects, nrepr); } } @@ -657,9 +657,9 @@ std::vector<SPItem*> sp_item_group_item_list(SPGroup * group) std::vector<SPItem*> s; g_return_val_if_fail(group != NULL, s); - for (SPObject *o = group->firstChild() ; o ; o = o->getNext() ) { - if ( dynamic_cast<SPItem *>(o) ) { - s.push_back((SPItem*)o); + for (auto& o: group->children) { + if ( dynamic_cast<SPItem *>(&o) ) { + s.push_back((SPItem*)&o); } } return s; @@ -730,8 +730,8 @@ void SPGroup::_updateLayerMode(unsigned int display_key) { void SPGroup::translateChildItems(Geom::Translate const &tr) { if ( hasChildren() ) { - for (SPObject *o = firstChild() ; o ; o = o->getNext() ) { - SPItem *item = dynamic_cast<SPItem *>(o); + for (auto& o: children) { + SPItem *item = dynamic_cast<SPItem *>(&o); if ( item ) { sp_item_move_rel(item, tr); } @@ -743,14 +743,14 @@ void SPGroup::translateChildItems(Geom::Translate const &tr) void SPGroup::scaleChildItemsRec(Geom::Scale const &sc, Geom::Point const &p, bool noRecurse) { if ( hasChildren() ) { - for (SPObject *o = firstChild() ; o ; o = o->getNext() ) { - if ( SPDefs *defs = dynamic_cast<SPDefs *>(o) ) { // select symbols from defs, ignore clips, masks, patterns - for (SPObject *defschild = defs->firstChild() ; defschild ; defschild = defschild->getNext() ) { - SPGroup *defsgroup = dynamic_cast<SPGroup *>(defschild); + for (auto& o: children) { + if ( SPDefs *defs = dynamic_cast<SPDefs *>(&o) ) { // select symbols from defs, ignore clips, masks, patterns + for (auto& defschild: defs->children) { + SPGroup *defsgroup = dynamic_cast<SPGroup *>(&defschild); if (defsgroup) defsgroup->scaleChildItemsRec(sc, p, false); } - } else if ( SPItem *item = dynamic_cast<SPItem *>(o) ) { + } else if ( SPItem *item = dynamic_cast<SPItem *>(&o) ) { SPGroup *group = dynamic_cast<SPGroup *>(item); if (group && !dynamic_cast<SPBox3D *>(item)) { /* Using recursion breaks clipping because transforms are applied @@ -866,8 +866,8 @@ void SPGroup::scaleChildItemsRec(Geom::Scale const &sc, Geom::Point const &p, bo gint SPGroup::getItemCount() const { gint len = 0; - for (SPObject const *o = this->firstChild() ; o ; o = o->getNext() ) { - if (dynamic_cast<SPItem const *>(o)) { + for (auto& child: children) { + if (dynamic_cast<SPItem const *>(&child)) { len++; } } diff --git a/src/sp-item.cpp b/src/sp-item.cpp index 01cb2d09f..0ba74f9fd 100644 --- a/src/sp-item.cpp +++ b/src/sp-item.cpp @@ -298,50 +298,35 @@ bool is_item(SPObject const &object) { void SPItem::raiseToTop() { using Inkscape::Algorithms::find_last_if; - SPObject *topmost=find_last_if<SPObject::SiblingIterator>( - next, NULL, &is_item - ); - if (topmost) { + auto topmost = find_last_if(++parent->children.iterator_to(*this), parent->children.end(), &is_item); + if (topmost != parent->children.end()) { getRepr()->parent()->changeOrder( getRepr(), topmost->getRepr() ); } } void SPItem::raiseOne() { - SPObject *next_higher=std::find_if<SPObject::SiblingIterator>( - next, NULL, &is_item - ); - if (next_higher) { + auto next_higher = std::find_if(++parent->children.iterator_to(*this), parent->children.end(), &is_item); + if (next_higher != parent->children.end()) { Inkscape::XML::Node *ref = next_higher->getRepr(); getRepr()->parent()->changeOrder(getRepr(), ref); } } void SPItem::lowerOne() { - using Inkscape::Util::MutableList; - using Inkscape::Util::reverse_list; - - MutableList<SPObject &> next_lower=std::find_if( - reverse_list<SPObject::SiblingIterator>( - parent->firstChild(), this - ), - MutableList<SPObject &>(), - &is_item - ); - if (next_lower) { - ++next_lower; - Inkscape::XML::Node *ref = ( next_lower ? next_lower->getRepr() : NULL ); + using Inkscape::Algorithms::find_last_if; + + auto next_lower = find_last_if(parent->children.begin(), parent->children.iterator_to(*this), &is_item); + if (next_lower != parent->children.iterator_to(*this)) { + next_lower--; + Inkscape::XML::Node *ref = next_lower->getRepr(); getRepr()->parent()->changeOrder(getRepr(), ref); } } void SPItem::lowerToBottom() { - using Inkscape::Algorithms::find_last_if; - using Inkscape::Util::MutableList; - using Inkscape::Util::reverse_list; - - SPObject * bottom=parent->firstChild(); - while(dynamic_cast<SPObject*>(bottom) && dynamic_cast<SPObject*>(bottom->next) && bottom!=this && !is_item(*(bottom->next))) bottom=bottom->next; - if (bottom && bottom != this) { + auto bottom = std::find_if(parent->children.begin(), parent->children.iterator_to(*this), &is_item); + if (bottom != parent->children.iterator_to(*this)) { + bottom--; Inkscape::XML::Node *ref = bottom->getRepr() ; parent->getRepr()->changeOrder(getRepr(), ref); } @@ -356,8 +341,8 @@ void SPItem::moveTo(SPItem *target, bool intoafter) { // Assume move to the "first" in the top node, find the top node intoafter = false; SPObject* bottom = this->document->getObjectByRepr(our_ref->root())->firstChild(); - while(!dynamic_cast<SPItem*>(bottom->next)){ - bottom=bottom->next; + while(!dynamic_cast<SPItem*>(bottom->getNext())){ + bottom = bottom->getNext(); } target_ref = bottom->getRepr(); } @@ -710,9 +695,9 @@ Inkscape::XML::Node* SPItem::write(Inkscape::XML::Document *xml_doc, Inkscape::X // so we need to add any children from the underlying object to the new repr if (flags & SP_OBJECT_WRITE_BUILD) { GSList *l = NULL; - for (SPObject *child = object->firstChild(); child != NULL; child = child->next ) { - if (dynamic_cast<SPTitle *>(child) || dynamic_cast<SPDesc *>(child)) { - Inkscape::XML::Node *crepr = child->updateRepr(xml_doc, NULL, flags); + for (auto& child: object->children) { + if (dynamic_cast<SPTitle *>(&child) || dynamic_cast<SPDesc *>(&child)) { + Inkscape::XML::Node *crepr = child.updateRepr(xml_doc, NULL, flags); if (crepr) { l = g_slist_prepend (l, crepr); } @@ -724,9 +709,9 @@ Inkscape::XML::Node* SPItem::write(Inkscape::XML::Document *xml_doc, Inkscape::X l = g_slist_remove (l, l->data); } } else { - for (SPObject *child = object->firstChild() ; child != NULL; child = child->next ) { - if (dynamic_cast<SPTitle *>(child) || dynamic_cast<SPDesc *>(child)) { - child->updateRepr(flags); + for (auto& child: object->children) { + if (dynamic_cast<SPTitle *>(&child) || dynamic_cast<SPDesc *>(&child)) { + child.updateRepr(flags); } } } @@ -933,12 +918,12 @@ unsigned int SPItem::pos_in_parent() const { unsigned int pos = 0; - for ( SPObject *iter = parent->firstChild() ; iter ; iter = iter->next) { - if (iter == this) { + for (auto& iter: parent->children) { + if (&iter == this) { return pos; } - if (dynamic_cast<SPItem *>(iter)) { + if (dynamic_cast<SPItem *>(&iter)) { pos++; } } @@ -979,8 +964,8 @@ void SPItem::getSnappoints(std::vector<Inkscape::SnapCandidatePoint> &p, Inkscap for (std::list<SPObject const *>::const_iterator o = clips_and_masks.begin(); o != clips_and_masks.end(); ++o) { if (*o) { // obj is a group object, the children are the actual clippers - for (SPObject *child = (*o)->children ; child ; child = child->next) { - SPItem *item = dynamic_cast<SPItem *>(child); + for(auto& child: (*o)->children) { + SPItem *item = dynamic_cast<SPItem *>(const_cast<SPObject*>(&child)); if (item) { std::vector<Inkscape::SnapCandidatePoint> p_clip_or_mask; // Please note the recursive call here! @@ -1307,8 +1292,8 @@ void SPItem::adjust_stroke_width_recursive(double expansion) // A clone's child is the ghost of its original - we must not touch it, skip recursion if ( !dynamic_cast<SPUse *>(this) ) { - for ( SPObject *o = children; o; o = o->getNext() ) { - SPItem *item = dynamic_cast<SPItem *>(o); + for (auto& o: children) { + SPItem *item = dynamic_cast<SPItem *>(&o); if (item) { item->adjust_stroke_width_recursive(expansion); } @@ -1322,8 +1307,8 @@ void SPItem::freeze_stroke_width_recursive(bool freeze) // A clone's child is the ghost of its original - we must not touch it, skip recursion if ( !dynamic_cast<SPUse *>(this) ) { - for ( SPObject *o = children; o; o = o->getNext() ) { - SPItem *item = dynamic_cast<SPItem *>(o); + for (auto& o: children) { + SPItem *item = dynamic_cast<SPItem *>(&o); if (item) { item->freeze_stroke_width_recursive(freeze); } @@ -1342,10 +1327,10 @@ sp_item_adjust_rects_recursive(SPItem *item, Geom::Affine advertized_transform) rect->compensateRxRy(advertized_transform); } - for (SPObject *o = item->children; o != NULL; o = o->next) { - SPItem *item = dynamic_cast<SPItem *>(o); - if (item) { - sp_item_adjust_rects_recursive(item, advertized_transform); + for(auto& o: item->children) { + SPItem *itm = dynamic_cast<SPItem *>(&o); + if (itm) { + sp_item_adjust_rects_recursive(itm, advertized_transform); } } } @@ -1362,8 +1347,8 @@ void SPItem::adjust_paint_recursive (Geom::Affine advertized_transform, Geom::Af // also we do not recurse into clones, because a clone's child is the ghost of its original - // we must not touch it if (!(this && (dynamic_cast<SPText *>(this) || dynamic_cast<SPUse *>(this)))) { - for (SPObject *o = children; o != NULL; o = o->next) { - SPItem *item = dynamic_cast<SPItem *>(o); + for (auto& o: children) { + SPItem *item = dynamic_cast<SPItem *>(&o); if (item) { // At the level of the transformed item, t_ancestors is identity; // below it, it is the accmmulated chain of transforms from this level to the top level @@ -1671,8 +1656,8 @@ SPItem const *sp_item_first_item_child(SPObject const *obj) SPItem *sp_item_first_item_child(SPObject *obj) { SPItem *child = 0; - for ( SPObject *iter = obj->firstChild() ; iter ; iter = iter->next ) { - SPItem *tmp = dynamic_cast<SPItem *>(iter); + for (auto& iter: obj->children) { + SPItem *tmp = dynamic_cast<SPItem *>(&iter); if ( tmp ) { child = tmp; break; diff --git a/src/sp-mask.cpp b/src/sp-mask.cpp index e860206a2..4690ffda2 100644 --- a/src/sp-mask.cpp +++ b/src/sp-mask.cpp @@ -137,12 +137,8 @@ void SPMask::update(SPCtx* ctx, unsigned int flags) { flags &= SP_OBJECT_MODIFIED_CASCADE; - std::vector<SPObject *> children = this->childList(false); - for (std::vector<SPObject *>::const_iterator child = children.begin();child != children.end();++child) { - sp_object_ref(*child); - } - - + std::vector<SPObject *> children = this->childList(true); + for (std::vector<SPObject *>::const_iterator child = children.begin();child != children.end();++child) { if (flags || ((*child)->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { (*child)->updateDisplay(ctx, flags); @@ -171,11 +167,8 @@ void SPMask::modified(unsigned int flags) { flags &= SP_OBJECT_MODIFIED_CASCADE; - std::vector<SPObject *> children = this->childList(false); - for (std::vector<SPObject *>::const_iterator child = children.begin();child != children.end();++child) { - sp_object_ref(*child); - } - + std::vector<SPObject *> children = this->childList(true); + for (std::vector<SPObject *>::const_iterator child = children.begin();child != children.end();++child) { if (flags || ((*child)->mflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { (*child)->emitModified(flags); @@ -233,9 +226,9 @@ Inkscape::DrawingItem *SPMask::sp_mask_show(Inkscape::Drawing &drawing, unsigned Inkscape::DrawingGroup *ai = new Inkscape::DrawingGroup(drawing); this->display = sp_mask_view_new_prepend (this->display, key, ai); - for ( SPObject *child = this->firstChild() ; child; child = child->getNext() ) { - if (SP_IS_ITEM (child)) { - Inkscape::DrawingItem *ac = SP_ITEM (child)->invoke_show (drawing, key, SP_ITEM_REFERENCE_FLAGS); + for (auto& child: children) { + if (SP_IS_ITEM (&child)) { + Inkscape::DrawingItem *ac = SP_ITEM (&child)->invoke_show (drawing, key, SP_ITEM_REFERENCE_FLAGS); if (ac) { ai->prependChild(ac); @@ -256,9 +249,9 @@ void SPMask::sp_mask_hide(unsigned int key) { g_return_if_fail (this != NULL); g_return_if_fail (SP_IS_MASK (this)); - for ( SPObject *child = this->firstChild(); child; child = child->getNext()) { - if (SP_IS_ITEM (child)) { - SP_ITEM(child)->invoke_hide (key); + for (auto& child: children) { + if (SP_IS_ITEM (&child)) { + SP_ITEM(&child)->invoke_hide (key); } } diff --git a/src/sp-mesh-array.cpp b/src/sp-mesh-array.cpp index 355150893..6bd5c85d7 100644 --- a/src/sp-mesh-array.cpp +++ b/src/sp-mesh-array.cpp @@ -632,16 +632,16 @@ void SPMeshNodeArray::read( SPMesh *mg_in ) { guint max_column = 0; guint irow = 0; // Corresponds to top of patch being read in. - for ( SPObject *ro = mg->firstChild() ; ro ; ro = ro->getNext() ) { + for (auto& ro: mg->children) { - if (SP_IS_MESHROW(ro)) { + if (SP_IS_MESHROW(&ro)) { guint icolumn = 0; // Corresponds to left of patch being read in. - for ( SPObject *po = ro->firstChild() ; po ; po = po->getNext() ) { + for (auto& po: ro.children) { - if (SP_IS_MESHPATCH(po)) { + if (SP_IS_MESHPATCH(&po)) { - SPMeshpatch *patch = SP_MESHPATCH(po); + SPMeshpatch *patch = SP_MESHPATCH(&po); // std::cout << "SPMeshNodeArray::read: row size: " << nodes.size() << std::endl; SPMeshPatchI new_patch( &nodes, irow, icolumn ); // Adds new nodes. @@ -652,15 +652,15 @@ void SPMeshNodeArray::read( SPMesh *mg_in ) { // Only 'top' side defined for first row. if( irow != 0 ) ++istop; - for ( SPObject *so = po->firstChild() ; so ; so = so->getNext() ) { - if (SP_IS_STOP(so)) { + for (auto& so: po.children) { + if (SP_IS_STOP(&so)) { if( istop > 3 ) { // std::cout << " Mesh Gradient: Too many stops: " << istop << std::endl; break; } - SPStop *stop = SP_STOP(so); + SPStop *stop = SP_STOP(&so); // Handle top of first row. if( istop == 0 && icolumn == 0 ) { @@ -848,15 +848,15 @@ void SPMeshNodeArray::write( SPMesh *mg ) { // First we must delete reprs for old mesh rows and patches. GSList *descendant_reprs = NULL; GSList *descendant_objects = NULL; - for ( SPObject *row = mg->firstChild(); row; row = row->getNext() ) { - descendant_reprs = g_slist_prepend (descendant_reprs, row->getRepr()); - descendant_objects = g_slist_prepend (descendant_objects, row ); - for ( SPObject *patch = row->firstChild(); patch; patch = patch->getNext() ) { - descendant_reprs = g_slist_prepend (descendant_reprs, patch->getRepr()); - descendant_objects = g_slist_prepend (descendant_objects, patch ); - for ( SPObject *stop = patch->firstChild(); stop; stop = stop->getNext() ) { - descendant_reprs = g_slist_prepend (descendant_reprs, stop->getRepr()); - descendant_objects = g_slist_prepend (descendant_objects, stop ); + for (auto& row: mg->children) { + descendant_reprs = g_slist_prepend (descendant_reprs, row.getRepr()); + descendant_objects = g_slist_prepend (descendant_objects, &row); + for (auto& patch: row.children) { + descendant_reprs = g_slist_prepend (descendant_reprs, patch.getRepr()); + descendant_objects = g_slist_prepend (descendant_objects, &patch); + for (auto& stop: patch.children) { + descendant_reprs = g_slist_prepend (descendant_reprs, stop.getRepr()); + descendant_objects = g_slist_prepend (descendant_objects, &stop); } } } diff --git a/src/sp-namedview.cpp b/src/sp-namedview.cpp index 45e3d4cf8..b9526433f 100644 --- a/src/sp-namedview.cpp +++ b/src/sp-namedview.cpp @@ -246,9 +246,9 @@ void SPNamedView::build(SPDocument *document, Inkscape::XML::Node *repr) { this->readAttr( "inkscape:lockguides" ); /* Construct guideline list */ - for (SPObject *o = this->firstChild() ; o; o = o->getNext() ) { - if (SP_IS_GUIDE(o)) { - SPGuide * g = SP_GUIDE(o); + for (auto& o: children) { + if (SP_IS_GUIDE(&o)) { + SPGuide * g = SP_GUIDE(&o); this->guides.push_back(g); //g_object_set(G_OBJECT(g), "color", nv->guidecolor, "hicolor", nv->guidehicolor, NULL); g->setColor(this->guidecolor); @@ -856,9 +856,9 @@ void sp_namedview_update_layers_from_document (SPDesktop *desktop) } // if that didn't work out, look for the topmost layer if (!layer) { - for ( SPObject *iter = document->getRoot()->firstChild(); iter ; iter = iter->getNext() ) { - if (desktop->isLayer(iter)) { - layer = iter; + for (auto& iter: document->getRoot()->children) { + if (desktop->isLayer(&iter)) { + layer = &iter; } } } diff --git a/src/sp-object-group.cpp b/src/sp-object-group.cpp index c3967461e..62c6f7a87 100644 --- a/src/sp-object-group.cpp +++ b/src/sp-object-group.cpp @@ -50,8 +50,8 @@ Inkscape::XML::Node *SPObjectGroup::write(Inkscape::XML::Document *xml_doc, Inks } GSList *l = 0; - for ( SPObject *child = this->firstChild() ; child ; child = child->getNext() ) { - Inkscape::XML::Node *crepr = child->updateRepr(xml_doc, NULL, flags); + for (auto& child: children) { + Inkscape::XML::Node *crepr = child.updateRepr(xml_doc, NULL, flags); if (crepr) { l = g_slist_prepend(l, crepr); @@ -64,8 +64,8 @@ Inkscape::XML::Node *SPObjectGroup::write(Inkscape::XML::Document *xml_doc, Inks l = g_slist_remove(l, l->data); } } else { - for ( SPObject *child = this->firstChild() ; child ; child = child->getNext() ) { - child->updateRepr(flags); + for (auto& child: children) { + child.updateRepr(flags); } } diff --git a/src/sp-object.cpp b/src/sp-object.cpp index 9cb386026..0cd7b371e 100644 --- a/src/sp-object.cpp +++ b/src/sp-object.cpp @@ -7,8 +7,9 @@ * Stephen Silver <sasilver@users.sourceforge.net> * Jon A. Cruz <jon@joncruz.org> * Abhishek Sharma + * Adrian Boguszewski * - * Copyright (C) 1999-2008 authors + * Copyright (C) 1999-2016 authors * Copyright (C) 2001-2002 Ximian, Inc. * * Released under GNU GPL, read the file 'COPYING' for more information @@ -16,6 +17,7 @@ #include <cstring> #include <string> +#include <boost/range/adaptor/transformed.hpp> #include "helper/sp-marshal.h" #include "xml/node-event-vector.h" @@ -114,8 +116,7 @@ static gchar *sp_object_get_unique_id(SPObject *object, */ SPObject::SPObject() : cloned(0), uflags(0), mflags(0), hrefcount(0), _total_hrefcount(0), - document(NULL), parent(NULL), children(NULL), _last_child(NULL), - next(NULL), id(NULL), repr(NULL), refCount(1),hrefList(std::list<SPObject*>()), + document(NULL), parent(NULL), id(NULL), repr(NULL), refCount(1), hrefList(std::list<SPObject*>()), _successor(NULL), _collection_policy(SPObject::COLLECT_WITH_PARENT), _label(NULL), _default_label(NULL) { @@ -148,6 +149,9 @@ SPObject::~SPObject() { sp_object_unref(this->_successor, NULL); this->_successor = NULL; } + if (parent) { + parent->children.erase(parent->children.iterator_to(*this)); + } if( style == NULL ) { // style pointer could be NULL if unreffed too many times. @@ -396,13 +400,12 @@ void SPObject::changeCSS(SPCSSAttr *css, gchar const *attr) } std::vector<SPObject*> SPObject::childList(bool add_ref, Action) { - std::vector<SPObject*> l; - for ( SPObject *child = firstChild() ; child; child = child->getNext() ) { + std::vector<SPObject*> l; + for (auto& child: children) { if (add_ref) { - sp_object_ref (child); + sp_object_ref(&child); } - - l.push_back(child); + l.push_back(&child); } return l; @@ -465,9 +468,9 @@ void SPObject::requestOrphanCollection() { } void SPObject::_sendDeleteSignalRecursive() { - for (SPObject *child = firstChild(); child; child = child->getNext()) { - child->_delete_signal.emit(child); - child->_sendDeleteSignalRecursive(); + for (auto& child: children) { + child._delete_signal.emit(&child); + child._sendDeleteSignalRecursive(); } } @@ -495,12 +498,12 @@ void SPObject::deleteObject(bool propagate, bool propagate_descendants) void SPObject::cropToObject(SPObject *except) { std::vector<SPObject*> toDelete; - for ( SPObject *child = this->firstChild(); child; child = child->getNext() ) { - if (SP_IS_ITEM(child)) { - if (child->isAncestorOf(except)) { - child->cropToObject(except); - } else if(child != except) { - toDelete.push_back(child); + for (auto& child: children) { + if (SP_IS_ITEM(&child)) { + if (child.isAncestorOf(except)) { + child.cropToObject(except); + } else if(&child != except) { + toDelete.push_back(&child); } } } @@ -523,60 +526,29 @@ void SPObject::attach(SPObject *object, SPObject *prev) object->parent = this; this->_updateTotalHRefCount(object->_total_hrefcount); - SPObject *next; - if (prev) { - next = prev->next; - prev->next = object; - } else { - next = this->children; - this->children = object; - } - object->next = next; - if (!next) { - this->_last_child = object; + auto it = children.begin(); + if (prev != nullptr) { + it = ++children.iterator_to(*prev); } + children.insert(it, *object); + if (!object->xml_space.set) object->xml_space.value = this->xml_space.value; } -void SPObject::reorder(SPObject *prev) -{ - //g_return_if_fail(object != NULL); - //g_return_if_fail(SP_IS_OBJECT(object)); - g_return_if_fail(this->parent != NULL); - g_return_if_fail(this != prev); - g_return_if_fail(!prev || SP_IS_OBJECT(prev)); - g_return_if_fail(!prev || prev->parent == this->parent); - - SPObject *const parent=this->parent; +void SPObject::reorder(SPObject* obj, SPObject* prev) { + g_return_if_fail(obj != nullptr); + g_return_if_fail(obj->parent); + g_return_if_fail(obj->parent == this); + g_return_if_fail(obj != prev); + g_return_if_fail(!prev || prev->parent == obj->parent); - SPObject *old_prev=NULL; - for ( SPObject *child = parent->children ; child && child != this ; - child = child->next ) - { - old_prev = child; + auto it = children.begin(); + if (prev != nullptr) { + it = ++children.iterator_to(*prev); } - SPObject *next=this->next; - if (old_prev) { - old_prev->next = next; - } else { - parent->children = next; - } - if (!next) { - parent->_last_child = old_prev; - } - if (prev) { - next = prev->next; - prev->next = this; - } else { - next = parent->children; - parent->children = this; - } - this->next = next; - if (!next) { - parent->_last_child = this; - } + children.splice(it, children, children.iterator_to(*obj)); } void SPObject::detach(SPObject *object) @@ -587,26 +559,9 @@ void SPObject::detach(SPObject *object) g_return_if_fail(SP_IS_OBJECT(object)); g_return_if_fail(object->parent == this); + children.erase(children.iterator_to(*object)); object->releaseReferences(); - SPObject *prev=NULL; - for ( SPObject *child = this->children ; child && child != object ; - child = child->next ) - { - prev = child; - } - - SPObject *next=object->next; - if (prev) { - prev->next = next; - } else { - this->children = next; - } - if (!next) { - this->_last_child = prev; - } - - object->next = NULL; object->parent = NULL; this->_updateTotalHRefCount(-object->_total_hrefcount); @@ -616,14 +571,14 @@ void SPObject::detach(SPObject *object) SPObject *SPObject::get_child_by_repr(Inkscape::XML::Node *repr) { g_return_val_if_fail(repr != NULL, NULL); - SPObject *result = 0; + SPObject *result = nullptr; - if ( _last_child && (_last_child->getRepr() == repr) ) { - result = _last_child; // optimization for common scenario + if (children.size() > 0 && children.back().getRepr() == repr) { + result = &children.back(); // optimization for common scenario } else { - for ( SPObject *child = children ; child ; child = child->next ) { - if ( child->getRepr() == repr ) { - result = child; + for (auto& child: children) { + if (child.getRepr() == repr) { + result = &child; break; } } @@ -654,10 +609,12 @@ void SPObject::child_added(Inkscape::XML::Node *child, Inkscape::XML::Node *ref) void SPObject::release() { SPObject* object = this; - debug("id=%p, typename=%s", object, g_type_name_from_instance((GTypeInstance*)object)); - while (object->children) { - object->detach(object->children); + auto tmp = children | boost::adaptors::transformed([](SPObject& obj){return &obj;}); + std::vector<SPObject *> toRelease(tmp.begin(), tmp.end()); + + for (auto& p: toRelease) { + object->detach(p); } } @@ -678,7 +635,7 @@ void SPObject::order_changed(Inkscape::XML::Node *child, Inkscape::XML::Node * / SPObject *ochild = object->get_child_by_repr(child); g_return_if_fail(ochild != NULL); SPObject *prev = new_ref ? object->get_child_by_repr(new_ref) : NULL; - ochild->reorder(prev); + object->reorder(ochild, prev); ochild->_position_changed_signal.emit(ochild); } @@ -840,15 +797,22 @@ void SPObject::releaseReferences() { SPObject *SPObject::getPrev() { - SPObject *prev = 0; - for ( SPObject *obj = parent->firstChild(); obj && !prev; obj = obj->getNext() ) { - if (obj->getNext() == this) { - prev = obj; - } + SPObject *prev = nullptr; + if (parent && !parent->children.empty() && &parent->children.front() != this) { + prev = &*(--parent->children.iterator_to(*this)); } return prev; } +SPObject* SPObject::getNext() +{ + SPObject *next = nullptr; + if (parent && !parent->children.empty() && &parent->children.back() != this) { + next = &*(++parent->children.iterator_to(*this)); + } + return next; +} + void SPObject::repr_child_added(Inkscape::XML::Node * /*repr*/, Inkscape::XML::Node *child, Inkscape::XML::Node *ref, gpointer data) { SPObject *object = SP_OBJECT(data); @@ -1512,8 +1476,11 @@ bool SPObject::setTitleOrDesc(gchar const *value, gchar const *svg_tagname, bool } else { // remove the current content of the 'text' or 'desc' element - SPObject *child; - while (NULL != (child = elem->firstChild())) child->deleteObject(); + auto tmp = elem->children | boost::adaptors::transformed([](SPObject& obj) { return &obj; }); + std::vector<SPObject*> vec(tmp.begin(), tmp.end()); + for (auto &child: vec) { + child->deleteObject(); + } } // add the new content @@ -1521,33 +1488,33 @@ bool SPObject::setTitleOrDesc(gchar const *value, gchar const *svg_tagname, bool return true; } -SPObject * SPObject::findFirstChild(gchar const *tagname) const +SPObject* SPObject::findFirstChild(gchar const *tagname) const { - for (SPObject *child = children; child; child = child->next) + for (auto& child: const_cast<SPObject*>(this)->children) { - if (child->repr->type() == Inkscape::XML::ELEMENT_NODE && - !strcmp(child->repr->name(), tagname)) { - return child; + if (child.repr->type() == Inkscape::XML::ELEMENT_NODE && + !strcmp(child.repr->name(), tagname)) { + return &child; } } - return NULL; + return nullptr; } char* SPObject::textualContent() const { GString* text = g_string_new(""); - for (const SPObject *child = firstChild(); child; child = child->next) + for (auto& child: children) { - Inkscape::XML::NodeType child_type = child->repr->type(); + Inkscape::XML::NodeType child_type = child.repr->type(); if (child_type == Inkscape::XML::ELEMENT_NODE) { - char* new_string = child->textualContent(); + char* new_string = child.textualContent(); g_string_append(text, new_string); g_free(new_string); } else if (child_type == Inkscape::XML::TEXT_NODE) { - g_string_append(text, child->repr->content()); + g_string_append(text, child.repr->content()); } } return g_string_free(text, FALSE); @@ -1564,8 +1531,8 @@ void SPObject::recursivePrintTree( unsigned level ) std::cout << " "; } std::cout << (getId()?getId():"No object id") << std::endl; - for (SPObject *child = children; child; child = child->next) { - child->recursivePrintTree( level+1 ); + for (auto& child: children) { + child.recursivePrintTree(level + 1); } } diff --git a/src/sp-object.h b/src/sp-object.h index 70d3e5df5..1c6212664 100644 --- a/src/sp-object.h +++ b/src/sp-object.h @@ -6,8 +6,9 @@ * Lauris Kaplinski <lauris@kaplinski.com> * Jon A. Cruz <jon@joncruz.org> * Abhishek Sharma + * Adrian Boguszewski * - * Copyright (C) 1999-2002 authors + * Copyright (C) 1999-2016 authors * Copyright (C) 2001-2002 Ximian, Inc. * * Released under GNU GPL, read the file 'COPYING' for more information @@ -53,6 +54,7 @@ class SPObject; #include <sigc++/functors/slot.h> #include <sigc++/signal.h> #include <vector> +#include <boost/intrusive/list.hpp> #include "version.h" #include "util/forward-pointer-iterator.h" @@ -206,9 +208,6 @@ public: unsigned int _total_hrefcount; /* our hrefcount + total descendants */ SPDocument *document; /* Document we are part of */ SPObject *parent; /* Our parent (only one allowed) */ - SPObject *children; /* Our children */ - SPObject *_last_child; /* Remembered last child */ - SPObject *next; /* Next object in linked list */ private: SPObject(const SPObject&); @@ -216,6 +215,7 @@ private: char *id; /* Our very own unique id */ Inkscape::XML::Node *repr; /* Our xml representation */ + public: int refCount; std::list<SPObject*> hrefList; @@ -279,17 +279,9 @@ public: return object->parent; } }; - /// Switch containing next() method. - struct SiblingIteratorStrategy { - static SPObject const *next(SPObject const *object) { - return object->next; - } - }; typedef Inkscape::Util::ForwardPointerIterator<SPObject, ParentIteratorStrategy> ParentIterator; typedef Inkscape::Util::ForwardPointerIterator<SPObject const, ParentIteratorStrategy> ConstParentIterator; - typedef Inkscape::Util::ForwardPointerIterator<SPObject, SiblingIteratorStrategy> SiblingIterator; - typedef Inkscape::Util::ForwardPointerIterator<SPObject const, SiblingIteratorStrategy> ConstSiblingIterator; bool isSiblingOf(SPObject const *object) const { if (object == NULL) return false; @@ -306,24 +298,21 @@ public: */ SPObject const *nearestCommonAncestor(SPObject const *object) const; - /* A non-const version can be similarly constructed if you want one. - * (Don't just cast away the constness, which would be ill-formed.) */ - SPObject *getNext() {return next;} - - SPObject const *getNext() const {return next;} + /* Returns next object in sibling list or NULL. */ + SPObject *getNext(); /** * Returns previous object in sibling list or NULL. */ SPObject *getPrev(); - bool hasChildren() const { return ( children != NULL ); } + bool hasChildren() const { return ( children.size() > 0 ); } - SPObject *firstChild() { return children; } - SPObject const *firstChild() const { return children; } + SPObject *firstChild() { return children.empty() ? nullptr : &children.front(); } + SPObject const *firstChild() const { return children.empty() ? nullptr : &children.front(); } - SPObject *lastChild() { return _last_child; } - SPObject const *lastChild() const { return _last_child; } + SPObject *lastChild() { return children.empty() ? nullptr : &children.back(); } + SPObject const *lastChild() const { return children.empty() ? nullptr : &children.back(); } enum Action { ActionGeneral, ActionBBox, ActionUpdate, ActionShow }; @@ -681,9 +670,9 @@ public: void attach(SPObject *object, SPObject *prev); /** - * In list of object's siblings, move object behind prev. + * In list of object's children, move object behind prev. */ - void reorder(SPObject *prev); + void reorder(SPObject* obj, SPObject *prev); /** * Remove object from parent's children, release and unref it. @@ -858,7 +847,17 @@ protected: virtual Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, unsigned int flags); + typedef boost::intrusive::list_member_hook<> ListHook; + ListHook _child_hook; public: + typedef boost::intrusive::list< + SPObject, + boost::intrusive::member_hook< + SPObject, + ListHook, + &SPObject::_child_hook + >> ChildrenList; + ChildrenList children; virtual void read_content(); void recursivePrintTree(unsigned level = 0); // For debugging diff --git a/src/sp-pattern.cpp b/src/sp-pattern.cpp index a68bee721..77fa9034d 100644 --- a/src/sp-pattern.cpp +++ b/src/sp-pattern.cpp @@ -219,8 +219,8 @@ void SPPattern::_getChildren(std::list<SPObject *> &l) { for (SPPattern *pat_i = this; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { if (pat_i->firstChild()) { // find the first one with children - for (SPObject *child = pat_i->firstChild(); child; child = child->getNext()) { - l.push_back(child); + for (auto& child: pat_i->children) { + l.push_back(&child); } break; // do not go further up the chain if children are found } @@ -315,8 +315,8 @@ guint SPPattern::_countHrefs(SPObject *o) const i++; } - for (SPObject *child = o->firstChild(); child != NULL; child = child->next) { - i += _countHrefs(child); + for (auto& child: o->children) { + i += _countHrefs(&child); } return i; @@ -504,13 +504,13 @@ Geom::OptRect SPPattern::viewbox() const bool SPPattern::_hasItemChildren() const { - bool hasChildren = false; - for (SPObject const *child = firstChild(); child && !hasChildren; child = child->getNext()) { - if (SP_IS_ITEM(child)) { - hasChildren = true; + for (auto& child: children) { + if (SP_IS_ITEM(&child)) { + return true; } } - return hasChildren; + + return false; } bool SPPattern::isValid() const @@ -554,12 +554,12 @@ cairo_pattern_t *SPPattern::pattern_new(cairo_t *base_ct, Geom::OptRect const &b Inkscape::DrawingGroup *root = new Inkscape::DrawingGroup(drawing); drawing.setRoot(root); - for (SPObject *child = shown->firstChild(); child != NULL; child = child->getNext()) { - if (SP_IS_ITEM(child)) { + for (auto& child: shown->children) { + if (SP_IS_ITEM(&child)) { // for each item in pattern, show it on our drawing, add to the group, // and connect to the release signal in case the item gets deleted Inkscape::DrawingItem *cai; - cai = SP_ITEM(child)->invoke_show(drawing, dkey, SP_ITEM_SHOW_DISPLAY); + cai = SP_ITEM(&child)->invoke_show(drawing, dkey, SP_ITEM_SHOW_DISPLAY); root->appendChild(cai); } } @@ -650,9 +650,9 @@ cairo_pattern_t *SPPattern::pattern_new(cairo_t *base_ct, Geom::OptRect const &b // Render drawing to pattern_surface via drawing context, this calls root->render // which is really DrawingItem->render(). drawing.render(dc, one_tile); - for (SPObject *child = shown->firstChild(); child != NULL; child = child->getNext()) { - if (SP_IS_ITEM(child)) { - SP_ITEM(child)->invoke_hide(dkey); + for (auto& child: shown->children) { + if (SP_IS_ITEM(&child)) { + SP_ITEM(&child)->invoke_hide(dkey); } } diff --git a/src/sp-root.cpp b/src/sp-root.cpp index 98eae2159..34047054a 100644 --- a/src/sp-root.cpp +++ b/src/sp-root.cpp @@ -73,9 +73,9 @@ void SPRoot::build(SPDocument *document, Inkscape::XML::Node *repr) SPGroup::build(document, repr); // Search for first <defs> node - for (SPObject *o = this->firstChild() ; o ; o = o->getNext()) { - if (SP_IS_DEFS(o)) { - this->defs = SP_DEFS(o); + for (auto& o: children) { + if (SP_IS_DEFS(&o)) { + this->defs = SP_DEFS(&o); break; } } @@ -174,9 +174,9 @@ void SPRoot::child_added(Inkscape::XML::Node *child, Inkscape::XML::Node *ref) if (co && SP_IS_DEFS(co)) { // We search for first <defs> node - it is not beautiful, but works - for (SPObject *c = this->firstChild() ; c ; c = c->getNext()) { - if (SP_IS_DEFS(c)) { - this->defs = SP_DEFS(c); + for (auto& c: children) { + if (SP_IS_DEFS(&c)) { + this->defs = SP_DEFS(&c); break; } } @@ -189,7 +189,8 @@ void SPRoot::remove_child(Inkscape::XML::Node *child) SPObject *iter = 0; // We search for first remaining <defs> node - it is not beautiful, but works - for (iter = this->firstChild() ; iter ; iter = iter->getNext()) { + for (auto& child: children) { + iter = &child; if (SP_IS_DEFS(iter) && (SPDefs *)iter != this->defs) { this->defs = (SPDefs *)iter; break; diff --git a/src/sp-switch.cpp b/src/sp-switch.cpp index 1e0d81db9..d6ab1e904 100644 --- a/src/sp-switch.cpp +++ b/src/sp-switch.cpp @@ -31,9 +31,10 @@ SPSwitch::~SPSwitch() { SPObject *SPSwitch::_evaluateFirst() { SPObject *first = 0; - for (SPObject *child = this->firstChild() ; child && !first ; child = child->getNext() ) { - if (SP_IS_ITEM(child) && sp_item_evaluate(SP_ITEM(child))) { - first = child; + for (auto& child: children) { + if (SP_IS_ITEM(&child) && sp_item_evaluate(SP_ITEM(&child))) { + first = &child; + break; } } diff --git a/src/sp-text.cpp b/src/sp-text.cpp index 2e1d4993d..9beb812f5 100644 --- a/src/sp-text.cpp +++ b/src/sp-text.cpp @@ -150,9 +150,9 @@ void SPText::update(SPCtx *ctx, guint flags) { // Create temporary list of children GSList *l = NULL; - for (SPObject *child = this->firstChild() ; child ; child = child->getNext() ) { - sp_object_ref(child, this); - l = g_slist_prepend (l, child); + for (auto& child: children) { + sp_object_ref(&child, this); + l = g_slist_prepend (l, &child); } l = g_slist_reverse (l); @@ -230,9 +230,9 @@ void SPText::modified(guint flags) { // Create temporary list of children GSList *l = NULL; - for (SPObject *child = this->firstChild() ; child ; child = child->getNext() ) { - sp_object_ref(child, this); - l = g_slist_prepend (l, child); + for (auto& child: children) { + sp_object_ref(&child, this); + l = g_slist_prepend (l, &child); } l = g_slist_reverse (l); @@ -257,17 +257,17 @@ Inkscape::XML::Node *SPText::write(Inkscape::XML::Document *xml_doc, Inkscape::X GSList *l = NULL; - for (SPObject *child = this->firstChild() ; child ; child = child->getNext() ) { - if (SP_IS_TITLE(child) || SP_IS_DESC(child)) { + for (auto& child: children) { + if (SP_IS_TITLE(&child) || SP_IS_DESC(&child)) { continue; } Inkscape::XML::Node *crepr = NULL; - if (SP_IS_STRING(child)) { - crepr = xml_doc->createTextNode(SP_STRING(child)->string.c_str()); + if (SP_IS_STRING(&child)) { + crepr = xml_doc->createTextNode(SP_STRING(&child)->string.c_str()); } else { - crepr = child->updateRepr(xml_doc, NULL, flags); + crepr = child.updateRepr(xml_doc, NULL, flags); } if (crepr) { @@ -281,15 +281,15 @@ Inkscape::XML::Node *SPText::write(Inkscape::XML::Document *xml_doc, Inkscape::X l = g_slist_remove (l, l->data); } } else { - for (SPObject *child = this->firstChild() ; child ; child = child->getNext() ) { - if (SP_IS_TITLE(child) || SP_IS_DESC(child)) { + for (auto& child: children) { + if (SP_IS_TITLE(&child) || SP_IS_DESC(&child)) { continue; } - if (SP_IS_STRING(child)) { - child->getRepr()->setContent(SP_STRING(child)->string.c_str()); + if (SP_IS_STRING(&child)) { + child.getRepr()->setContent(SP_STRING(&child)->string.c_str()); } else { - child->updateRepr(flags); + child.updateRepr(flags); } } } @@ -601,16 +601,16 @@ unsigned SPText::_buildLayoutInput(SPObject *root, Inkscape::Text::Layout::Optio } } - for (SPObject *child = root->firstChild() ; child ; child = child->getNext() ) { - SPString *str = dynamic_cast<SPString *>(child); + for (auto& child: root->children) { + SPString *str = dynamic_cast<SPString *>(&child); if (str) { Glib::ustring const &string = str->string; // std::cout << " Appending: >" << string << "<" << std::endl; - layout.appendText(string, root->style, child, &optional_attrs, child_attrs_offset + length); + layout.appendText(string, root->style, &child, &optional_attrs, child_attrs_offset + length); length += string.length(); - } else if (!sp_repr_is_meta_element(child->getRepr())) { + } else if (!sp_repr_is_meta_element(child.getRepr())) { /* ^^^^ XML Tree being directly used here while it shouldn't be.*/ - length += _buildLayoutInput(child, optional_attrs, child_attrs_offset + length, in_textpath); + length += _buildLayoutInput(&child, optional_attrs, child_attrs_offset + length, in_textpath); } } @@ -623,9 +623,9 @@ void SPText::rebuildLayout() Inkscape::Text::Layout::OptionalTextTagAttrs optional_attrs; _buildLayoutInput(this, optional_attrs, 0, false); layout.calculateFlow(); - for (SPObject *child = firstChild() ; child ; child = child->getNext() ) { - if (SP_IS_TEXTPATH(child)) { - SPTextPath const *textpath = SP_TEXTPATH(child); + for (auto& child: children) { + if (SP_IS_TEXTPATH(&child)) { + SPTextPath const *textpath = SP_TEXTPATH(&child); if (textpath->originalPath != NULL) { //g_print("%s", layout.dumpAsText().c_str()); layout.fitToPathAlign(textpath->startOffset, *textpath->originalPath); @@ -635,9 +635,9 @@ void SPText::rebuildLayout() //g_print("%s", layout.dumpAsText().c_str()); // set the x,y attributes on role:line spans - for (SPObject *child = firstChild() ; child ; child = child->getNext() ) { - if (SP_IS_TSPAN(child)) { - SPTSpan *tspan = SP_TSPAN(child); + for (auto& child: children) { + if (SP_IS_TSPAN(&child)) { + SPTSpan *tspan = SP_TSPAN(&child); if ( (tspan->role != SP_TSPAN_ROLE_UNSPECIFIED) && tspan->attributes.singleXYCoordinates() ) { Inkscape::Text::Layout::iterator iter = layout.sourceToIterator(tspan); @@ -671,9 +671,9 @@ void SPText::_adjustFontsizeRecursive(SPItem *item, double ex, bool is_root) item->updateRepr(); } - for (SPObject *o = item->children; o != NULL; o = o->next) { - if (SP_IS_ITEM(o)) - _adjustFontsizeRecursive(SP_ITEM(o), ex, false); + for(auto& o: item->children) { + if (SP_IS_ITEM(&o)) + _adjustFontsizeRecursive(SP_ITEM(&o), ex, false); } } @@ -690,9 +690,9 @@ void SPText::_adjustCoordsRecursive(SPItem *item, Geom::Affine const &m, double SP_TREF(item)->attributes.transform(m, ex, ex, is_root); } - for (SPObject *o = item->children; o != NULL; o = o->next) { - if (SP_IS_ITEM(o)) - _adjustCoordsRecursive(SP_ITEM(o), m, ex, false); + for(auto& o: item->children) { + if (SP_IS_ITEM(&o)) + _adjustCoordsRecursive(SP_ITEM(&o), m, ex, false); } } diff --git a/src/sp-tref.cpp b/src/sp-tref.cpp index 20bfc8cd0..e25ddb5a4 100644 --- a/src/sp-tref.cpp +++ b/src/sp-tref.cpp @@ -501,9 +501,9 @@ sp_tref_convert_to_tspan(SPObject *obj) //////////////////// else { GSList *l = NULL; - for (SPObject *child = obj->firstChild() ; child != NULL ; child = child->getNext() ) { - sp_object_ref(child, obj); - l = g_slist_prepend (l, child); + for (auto& child: obj->children) { + sp_object_ref(&child, obj); + l = g_slist_prepend (l, &child); } l = g_slist_reverse (l); while (l) { diff --git a/src/sp-tspan.cpp b/src/sp-tspan.cpp index 2b4ecf92b..2e169ad77 100644 --- a/src/sp-tspan.cpp +++ b/src/sp-tspan.cpp @@ -94,9 +94,9 @@ void SPTSpan::update(SPCtx *ctx, guint flags) { } childflags &= SP_OBJECT_MODIFIED_CASCADE; - for ( SPObject *ochild = this->firstChild() ; ochild ; ochild = ochild->getNext() ) { - if ( flags || ( ochild->uflags & SP_OBJECT_MODIFIED_FLAG )) { - ochild->updateDisplay(ctx, childflags); + for (auto& ochild: children) { + if ( flags || ( ochild.uflags & SP_OBJECT_MODIFIED_FLAG )) { + ochild.updateDisplay(ctx, childflags); } } @@ -126,9 +126,9 @@ void SPTSpan::modified(unsigned int flags) { flags &= SP_OBJECT_MODIFIED_CASCADE; - for ( SPObject *ochild = this->firstChild() ; ochild ; ochild = ochild->getNext() ) { - if (flags || (ochild->mflags & SP_OBJECT_MODIFIED_FLAG)) { - ochild->emitModified(flags); + for (auto& ochild: children) { + if (flags || (ochild.mflags & SP_OBJECT_MODIFIED_FLAG)) { + ochild.emitModified(flags); } } } @@ -173,15 +173,15 @@ Inkscape::XML::Node* SPTSpan::write(Inkscape::XML::Document *xml_doc, Inkscape:: if ( flags&SP_OBJECT_WRITE_BUILD ) { GSList *l = NULL; - for (SPObject* child = this->firstChild() ; child ; child = child->getNext() ) { + for (auto& child: children) { Inkscape::XML::Node* c_repr=NULL; - if ( SP_IS_TSPAN(child) || SP_IS_TREF(child) ) { - c_repr = child->updateRepr(xml_doc, NULL, flags); - } else if ( SP_IS_TEXTPATH(child) ) { - //c_repr = child->updateRepr(xml_doc, NULL, flags); // shouldn't happen - } else if ( SP_IS_STRING(child) ) { - c_repr = xml_doc->createTextNode(SP_STRING(child)->string.c_str()); + if ( SP_IS_TSPAN(&child) || SP_IS_TREF(&child) ) { + c_repr = child.updateRepr(xml_doc, NULL, flags); + } else if ( SP_IS_TEXTPATH(&child) ) { + //c_repr = child.updateRepr(xml_doc, NULL, flags); // shouldn't happen + } else if ( SP_IS_STRING(&child) ) { + c_repr = xml_doc->createTextNode(SP_STRING(&child)->string.c_str()); } if ( c_repr ) { @@ -195,13 +195,13 @@ Inkscape::XML::Node* SPTSpan::write(Inkscape::XML::Document *xml_doc, Inkscape:: l = g_slist_remove(l, l->data); } } else { - for (SPObject* child = this->firstChild() ; child ; child = child->getNext() ) { - if ( SP_IS_TSPAN(child) || SP_IS_TREF(child) ) { - child->updateRepr(flags); - } else if ( SP_IS_TEXTPATH(child) ) { + for (auto& child: children) { + if ( SP_IS_TSPAN(&child) || SP_IS_TREF(&child) ) { + child.updateRepr(flags); + } else if ( SP_IS_TEXTPATH(&child) ) { //c_repr = child->updateRepr(xml_doc, NULL, flags); // shouldn't happen - } else if ( SP_IS_STRING(child) ) { - child->getRepr()->setContent(SP_STRING(child)->string.c_str()); + } else if ( SP_IS_STRING(&child) ) { + child.getRepr()->setContent(SP_STRING(&child)->string.c_str()); } } } @@ -311,9 +311,9 @@ void SPTextPath::update(SPCtx *ctx, guint flags) { flags &= SP_OBJECT_MODIFIED_CASCADE; - for ( SPObject *ochild = this->firstChild() ; ochild ; ochild = ochild->getNext() ) { - if ( flags || ( ochild->uflags & SP_OBJECT_MODIFIED_FLAG )) { - ochild->updateDisplay(ctx, flags); + for (auto& ochild: children) { + if ( flags || ( ochild.uflags & SP_OBJECT_MODIFIED_FLAG )) { + ochild.updateDisplay(ctx, flags); } } @@ -365,9 +365,9 @@ void SPTextPath::modified(unsigned int flags) { flags &= SP_OBJECT_MODIFIED_CASCADE; - for ( SPObject *ochild = this->firstChild() ; ochild ; ochild = ochild->getNext() ) { - if (flags || (ochild->mflags & SP_OBJECT_MODIFIED_FLAG)) { - ochild->emitModified(flags); + for (auto& ochild: children) { + if (flags || (ochild.mflags & SP_OBJECT_MODIFIED_FLAG)) { + ochild.emitModified(flags); } } } @@ -397,15 +397,15 @@ Inkscape::XML::Node* SPTextPath::write(Inkscape::XML::Document *xml_doc, Inkscap if ( flags & SP_OBJECT_WRITE_BUILD ) { GSList *l = NULL; - for (SPObject* child = this->firstChild() ; child ; child = child->getNext() ) { + for (auto& child: children) { Inkscape::XML::Node* c_repr=NULL; - if ( SP_IS_TSPAN(child) || SP_IS_TREF(child) ) { - c_repr = child->updateRepr(xml_doc, NULL, flags); - } else if ( SP_IS_TEXTPATH(child) ) { + if ( SP_IS_TSPAN(&child) || SP_IS_TREF(&child) ) { + c_repr = child.updateRepr(xml_doc, NULL, flags); + } else if ( SP_IS_TEXTPATH(&child) ) { //c_repr = child->updateRepr(xml_doc, NULL, flags); // shouldn't happen - } else if ( SP_IS_STRING(child) ) { - c_repr = xml_doc->createTextNode(SP_STRING(child)->string.c_str()); + } else if ( SP_IS_STRING(&child) ) { + c_repr = xml_doc->createTextNode(SP_STRING(&child)->string.c_str()); } if ( c_repr ) { @@ -419,13 +419,13 @@ Inkscape::XML::Node* SPTextPath::write(Inkscape::XML::Document *xml_doc, Inkscap l = g_slist_remove(l, l->data); } } else { - for (SPObject* child = this->firstChild() ; child ; child = child->getNext() ) { - if ( SP_IS_TSPAN(child) || SP_IS_TREF(child) ) { - child->updateRepr(flags); - } else if ( SP_IS_TEXTPATH(child) ) { - //c_repr = child->updateRepr(xml_doc, NULL, flags); // shouldn't happen - } else if ( SP_IS_STRING(child) ) { - child->getRepr()->setContent(SP_STRING(child)->string.c_str()); + for (auto& child: children) { + if ( SP_IS_TSPAN(&child) || SP_IS_TREF(&child) ) { + child.updateRepr(flags); + } else if ( SP_IS_TEXTPATH(&child) ) { + //c_repr = child.updateRepr(xml_doc, NULL, flags); // shouldn't happen + } else if ( SP_IS_STRING(&child) ) { + child.getRepr()->setContent(SP_STRING(&child)->string.c_str()); } } } @@ -464,8 +464,8 @@ void sp_textpath_to_text(SPObject *tp) // make a list of textpath children GSList *tp_reprs = NULL; - for (SPObject *o = tp->firstChild() ; o != NULL; o = o->next) { - tp_reprs = g_slist_prepend(tp_reprs, o->getRepr()); + for (auto& o: tp->children) { + tp_reprs = g_slist_prepend(tp_reprs, o.getRepr()); } for ( GSList *i = tp_reprs ; i ; i = i->next ) { diff --git a/src/sp-use.cpp b/src/sp-use.cpp index 59064ce21..6ba03dad9 100644 --- a/src/sp-use.cpp +++ b/src/sp-use.cpp @@ -435,27 +435,23 @@ void SPUse::move_compensate(Geom::Affine const *mp) { //BUT move clippaths accordingly. //if clone has a clippath, move it accordingly if(clip_ref->getObject()){ - SPObject *clip = clip_ref->getObject()->firstChild() ; - while(clip){ - SPItem *item = (SPItem*) clip; + for(auto& clip: clip_ref->getObject()->children){ + SPItem *item = (SPItem*) &clip; if(item){ item->transform *= m; Geom::Affine identity; - item->doWriteTransform(clip->getRepr(),item->transform, &identity); + item->doWriteTransform(clip.getRepr(),item->transform, &identity); } - clip = clip->getNext(); } } if(mask_ref->getObject()){ - SPObject *mask = mask_ref->getObject()->firstChild() ; - while(mask){ - SPItem *item = (SPItem*) mask; + for(auto& mask: mask_ref->getObject()->children){ + SPItem *item = (SPItem*) &mask; if(item){ item->transform *= m; Geom::Affine identity; - item->doWriteTransform(mask->getRepr(),item->transform, &identity); + item->doWriteTransform(mask.getRepr(),item->transform, &identity); } - mask = mask->getNext(); } } return; @@ -479,27 +475,23 @@ void SPUse::move_compensate(Geom::Affine const *mp) { //if clone has a clippath, move it accordingly if(clip_ref->getObject()){ - SPObject *clip = clip_ref->getObject()->firstChild() ; - while(clip){ - SPItem *item = (SPItem*) clip; + for(auto& clip: clip_ref->getObject()->children){ + SPItem *item = (SPItem*) &clip; if(item){ item->transform *= clone_move.inverse(); Geom::Affine identity; - item->doWriteTransform(clip->getRepr(),item->transform, &identity); + item->doWriteTransform(clip.getRepr(),item->transform, &identity); } - clip = clip->getNext(); } } if(mask_ref->getObject()){ - SPObject *mask = mask_ref->getObject()->firstChild() ; - while(mask){ - SPItem *item = (SPItem*) mask; + for(auto& mask: mask_ref->getObject()->children){ + SPItem *item = (SPItem*) &mask; if(item){ item->transform *= clone_move.inverse(); Geom::Affine identity; - item->doWriteTransform(mask->getRepr(),item->transform, &identity); + item->doWriteTransform(mask.getRepr(),item->transform, &identity); } - mask = mask->getNext(); } } diff --git a/src/splivarot.cpp b/src/splivarot.cpp index c2e5a2f2e..7a5df4c97 100644 --- a/src/splivarot.cpp +++ b/src/splivarot.cpp @@ -34,7 +34,6 @@ #include "message-stack.h" #include "selection.h" -#include "desktop.h" #include <glibmm/i18n.h> #include "xml/repr-sorting.h" @@ -48,65 +47,96 @@ #include "verbs.h" #include "2geom/svg-path-parser.h" // to get from SVG on boolean to Geom::Path +enum BoolOpErrors { + DONE, + DONE_NO_PATH, + DONE_NO_ACTION, + ERR_TOO_LESS_PATHS_1, + ERR_TOO_LESS_PATHS_2, + ERR_NO_PATHS, + ERR_Z_ORDER +}; + using Inkscape::DocumentUndo; bool Ancetre(Inkscape::XML::Node *a, Inkscape::XML::Node *who); -void sp_selected_path_boolop(Inkscape::Selection *selection, SPDesktop *desktop, bool_op bop, const unsigned int verb=SP_VERB_NONE, const Glib::ustring description=""); +void sp_selected_path_boolop_ui(Inkscape::Selection *selection, SPDesktop *desktop, bool_op bop, + const unsigned int verb = SP_VERB_NONE, const Glib::ustring description = ""); +BoolOpErrors sp_selected_path_boolop(Inkscape::ObjectSet *set, bool_op bop); void sp_selected_path_do_offset(SPDesktop *desktop, bool expand, double prefOffset); void sp_selected_path_create_offset_object(SPDesktop *desktop, int expand, bool updating); void sp_selected_path_union(Inkscape::Selection *selection, SPDesktop *desktop) { - sp_selected_path_boolop(selection, desktop, bool_op_union, SP_VERB_SELECTION_UNION, _("Union")); + sp_selected_path_boolop_ui(selection, desktop, bool_op_union, SP_VERB_SELECTION_UNION, _("Union")); } void -sp_selected_path_union_skip_undo(Inkscape::Selection *selection, SPDesktop *desktop) +sp_selected_path_union_skip_undo(Inkscape::ObjectSet *set) { - sp_selected_path_boolop(selection, desktop, bool_op_union, SP_VERB_NONE, _("Union")); + sp_selected_path_boolop(set, bool_op_union); } void sp_selected_path_intersect(Inkscape::Selection *selection, SPDesktop *desktop) { - sp_selected_path_boolop(selection, desktop, bool_op_inters, SP_VERB_SELECTION_INTERSECT, _("Intersection")); + sp_selected_path_boolop_ui(selection, desktop, bool_op_inters, SP_VERB_SELECTION_INTERSECT, _("Intersection")); +} + +void +sp_selected_path_intersect_skip_undo(Inkscape::ObjectSet *set) +{ + sp_selected_path_boolop(set, bool_op_inters); } void sp_selected_path_diff(Inkscape::Selection *selection, SPDesktop *desktop) { - sp_selected_path_boolop(selection, desktop, bool_op_diff, SP_VERB_SELECTION_DIFF, _("Difference")); + sp_selected_path_boolop_ui(selection, desktop, bool_op_diff, SP_VERB_SELECTION_DIFF, _("Difference")); } void -sp_selected_path_diff_skip_undo(Inkscape::Selection *selection, SPDesktop *desktop) +sp_selected_path_diff_skip_undo(Inkscape::ObjectSet *set) { - sp_selected_path_boolop(selection, desktop, bool_op_diff, SP_VERB_NONE, _("Difference")); + sp_selected_path_boolop(set, bool_op_diff); } void sp_selected_path_symdiff(Inkscape::Selection *selection, SPDesktop *desktop) { - sp_selected_path_boolop(selection, desktop, bool_op_symdiff, SP_VERB_SELECTION_SYMDIFF, _("Exclusion")); + sp_selected_path_boolop_ui(selection, desktop, bool_op_symdiff, SP_VERB_SELECTION_SYMDIFF, _("Exclusion")); +} + +void +sp_selected_path_symdiff_skip_undo(Inkscape::ObjectSet *set) +{ + sp_selected_path_boolop(set, bool_op_symdiff); } + void sp_selected_path_cut(Inkscape::Selection *selection, SPDesktop *desktop) { - sp_selected_path_boolop(selection, desktop, bool_op_cut, SP_VERB_SELECTION_CUT, _("Division")); + sp_selected_path_boolop_ui(selection, desktop, bool_op_cut, SP_VERB_SELECTION_CUT, _("Division")); } void -sp_selected_path_cut_skip_undo(Inkscape::Selection *selection, SPDesktop *desktop) +sp_selected_path_cut_skip_undo(Inkscape::ObjectSet *set) { - sp_selected_path_boolop(selection, desktop, bool_op_cut, SP_VERB_NONE, _("Division")); + sp_selected_path_boolop(set, bool_op_cut); } void sp_selected_path_slice(Inkscape::Selection *selection, SPDesktop *desktop) { - sp_selected_path_boolop(selection, desktop, bool_op_slice, SP_VERB_SELECTION_SLICE, _("Cut path")); + sp_selected_path_boolop_ui(selection, desktop, bool_op_slice, SP_VERB_SELECTION_SLICE, _("Cut path")); +} + +void +sp_selected_path_slice_skip_undo(Inkscape::ObjectSet *set) +{ + sp_selected_path_boolop(set, bool_op_slice); } // helper for printing error messages, regardless of whether we have a GUI or not @@ -322,20 +352,17 @@ Geom::PathVector pathliv_to_pathvector(Path *pathliv){ // boolean operations on the desktop // take the source paths from the file, do the operation, delete the originals and add the results -void -sp_selected_path_boolop(Inkscape::Selection *selection, SPDesktop *desktop, bool_op bop, const unsigned int verb, const Glib::ustring description) +BoolOpErrors sp_selected_path_boolop(Inkscape::ObjectSet * set, bool_op bop) { - SPDocument *doc = selection->layers()->getDocument(); - std::vector<SPItem*> il= selection->itemList(); - + SPDocument *doc = set->desktop()->getDocument(); + std::vector<SPItem*> il(set->items().begin(), set->items().end()); + // allow union on a single object for the purpose of removing self overlapse (svn log, revision 13334) - if ( (il.size() < 2) && (bop != bool_op_union)) { - boolop_display_error_message(desktop, _("Select <b>at least 2 paths</b> to perform a boolean operation.")); - return; + if (il.size() < 2 && bop != bool_op_union) { + return ERR_TOO_LESS_PATHS_2; } - else if ( il.size() < 1 ) { - boolop_display_error_message(desktop, _("Select <b>at least 1 path</b> to perform a boolean union.")); - return; + else if (il.size() < 1) { + return ERR_TOO_LESS_PATHS_1; } g_assert(!il.empty()); @@ -351,8 +378,7 @@ sp_selected_path_boolop(Inkscape::Selection *selection, SPDesktop *desktop, bool Inkscape::XML::Node *b = il.back()->getRepr(); if (a == NULL || b == NULL) { - boolop_display_error_message(desktop, _("Unable to determine the <b>z-order</b> of the objects selected for difference, XOR, division, or path cut.")); - return; + return ERR_Z_ORDER; } if (Ancetre(a, b)) { @@ -366,8 +392,7 @@ sp_selected_path_boolop(Inkscape::Selection *selection, SPDesktop *desktop, bool // find their lowest common ancestor Inkscape::XML::Node *parent = LCA(a, b); if (parent == NULL) { - boolop_display_error_message(desktop, _("Unable to determine the <b>z-order</b> of the objects selected for difference, XOR, division, or path cut.")); - return; + return ERR_Z_ORDER; } // find the children of the LCA that lead from it to the a and b @@ -396,8 +421,7 @@ sp_selected_path_boolop(Inkscape::Selection *selection, SPDesktop *desktop, bool SPItem *item = *l; if (!SP_IS_SHAPE(item) && !SP_IS_TEXT(item) && !SP_IS_FLOWTEXT(item)) { - boolop_display_error_message(desktop, _("One of the objects is <b>not a path</b>, cannot perform boolean operation.")); - return; + return ERR_NO_PATHS; } } @@ -430,7 +454,7 @@ sp_selected_path_boolop(Inkscape::Selection *selection, SPDesktop *desktop, bool if (originaux[curOrig] == NULL || originaux[curOrig]->descr_cmd.size() <= 1) { for (int i = curOrig; i >= 0; i--) delete originaux[i]; - return; + return DONE_NO_ACTION; } curOrig++; } @@ -491,18 +515,18 @@ sp_selected_path_boolop(Inkscape::Selection *selection, SPDesktop *desktop, bool bool zeroA = theShapeA->numberOfEdges() == 0; bool zeroB = theShapeB->numberOfEdges() == 0; if (zeroA || zeroB) { - // We might need to do a swap. Apply the above rules depending on operation type. - bool resultIsB = ((bop == bool_op_union || bop == bool_op_symdiff) && zeroA) - || ((bop == bool_op_inters) && zeroB) - || (bop == bool_op_diff); + // We might need to do a swap. Apply the above rules depending on operation type. + bool resultIsB = ((bop == bool_op_union || bop == bool_op_symdiff) && zeroA) + || ((bop == bool_op_inters) && zeroB) + || (bop == bool_op_diff); if (resultIsB) { - // Swap A and B to use B as the result + // Swap A and B to use B as the result Shape *swap = theShapeB; theShapeB = theShapeA; theShapeA = swap; } } else { - // Just do the Boolean operation as usual + // Just do the Boolean operation as usual // les elements arrivent en ordre inverse dans la liste theShape->Booleen(theShapeB, theShapeA, bop); Shape *swap = theShape; @@ -663,24 +687,23 @@ sp_selected_path_boolop(Inkscape::Selection *selection, SPDesktop *desktop, bool for (std::vector<SPItem*>::const_iterator l = il.begin(); l != il.end(); l++){ (*l)->deleteObject(); } - DocumentUndo::done(doc, SP_VERB_NONE, description); - selection->clear(); + set->clear(); delete res; - return; + return DONE_NO_PATH; } // get the source path object SPObject *source; if ( bop == bool_op_diff || bop == bool_op_cut || bop == bool_op_slice ) { if (reverseOrderForOp) { - source = il[0]; + source = il[0]; } else { - source = il.back(); + source = il.back(); } } else { // find out the bottom object - std::vector<Inkscape::XML::Node*> sorted(selection->reprList()); + std::vector<Inkscape::XML::Node*> sorted(set->xmlNodes().begin(), set->xmlNodes().end()); sort(sorted.begin(),sorted.end(),sp_repr_compare_position_bool); @@ -708,7 +731,7 @@ sp_selected_path_boolop(Inkscape::Selection *selection, SPDesktop *desktop, bool gchar *title = source->title(); gchar *desc = source->desc(); // remove source paths - selection->clear(); + set->clear(); for (std::vector<SPItem*>::const_iterator l = il.begin(); l != il.end(); l++){ // if this is the bottommost object, if (!strcmp(reinterpret_cast<SPObject *>(*l)->getRepr()->attribute("id"), id)) { @@ -787,7 +810,7 @@ sp_selected_path_boolop(Inkscape::Selection *selection, SPDesktop *desktop, bool // move to the saved position repr->setPosition(pos > 0 ? pos : 0); - selection->add(repr); + set->add(doc->getObjectByRepr(repr)); Inkscape::GC::release(repr); delete resPath[i]; @@ -815,14 +838,14 @@ sp_selected_path_boolop(Inkscape::Selection *selection, SPDesktop *desktop, bool repr->setAttribute("id", id); parent->appendChild(repr); if (title) { - doc->getObjectByRepr(repr)->setTitle(title); - } + doc->getObjectByRepr(repr)->setTitle(title); + } if (desc) { - doc->getObjectByRepr(repr)->setDesc(desc); + doc->getObjectByRepr(repr)->setDesc(desc); } - repr->setPosition(pos > 0 ? pos : 0); + repr->setPosition(pos > 0 ? pos : 0); - selection->add(repr); + set->add(doc->getObjectByRepr(repr)); Inkscape::GC::release(repr); } @@ -830,11 +853,39 @@ sp_selected_path_boolop(Inkscape::Selection *selection, SPDesktop *desktop, bool if (title) g_free(title); if (desc) g_free(desc); - if (verb != SP_VERB_NONE) { - DocumentUndo::done(doc, verb, description); - } - delete res; + + return DONE; +} + +void sp_selected_path_boolop_ui(Inkscape::Selection *selection, SPDesktop *desktop, bool_op bop, const unsigned int verb, + const Glib::ustring description) +{ + SPDocument *doc = selection->desktop()->getDocument(); + BoolOpErrors returnCode = sp_selected_path_boolop(selection, bop); + switch(returnCode) { + case ERR_TOO_LESS_PATHS_1: + boolop_display_error_message(desktop, _("Select <b>at least 1 path</b> to perform a boolean union.")); + return; + case ERR_TOO_LESS_PATHS_2: + boolop_display_error_message(desktop, _("Select <b>at least 2 paths</b> to perform a boolean operation.")); + return; + case ERR_NO_PATHS: + boolop_display_error_message(desktop, _("One of the objects is <b>not a path</b>, cannot perform boolean operation.")); + return; + case ERR_Z_ORDER: + boolop_display_error_message(desktop, _("Unable to determine the <b>z-order</b> of the objects selected for difference, XOR, division, or path cut.")); + return; + case DONE_NO_PATH: + DocumentUndo::done(doc, SP_VERB_NONE, description); + return; + case DONE: + DocumentUndo::done(doc, verb, description); + return; + case DONE_NO_ACTION: + default: + return; + } } static @@ -880,9 +931,9 @@ void item_outline_add_marker_child( SPItem const *item, Geom::Affine marker_tran // note: a marker child item can be an item group! if (SP_IS_GROUP(item)) { // recurse through all childs: - for (SPObject const *o = item->firstChild() ; o ; o = o->getNext() ) { - if ( SP_IS_ITEM(o) ) { - item_outline_add_marker_child(SP_ITEM(o), tr, pathv_in); + for (auto& o: item->children) { + if ( SP_IS_ITEM(&o) ) { + item_outline_add_marker_child(SP_ITEM(&o), tr, pathv_in); } } } else { @@ -1150,6 +1201,7 @@ sp_item_path_outline(SPItem *item, SPDesktop *desktop, bool legacy) if (lpeitem) { lpeitem->removeAllPathEffects(true); } + SPGroup *group = dynamic_cast<SPGroup *>(item); if (group) { if (legacy) { @@ -1638,7 +1690,7 @@ sp_selected_path_outline(SPDesktop *desktop, bool legacy) bool scale_stroke = prefs->getBool("/options/transform/stroke", true); prefs->setBool("/options/transform/stroke", true); bool did = false; - std::vector<SPItem*> il(selection->itemList()); + std::vector<SPItem*> il(selection->items().begin(), selection->items().end()); for (std::vector<SPItem*>::const_iterator l = il.begin(); l != il.end(); l++){ SPItem *item = *l; did = sp_item_path_outline(item, desktop, legacy); @@ -1910,7 +1962,7 @@ sp_selected_path_do_offset(SPDesktop *desktop, bool expand, double prefOffset) } bool did = false; - std::vector<SPItem*> il(selection->itemList()); + std::vector<SPItem*> il(selection->items().begin(), selection->items().end()); for (std::vector<SPItem*>::const_iterator l = il.begin(); l != il.end(); l++){ SPItem *item = *l; SPCurve *curve = NULL; @@ -2335,7 +2387,7 @@ sp_selected_path_simplify_selection(SPDesktop *desktop, float threshold, bool ju return; } - std::vector<SPItem*> items(selection->itemList()); + std::vector<SPItem*> items(selection->items().begin(), selection->items().end()); bool didSomething = sp_selected_path_simplify_items(desktop, selection, items, threshold, diff --git a/src/splivarot.h b/src/splivarot.h index 665946f71..6adc05946 100644 --- a/src/splivarot.h +++ b/src/splivarot.h @@ -17,6 +17,7 @@ class SPItem; namespace Inkscape { class Selection; + class ObjectSet; } // boolean operations @@ -27,14 +28,17 @@ namespace Inkscape { // command-line mode, i.e. without a desktop. If a desktop is not // provided (desktop == NULL), error messages will be shown on stderr. void sp_selected_path_union (Inkscape::Selection *selection, SPDesktop *desktop); -void sp_selected_path_union_skip_undo (Inkscape::Selection *selection, SPDesktop *desktop); +void sp_selected_path_union_skip_undo (Inkscape::ObjectSet *set); void sp_selected_path_intersect (Inkscape::Selection *selection, SPDesktop *desktop); +void sp_selected_path_intersect_skip_undo (Inkscape::ObjectSet *set); void sp_selected_path_diff (Inkscape::Selection *selection, SPDesktop *desktop); -void sp_selected_path_diff_skip_undo (Inkscape::Selection *selection, SPDesktop *desktop); +void sp_selected_path_diff_skip_undo (Inkscape::ObjectSet *set); void sp_selected_path_symdiff (Inkscape::Selection *selection, SPDesktop *desktop); +void sp_selected_path_symdiff_skip_undo (Inkscape::ObjectSet *set); void sp_selected_path_cut (Inkscape::Selection *selection, SPDesktop *desktop); -void sp_selected_path_cut_skip_undo (Inkscape::Selection *selection, SPDesktop *desktop); +void sp_selected_path_cut_skip_undo (Inkscape::ObjectSet *set); void sp_selected_path_slice (Inkscape::Selection *selection, SPDesktop *desktop); +void sp_selected_path_slice_skip_undo (Inkscape::ObjectSet *set); // offset/inset of a curve // takes the fill-rule in consideration diff --git a/src/text-chemistry.cpp b/src/text-chemistry.cpp index ddadf8275..2b731c75d 100644 --- a/src/text-chemistry.cpp +++ b/src/text-chemistry.cpp @@ -42,8 +42,8 @@ using Inkscape::DocumentUndo; static SPItem * flowtext_in_selection(Inkscape::Selection *selection) { - std::vector<SPItem*> items = selection->itemList(); - for(std::vector<SPItem*>::const_iterator i=items.begin();i!=items.end();++i){ + auto items = selection->items(); + for(auto i=items.begin();i!=items.end();++i){ if (SP_IS_FLOWTEXT(*i)) return *i; } @@ -53,8 +53,8 @@ flowtext_in_selection(Inkscape::Selection *selection) static SPItem * text_or_flowtext_in_selection(Inkscape::Selection *selection) { - std::vector<SPItem*> items = selection->itemList(); - for(std::vector<SPItem*>::const_iterator i=items.begin();i!=items.end();++i){ + auto items = selection->items(); + for(auto i=items.begin();i!=items.end();++i){ if (SP_IS_TEXT(*i) || SP_IS_FLOWTEXT(*i)) return *i; } @@ -64,8 +64,8 @@ text_or_flowtext_in_selection(Inkscape::Selection *selection) static SPItem * shape_in_selection(Inkscape::Selection *selection) { - std::vector<SPItem*> items = selection->itemList(); - for(std::vector<SPItem*>::const_iterator i=items.begin();i!=items.end();++i){ + auto items = selection->items(); + for(auto i=items.begin();i!=items.end();++i){ if (SP_IS_SHAPE(*i)) return *i; } @@ -86,7 +86,7 @@ text_put_on_path() Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc(); - if (!text || !shape || selection->itemList().size() != 2) { + if (!text || !shape || boost::distance(selection->items()) != 2) { desktop->getMessageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>a text and a path</b> to put text on path.")); return; } @@ -141,8 +141,8 @@ text_put_on_path() // make a list of text children GSList *text_reprs = NULL; - for (SPObject *o = text->children; o != NULL; o = o->next) { - text_reprs = g_slist_prepend(text_reprs, o->getRepr()); + for(auto& o: text->children) { + text_reprs = g_slist_prepend(text_reprs, o.getRepr()); } // create textPath and put it into the text @@ -195,8 +195,8 @@ text_remove_from_path() } bool did = false; - std::vector<SPItem*> items(selection->itemList()); - for(std::vector<SPItem*>::const_iterator i=items.begin();i!=items.end();++i){ + auto items = selection->items(); + for(auto i=items.begin();i!=items.end();++i){ SPObject *obj = *i; if (SP_IS_TEXT_TEXTPATH(obj)) { @@ -213,7 +213,8 @@ text_remove_from_path() } else { DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_TEXT, _("Remove text from path")); - selection->setList(selection->itemList()); // reselect to update statusbar description + std::vector<SPItem *> vec(selection->items().begin(), selection->items().end()); + selection->setList(vec); // reselect to update statusbar description } } @@ -238,9 +239,9 @@ text_remove_all_kerns_recursively(SPObject *o) g_strfreev(xa_comma); } - for (SPObject *i = o->firstChild(); i != NULL; i = i->getNext()) { - text_remove_all_kerns_recursively(i); - i->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_TEXT_LAYOUT_MODIFIED_FLAG); + for (auto& i: o->children) { + text_remove_all_kerns_recursively(&i); + i.requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_TEXT_LAYOUT_MODIFIED_FLAG); } } @@ -259,8 +260,8 @@ text_remove_all_kerns() bool did = false; - std::vector<SPItem*> items = selection->itemList(); - for(std::vector<SPItem*>::const_iterator i=items.begin();i!=items.end();++i){ + auto items = selection->items(); + for(auto i=items.begin();i!=items.end();++i){ SPObject *obj = *i; if (!SP_IS_TEXT(obj) && !SP_IS_TSPAN(obj) && !SP_IS_FLOWTEXT(obj)) { @@ -295,7 +296,7 @@ text_flow_into_shape() SPItem *text = text_or_flowtext_in_selection(selection); SPItem *shape = shape_in_selection(selection); - if (!text || !shape || selection->itemList().size() < 2) { + if (!text || !shape || boost::distance(selection->items()) < 2) { desktop->getMessageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>a text</b> and one or more <b>paths or shapes</b> to flow text into frame.")); return; } @@ -319,8 +320,8 @@ text_flow_into_shape() g_return_if_fail(SP_IS_FLOWREGION(object)); /* Add clones */ - std::vector<SPItem*> items = selection->itemList(); - for(std::vector<SPItem*>::const_iterator i=items.begin();i!=items.end();++i){ + auto items = selection->items(); + for(auto i=items.begin();i!=items.end();++i){ SPItem *item = *i; if (SP_IS_SHAPE(item)){ Inkscape::XML::Node *clone = xml_doc->createElement("svg:use"); @@ -351,9 +352,9 @@ text_flow_into_shape() Inkscape::GC::release(text_repr); } else { // reflow an already flowed text, preserving paras - for (SPObject *o = text->children; o != NULL; o = o->next) { - if (SP_IS_FLOWPARA(o)) { - Inkscape::XML::Node *para_repr = o->getRepr()->duplicate(xml_doc); + for(auto& o: text->children) { + if (SP_IS_FLOWPARA(&o)) { + Inkscape::XML::Node *para_repr = o.getRepr()->duplicate(xml_doc); root_repr->appendChild(para_repr); object = doc->getObjectByRepr(para_repr); g_return_if_fail(SP_IS_FLOWPARA(object)); @@ -386,7 +387,7 @@ text_unflow () Inkscape::Selection *selection = desktop->getSelection(); - if (!flowtext_in_selection(selection) || selection->itemList().size() < 1) { + if (!flowtext_in_selection(selection) || boost::distance(selection->items()) < 1) { desktop->getMessageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>a flowed text</b> to unflow it.")); return; } @@ -394,8 +395,8 @@ text_unflow () std::vector<SPItem*> new_objs; GSList *old_objs = NULL; - std::vector<SPItem*> items = selection->itemList(); - for(std::vector<SPItem*>::const_iterator i=items.begin();i!=items.end();++i){ + auto items = selection->items(); + for(auto i=items.begin();i!=items.end();++i){ if (!SP_IS_FLOWTEXT(*i)) { continue; @@ -479,7 +480,7 @@ flowtext_to_text() bool did = false; std::vector<Inkscape::XML::Node*> reprs; - std::vector<SPItem*> items(selection->itemList()); + std::vector<SPItem*> items(selection->items().begin(), selection->items().end()); for(std::vector<SPItem*>::const_iterator i=items.begin();i!=items.end();++i){ SPItem *item = *i; diff --git a/src/text-editing.cpp b/src/text-editing.cpp index 6669abcef..6809a4bc5 100644 --- a/src/text-editing.cpp +++ b/src/text-editing.cpp @@ -89,8 +89,8 @@ bool sp_te_input_is_empty(SPObject const *item) if (SP_IS_STRING(item)) { empty = SP_STRING(item)->string.empty(); } else { - for (SPObject const *child = item->firstChild() ; child ; child = child->getNext()) { - if (!sp_te_input_is_empty(child)) { + for (auto& child: item->children) { + if (!sp_te_input_is_empty(&child)) { empty = false; break; } @@ -235,11 +235,11 @@ unsigned sp_text_get_length(SPObject const *item) length++; } - for (SPObject const *child = item->firstChild() ; child ; child = child->getNext()) { - if (SP_IS_STRING(child)) { - length += SP_STRING(child)->string.length(); + for (auto& child: item->children) { + if (SP_IS_STRING(&child)) { + length += SP_STRING(&child)->string.length(); } else { - length += sp_text_get_length(child); + length += sp_text_get_length(&child); } } } @@ -265,22 +265,22 @@ unsigned sp_text_get_length_upto(SPObject const *item, SPObject const *upto) } // Count the length of the children - for (SPObject const *child = item->firstChild() ; child ; child = child->getNext()) { - if (upto && child == upto) { + for (auto& child: item->children) { + if (upto && &child == upto) { // hit upto, return immediately return length; } - if (SP_IS_STRING(child)) { - length += SP_STRING(child)->string.length(); + if (SP_IS_STRING(&child)) { + length += SP_STRING(&child)->string.length(); } else { - if (upto && child->isAncestorOf(upto)) { + if (upto && child.isAncestorOf(upto)) { // upto is below us, recurse and break loop - length += sp_text_get_length_upto(child, upto); + length += sp_text_get_length_upto(&child, upto); return length; } else { // recurse and go to the next sibling - length += sp_text_get_length_upto(child, upto); + length += sp_text_get_length_upto(&child, upto); } } } @@ -321,8 +321,11 @@ to \a item at the same level. */ static unsigned sum_sibling_text_lengths_before(SPObject const *item) { unsigned char_index = 0; - for (SPObject *sibling = item->parent->firstChild() ; sibling && sibling != item ; sibling = sibling->getNext()) { - char_index += sp_text_get_length(sibling); + for (auto& sibling: item->parent->children) { + if (&sibling == item) { + break; + } + char_index += sp_text_get_length(&sibling); } return char_index; } @@ -855,11 +858,11 @@ static void sp_te_get_ustring_multiline(SPObject const *root, Glib::ustring *str if (*pending_line_break) { *string += '\n'; } - for (SPObject const *child = root->firstChild() ; child ; child = child->getNext()) { - if (SP_IS_STRING(child)) { - *string += SP_STRING(child)->string; + for (auto& child: root->children) { + if (SP_IS_STRING(&child)) { + *string += SP_STRING(&child)->string; } else { - sp_te_get_ustring_multiline(child, string, pending_line_break); + sp_te_get_ustring_multiline(&child, string, pending_line_break); } } if (!SP_IS_TEXT(root) && !SP_IS_TEXTPATH(root) && is_line_break_object(root)) { @@ -939,13 +942,10 @@ sp_te_set_repr_text_multiline(SPItem *text, gchar const *str) gchar *content = g_strdup (str); repr->setContent(""); - SPObject *child = object->firstChild(); - while (child) { - SPObject *next = child->getNext(); - if (!SP_IS_FLOWREGION(child) && !SP_IS_FLOWREGIONEXCLUDE(child)) { - repr->removeChild(child->getRepr()); + for (auto& child: object->children) { + if (!SP_IS_FLOWREGION(&child) && !SP_IS_FLOWREGIONEXCLUDE(&child)) { + repr->removeChild(child.getRepr()); } - child = next; } gchar *p = content; @@ -1403,17 +1403,17 @@ static void apply_css_recursive(SPObject *o, SPCSSAttr const *css) { sp_repr_css_change(o->getRepr(), const_cast<SPCSSAttr*>(css), "style"); - for (SPObject *child = o->firstChild() ; child ; child = child->getNext() ) { + for (auto& child: o->children) { if (sp_repr_css_property(const_cast<SPCSSAttr*>(css), "opacity", NULL) != NULL) { // Unset properties which are accumulating and thus should not be set recursively. // For example, setting opacity 0.5 on a group recursively would result in the visible opacity of 0.25 for an item in the group. SPCSSAttr *css_recurse = sp_repr_css_attr_new(); sp_repr_css_merge(css_recurse, const_cast<SPCSSAttr*>(css)); sp_repr_css_set_property(css_recurse, "opacity", NULL); - apply_css_recursive(child, css_recurse); + apply_css_recursive(&child, css_recurse); sp_repr_css_attr_unref(css_recurse); } else { - apply_css_recursive(child, const_cast<SPCSSAttr*>(css)); + apply_css_recursive(&child, const_cast<SPCSSAttr*>(css)); } } } @@ -1427,7 +1427,7 @@ static void recursively_apply_style(SPObject *common_ancestor, SPCSSAttr const * { bool passed_start = start_item == NULL ? true : false; Inkscape::XML::Document *xml_doc = common_ancestor->document->getReprDoc(); - + for (SPObject *child = common_ancestor->firstChild() ; child ; child = child->getNext()) { if (start_item == child) { passed_start = true; @@ -2071,8 +2071,8 @@ bool has_visible_text(SPObject *obj) if (SP_IS_STRING(obj) && !SP_STRING(obj)->string.empty()) { hasVisible = true; // maybe we should also check that it's not all whitespace? } else { - for (SPObject const *child = obj->firstChild() ; child ; child = child->getNext()) { - if (has_visible_text(const_cast<SPObject *>(child))) { + for (auto& child: obj->children) { + if (has_visible_text(const_cast<SPObject *>(&child))) { hasVisible = true; break; } diff --git a/src/trace/trace.cpp b/src/trace/trace.cpp index 379682668..52e99886a 100644 --- a/src/trace/trace.cpp +++ b/src/trace/trace.cpp @@ -65,7 +65,7 @@ SPImage *Tracer::getSelectedSPImage() if (sioxEnabled) { SPImage *img = NULL; - std::vector<SPItem*> const list = sel->itemList(); + auto list = sel->items(); std::vector<SPItem *> items; sioxShapes.clear(); @@ -74,7 +74,7 @@ SPImage *Tracer::getSelectedSPImage() them as bottom-to-top so that we can discover the image and any SPItems above it */ - for (std::vector<SPItem*>::const_iterator i=list.begin() ; list.end()!=i ; ++i) + for (auto i=list.begin() ; list.end()!=i ; ++i) { if (!SP_IS_ITEM(*i)) { diff --git a/src/ui/clipboard.cpp b/src/ui/clipboard.cpp index 14e9fdf32..66b13ed9d 100644 --- a/src/ui/clipboard.cpp +++ b/src/ui/clipboard.cpp @@ -510,8 +510,8 @@ bool ClipboardManagerImpl::pasteSize(SPDesktop *desktop, bool separately, bool a // resize each object in the selection if (separately) { - std::vector<SPItem*> itemlist=selection->itemList(); - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ + auto itemlist= selection->items(); + for(auto i=itemlist.begin();i!=itemlist.end();++i){ SPItem *item = *i; if (item) { Geom::OptRect obj_size = item->desktopVisualBounds(); @@ -527,8 +527,8 @@ bool ClipboardManagerImpl::pasteSize(SPDesktop *desktop, bool separately, bool a else { Geom::OptRect sel_size = selection->visualBounds(); if ( sel_size ) { - sp_selection_scale_relative(selection, sel_size->midpoint(), - _getScale(desktop, min, max, *sel_size, apply_x, apply_y)); + sp_object_set_scale_relative(selection, sel_size->midpoint(), + _getScale(desktop, min, max, *sel_size, apply_x, apply_y)); } } pasted = true; @@ -566,8 +566,8 @@ bool ClipboardManagerImpl::pastePathEffect(SPDesktop *desktop) desktop->doc()->importDefs(tempdoc); // make sure all selected items are converted to paths first (i.e. rectangles) sp_selected_to_lpeitems(desktop); - std::vector<SPItem*> itemlist=selection->itemList(); - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ + auto itemlist= selection->items(); + for(auto i=itemlist.begin();i!=itemlist.end();++i){ SPItem *item = *i; _applyPathEffect(item, effectstack); } @@ -649,9 +649,9 @@ Glib::ustring ClipboardManagerImpl::getShapeOrTextObjectId(SPDesktop *desktop) void ClipboardManagerImpl::_copySelection(Inkscape::Selection *selection) { // copy the defs used by all items - std::vector<SPItem*> itemlist=selection->itemList(); + auto itemlist= selection->items(); cloned_elements.clear(); - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ + for(auto i=itemlist.begin();i!=itemlist.end();++i){ SPItem *item = *i; if (item) { _copyUsedDefs(item); @@ -662,7 +662,7 @@ void ClipboardManagerImpl::_copySelection(Inkscape::Selection *selection) // copy the representation of the items std::vector<SPObject*> sorted_items; - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();++i) + for(auto i=itemlist.begin();i!=itemlist.end();++i) sorted_items.push_back(*i); sort(sorted_items.begin(),sorted_items.end(),sp_object_compare_position_bool); @@ -827,8 +827,8 @@ void ClipboardManagerImpl::_copyUsedDefs(SPItem *item) SPObject *mask = item->mask_ref->getObject(); _copyNode(mask->getRepr(), _doc, _defs); // recurse into the mask for its gradients etc. - for (SPObject *o = mask->children ; o != NULL ; o = o->next) { - SPItem *childItem = dynamic_cast<SPItem *>(o); + for(auto& o: mask->children) { + SPItem *childItem = dynamic_cast<SPItem *>(&o); if (childItem) { _copyUsedDefs(childItem); } @@ -845,8 +845,8 @@ void ClipboardManagerImpl::_copyUsedDefs(SPItem *item) } // recurse - for (SPObject *o = item->children ; o != NULL ; o = o->next) { - SPItem *childItem = dynamic_cast<SPItem *>(o); + for(auto& o: item->children) { + SPItem *childItem = dynamic_cast<SPItem *>(&o); if (childItem) { _copyUsedDefs(childItem); } @@ -882,8 +882,8 @@ void ClipboardManagerImpl::_copyPattern(SPPattern *pattern) _copyNode(pattern->getRepr(), _doc, _defs); // items in the pattern may also use gradients and other patterns, so recurse - for ( SPObject *child = pattern->firstChild() ; child ; child = child->getNext() ) { - SPItem *childItem = dynamic_cast<SPItem *>(child); + for (auto& child: pattern->children) { + SPItem *childItem = dynamic_cast<SPItem *>(&child); if (childItem) { _copyUsedDefs(childItem); } diff --git a/src/ui/dialog/align-and-distribute.cpp b/src/ui/dialog/align-and-distribute.cpp index 6006093ed..ed9ec3b0a 100644 --- a/src/ui/dialog/align-and-distribute.cpp +++ b/src/ui/dialog/align-and-distribute.cpp @@ -122,7 +122,7 @@ void ActionAlign::do_action(SPDesktop *desktop, int index) Inkscape::Preferences *prefs = Inkscape::Preferences::get(); bool sel_as_group = prefs->getBool("/dialogs/align/sel-as-groups"); - std::vector<SPItem*> selected(selection->itemList()); + std::vector<SPItem*> selected(selection->items().begin(), selection->items().end()); if (selected.empty()) return; const Coeffs &a = _allCoeffs[index]; @@ -282,7 +282,7 @@ private : Inkscape::Selection *selection = desktop->getSelection(); if (!selection) return; - std::vector<SPItem*> selected(selection->itemList()); + std::vector<SPItem*> selected(selection->items().begin(), selection->items().end()); if (selected.empty()) return; //Check 2 or more selected objects @@ -477,7 +477,9 @@ private : // xGap and yGap are the minimum space required between bounding rectangles. double const xGap = removeOverlapXGap.get_value(); double const yGap = removeOverlapYGap.get_value(); - removeoverlap(_dialog.getDesktop()->getSelection()->itemList(), xGap, yGap); + auto tmp = _dialog.getDesktop()->getSelection()->items(); + std::vector<SPItem *> vec(tmp.begin(), tmp.end()); + removeoverlap(vec, xGap, yGap); // restore compensation setting prefs->setInt("/options/clonecompensation/value", saved_compensation); @@ -508,8 +510,9 @@ private : int saved_compensation = prefs->getInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED); prefs->setInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED); - graphlayout(_dialog.getDesktop()->getSelection()->itemList()); - + auto tmp = _dialog.getDesktop()->getSelection()->items(); + std::vector<SPItem *> vec(tmp.begin(), tmp.end()); + graphlayout(vec); // restore compensation setting prefs->setInt("/options/clonecompensation/value", saved_compensation); @@ -568,7 +571,7 @@ private : Inkscape::Selection *selection = desktop->getSelection(); if (!selection) return; - std::vector<SPItem*> selected(selection->itemList()); + std::vector<SPItem*> selected(selection->items().begin(), selection->items().end()); if (selected.empty()) return; //Check 2 or more selected objects @@ -634,7 +637,8 @@ private : Inkscape::Preferences *prefs = Inkscape::Preferences::get(); int saved_compensation = prefs->getInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED); prefs->setInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED); - std::vector<SPItem*> x(_dialog.getDesktop()->getSelection()->itemList()); + auto tmp = _dialog.getDesktop()->getSelection()->items(); + std::vector<SPItem*> x(tmp.begin(), tmp.end()); unclump (x); // restore compensation setting @@ -665,7 +669,7 @@ private : Inkscape::Selection *selection = desktop->getSelection(); if (!selection) return; - std::vector<SPItem*> selected(selection->itemList()); + std::vector<SPItem*> selected(selection->items().begin(), selection->items().end()); if (selected.empty()) return; //Check 2 or more selected objects @@ -759,7 +763,7 @@ private : Inkscape::Selection *selection = desktop->getSelection(); if (!selection) return; - std::vector<SPItem*> selected(selection->itemList()); + std::vector<SPItem*> selected(selection->items().begin(), selection->items().end()); //Check 2 or more selected objects if (selected.size() < 2) return; diff --git a/src/ui/dialog/clonetiler.cpp b/src/ui/dialog/clonetiler.cpp index 97767e604..1fa7a6c71 100644 --- a/src/ui/dialog/clonetiler.cpp +++ b/src/ui/dialog/clonetiler.cpp @@ -1256,7 +1256,7 @@ void CloneTiler::clonetiler_change_selection(Inkscape::Selection *selection, Gtk return; } - if (selection->itemList().size() > 1) { + if (boost::distance(selection->items()) > 1) { gtk_widget_set_sensitive (buttons, FALSE); gtk_label_set_markup (GTK_LABEL(status), _("<small>More than one object selected.</small>")); return; @@ -1922,12 +1922,12 @@ void CloneTiler::clonetiler_trace_hide_tiled_clones_recursively(SPObject *from) if (!trace_drawing) return; - for (SPObject *o = from->firstChild(); o != NULL; o = o->next) { - SPItem *item = dynamic_cast<SPItem *>(o); - if (item && clonetiler_is_a_clone_of(o, NULL)) { + for (auto& o: from->children) { + SPItem *item = dynamic_cast<SPItem *>(&o); + if (item && clonetiler_is_a_clone_of(&o, NULL)) { item->invoke_hide(trace_visionkey); // FIXME: hide each tiled clone's original too! } - clonetiler_trace_hide_tiled_clones_recursively (o); + clonetiler_trace_hide_tiled_clones_recursively (&o); } } @@ -1993,7 +1993,7 @@ void CloneTiler::clonetiler_unclump(GtkWidget */*widget*/, void *) Inkscape::Selection *selection = desktop->getSelection(); // check if something is selected - if (selection->isEmpty() || selection->itemList().size() > 1) { + if (selection->isEmpty() || boost::distance(selection->items()) > 1) { desktop->getMessageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>one object</b> whose tiled clones to unclump.")); return; } @@ -2003,9 +2003,9 @@ void CloneTiler::clonetiler_unclump(GtkWidget */*widget*/, void *) std::vector<SPItem*> to_unclump; // not including the original - for (SPObject *child = parent->firstChild(); child != NULL; child = child->next) { - if (clonetiler_is_a_clone_of (child, obj)) { - to_unclump.push_back((SPItem*)child); + for (auto& child: parent->children) { + if (clonetiler_is_a_clone_of (&child, obj)) { + to_unclump.push_back((SPItem*)&child); } } @@ -2023,8 +2023,8 @@ guint CloneTiler::clonetiler_number_of_clones(SPObject *obj) guint n = 0; - for (SPObject *child = parent->firstChild(); child != NULL; child = child->next) { - if (clonetiler_is_a_clone_of (child, obj)) { + for (auto& child: parent->children) { + if (clonetiler_is_a_clone_of (&child, obj)) { n ++; } } @@ -2042,7 +2042,7 @@ void CloneTiler::clonetiler_remove(GtkWidget */*widget*/, GtkWidget *dlg, bool d Inkscape::Selection *selection = desktop->getSelection(); // check if something is selected - if (selection->isEmpty() || selection->itemList().size() > 1) { + if (selection->isEmpty() || boost::distance(selection->items()) > 1) { desktop->getMessageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select <b>one object</b> whose tiled clones to remove.")); return; } @@ -2052,9 +2052,9 @@ void CloneTiler::clonetiler_remove(GtkWidget */*widget*/, GtkWidget *dlg, bool d // remove old tiling GSList *to_delete = NULL; - for (SPObject *child = parent->firstChild(); child != NULL; child = child->next) { - if (clonetiler_is_a_clone_of (child, obj)) { - to_delete = g_slist_prepend (to_delete, child); + for (auto& child: parent->children) { + if (clonetiler_is_a_clone_of (&child, obj)) { + to_delete = g_slist_prepend (to_delete, &child); } } for (GSList *i = to_delete; i; i = i->next) { @@ -2120,7 +2120,7 @@ void CloneTiler::clonetiler_apply(GtkWidget */*widget*/, GtkWidget *dlg) } // Check if more than one object is selected. - if (selection->itemList().size() > 1) { + if (boost::distance(selection->items()) > 1) { desktop->getMessageStack()->flash(Inkscape::ERROR_MESSAGE, _("If you want to clone several objects, <b>group</b> them and <b>clone the group</b>.")); return; } diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp index 88fefe4f2..053549b73 100644 --- a/src/ui/dialog/document-properties.cpp +++ b/src/ui/dialog/document-properties.cpp @@ -1176,12 +1176,7 @@ void DocumentProperties::changeEmbeddedScript(){ for (std::vector<SPObject *>::const_iterator it = current.begin(); it != current.end(); ++it) { SPObject* obj = *it; if (id == obj->getId()){ - - int count=0; - for ( SPObject *child = obj->children ; child; child = child->next ) - { - count++; - } + int count = (int) obj->children.size(); if (count>1) g_warning("TODO: Found a script element with multiple (%d) child nodes! We must implement support for that!", count); @@ -1225,8 +1220,11 @@ void DocumentProperties::editEmbeddedScript(){ //XML Tree being used directly here while it shouldn't be. Inkscape::XML::Node *repr = obj->getRepr(); if (repr){ - SPObject *child; - while (NULL != (child = obj->firstChild())) child->deleteObject(); + auto tmp = obj->children | boost::adaptors::transformed([](SPObject& o) { return &o; }); + std::vector<SPObject*> vec(tmp.begin(), tmp.end()); + for (auto &child: vec) { + child->deleteObject(); + } obj->appendChildRepr(xml_doc->createTextNode(_EmbeddedContent.get_buffer()->get_text().c_str())); //TODO repr->set_content(_EmbeddedContent.get_buffer()->get_text()); diff --git a/src/ui/dialog/export.cpp b/src/ui/dialog/export.cpp index effbfc74d..670e4c8b5 100644 --- a/src/ui/dialog/export.cpp +++ b/src/ui/dialog/export.cpp @@ -543,7 +543,7 @@ void Export::onBatchClicked () void Export::updateCheckbuttons () { - gint num = SP_ACTIVE_DESKTOP->getSelection()->itemList().size(); + gint num = (gint) boost::distance(SP_ACTIVE_DESKTOP->getSelection()->items()); if (num >= 2) { batch_export.set_sensitive(true); batch_export.set_label(g_strdup_printf (ngettext("B_atch export %d selected object","B_atch export %d selected objects",num), num)); @@ -749,14 +749,14 @@ void Export::onAreaToggled () case SELECTION_SELECTION: if ((SP_ACTIVE_DESKTOP->getSelection())->isEmpty() == false) { - sp_selection_get_export_hints (SP_ACTIVE_DESKTOP->getSelection(), filename, &xdpi, &ydpi); + sp_object_set_get_export_hints(SP_ACTIVE_DESKTOP->getSelection(), filename, &xdpi, &ydpi); /* If we still don't have a filename -- let's build one that's nice */ if (filename.empty()) { const gchar * id = "object"; - const std::vector<XML::Node*> reprlst = SP_ACTIVE_DESKTOP->getSelection()->reprList(); - for(std::vector<XML::Node*>::const_iterator i=reprlst.begin(); reprlst.end() != i; ++i) { + auto reprlst = SP_ACTIVE_DESKTOP->getSelection()->xmlNodes(); + for(auto i=reprlst.begin(); reprlst.end() != i; ++i) { Inkscape::XML::Node * repr = *i; if (repr->attribute("id")) { id = repr->attribute("id"); @@ -946,7 +946,7 @@ void Export::onExport () if (batch_export.get_active ()) { // Batch export of selected objects - gint num = (desktop->getSelection()->itemList()).size(); + gint num = (gint) boost::distance(desktop->getSelection()->items()); gint n = 0; if (num < 1) { @@ -960,8 +960,8 @@ void Export::onExport () gint export_count = 0; - std::vector<SPItem*> itemlist=desktop->getSelection()->itemList(); - for(std::vector<SPItem*>::const_iterator i = itemlist.begin();i!=itemlist.end() && !interrupted ;++i){ + auto itemlist= desktop->getSelection()->items(); + for(auto i = itemlist.begin();i!=itemlist.end() && !interrupted ;++i){ SPItem *item = *i; prog_dlg->set_data("current", GINT_TO_POINTER(n)); @@ -1001,12 +1001,13 @@ void Export::onExport () MessageCleaner msgFlashCleanup(desktop->messageStack()->flashF(Inkscape::IMMEDIATE_MESSAGE, _("Exporting file <b>%s</b>..."), safeFile), desktop); std::vector<SPItem*> x; + std::vector<SPItem*> selected(desktop->getSelection()->items().begin(), desktop->getSelection()->items().end()); if (!sp_export_png_file (doc, path.c_str(), *area, width, height, dpi, dpi, nv->pagecolor, onProgressCallback, (void*)prog_dlg, TRUE, // overwrite without asking - hide ? (desktop->getSelection()->itemList()) : x + hide ? selected : x )) { gchar * error = g_strdup_printf(_("Could not export to filename %s.\n"), safeFile); @@ -1091,12 +1092,13 @@ void Export::onExport () /* Do export */ std::vector<SPItem*> x; + std::vector<SPItem*> selected(desktop->getSelection()->items().begin(), desktop->getSelection()->items().end()); ExportResult status = sp_export_png_file(desktop->getDocument(), path.c_str(), Geom::Rect(Geom::Point(x0, y0), Geom::Point(x1, y1)), width, height, xdpi, ydpi, nv->pagecolor, onProgressCallback, (void*)prog_dlg, FALSE, - hide ? (desktop->getSelection()->itemList()) : x + hide ? selected : x ); if (status == EXPORT_ERROR) { gchar * safeFile = Inkscape::IO::sanitizeString(path.c_str()); @@ -1162,15 +1164,14 @@ void Export::onExport () break; } case SELECTION_SELECTION: { - std::vector<XML::Node*> reprlst; SPDocument * doc = SP_ACTIVE_DOCUMENT; bool modified = false; bool saved = DocumentUndo::getUndoSensitive(doc); DocumentUndo::setUndoSensitive(doc, false); - reprlst = desktop->getSelection()->reprList(); + auto reprlst = desktop->getSelection()->xmlNodes(); - for(std::vector<Inkscape::XML::Node*>::const_iterator i=reprlst.begin(); reprlst.end() != i; ++i) { + for(auto i=reprlst.begin(); reprlst.end() != i; ++i) { Inkscape::XML::Node * repr = *i; const gchar * temp_string; Glib::ustring dir = Glib::path_get_dirname(filename.c_str()); diff --git a/src/ui/dialog/filter-effects-dialog.cpp b/src/ui/dialog/filter-effects-dialog.cpp index 97fa47f2f..8dbc90cc5 100644 --- a/src/ui/dialog/filter-effects-dialog.cpp +++ b/src/ui/dialog/filter-effects-dialog.cpp @@ -84,9 +84,7 @@ static int input_count(const SPFilterPrimitive* prim) return 2; else if(SP_IS_FEMERGE(prim)) { // Return the number of feMergeNode connections plus an extra - int count = 1; - for(const SPObject* o = prim->firstChild(); o; o = o->next, ++count){}; - return count; + return (int) (prim->children.size() + 1); } else return 1; @@ -655,7 +653,7 @@ private: void select_svg_element(){ Inkscape::Selection* sel = _desktop->getSelection(); if (sel->isEmpty()) return; - Inkscape::XML::Node* node = sel->reprList()[0]; + Inkscape::XML::Node* node = sel->xmlNodes().front(); if (!node || !node->matchAttributeName("id")) return; std::ostringstream xlikhref; @@ -1024,11 +1022,10 @@ public: // FuncNode can be in any order so we must search to find correct one. SPFeFuncNode* find_node(SPFeComponentTransfer* ct) { - SPObject* node = ct->children; SPFeFuncNode* funcNode = NULL; bool found = false; - for(;node;node=node->next){ - funcNode = SP_FEFUNCNODE(node); + for(auto& node: ct->children) { + funcNode = SP_FEFUNCNODE(&node); if( funcNode->channel == _channel ) { found = true; break; @@ -1192,7 +1189,7 @@ protected: _locked = true; - SPObject* child = o->children; + SPObject* child = o->firstChild(); if(SP_IS_FEDISTANTLIGHT(child)) _light_source.set_active(0); @@ -1217,7 +1214,7 @@ private: if(prim) { _locked = true; - SPObject* child = prim->children; + SPObject* child = prim->firstChild(); const int ls = _light_source.get_active_row_number(); // Check if the light source type has changed if(!(ls == -1 && !child) && @@ -1251,8 +1248,8 @@ private: _light_box.show_all(); SPFilterPrimitive* prim = _dialog._primitive_list.get_selected(); - if(prim && prim->children) - _settings.show_and_update(_light_source.get_active_data()->id, prim->children); + if(prim && prim->firstChild()) + _settings.show_and_update(_light_source.get_active_data()->id, prim->firstChild()); } FilterEffectsDialog& _dialog; @@ -1438,8 +1435,8 @@ void FilterEffectsDialog::FilterModifier::update_selection(Selection *sel) } std::set<SPObject*> used; - std::vector<SPItem*> itemlist=sel->itemList(); - for(std::vector<SPItem*>::const_iterator i=itemlist.begin(); itemlist.end() != i; ++i) { + auto itemlist= sel->items(); + for(auto i=itemlist.begin(); itemlist.end() != i; ++i) { SPObject *obj = *i; SPStyle *style = obj->style; if (!style || !SP_IS_ITEM(obj)) { @@ -1519,8 +1516,8 @@ void FilterEffectsDialog::FilterModifier::on_selection_toggled(const Glib::ustri if((*iter)[_columns.sel] == 1) filter = 0; - std::vector<SPItem*> itemlist=sel->itemList(); - for(std::vector<SPItem*>::const_iterator i=itemlist.begin(); itemlist.end() != i; ++i) { + auto itemlist= sel->items(); + for(auto i=itemlist.begin(); itemlist.end() != i; ++i) { SPItem * item = *i; SPStyle *style = item->style; g_assert(style != NULL); @@ -1808,26 +1805,25 @@ void FilterEffectsDialog::PrimitiveList::update() bool active_found = false; _dialog._primitive_box->set_sensitive(true); _dialog.update_filter_general_settings_view(); - for(SPObject *prim_obj = f->children; - prim_obj && SP_IS_FILTER_PRIMITIVE(prim_obj); - prim_obj = prim_obj->next) { - SPFilterPrimitive *prim = SP_FILTER_PRIMITIVE(prim_obj); - if(prim) { - Gtk::TreeModel::Row row = *_model->append(); - row[_columns.primitive] = prim; - - //XML Tree being used directly here while it shouldn't be. - row[_columns.type_id] = FPConverter.get_id_from_key(prim->getRepr()->name()); - row[_columns.type] = _(FPConverter.get_label(row[_columns.type_id]).c_str()); - - if (prim->getId()) { - row[_columns.id] = Glib::ustring(prim->getId()); - } - - if(prim == active_prim) { - get_selection()->select(row); - active_found = true; - } + for(auto& prim_obj: f->children) { + SPFilterPrimitive *prim = SP_FILTER_PRIMITIVE(&prim_obj); + if(!prim) { + break; + } + Gtk::TreeModel::Row row = *_model->append(); + row[_columns.primitive] = prim; + + //XML Tree being used directly here while it shouldn't be. + row[_columns.type_id] = FPConverter.get_id_from_key(prim->getRepr()->name()); + row[_columns.type] = _(FPConverter.get_label(row[_columns.type_id]).c_str()); + + if (prim->getId()) { + row[_columns.id] = Glib::ustring(prim->getId()); + } + + if(prim == active_prim) { + get_selection()->select(row); + active_found = true; } } @@ -2214,11 +2210,12 @@ const Gtk::TreeIter FilterEffectsDialog::PrimitiveList::find_result(const Gtk::T if(SP_IS_FEMERGE(prim)) { int c = 0; bool found = false; - for(const SPObject* o = prim->firstChild(); o; o = o->next, ++c) { - if(c == attr && SP_IS_FEMERGENODE(o)) { - image = SP_FEMERGENODE(o)->input; + for (auto& o: prim->children) { + if(c == attr && SP_IS_FEMERGENODE(&o)) { + image = SP_FEMERGENODE(&o)->input; found = true; } + ++c; } if(!found) return target; @@ -2405,21 +2402,23 @@ bool FilterEffectsDialog::PrimitiveList::on_button_release_event(GdkEventButton* if(SP_IS_FEMERGE(prim)) { int c = 1; bool handled = false; - for(SPObject* o = prim->firstChild(); o && !handled; o = o->next, ++c) { - if(c == _in_drag && SP_IS_FEMERGENODE(o)) { + for (auto& o: prim->children) { + if(c == _in_drag && SP_IS_FEMERGENODE(&o)) { // If input is null, delete it if(!in_val) { //XML Tree being used directly here while it shouldn't be. - sp_repr_unparent(o->getRepr()); + sp_repr_unparent(o.getRepr()); DocumentUndo::done(prim->document, SP_VERB_DIALOG_FILTER_EFFECTS, _("Remove merge node")); (*get_selection()->get_selected())[_columns.primitive] = prim; + } else { + _dialog.set_attr(&o, SP_ATTR_IN, in_val); } - else - _dialog.set_attr(o, SP_ATTR_IN, in_val); handled = true; + break; } + ++c; } // Add new input? if(!handled && c == _in_drag && in_val) { @@ -2938,7 +2937,7 @@ void FilterEffectsDialog::set_filternode_attr(const AttrWidget* input) void FilterEffectsDialog::set_child_attr_direct(const AttrWidget* input) { - set_attr(_primitive_list.get_selected()->children, input->get_attribute(), input->get_as_attribute().c_str()); + set_attr(_primitive_list.get_selected()->firstChild(), input->get_attribute(), input->get_as_attribute().c_str()); } void FilterEffectsDialog::set_attr(SPObject* o, const SPAttributeEnum attr, const gchar* val) diff --git a/src/ui/dialog/find.cpp b/src/ui/dialog/find.cpp index 8b6067e82..b4f7902f5 100644 --- a/src/ui/dialog/find.cpp +++ b/src/ui/dialog/find.cpp @@ -740,22 +740,22 @@ std::vector<SPItem*> &Find::all_items (SPObject *r, std::vector<SPItem*> &l, boo return l; // we're not interested in metadata } - for (SPObject *child = r->firstChild(); child; child = child->getNext()) { - SPItem *item = dynamic_cast<SPItem *>(child); - if (item && !child->cloned && !desktop->isLayer(item)) { + for (auto& child: r->children) { + SPItem *item = dynamic_cast<SPItem *>(&child); + if (item && !child.cloned && !desktop->isLayer(item)) { if ((hidden || !desktop->itemIsHidden(item)) && (locked || !item->isLocked())) { - l.insert(l.begin(),(SPItem*)child); + l.insert(l.begin(),(SPItem*)&child); } } - l = all_items (child, l, hidden, locked); + l = all_items (&child, l, hidden, locked); } return l; } std::vector<SPItem*> &Find::all_selection_items (Inkscape::Selection *s, std::vector<SPItem*> &l, SPObject *ancestor, bool hidden, bool locked) { - std::vector<SPItem*> itemlist=s->itemList(); - for(std::vector<SPItem*>::const_reverse_iterator i=itemlist.rbegin(); itemlist.rend() != i; ++i) { + auto itemlist= s->items(); + for(auto i=boost::rbegin(itemlist); boost::rend(itemlist) != i; ++i) { SPObject *obj = *i; SPItem *item = dynamic_cast<SPItem *>(obj); g_assert(item != NULL); diff --git a/src/ui/dialog/font-substitution.cpp b/src/ui/dialog/font-substitution.cpp index 76af412ca..abae8ea70 100644 --- a/src/ui/dialog/font-substitution.cpp +++ b/src/ui/dialog/font-substitution.cpp @@ -173,7 +173,7 @@ std::vector<SPItem*> FontSubstitution::getFontReplacedItems(SPDocument* doc, Gli family = SP_TEXT(parent_text)->layout.getFontFamily(0); // Add all the spans fonts to the set gint ii = 0; - for (SPObject *child = parent_text->firstChild() ; child ; child = child->getNext() ) { + for (auto& child: parent_text->children) { family = SP_TEXT(parent_text)->layout.getFontFamily(ii); setFontSpans.insert(family); ii++; diff --git a/src/ui/dialog/glyphs.cpp b/src/ui/dialog/glyphs.cpp index 3b9a13bdb..9c1236ca9 100644 --- a/src/ui/dialog/glyphs.cpp +++ b/src/ui/dialog/glyphs.cpp @@ -516,8 +516,8 @@ void GlyphsPanel::setTargetDesktop(SPDesktop *desktop) void GlyphsPanel::insertText() { SPItem *textItem = 0; - std::vector<SPItem*> itemlist=targetDesktop->selection->itemList(); - for(std::vector<SPItem*>::const_iterator i=itemlist.begin(); itemlist.end() != i; ++i) { + auto itemlist= targetDesktop->selection->items(); + for(auto i=itemlist.begin(); itemlist.end() != i; ++i) { if (SP_IS_TEXT(*i) || SP_IS_FLOWTEXT(*i)) { textItem = *i; break; @@ -617,8 +617,8 @@ void GlyphsPanel::selectionModifiedCB(guint flags) void GlyphsPanel::calcCanInsert() { int items = 0; - std::vector<SPItem*> itemlist=targetDesktop->selection->itemList(); - for(std::vector<SPItem*>::const_iterator i=itemlist.begin(); itemlist.end() != i; ++i) { + auto itemlist= targetDesktop->selection->items(); + for(auto i=itemlist.begin(); itemlist.end() != i; ++i) { if (SP_IS_TEXT(*i) || SP_IS_FLOWTEXT(*i)) { ++items; } diff --git a/src/ui/dialog/grid-arrange-tab.cpp b/src/ui/dialog/grid-arrange-tab.cpp index de84abd12..5872393ae 100644 --- a/src/ui/dialog/grid-arrange-tab.cpp +++ b/src/ui/dialog/grid-arrange-tab.cpp @@ -156,7 +156,11 @@ void GridArrangeTab::arrange() desktop->getDocument()->ensureUpToDate(); Inkscape::Selection *selection = desktop->getSelection(); - const std::vector<SPItem*> items = selection ? selection->itemList() : std::vector<SPItem*>(); + std::vector<SPItem*> items; + if (selection) { + items.insert(items.end(), selection->items().begin(), selection->items().end()); + } + for(std::vector<SPItem*>::const_iterator i = items.begin();i!=items.end(); ++i){ SPItem *item = *i; Geom::OptRect b = item->documentVisualBounds(); @@ -185,7 +189,7 @@ void GridArrangeTab::arrange() // require the sorting done before we can calculate row heights etc. g_return_if_fail(selection); - std::vector<SPItem*> sorted(selection->itemList()); + std::vector<SPItem*> sorted(selection->items().begin(), selection->items().end()); sort(sorted.begin(),sorted.end(),sp_compare_y_position); sort(sorted.begin(),sorted.end(),sp_compare_x_position); @@ -361,8 +365,7 @@ void GridArrangeTab::on_row_spinbutton_changed() Inkscape::Selection *selection = desktop ? desktop->selection : 0; g_return_if_fail( selection ); - std::vector<SPItem*> const items = selection->itemList(); - int selcount = items.size(); + int selcount = (int) boost::distance(selection->items()); double PerCol = ceil(selcount / NoOfColsSpinner.get_value()); NoOfRowsSpinner.set_value(PerCol); @@ -387,7 +390,7 @@ void GridArrangeTab::on_col_spinbutton_changed() Inkscape::Selection *selection = desktop ? desktop->selection : 0; g_return_if_fail(selection); - int selcount = selection->itemList().size(); + int selcount = (int) boost::distance(selection->items()); double PerRow = ceil(selcount / NoOfRowsSpinner.get_value()); NoOfColsSpinner.set_value(PerRow); @@ -524,7 +527,10 @@ void GridArrangeTab::updateSelection() updating = true; SPDesktop *desktop = Parent->getDesktop(); Inkscape::Selection *selection = desktop ? desktop->selection : 0; - std::vector<SPItem*> const items = selection ? selection->itemList() : std::vector<SPItem*>(); + std::vector<SPItem*> items; + if (selection) { + items.insert(items.end(), selection->items().begin(), selection->items().end()); + } if (!items.empty()) { int selcount = items.size(); @@ -591,7 +597,7 @@ GridArrangeTab::GridArrangeTab(ArrangeDialog *parent) g_return_if_fail( selection ); int selcount = 1; if (!selection->isEmpty()) { - selcount = selection->itemList().size(); + selcount = (int) boost::distance(selection->items()); } diff --git a/src/ui/dialog/icon-preview.cpp b/src/ui/dialog/icon-preview.cpp index 8dd0ae489..a4fcc9947 100644 --- a/src/ui/dialog/icon-preview.cpp +++ b/src/ui/dialog/icon-preview.cpp @@ -359,8 +359,8 @@ void IconPreviewPanel::refreshPreview() if ( sel ) { //g_message("found a selection to play with"); - std::vector<SPItem*> const items = sel->itemList(); - for(std::vector<SPItem*>::const_iterator i=items.begin();!target && i!=items.end();++i){ + auto items = sel->items(); + for(auto i=items.begin();!target && i!=items.end();++i){ SPItem* item = *i; gchar const *id = item->getId(); if ( id ) { diff --git a/src/ui/dialog/objects.cpp b/src/ui/dialog/objects.cpp index 471097797..09ffc9c4c 100644 --- a/src/ui/dialog/objects.cpp +++ b/src/ui/dialog/objects.cpp @@ -330,12 +330,11 @@ void ObjectsPanel::_objectsChanged(SPObject */*obj*/) void ObjectsPanel::_addObject(SPObject* obj, Gtk::TreeModel::Row* parentRow) { if ( _desktop && obj ) { - for ( SPObject *child = obj->children; child != NULL; child = child->next) { - - if (SP_IS_ITEM(child)) + for(auto& child: obj->children) { + if (SP_IS_ITEM(&child)) { - SPItem * item = SP_ITEM(child); - SPGroup * group = SP_IS_GROUP(child) ? SP_GROUP(child) : 0; + SPItem * item = SP_ITEM(&child); + SPGroup * group = SP_IS_GROUP(&child) ? SP_GROUP(&child) : 0; //Add the item to the tree and set the column information Gtk::TreeModel::iterator iter = parentRow ? _store->prepend(parentRow->children()) : _store->prepend(); @@ -362,14 +361,14 @@ void ObjectsPanel::_addObject(SPObject* obj, Gtk::TreeModel::Row* parentRow) } //Add an object watcher to the item - ObjectsPanel::ObjectWatcher *w = new ObjectsPanel::ObjectWatcher(this, child); - child->getRepr()->addObserver(*w); + ObjectsPanel::ObjectWatcher *w = new ObjectsPanel::ObjectWatcher(this, &child); + child.getRepr()->addObserver(*w); _objectWatchers.push_back(w); //If the item is a group, recursively add its children if (group) { - _addObject( child, &row ); + _addObject( &child, &row ); } } } @@ -389,9 +388,8 @@ void ObjectsPanel::_updateObject( SPObject *obj, bool recurse ) { //end mark if (recurse) { - for (SPObject * iter = obj->children; iter != NULL; iter = iter->next) - { - _updateObject(iter, recurse); + for (auto& iter: obj->children) { + _updateObject(&iter, recurse); } } } @@ -468,8 +466,8 @@ void ObjectsPanel::_objectsSelected( Selection *sel ) { _selectedConnection.block(); _tree.get_selection()->unselect_all(); SPItem *item = NULL; - std::vector<SPItem*> const items = sel->itemList(); - for(std::vector<SPItem*>::const_iterator i=items.begin(); i!=items.end(); ++i){ + auto items = sel->items(); + for(auto i=items.begin(); i!=items.end(); ++i){ item = *i; if (setOpacity) { @@ -506,19 +504,22 @@ void ObjectsPanel::_setCompositingValues(SPItem *item) SPGaussianBlur *spblur = NULL; if (item->style->getFilter()) { - for(SPObject *primitive_obj = item->style->getFilter()->children; primitive_obj && SP_IS_FILTER_PRIMITIVE(primitive_obj); primitive_obj = primitive_obj->next) { - if(SP_IS_FEBLEND(primitive_obj) && !spblend) { - //Get the blend mode - spblend = SP_FEBLEND(primitive_obj); - } - - if(SP_IS_GAUSSIANBLUR(primitive_obj) && !spblur) { - //Get the blur value - spblur = SP_GAUSSIANBLUR(primitive_obj); - } + for (auto& primitive_obj: item->style->getFilter()->children) { + if (!SP_IS_FILTER_PRIMITIVE(&primitive_obj)) { + break; } + if(SP_IS_FEBLEND(&primitive_obj) && !spblend) { + //Get the blend mode + spblend = SP_FEBLEND(&primitive_obj); + } + + if(SP_IS_GAUSSIANBLUR(&primitive_obj) && !spblur) { + //Get the blur value + spblur = SP_GAUSSIANBLUR(&primitive_obj); + } + } } - + //Set the blend mode _fe_cb.set_blend_mode(spblend ? spblend->blend_mode : Inkscape::Filters::BLEND_NORMAL); @@ -1278,9 +1279,9 @@ bool ObjectsPanel::_executeAction() break; case BUTTON_COLLAPSE_ALL: { - for (SPObject* obj = _document->getRoot()->firstChild(); obj != NULL; obj = obj->next) { - if (SP_IS_GROUP(obj)) { - _setCollapsed(SP_GROUP(obj)); + for (auto& obj: _document->getRoot()->children) { + if (SP_IS_GROUP(&obj)) { + _setCollapsed(SP_GROUP(&obj)); } } _objectsChanged(_document->getRoot()); @@ -1390,9 +1391,10 @@ void ObjectsPanel::_setCollapsed(SPGroup * group) { group->setExpanded(false); group->updateRepr(SP_OBJECT_WRITE_NO_CHILDREN | SP_OBJECT_WRITE_EXT); - for (SPObject *iter = group->children; iter != NULL; iter = iter->next) - { - if (SP_IS_GROUP(iter)) _setCollapsed(SP_GROUP(iter)); + for (auto& iter: group->children) { + if (SP_IS_GROUP(&iter)) { + _setCollapsed(SP_GROUP(&iter)); + } } } @@ -1503,11 +1505,14 @@ void ObjectsPanel::_blendChangedIter(const Gtk::TreeIter& iter, Glib::ustring bl if (blendmode != "normal") { gdouble radius = 0; if (item->style->getFilter()) { - for (SPObject *primitive = item->style->getFilter()->children; primitive && SP_IS_FILTER_PRIMITIVE(primitive); primitive = primitive->next) { - if (SP_IS_GAUSSIANBLUR(primitive)) { + for (auto& primitive: item->style->getFilter()->children) { + if (!SP_IS_FILTER_PRIMITIVE(&primitive)) { + break; + } + if (SP_IS_GAUSSIANBLUR(&primitive)) { Geom::OptRect bbox = item->bounds(SPItem::GEOMETRIC_BBOX); if (bbox) { - radius = SP_GAUSSIANBLUR(primitive)->stdDeviation.getNumber(); + radius = SP_GAUSSIANBLUR(&primitive)->stdDeviation.getNumber(); } } } @@ -1515,13 +1520,16 @@ void ObjectsPanel::_blendChangedIter(const Gtk::TreeIter& iter, Glib::ustring bl SPFilter *filter = new_filter_simple_from_item(_document, item, blendmode.c_str(), radius); sp_style_set_property_url(item, "filter", filter, false); } else { - for (SPObject *primitive = item->style->getFilter()->children; primitive && SP_IS_FILTER_PRIMITIVE(primitive); primitive = primitive->next) { - if (SP_IS_FEBLEND(primitive)) { - primitive->deleteObject(); + for (auto& primitive: item->style->getFilter()->children) { + if (!SP_IS_FILTER_PRIMITIVE(&primitive)) { + break; + } + if (SP_IS_FEBLEND(&primitive)) { + primitive.deleteObject(); break; } } - if (!item->style->getFilter()->children) { + if (!item->style->getFilter()->firstChild()) { remove_filter(item, false); } } @@ -1572,13 +1580,16 @@ void ObjectsPanel::_blurChangedIter(const Gtk::TreeIter& iter, double blur) SPFilter *filter = modify_filter_gaussian_blur_from_item(_document, item, radius); sp_style_set_property_url(item, "filter", filter, false); } else if (item->style->filter.set && item->style->getFilter()) { - for (SPObject *primitive = item->style->getFilter()->children; primitive && SP_IS_FILTER_PRIMITIVE(primitive); primitive = primitive->next) { - if (SP_IS_GAUSSIANBLUR(primitive)) { - primitive->deleteObject(); + for (auto& primitive: item->style->getFilter()->children) { + if (!SP_IS_FILTER_PRIMITIVE(&primitive)) { + break; + } + if (SP_IS_GAUSSIANBLUR(&primitive)) { + primitive.deleteObject(); break; } } - if (!item->style->getFilter()->children) { + if (!item->style->getFilter()->firstChild()) { remove_filter(item, false); } } diff --git a/src/ui/dialog/pixelartdialog.cpp b/src/ui/dialog/pixelartdialog.cpp index 62e6bf591..b838b0842 100644 --- a/src/ui/dialog/pixelartdialog.cpp +++ b/src/ui/dialog/pixelartdialog.cpp @@ -366,8 +366,8 @@ void PixelArtDialogImpl::vectorize() return; } - std::vector<SPItem*> const items = desktop->selection->itemList(); - for(std::vector<SPItem*>::const_iterator i=items.begin(); i!=items.end();++i){ + auto items = desktop->selection->items(); + for(auto i=items.begin(); i!=items.end();++i){ if ( !SP_IS_IMAGE(*i) ) continue; diff --git a/src/ui/dialog/polar-arrange-tab.cpp b/src/ui/dialog/polar-arrange-tab.cpp index 6324ec57f..c51881a96 100644 --- a/src/ui/dialog/polar-arrange-tab.cpp +++ b/src/ui/dialog/polar-arrange-tab.cpp @@ -264,7 +264,7 @@ static void moveToPoint(int anchor, SPItem *item, Geom::Point p) void PolarArrangeTab::arrange() { Inkscape::Selection *selection = parent->getDesktop()->getSelection(); - const std::vector<SPItem*> tmp(selection->itemList()); + const std::vector<SPItem*> tmp(selection->items().begin(), selection->items().end()); SPGenericEllipse *referenceEllipse = NULL; // Last ellipse in selection bool arrangeOnEllipse = !arrangeOnParametersRadio.get_active(); diff --git a/src/ui/dialog/spellcheck.cpp b/src/ui/dialog/spellcheck.cpp index 61fa4c22b..045ce3459 100644 --- a/src/ui/dialog/spellcheck.cpp +++ b/src/ui/dialog/spellcheck.cpp @@ -227,14 +227,14 @@ GSList *SpellCheck::allTextItems (SPObject *r, GSList *l, bool hidden, bool lock return l; // we're not interested in metadata } - for (SPObject *child = r->firstChild(); child; child = child->next) { - if (SP_IS_ITEM (child) && !child->cloned && !desktop->isLayer(SP_ITEM(child))) { - if ((hidden || !desktop->itemIsHidden(SP_ITEM(child))) && (locked || !SP_ITEM(child)->isLocked())) { - if (SP_IS_TEXT(child) || SP_IS_FLOWTEXT(child)) - l = g_slist_prepend (l, child); + for (auto& child: r->children) { + if (SP_IS_ITEM (&child) && !child.cloned && !desktop->isLayer(SP_ITEM(&child))) { + if ((hidden || !desktop->itemIsHidden(SP_ITEM(&child))) && (locked || !SP_ITEM(&child)->isLocked())) { + if (SP_IS_TEXT(&child) || SP_IS_FLOWTEXT(&child)) + l = g_slist_prepend (l, &child); } } - l = allTextItems (child, l, hidden, locked); + l = allTextItems (&child, l, hidden, locked); } return l; } diff --git a/src/ui/dialog/svg-fonts-dialog.cpp b/src/ui/dialog/svg-fonts-dialog.cpp index 87bab72e9..6a87f3714 100644 --- a/src/ui/dialog/svg-fonts-dialog.cpp +++ b/src/ui/dialog/svg-fonts-dialog.cpp @@ -113,11 +113,11 @@ void SvgFontsDialog::AttrEntry::set_text(char* t){ void SvgFontsDialog::AttrEntry::on_attr_changed(){ SPObject* o = NULL; - for(SPObject* node = this->dialog->get_selected_spfont()->children; node; node=node->next){ + for (auto& node: dialog->get_selected_spfont()->children) { switch(this->attr){ case SP_PROP_FONT_FAMILY: - if (SP_IS_FONTFACE(node)){ - o = node; + if (SP_IS_FONTFACE(&node)){ + o = &node; continue; } break; @@ -168,9 +168,9 @@ void GlyphComboBox::update(SPFont* spfont){ this->append(""); //Gtk is refusing to clear the combobox when I comment out this line this->remove_all(); - for(SPObject* node = spfont->children; node; node=node->next){ - if (SP_IS_GLYPH(node)){ - this->append((static_cast<SPGlyph*>(node))->unicode); + for (auto& node: spfont->children) { + if (SP_IS_GLYPH(&node)){ + this->append((static_cast<SPGlyph*>(&node))->unicode); } } } @@ -306,10 +306,9 @@ void SvgFontsDialog::update_global_settings_tab(){ SPFont* font = get_selected_spfont(); if (!font) return; - SPObject* obj; - for (obj=font->children; obj; obj=obj->next){ - if (SP_IS_FONTFACE(obj)){ - _familyname_entry->set_text((SP_FONTFACE(obj))->font_family); + for (auto& obj: font->children) { + if (SP_IS_FONTFACE(&obj)){ + _familyname_entry->set_text((SP_FONTFACE(&obj))->font_family); } } } @@ -412,12 +411,12 @@ SvgFontsDialog::populate_glyphs_box() SPFont* spfont = this->get_selected_spfont(); _glyphs_observer.set(spfont); - for(SPObject* node = spfont->children; node; node=node->next){ - if (SP_IS_GLYPH(node)){ + for (auto& node: spfont->children) { + if (SP_IS_GLYPH(&node)){ Gtk::TreeModel::Row row = *(_GlyphsListStore->append()); - row[_GlyphsListColumns.glyph_node] = static_cast<SPGlyph*>(node); - row[_GlyphsListColumns.glyph_name] = (static_cast<SPGlyph*>(node))->glyph_name; - row[_GlyphsListColumns.unicode] = (static_cast<SPGlyph*>(node))->unicode; + row[_GlyphsListColumns.glyph_node] = static_cast<SPGlyph*>(&node); + row[_GlyphsListColumns.glyph_name] = (static_cast<SPGlyph*>(&node))->glyph_name; + row[_GlyphsListColumns.unicode] = (static_cast<SPGlyph*>(&node))->unicode; } } } @@ -430,13 +429,13 @@ SvgFontsDialog::populate_kerning_pairs_box() SPFont* spfont = this->get_selected_spfont(); - for(SPObject* node = spfont->children; node; node=node->next){ - if (SP_IS_HKERN(node)){ + for (auto& node: spfont->children) { + if (SP_IS_HKERN(&node)){ Gtk::TreeModel::Row row = *(_KerningPairsListStore->append()); - row[_KerningPairsListColumns.first_glyph] = (static_cast<SPGlyphKerning*>(node))->u1->attribute_string().c_str(); - row[_KerningPairsListColumns.second_glyph] = (static_cast<SPGlyphKerning*>(node))->u2->attribute_string().c_str(); - row[_KerningPairsListColumns.kerning_value] = (static_cast<SPGlyphKerning*>(node))->k; - row[_KerningPairsListColumns.spnode] = static_cast<SPGlyphKerning*>(node); + row[_KerningPairsListColumns.first_glyph] = (static_cast<SPGlyphKerning*>(&node))->u1->attribute_string().c_str(); + row[_KerningPairsListColumns.second_glyph] = (static_cast<SPGlyphKerning*>(&node))->u2->attribute_string().c_str(); + row[_KerningPairsListColumns.kerning_value] = (static_cast<SPGlyphKerning*>(&node))->k; + row[_KerningPairsListColumns.spnode] = static_cast<SPGlyphKerning*>(&node); } } } @@ -491,11 +490,10 @@ void SvgFontsDialog::add_glyph(){ Geom::PathVector SvgFontsDialog::flip_coordinate_system(Geom::PathVector pathv){ double units_per_em = 1000; - SPObject* obj; - for (obj = get_selected_spfont()->children; obj; obj=obj->next){ - if (SP_IS_FONTFACE(obj)){ + for (auto& obj: get_selected_spfont()->children) { + if (SP_IS_FONTFACE(&obj)){ //XML Tree being directly used here while it shouldn't be. - sp_repr_get_double(obj->getRepr(), "units-per-em", &units_per_em); + sp_repr_get_double(obj.getRepr(), "units-per-em", &units_per_em); } } @@ -522,7 +520,7 @@ void SvgFontsDialog::set_glyph_description_from_selected_path(){ return; } - Inkscape::XML::Node* node = sel->reprList().front(); + Inkscape::XML::Node* node = sel->xmlNodes().front(); if (!node) return;//TODO: should this be an assert? if (!node->matchAttributeName("d") || !node->attribute("d")){ char *msg = _("The selected object does not have a <b>path</b> description."); @@ -564,7 +562,7 @@ void SvgFontsDialog::missing_glyph_description_from_selected_path(){ return; } - Inkscape::XML::Node* node = sel->reprList().front(); + Inkscape::XML::Node* node = sel->xmlNodes().front(); if (!node) return;//TODO: should this be an assert? if (!node->matchAttributeName("d") || !node->attribute("d")){ char *msg = _("The selected object does not have a <b>path</b> description."); @@ -574,13 +572,12 @@ void SvgFontsDialog::missing_glyph_description_from_selected_path(){ Geom::PathVector pathv = sp_svg_read_pathv(node->attribute("d")); - SPObject* obj; - for (obj = get_selected_spfont()->children; obj; obj=obj->next){ - if (SP_IS_MISSING_GLYPH(obj)){ + for (auto& obj: get_selected_spfont()->children) { + if (SP_IS_MISSING_GLYPH(&obj)){ //XML Tree being directly used here while it shouldn't be. gchar *str = sp_svg_write_path (flip_coordinate_system(pathv)); - obj->getRepr()->setAttribute("d", str); + obj.getRepr()->setAttribute("d", str); g_free(str); DocumentUndo::done(doc, SP_VERB_DIALOG_SVG_FONTS, _("Set glyph curves")); } @@ -597,11 +594,10 @@ void SvgFontsDialog::reset_missing_glyph_description(){ } SPDocument* doc = desktop->getDocument(); - SPObject* obj; - for (obj = get_selected_spfont()->children; obj; obj=obj->next){ - if (SP_IS_MISSING_GLYPH(obj)){ + for (auto& obj: get_selected_spfont()->children) { + if (SP_IS_MISSING_GLYPH(&obj)){ //XML Tree being directly used here while it shouldn't be. - obj->getRepr()->setAttribute("d", (char*) "M0,0h1000v1024h-1000z"); + obj.getRepr()->setAttribute("d", (char*) "M0,0h1000v1024h-1000z"); DocumentUndo::done(doc, SP_VERB_DIALOG_SVG_FONTS, _("Reset missing-glyph")); } } @@ -736,12 +732,12 @@ void SvgFontsDialog::add_kerning_pair(){ //look for this kerning pair on the currently selected font this->kerning_pair = NULL; - for(SPObject* node = this->get_selected_spfont()->children; node; node=node->next){ + for (auto& node: get_selected_spfont()->children) { //TODO: It is not really correct to get only the first byte of each string. //TODO: We should also support vertical kerning - if (SP_IS_HKERN(node) && (static_cast<SPGlyphKerning*>(node))->u1->contains((gchar) first_glyph.get_active_text().c_str()[0]) - && (static_cast<SPGlyphKerning*>(node))->u2->contains((gchar) second_glyph.get_active_text().c_str()[0]) ){ - this->kerning_pair = static_cast<SPGlyphKerning*>(node); + if (SP_IS_HKERN(&node) && (static_cast<SPGlyphKerning*>(&node))->u1->contains((gchar) first_glyph.get_active_text().c_str()[0]) + && (static_cast<SPGlyphKerning*>(&node))->u2->contains((gchar) second_glyph.get_active_text().c_str()[0]) ){ + this->kerning_pair = static_cast<SPGlyphKerning*>(&node); continue; } } @@ -850,11 +846,10 @@ SPFont *new_font(SPDocument *document) void set_font_family(SPFont* font, char* str){ if (!font) return; - SPObject* obj; - for (obj=font->children; obj; obj=obj->next){ - if (SP_IS_FONTFACE(obj)){ + for (auto& obj: font->children) { + if (SP_IS_FONTFACE(&obj)){ //XML Tree being directly used here while it shouldn't be. - obj->getRepr()->setAttribute("font-family", str); + obj.getRepr()->setAttribute("font-family", str); } } @@ -871,11 +866,10 @@ void SvgFontsDialog::add_font(){ font->setLabel(os.str().c_str()); os2 << "SVGFont " << count; - SPObject* obj; - for (obj=font->children; obj; obj=obj->next){ - if (SP_IS_FONTFACE(obj)){ + for (auto& obj: font->children) { + if (SP_IS_FONTFACE(&obj)){ //XML Tree being directly used here while it shouldn't be. - obj->getRepr()->setAttribute("font-family", os2.str().c_str()); + obj.getRepr()->setAttribute("font-family", os2.str().c_str()); } } diff --git a/src/ui/dialog/swatches.cpp b/src/ui/dialog/swatches.cpp index b3767f584..3012c5c26 100644 --- a/src/ui/dialog/swatches.cpp +++ b/src/ui/dialog/swatches.cpp @@ -114,7 +114,7 @@ static void editGradientImpl( SPDesktop* desktop, SPGradient* gr ) bool shown = false; if ( desktop && desktop->doc() ) { Inkscape::Selection *selection = desktop->getSelection(); - std::vector<SPItem*> const items = selection->itemList(); + std::vector<SPItem*> const items(selection->items().begin(), selection->items().end()); if (!items.empty()) { SPStyle query( desktop->doc() ); int result = objects_query_fillstroke((items), &query, true); diff --git a/src/ui/dialog/symbols.cpp b/src/ui/dialog/symbols.cpp index de4e127bd..4840b897b 100644 --- a/src/ui/dialog/symbols.cpp +++ b/src/ui/dialog/symbols.cpp @@ -432,11 +432,6 @@ void SymbolsDialog::iconChanged() { SPObject* symbol = symbolDocument->getObjectById(symbol_id); if( symbol ) { - if( symbolDocument == currentDocument ) { - // Select the symbol on the canvas so it can be manipulated - currentDesktop->selection->set( symbol, false ); - } - // Find style for use in <use> // First look for default style stored in <symbol> gchar const* style = symbol->getAttribute("inkscape:symbol-style"); @@ -619,8 +614,8 @@ GSList* SymbolsDialog::symbols_in_doc_recursive (SPObject *r, GSList *l) l = g_slist_prepend (l, r); } - for (SPObject *child = r->firstChild(); child; child = child->getNext()) { - l = symbols_in_doc_recursive( child, l ); + for (auto& child: r->children) { + l = symbols_in_doc_recursive( &child, l ); } return l; @@ -641,8 +636,8 @@ GSList* SymbolsDialog::use_in_doc_recursive (SPObject *r, GSList *l) l = g_slist_prepend (l, r); } - for (SPObject *child = r->firstChild(); child; child = child->getNext()) { - l = use_in_doc_recursive( child, l ); + for (auto& child: r->children) { + l = use_in_doc_recursive( &child, l ); } return l; diff --git a/src/ui/dialog/tags.cpp b/src/ui/dialog/tags.cpp index 768e13d43..dfe71bddb 100644 --- a/src/ui/dialog/tags.cpp +++ b/src/ui/dialog/tags.cpp @@ -335,8 +335,8 @@ void TagsPanel::_objectsSelected( Selection *sel ) { _selectedConnection.block(); _tree.get_selection()->unselect_all(); - std::vector<SPObject*> tmp=sel->list(); - for(std::vector<SPObject*>::const_iterator i=tmp.begin();i!=tmp.end();++i) + auto tmp = sel->objects(); + for(auto i = tmp.begin(); i != tmp.end(); ++i) { SPObject *obj = *i; _store->foreach(sigc::bind<SPObject *>( sigc::mem_fun(*this, &TagsPanel::_checkForSelected), obj)); @@ -386,26 +386,26 @@ void TagsPanel::_objectsChanged(SPObject* root) void TagsPanel::_addObject( SPDocument* doc, SPObject* obj, Gtk::TreeModel::Row* parentRow ) { if ( _desktop && obj ) { - for ( SPObject *child = obj->children; child != NULL; child = child->next) { - if (SP_IS_TAG(child)) + for (auto& child: obj->children) { + if (SP_IS_TAG(&child)) { Gtk::TreeModel::iterator iter = parentRow ? _store->prepend(parentRow->children()) : _store->prepend(); Gtk::TreeModel::Row row = *iter; - row[_model->_colObject] = child; + row[_model->_colObject] = &child; row[_model->_colParentObject] = NULL; - row[_model->_colLabel] = child->label() ? child->label() : child->getId(); + row[_model->_colLabel] = child.label() ? child.label() : child.getId(); row[_model->_colAddRemove] = true; row[_model->_colAllowAddRemove] = true; _tree.expand_to_path( _store->get_path(iter) ); - TagsPanel::ObjectWatcher *w = new TagsPanel::ObjectWatcher(this, child); - child->getRepr()->addObserver(*w); + TagsPanel::ObjectWatcher *w = new TagsPanel::ObjectWatcher(this, &child); + child.getRepr()->addObserver(*w); _objectWatchers.push_back(w); - _addObject( doc, child, &row ); + _addObject( doc, &child, &row ); } } - if (SP_IS_TAG(obj) && obj->children) + if (SP_IS_TAG(obj) && obj->firstChild()) { Gtk::TreeModel::iterator iteritems = parentRow ? _store->append(parentRow->children()) : _store->prepend(); Gtk::TreeModel::Row rowitems = *iteritems; @@ -416,16 +416,16 @@ void TagsPanel::_addObject( SPDocument* doc, SPObject* obj, Gtk::TreeModel::Row* rowitems[_model->_colAllowAddRemove] = false; _tree.expand_to_path( _store->get_path(iteritems) ); - - for ( SPObject *child = obj->children; child != NULL; child = child->next) { - if (SP_IS_TAG_USE(child)) + + for (auto& child: obj->children) { + if (SP_IS_TAG_USE(&child)) { - SPItem *item = SP_TAG_USE(child)->ref->getObject(); + SPItem *item = SP_TAG_USE(&child)->ref->getObject(); Gtk::TreeModel::iterator iter = _store->prepend(rowitems->children()); Gtk::TreeModel::Row row = *iter; - row[_model->_colObject] = child; + row[_model->_colObject] = &child; row[_model->_colParentObject] = NULL; - row[_model->_colLabel] = item ? (item->label() ? item->label() : item->getId()) : SP_TAG_USE(child)->href; + row[_model->_colLabel] = item ? (item->label() ? item->label() : item->getId()) : SP_TAG_USE(&child)->href; row[_model->_colAddRemove] = false; row[_model->_colAllowAddRemove] = true; @@ -434,7 +434,7 @@ void TagsPanel::_addObject( SPDocument* doc, SPObject* obj, Gtk::TreeModel::Row* } if (item) { - TagsPanel::ObjectWatcher *w = new TagsPanel::ObjectWatcher(this, child, item->getRepr()); + TagsPanel::ObjectWatcher *w = new TagsPanel::ObjectWatcher(this, &child, item->getRepr()); item->getRepr()->addObserver(*w); _objectWatchers.push_back(w); } @@ -446,12 +446,11 @@ void TagsPanel::_addObject( SPDocument* doc, SPObject* obj, Gtk::TreeModel::Row* void TagsPanel::_select_tag( SPTag * tag ) { - for (SPObject * child = tag->children; child != NULL; child = child->next) - { - if (SP_IS_TAG(child)) { - _select_tag(SP_TAG(child)); - } else if (SP_IS_TAG_USE(child)) { - SPObject * obj = SP_TAG_USE(child)->ref->getObject(); + for (auto& child: tag->children) { + if (SP_IS_TAG(&child)) { + _select_tag(SP_TAG(&child)); + } else if (SP_IS_TAG_USE(&child)) { + SPObject * obj = SP_TAG_USE(&child)->ref->getObject(); if (obj) { if (_desktop->selection->isEmpty()) _desktop->setCurrentLayer(obj->parent); _desktop->selection->add(obj); @@ -633,12 +632,12 @@ bool TagsPanel::_handleButtonEvent(GdkEventButton* event) if (col == _tree.get_column(COL_ADD - 1) && down_at_add) { if (SP_IS_TAG(obj)) { bool wasadded = false; - std::vector<SPItem*> items=_desktop->selection->itemList(); - for(std::vector<SPItem*>::const_iterator i=items.begin();i!=items.end();++i){ + auto items= _desktop->selection->items(); + for(auto i=items.begin();i!=items.end();++i){ SPObject *newobj = *i; bool addchild = true; - for ( SPObject *child = obj->children; child != NULL; child = child->next) { - if (SP_IS_TAG_USE(child) && SP_TAG_USE(child)->ref->getObject() == newobj) { + for (auto& child: obj->children) { + if (SP_IS_TAG_USE(&child) && SP_TAG_USE(&child)->ref->getObject() == newobj) { addchild = false; } } diff --git a/src/ui/dialog/text-edit.cpp b/src/ui/dialog/text-edit.cpp index 5d50a6c30..50c6c1553 100644 --- a/src/ui/dialog/text-edit.cpp +++ b/src/ui/dialog/text-edit.cpp @@ -413,8 +413,8 @@ SPItem *TextEdit::getSelectedTextItem (void) if (!SP_ACTIVE_DESKTOP) return NULL; - std::vector<SPItem*> tmp=SP_ACTIVE_DESKTOP->getSelection()->itemList(); - for(std::vector<SPItem*>::const_iterator i=tmp.begin();i!=tmp.end();++i) + auto tmp= SP_ACTIVE_DESKTOP->getSelection()->items(); + for(auto i=tmp.begin();i!=tmp.end();++i) { if (SP_IS_TEXT(*i) || SP_IS_FLOWTEXT(*i)) return *i; @@ -431,8 +431,8 @@ unsigned TextEdit::getSelectedTextCount (void) unsigned int items = 0; - std::vector<SPItem*> tmp=SP_ACTIVE_DESKTOP->getSelection()->itemList(); - for(std::vector<SPItem*>::const_iterator i=tmp.begin();i!=tmp.end();++i) + auto tmp= SP_ACTIVE_DESKTOP->getSelection()->items(); + for(auto i=tmp.begin();i!=tmp.end();++i) { if (SP_IS_TEXT(*i) || SP_IS_FLOWTEXT(*i)) ++items; @@ -538,11 +538,11 @@ void TextEdit::onApply() SPDesktop *desktop = SP_ACTIVE_DESKTOP; unsigned items = 0; - const std::vector<SPItem*> item_list = desktop->getSelection()->itemList(); + auto item_list = desktop->getSelection()->items(); SPCSSAttr *css = fillTextStyle (); sp_desktop_set_style(desktop, css, true); - for(std::vector<SPItem*>::const_iterator i=item_list.begin();i!=item_list.end();++i){ + for(auto i=item_list.begin();i!=item_list.end();++i){ // apply style to the reprs of all text objects in the selection if (SP_IS_TEXT (*i)) { diff --git a/src/ui/dialog/transformation.cpp b/src/ui/dialog/transformation.cpp index 5fb5bdfc4..7f1492cd7 100644 --- a/src/ui/dialog/transformation.cpp +++ b/src/ui/dialog/transformation.cpp @@ -544,7 +544,7 @@ void Transformation::updatePageTransform(Inkscape::Selection *selection) { if (selection && !selection->isEmpty()) { if (_check_replace_matrix.get_active()) { - Geom::Affine current (selection->itemList()[0]->transform); // take from the first item in selection + Geom::Affine current (selection->items().front()->transform); // take from the first item in selection Geom::Affine new_displayed = current; @@ -617,19 +617,19 @@ void Transformation::applyPageMove(Inkscape::Selection *selection) if (!prefs->getBool("/dialogs/transformation/applyseparately")) { // move selection as a whole if (_check_move_relative.get_active()) { - sp_selection_move_relative(selection, x, y); + sp_object_set_move_relative(selection, x, y); } else { Geom::OptRect bbox = selection->preferredBounds(); if (bbox) { - sp_selection_move_relative(selection, - x - bbox->min()[Geom::X], y - bbox->min()[Geom::Y]); + sp_object_set_move_relative(selection, + x - bbox->min()[Geom::X], y - bbox->min()[Geom::Y]); } } } else { if (_check_move_relative.get_active()) { // shift each object relatively to the previous one - std::vector<SPItem*> selected(selection->itemList()); + std::vector<SPItem*> selected(selection->items().begin(), selection->items().end()); if (selected.empty()) return; if (fabs(x) > 1e-6) { @@ -685,8 +685,8 @@ void Transformation::applyPageMove(Inkscape::Selection *selection) } else { Geom::OptRect bbox = selection->preferredBounds(); if (bbox) { - sp_selection_move_relative(selection, - x - bbox->min()[Geom::X], y - bbox->min()[Geom::Y]); + sp_object_set_move_relative(selection, + x - bbox->min()[Geom::X], y - bbox->min()[Geom::Y]); } } } @@ -704,8 +704,8 @@ void Transformation::applyPageScale(Inkscape::Selection *selection) bool transform_stroke = prefs->getBool("/options/transform/stroke", true); bool preserve = prefs->getBool("/options/preservetransform/value", false); if (prefs->getBool("/dialogs/transformation/applyseparately")) { - std::vector<SPItem*> tmp=selection->itemList(); - for(std::vector<SPItem*>::const_iterator i=tmp.begin();i!=tmp.end();++i){ + auto tmp= selection->items(); + for(auto i=tmp.begin();i!=tmp.end();++i){ SPItem *item = *i; Geom::OptRect bbox_pref = item->desktopPreferredBounds(); Geom::OptRect bbox_geom = item->desktopGeometricBounds(); @@ -750,7 +750,7 @@ void Transformation::applyPageScale(Inkscape::Selection *selection) double y1 = bbox_pref->midpoint()[Geom::Y] + new_height/2; Geom::Affine scaler = get_scale_transform_for_variable_stroke (*bbox_pref, *bbox_geom, transform_stroke, preserve, x0, y0, x1, y1); - sp_selection_apply_affine(selection, scaler); + sp_object_set_apply_affine(selection, scaler); } } @@ -768,15 +768,15 @@ void Transformation::applyPageRotate(Inkscape::Selection *selection) } if (prefs->getBool("/dialogs/transformation/applyseparately")) { - std::vector<SPItem*> tmp=selection->itemList(); - for(std::vector<SPItem*>::const_iterator i=tmp.begin();i!=tmp.end();++i){ + auto tmp= selection->items(); + for(auto i=tmp.begin();i!=tmp.end();++i){ SPItem *item = *i; sp_item_rotate_rel(item, Geom::Rotate (angle*M_PI/180.0)); } } else { boost::optional<Geom::Point> center = selection->center(); if (center) { - sp_selection_rotate_relative(selection, *center, angle); + sp_object_set_rotate_relative(selection, *center, angle); } } @@ -788,8 +788,8 @@ void Transformation::applyPageSkew(Inkscape::Selection *selection) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); if (prefs->getBool("/dialogs/transformation/applyseparately")) { - std::vector<SPItem*> items=selection->itemList(); - for(std::vector<SPItem*>::const_iterator i = items.begin();i!=items.end();++i){ + auto items = selection->items(); + for(auto i = items.begin();i!=items.end();++i){ SPItem *item = *i; if (!_units_skew.isAbsolute()) { // percentage @@ -843,7 +843,7 @@ void Transformation::applyPageSkew(Inkscape::Selection *selection) getDesktop()->getMessageStack()->flash(Inkscape::WARNING_MESSAGE, _("Transform matrix is singular, <b>not used</b>.")); return; } - sp_selection_skew_relative(selection, *center, 0.01*skewX, 0.01*skewY); + sp_object_set_skew_relative(selection, *center, 0.01 * skewX, 0.01 * skewY); } else if (_units_skew.isRadial()) { //deg or rad double angleX = _scalar_skew_horizontal.getValue("rad"); double angleY = _scalar_skew_vertical.getValue("rad"); @@ -856,7 +856,7 @@ void Transformation::applyPageSkew(Inkscape::Selection *selection) } double skewX = tan(-angleX); double skewY = tan(angleY); - sp_selection_skew_relative(selection, *center, skewX, skewY); + sp_object_set_skew_relative(selection, *center, skewX, skewY); } else { // absolute displacement double skewX = _scalar_skew_horizontal.getValue("px"); double skewY = _scalar_skew_vertical.getValue("px"); @@ -864,7 +864,7 @@ void Transformation::applyPageSkew(Inkscape::Selection *selection) getDesktop()->getMessageStack()->flash(Inkscape::WARNING_MESSAGE, _("Transform matrix is singular, <b>not used</b>.")); return; } - sp_selection_skew_relative(selection, *center, skewX/height, skewY/width); + sp_object_set_skew_relative(selection, *center, skewX / height, skewY / width); } } } @@ -890,14 +890,14 @@ void Transformation::applyPageTransform(Inkscape::Selection *selection) } if (_check_replace_matrix.get_active()) { - std::vector<SPItem*> tmp=selection->itemList(); - for(std::vector<SPItem*>::const_iterator i=tmp.begin();i!=tmp.end();++i){ + auto tmp = selection->items(); + for(auto i=tmp.begin();i!=tmp.end();++i){ SPItem *item = *i; item->set_item_transform(displayed); item->updateRepr(); } } else { - sp_selection_apply_affine(selection, displayed); // post-multiply each object's transform + sp_object_set_apply_affine(selection, displayed); // post-multiply each object's transform } DocumentUndo::done(selection->desktop()->getDocument(), SP_VERB_DIALOG_TRANSFORM, @@ -1043,7 +1043,7 @@ void Transformation::onReplaceMatrixToggled() double f = _scalar_transform_f.getValue(); Geom::Affine displayed (a, b, c, d, e, f); - Geom::Affine current = selection->itemList()[0]->transform; // take from the first item in selection + Geom::Affine current = selection->items().front()->transform; // take from the first item in selection Geom::Affine new_displayed; if (_check_replace_matrix.get_active()) { diff --git a/src/ui/interface.cpp b/src/ui/interface.cpp index 3c754be29..b47e66451 100644 --- a/src/ui/interface.cpp +++ b/src/ui/interface.cpp @@ -1210,7 +1210,7 @@ sp_ui_drag_data_received(GtkWidget *widget, Geom::OptRect sel_bbox = selection->visualBounds(); if (sel_bbox) { Geom::Point m( desktop->point() - sel_bbox->midpoint() ); - sp_selection_move_relative(selection, m, false); + sp_object_set_move_relative(selection, m, false); } } @@ -2056,8 +2056,8 @@ void ContextMenu::ImageEdit(void) } #endif - std::vector<SPItem*> itemlist=_desktop->selection->itemList(); - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ + auto itemlist= _desktop->selection->items(); + for(auto i=itemlist.begin();i!=itemlist.end();++i){ Inkscape::XML::Node *ir = (*i)->getRepr(); const gchar *href = ir->attribute("xlink:href"); diff --git a/src/ui/tools/box3d-tool.cpp b/src/ui/tools/box3d-tool.cpp index 9b5b264bc..94488a700 100644 --- a/src/ui/tools/box3d-tool.cpp +++ b/src/ui/tools/box3d-tool.cpp @@ -109,8 +109,8 @@ static void sp_box3d_context_ensure_persp_in_defs(SPDocument *document) { SPDefs *defs = document->getDefs(); bool has_persp = false; - for ( SPObject *child = defs->firstChild(); child; child = child->getNext() ) { - if (SP_IS_PERSP3D(child)) { + for (auto& child: defs->children) { + if (SP_IS_PERSP3D(&child)) { has_persp = true; break; } diff --git a/src/ui/tools/calligraphic-tool.cpp b/src/ui/tools/calligraphic-tool.cpp index 84c4adc89..d623035d9 100644 --- a/src/ui/tools/calligraphic-tool.cpp +++ b/src/ui/tools/calligraphic-tool.cpp @@ -921,10 +921,10 @@ void CalligraphicTool::set_to_accumulated(bool unionize, bool subtract) { if (unionize) { desktop->getSelection()->add(this->repr); - sp_selected_path_union_skip_undo(desktop->getSelection(), desktop); + sp_selected_path_union_skip_undo(desktop->getSelection()); } else if (subtract) { desktop->getSelection()->add(this->repr); - sp_selected_path_diff_skip_undo(desktop->getSelection(), desktop); + sp_selected_path_diff_skip_undo(desktop->getSelection()); } else { if (this->keep_selected) { desktop->getSelection()->set(this->repr); diff --git a/src/ui/tools/connector-tool.cpp b/src/ui/tools/connector-tool.cpp index 605b573d7..84f7f318c 100644 --- a/src/ui/tools/connector-tool.cpp +++ b/src/ui/tools/connector-tool.cpp @@ -1107,9 +1107,9 @@ void ConnectorTool::_setActiveShape(SPItem *item) { // The idea here is to try and add a group's children to solidify // connection handling. We react to path objects with only one node. - for (SPObject *child = item->firstChild() ; child ; child = child->getNext() ) { - if (SP_IS_PATH(child) && SP_PATH(child)->nodesInPath() == 1) { - this->_activeShapeAddKnot((SPItem *) child); + for (auto& child: item->children) { + if (SP_IS_PATH(&child) && SP_PATH(&child)->nodesInPath() == 1) { + this->_activeShapeAddKnot((SPItem *) &child); } } this->_activeShapeAddKnot(item); @@ -1299,8 +1299,8 @@ void cc_selection_set_avoid(bool const set_avoid) int changes = 0; - std::vector<SPItem*> l = selection->itemList(); - for(std::vector<SPItem*>::const_iterator i=l.begin();i!=l.end(); ++i) { + auto l = selection->items(); + for(auto i=l.begin();i!=l.end(); ++i) { SPItem *item = *i; char const *value = (set_avoid) ? "true" : NULL; diff --git a/src/ui/tools/eraser-tool.cpp b/src/ui/tools/eraser-tool.cpp index 838522b34..d18db8266 100644 --- a/src/ui/tools/eraser-tool.cpp +++ b/src/ui/tools/eraser-tool.cpp @@ -681,7 +681,7 @@ void EraserTool::set_to_accumulated() { } } } else { - toWorkOn = selection->itemList(); + toWorkOn.insert(toWorkOn.end(), selection->items().begin(), selection->items().end()); } wasSelection = true; } @@ -697,7 +697,6 @@ void EraserTool::set_to_accumulated() { item->deleteObject(true); sp_object_unref(item); workDone = true; - workDone = true; } else if (SP_IS_GROUP(item) || use ) { /*Do nothing*/ } else { @@ -708,7 +707,7 @@ void EraserTool::set_to_accumulated() { Inkscape::GC::release(dup); // parent takes over selection->set(dup); if (!this->nowidth) { - sp_selected_path_union_skip_undo(selection, desktop); + sp_selected_path_union_skip_undo(selection); } selection->add(item); if(item->style->fill_rule.value == SP_WIND_RULE_EVENODD){ @@ -719,9 +718,9 @@ void EraserTool::set_to_accumulated() { css = 0; } if (this->nowidth) { - sp_selected_path_cut_skip_undo(selection, desktop); + sp_selected_path_cut_skip_undo(selection); } else { - sp_selected_path_diff_skip_undo(selection, desktop); + sp_selected_path_diff_skip_undo(selection); } workDone = true; // TODO set this only if something was cut. bool break_apart = prefs->getBool("/tools/eraser/break_apart", false); @@ -734,7 +733,7 @@ void EraserTool::set_to_accumulated() { } if ( !selection->isEmpty() ) { // If the item was not completely erased, track the new remainder. - std::vector<SPItem*> nowSel(selection->itemList()); + std::vector<SPItem*> nowSel(selection->items().begin(), selection->items().end()); for (std::vector<SPItem*>::const_iterator i2 = nowSel.begin();i2!=nowSel.end();++i2) { remainingItems.push_back(*i2); } diff --git a/src/ui/tools/flood-tool.cpp b/src/ui/tools/flood-tool.cpp index 2f125e6ed..0b893a7ba 100644 --- a/src/ui/tools/flood-tool.cpp +++ b/src/ui/tools/flood-tool.cpp @@ -446,7 +446,7 @@ static void do_trace(bitmap_coords_info bci, guchar *trace_px, SPDesktop *deskto ngettext("Area filled, path with <b>%d</b> node created and unioned with selection.","Area filled, path with <b>%d</b> nodes created and unioned with selection.", SP_PATH(reprobj)->nodesInPath()), SP_PATH(reprobj)->nodesInPath() ); selection->add(reprobj); - sp_selected_path_union_skip_undo(desktop->getSelection(), desktop); + sp_selected_path_union_skip_undo(desktop->getSelection()); } else { desktop->messageStack()->flashF( Inkscape::WARNING_MESSAGE, ngettext("Area filled, path with <b>%d</b> node created.","Area filled, path with <b>%d</b> nodes created.", diff --git a/src/ui/tools/gradient-tool.cpp b/src/ui/tools/gradient-tool.cpp index e4814c3de..a084a8fd9 100644 --- a/src/ui/tools/gradient-tool.cpp +++ b/src/ui/tools/gradient-tool.cpp @@ -99,7 +99,7 @@ void GradientTool::selection_changed(Inkscape::Selection*) { if (selection == NULL) { return; } - guint n_obj = selection->itemList().size(); + guint n_obj = (guint) boost::distance(selection->items()); if (!drag->isNonEmpty() || selection->isEmpty()) return; @@ -485,10 +485,10 @@ bool GradientTool::root_handler(GdkEvent* event) { if (over_line) { // we take the first item in selection, because with doubleclick, the first click // always resets selection to the single object under cursor - sp_gradient_context_add_stop_near_point(this, SP_ITEM(selection->itemList().front()), this->mousepoint_doc, event->button.time); + sp_gradient_context_add_stop_near_point(this, SP_ITEM(selection->items().front()), this->mousepoint_doc, event->button.time); } else { - std::vector<SPItem*> items=selection->itemList(); - for (std::vector<SPItem*>::const_iterator i = items.begin();i!=items.end();++i) { + auto items= selection->items(); + for (auto i = items.begin();i!=items.end();++i) { SPItem *item = *i; SPGradientType new_type = (SPGradientType) prefs->getInt("/tools/gradient/newgradient", SP_GRADIENT_TYPE_LINEAR); Inkscape::PaintTarget fsmode = (prefs->getInt("/tools/gradient/newfillorstroke", 1) != 0) ? Inkscape::FOR_FILL : Inkscape::FOR_STROKE; @@ -890,7 +890,7 @@ static void sp_gradient_drag(GradientTool &rc, Geom::Point const pt, guint /*sta } else { // Starting from empty space: // Sort items so that the topmost comes last - std::vector<SPItem*> items(selection->itemList()); + std::vector<SPItem*> items(selection->items().begin(), selection->items().end()); sort(items.begin(),items.end(),sp_item_repr_compare_position); // take topmost vector = sp_gradient_vector_for_object(document, desktop, SP_ITEM(items.back()), fill_or_stroke); @@ -900,8 +900,8 @@ static void sp_gradient_drag(GradientTool &rc, Geom::Point const pt, guint /*sta SPCSSAttr *css = sp_repr_css_attr_new(); sp_repr_css_set_property(css, "fill-opacity", "1.0"); - std::vector<SPItem*> itemlist = selection->itemList(); - for (std::vector<SPItem*>::const_iterator i = itemlist.begin();i!=itemlist.end();++i) { + auto itemlist = selection->items(); + for (auto i = itemlist.begin();i!=itemlist.end();++i) { //FIXME: see above sp_repr_css_change_recursive((*i)->getRepr(), css, "style"); @@ -924,7 +924,7 @@ static void sp_gradient_drag(GradientTool &rc, Geom::Point const pt, guint /*sta ec->_grdrag->local_change = true; // give the grab out-of-bounds values of xp/yp because we're already dragging // and therefore are already out of tolerance - ec->_grdrag->grabKnot (selection->itemList()[0], + ec->_grdrag->grabKnot (selection->items().front(), type == SP_GRADIENT_TYPE_LINEAR? POINT_LG_END : POINT_RG_R1, -1, // ignore number (though it is always 1) fill_or_stroke, 99999, 99999, etime); @@ -933,7 +933,7 @@ static void sp_gradient_drag(GradientTool &rc, Geom::Point const pt, guint /*sta // status text; we do not track coords because this branch is run once, not all the time // during drag - int n_objects = selection->itemList().size(); + int n_objects = (int) boost::distance(selection->items()); rc.message_context->setF(Inkscape::NORMAL_MESSAGE, ngettext("<b>Gradient</b> for %d object; with <b>Ctrl</b> to snap angle", "<b>Gradient</b> for %d objects; with <b>Ctrl</b> to snap angle", n_objects), diff --git a/src/ui/tools/lpe-tool.cpp b/src/ui/tools/lpe-tool.cpp index ee85dd28c..29e4c9e74 100644 --- a/src/ui/tools/lpe-tool.cpp +++ b/src/ui/tools/lpe-tool.cpp @@ -393,8 +393,8 @@ lpetool_create_measuring_items(LpeTool *lc, Inkscape::Selection *selection) SPCanvasGroup *tmpgrp = lc->desktop->getTempGroup(); gchar *arc_length; double lengthval; - std::vector<SPItem*> items=selection->itemList(); - for(std::vector<SPItem*>::const_iterator i=items.begin();i!=items.end();++i){ + auto items= selection->items(); + for(auto i=items.begin();i!=items.end();++i){ if (SP_IS_PATH(*i)) { path = SP_PATH(*i); curve = path->getCurve(); diff --git a/src/ui/tools/mesh-tool.cpp b/src/ui/tools/mesh-tool.cpp index 32e70bc19..f2cf8c4a2 100644 --- a/src/ui/tools/mesh-tool.cpp +++ b/src/ui/tools/mesh-tool.cpp @@ -102,7 +102,7 @@ void MeshTool::selection_changed(Inkscape::Selection* /*sel*/) { return; } - guint n_obj = selection->itemList().size(); + guint n_obj = (guint) boost::distance(selection->items()); if (!drag->isNonEmpty() || selection->isEmpty()) { return; @@ -466,11 +466,11 @@ bool MeshTool::root_handler(GdkEvent* event) { if (over_line) { // We take the first item in selection, because with doubleclick, the first click // always resets selection to the single object under cursor - sp_mesh_context_split_near_point(this, selection->itemList()[0], this->mousepoint_doc, event->button.time); + sp_mesh_context_split_near_point(this, selection->items().front(), this->mousepoint_doc, event->button.time); } else { // Create a new gradient with default coordinates. - std::vector<SPItem*> items=selection->itemList(); - for(std::vector<SPItem*>::const_iterator i=items.begin();i!=items.end();++i){ + auto items= selection->items(); + for(auto i=items.begin();i!=items.end();++i){ SPItem *item = *i; SPGradientType new_type = SP_GRADIENT_TYPE_MESH; Inkscape::PaintTarget fsmode = (prefs->getInt("/tools/gradient/newfillorstroke", 1) != 0) ? Inkscape::FOR_FILL : Inkscape::FOR_STROKE; @@ -944,7 +944,7 @@ static void sp_mesh_end_drag(MeshTool &rc) { } else { // Starting from empty space: // Sort items so that the topmost comes last - std::vector<SPItem*> items(selection->itemList()); + std::vector<SPItem*> items(selection->items().begin(), selection->items().end()); sort(items.begin(),items.end(),sp_item_repr_compare_position); // take topmost vector = sp_gradient_vector_for_object(document, desktop, SP_ITEM(items.back()), fill_or_stroke); @@ -954,8 +954,8 @@ static void sp_mesh_end_drag(MeshTool &rc) { SPCSSAttr *css = sp_repr_css_attr_new(); sp_repr_css_set_property(css, "fill-opacity", "1.0"); - std::vector<SPItem*> items=selection->itemList(); - for(std::vector<SPItem*>::const_iterator i=items.begin();i!=items.end();++i){ + auto items= selection->items(); + for(auto i=items.begin();i!=items.end();++i){ //FIXME: see above sp_repr_css_change_recursive((*i)->getRepr(), css, "style"); @@ -971,7 +971,7 @@ static void sp_mesh_end_drag(MeshTool &rc) { // status text; we do not track coords because this branch is run once, not all the time // during drag - int n_objects = selection->itemList().size(); + int n_objects = (int) boost::distance(selection->items()); rc.message_context->setF(Inkscape::NORMAL_MESSAGE, ngettext("<b>Gradient</b> for %d object; with <b>Ctrl</b> to snap angle", "<b>Gradient</b> for %d objects; with <b>Ctrl</b> to snap angle", n_objects), diff --git a/src/ui/tools/node-tool.cpp b/src/ui/tools/node-tool.cpp index bf18d4a2e..f7f09610c 100644 --- a/src/ui/tools/node-tool.cpp +++ b/src/ui/tools/node-tool.cpp @@ -372,8 +372,8 @@ void gather_items(NodeTool *nt, SPItem *base, SPObject *obj, Inkscape::UI::Shape r.role = role; s.insert(r); } else if (role != SHAPE_ROLE_NORMAL && (SP_IS_GROUP(obj) || SP_IS_OBJECTGROUP(obj))) { - for (SPObject *c = obj->children; c; c = c->next) { - gather_items(nt, base, c, role, s); + for (auto& c: obj->children) { + gather_items(nt, base, &c, role, s); } } else if (SP_IS_ITEM(obj)) { SPItem *item = static_cast<SPItem*>(obj); @@ -401,8 +401,8 @@ void NodeTool::selection_changed(Inkscape::Selection *sel) { std::set<ShapeRecord> shapes; - std::vector<SPItem*> items=sel->itemList(); - for(std::vector<SPItem*>::const_iterator i=items.begin();i!=items.end();++i){ + auto items= sel->items(); + for(auto i=items.begin();i!=items.end();++i){ SPObject *obj = *i; if (SP_IS_ITEM(obj)) { @@ -437,8 +437,9 @@ void NodeTool::selection_changed(Inkscape::Selection *sel) { } } + std::vector<SPItem *> vec(sel->items().begin(), sel->items().end()); _previous_selection = _current_selection; - _current_selection = sel->itemList(); + _current_selection = vec; this->_multipath->setItems(shapes); this->update_tip(NULL); diff --git a/src/ui/tools/select-tool.cpp b/src/ui/tools/select-tool.cpp index 34ca2926d..86a2dbed3 100644 --- a/src/ui/tools/select-tool.cpp +++ b/src/ui/tools/select-tool.cpp @@ -467,7 +467,7 @@ bool SelectTool::root_handler(GdkEvent* event) { case GDK_2BUTTON_PRESS: if (event->button.button == 1) { if (!selection->isEmpty()) { - SPItem *clicked_item = selection->itemList()[0]; + SPItem *clicked_item = selection->items().front(); if (dynamic_cast<SPGroup *>(clicked_item) && !dynamic_cast<SPBox3D *>(clicked_item)) { // enter group if it's not a 3D box desktop->setCurrentLayer(clicked_item); diff --git a/src/ui/tools/spray-tool.cpp b/src/ui/tools/spray-tool.cpp index 3fafac2a7..3649008ff 100644 --- a/src/ui/tools/spray-tool.cpp +++ b/src/ui/tools/spray-tool.cpp @@ -13,6 +13,7 @@ * Jon A. Cruz <jon@joncruz.org> * Abhishek Sharma * Jabiertxo Arraiza <jabier.arraiza@marker.es> + * Adrian Boguszewski * * Copyright (C) 2009 authors * @@ -182,6 +183,7 @@ SprayTool::SprayTool() } SprayTool::~SprayTool() { + object_set.clear(); this->enableGrDrag(false); this->style_set_connection.disconnect(); @@ -196,7 +198,7 @@ void SprayTool::update_cursor(bool /*with_shift*/) { gchar *sel_message = NULL; if (!desktop->selection->isEmpty()) { - num = desktop->selection->itemList().size(); + num = (guint) boost::distance(desktop->selection->items()); sel_message = g_strdup_printf(ngettext("<b>%i</b> object selected","<b>%i</b> objects selected",num), num); } else { sel_message = g_strdup_printf("%s", _("<b>Nothing</b> selected")); @@ -577,7 +579,7 @@ static bool fit_item(SPDesktop *desktop, if (selection->isEmpty()) { return false; } - std::vector<SPItem*> const items_selected(selection->itemList()); + std::vector<SPItem*> const items_selected(selection->items().begin(), selection->items().end()); std::vector<SPItem*> items_down_erased; for (std::vector<SPItem*>::const_iterator i=items_down.begin(); i!=items_down.end(); ++i) { SPItem *item_down = *i; @@ -848,7 +850,7 @@ static bool fit_item(SPDesktop *desktop, } static bool sp_spray_recursive(SPDesktop *desktop, - Inkscape::Selection *selection, + Inkscape::ObjectSet *set, SPItem *item, Geom::Point p, Geom::Point /*vector*/, @@ -893,7 +895,7 @@ static bool sp_spray_recursive(SPDesktop *desktop, if (box) { // convert 3D boxes to ordinary groups before spraying their shapes item = box3d_convert_to_group(box); - selection->add(item); + set->add(item); } } @@ -982,23 +984,11 @@ static bool sp_spray_recursive(SPDesktop *desktop, } #ifdef ENABLE_SPRAY_MODE_SINGLE_PATH } else if (mode == SPRAY_MODE_SINGLE_PATH) { + long setSize = boost::distance(set->items()); + SPItem *parent_item = setSize > 0 ? set->items().front() : nullptr; // Initial object + SPItem *unionResult = setSize > 1 ? *(++set->items().begin()) : nullptr; // Previous union + SPItem *item_copied = nullptr; // Projected object - SPItem *parent_item = NULL; // Initial object - SPItem *item_copied = NULL; // Projected object - SPItem *unionResult = NULL; // Previous union - - int i=1; - std::vector<SPItem*> items=selection->itemList(); - for(std::vector<SPItem*>::const_iterator it=items.begin();it!=items.end(); ++it){ - SPItem *item1 = *it; - if (i == 1) { - parent_item = item1; - } - if (i == 2) { - unionResult = item1; - } - i++; - } if (parent_item) { SPDocument *doc = parent_item->document; Inkscape::XML::Document* xml_doc = doc->getReprDoc(); @@ -1031,13 +1021,13 @@ static bool sp_spray_recursive(SPDesktop *desktop, sp_item_move_rel(item_copied, Geom::Translate(move[Geom::X], -move[Geom::Y])); // Union and duplication - selection->clear(); - selection->add(item_copied); + set->clear(); + set->add(item_copied); if (unionResult) { // No need to add the very first item (initialized with NULL). - selection->add(unionResult); + set->add(unionResult); } - sp_selected_path_union_skip_undo(selection, selection->desktop()); - selection->add(parent_item); + sp_selected_path_union_skip_undo(set); + set->add(parent_item); Inkscape::GC::release(copy); did = true; } @@ -1132,9 +1122,8 @@ static bool sp_spray_recursive(SPDesktop *desktop, static bool sp_spray_dilate(SprayTool *tc, Geom::Point /*event_p*/, Geom::Point p, Geom::Point vector, bool reverse) { SPDesktop *desktop = tc->desktop; - Inkscape::Selection *selection = desktop->getSelection(); - - if (selection->isEmpty()) { + Inkscape::ObjectSet *set = tc->objectSet(); + if (set->isEmpty()) { return false; } @@ -1156,7 +1145,7 @@ static bool sp_spray_dilate(SprayTool *tc, Geom::Point /*event_p*/, Geom::Point double move_standard_deviation = get_move_standard_deviation(tc); { - std::vector<SPItem*> const items(selection->itemList()); + std::vector<SPItem*> const items(set->items().begin(), set->items().end()); for(std::vector<SPItem*>::const_iterator i=items.begin();i!=items.end(); ++i){ SPItem *item = *i; @@ -1168,7 +1157,7 @@ static bool sp_spray_dilate(SprayTool *tc, Geom::Point /*event_p*/, Geom::Point SPItem *item = *i; g_assert(item != NULL); if (sp_spray_recursive(desktop - , selection + , set , item , p, vector , tc->mode @@ -1262,6 +1251,11 @@ bool SprayTool::root_handler(GdkEvent* event) { this->is_dilating = true; this->has_dilated = false; + object_set = *desktop->getSelection(); + if (mode == SPRAY_MODE_SINGLE_PATH) { + desktop->getSelection()->clear(); + } + if(this->is_dilating && event->button.button == 1 && !this->space_panning) { sp_spray_dilate(this, motion_w, desktop->dt2doc(motion_dt), Geom::Point(0,0), MOD__SHIFT(event)); } @@ -1285,7 +1279,7 @@ bool SprayTool::root_handler(GdkEvent* event) { guint num = 0; if (!desktop->selection->isEmpty()) { - num = desktop->selection->itemList().size(); + num = (guint) boost::distance(desktop->selection->items()); } if (num == 0) { this->message_context->flash(Inkscape::ERROR_MESSAGE, _("<b>Nothing selected!</b> Select objects to spray.")); @@ -1370,6 +1364,8 @@ bool SprayTool::root_handler(GdkEvent* event) { SP_VERB_CONTEXT_SPRAY, _("Spray with clones")); break; case SPRAY_MODE_SINGLE_PATH: + sp_selected_path_union_skip_undo(objectSet()); + desktop->getSelection()->add(object_set.objects().begin(), object_set.objects().end()); DocumentUndo::done(this->desktop->getDocument(), SP_VERB_CONTEXT_SPRAY, _("Spray in single path")); break; diff --git a/src/ui/tools/spray-tool.h b/src/ui/tools/spray-tool.h index c81110b37..d5504d565 100644 --- a/src/ui/tools/spray-tool.h +++ b/src/ui/tools/spray-tool.h @@ -13,6 +13,7 @@ * Vincent MONTAGNE * Pierre BARBRY-BLOT * Jabiertxo ARRAIZA + * Adrian Boguszewski * * Copyright (C) 2009 authors * @@ -120,8 +121,14 @@ public: virtual const std::string& getPrefsPath(); - void update_cursor(bool /*with_shift*/); + + ObjectSet* objectSet() { + return &object_set; + } + +private: + ObjectSet object_set; }; } diff --git a/src/ui/tools/tool-base.cpp b/src/ui/tools/tool-base.cpp index f85744744..8a35882b9 100644 --- a/src/ui/tools/tool-base.cpp +++ b/src/ui/tools/tool-base.cpp @@ -1051,9 +1051,8 @@ void sp_event_root_menu_popup(SPDesktop *desktop, SPItem *item, GdkEvent *event) item = sp_event_context_find_item (desktop, Geom::Point(event->button.x, event->button.y), FALSE, FALSE); - /* fixme: This is not what I want but works for now (Lauris) */ - if (event->type == GDK_KEY_PRESS) { - item = desktop->getSelection()->itemList().front(); + if (event->type == GDK_KEY_PRESS && !desktop->getSelection()->isEmpty()) { + item = desktop->getSelection()->items().front(); } ContextMenu* CM = new ContextMenu(desktop, item); @@ -1127,8 +1126,9 @@ SPItem *sp_event_context_find_item(SPDesktop *desktop, Geom::Point const &p, SPItem *item = 0; if (select_under) { - SPItem *selected_at_point = desktop->getItemFromListAtPointBottom( - desktop->selection->itemList(), p); + auto tmp = desktop->selection->items(); + std::vector<SPItem *> vec(tmp.begin(), tmp.end()); + SPItem *selected_at_point = desktop->getItemFromListAtPointBottom(vec, p); item = desktop->getItemAtPoint(p, into_groups, selected_at_point); if (item == NULL) { // we may have reached bottom, flip over to the top item = desktop->getItemAtPoint(p, into_groups, NULL); diff --git a/src/ui/tools/tweak-tool.cpp b/src/ui/tools/tweak-tool.cpp index fbf1b2a0b..a0394ecd4 100644 --- a/src/ui/tools/tweak-tool.cpp +++ b/src/ui/tools/tweak-tool.cpp @@ -141,7 +141,7 @@ void TweakTool::update_cursor (bool with_shift) { gchar *sel_message = NULL; if (!desktop->selection->isEmpty()) { - num = desktop->selection->itemList().size(); + num = (guint) boost::distance(desktop->selection->items()); sel_message = g_strdup_printf(ngettext("<b>%i</b> object selected","<b>%i</b> objects selected",num), num); } else { sel_message = g_strdup_printf("%s", _("<b>Nothing</b> selected")); @@ -373,9 +373,9 @@ sp_tweak_dilate_recursive (Inkscape::Selection *selection, SPItem *item, Geom::P if (dynamic_cast<SPGroup *>(item) && !dynamic_cast<SPBox3D *>(item)) { GSList *children = NULL; - for (SPObject *child = item->firstChild() ; child; child = child->getNext() ) { - if (dynamic_cast<SPItem *>(static_cast<SPObject *>(child))) { - children = g_slist_prepend(children, child); + for (auto& child: item->children) { + if (dynamic_cast<SPItem *>(static_cast<SPObject *>(&child))) { + children = g_slist_prepend(children, &child); } } @@ -820,8 +820,8 @@ static void tweak_colors_in_gradient(SPItem *item, Inkscape::PaintTarget fill_or double offset_l = 0; double offset_h = 0; SPObject *child_prev = NULL; - for (SPObject *child = vector->firstChild(); child; child = child->getNext()) { - SPStop *stop = dynamic_cast<SPStop *>(child); + for (auto& child: vector->children) { + SPStop *stop = dynamic_cast<SPStop *>(&child); if (!stop) { continue; } @@ -866,7 +866,7 @@ static void tweak_colors_in_gradient(SPItem *item, Inkscape::PaintTarget fill_or } offset_l = offset_h; - child_prev = child; + child_prev = &child; } } @@ -882,8 +882,8 @@ sp_tweak_color_recursive (guint mode, SPItem *item, SPItem *item_at_point, bool did = false; if (dynamic_cast<SPGroup *>(item)) { - for (SPObject *child = item->firstChild() ; child; child = child->getNext() ) { - SPItem *childItem = dynamic_cast<SPItem *>(child); + for (auto& child: item->children) { + SPItem *childItem = dynamic_cast<SPItem *>(&child); if (childItem) { if (sp_tweak_color_recursive (mode, childItem, item_at_point, fill_goal, do_fill, @@ -939,9 +939,8 @@ sp_tweak_color_recursive (guint mode, SPItem *item, SPItem *item_at_point, Geom::Affine i2dt = item->i2dt_affine (); if (style->filter.set && style->getFilter()) { //cycle through filter primitives - SPObject *primitive_obj = style->getFilter()->children; - while (primitive_obj) { - SPFilterPrimitive *primitive = dynamic_cast<SPFilterPrimitive *>(primitive_obj); + for (auto& primitive_obj: style->getFilter()->children) { + SPFilterPrimitive *primitive = dynamic_cast<SPFilterPrimitive *>(&primitive_obj); if (primitive) { //if primitive is gaussianblur SPGaussianBlur * spblur = dynamic_cast<SPGaussianBlur *>(primitive); @@ -950,7 +949,6 @@ sp_tweak_color_recursive (guint mode, SPItem *item, SPItem *item_at_point, blur_now += num * i2dt.descrim(); // sum all blurs in the filter } } - primitive_obj = primitive_obj->next; } } double perimeter = bbox->dimensions()[Geom::X] + bbox->dimensions()[Geom::Y]; @@ -1064,8 +1062,8 @@ sp_tweak_dilate (TweakTool *tc, Geom::Point event_p, Geom::Point p, Geom::Point double move_force = get_move_force(tc); double color_force = MIN(sqrt(path_force)/20.0, 1); - std::vector<SPItem*> items=selection->itemList(); - for(std::vector<SPItem*>::const_iterator i=items.begin();i!=items.end(); ++i){ + auto items= selection->items(); + for(auto i=items.begin();i!=items.end(); ++i){ SPItem *item = *i; if (is_color_mode (tc->mode)) { @@ -1173,7 +1171,7 @@ bool TweakTool::root_handler(GdkEvent* event) { guint num = 0; if (!desktop->selection->isEmpty()) { - num = desktop->selection->itemList().size(); + num = (guint) boost::distance(desktop->selection->items()); } if (num == 0) { this->message_context->flash(Inkscape::ERROR_MESSAGE, _("<b>Nothing selected!</b> Select objects to tweak.")); diff --git a/src/ui/widget/layer-selector.cpp b/src/ui/widget/layer-selector.cpp index 7ee34f3b3..4432a6e09 100644 --- a/src/ui/widget/layer-selector.cpp +++ b/src/ui/widget/layer-selector.cpp @@ -19,6 +19,8 @@ #include "ui/dialog/layer-properties.h" #include <glibmm/i18n.h> +#include <boost/range/adaptor/filtered.hpp> +#include <boost/range/adaptor/reversed.hpp> #include "desktop.h" @@ -346,27 +348,17 @@ void LayerSelector::_buildSiblingEntries( unsigned depth, SPObject &parent, Inkscape::Util::List<SPObject &> hierarchy ) { - using Inkscape::Util::List; using Inkscape::Util::rest; - using Inkscape::Util::reverse_list_in_place; - using Inkscape::Util::filter_list; - Inkscape::Util::List<SPObject &> siblings( - reverse_list_in_place( - filter_list<SPObject::SiblingIterator>( - is_layer(_desktop), parent.firstChild(), NULL - ) - ) - ); + auto siblings = parent.children | boost::adaptors::filtered(is_layer(_desktop)) | boost::adaptors::reversed; SPObject *layer( hierarchy ? &*hierarchy : NULL ); - while (siblings) { - _buildEntry(depth, *siblings); - if ( &*siblings == layer ) { + for (auto& sib: siblings) { + _buildEntry(depth, sib); + if ( &sib == layer ) { _buildSiblingEntries(depth+1, *layer, rest(hierarchy)); } - ++siblings; } } diff --git a/src/ui/widget/object-composite-settings.cpp b/src/ui/widget/object-composite-settings.cpp index c8ac20c54..1727660c8 100644 --- a/src/ui/widget/object-composite-settings.cpp +++ b/src/ui/widget/object-composite-settings.cpp @@ -118,7 +118,7 @@ ObjectCompositeSettings::_blendBlurValueChanged() const Glib::ustring blendmode = _fe_cb.get_blend_mode(); //apply created filter to every selected item - std::vector<SPObject*> sel=_subject->list(); + std::vector<SPObject*> sel = _subject->list(); for (std::vector<SPObject*>::const_iterator i = sel.begin() ; i != sel.end() ; ++i ) { if (!SP_IS_ITEM(*i)) { continue; diff --git a/src/ui/widget/style-subject.cpp b/src/ui/widget/style-subject.cpp index 811ed2221..a779e6feb 100644 --- a/src/ui/widget/style-subject.cpp +++ b/src/ui/widget/style-subject.cpp @@ -54,11 +54,13 @@ Inkscape::Selection *StyleSubject::Selection::_getSelection() const { } } -std::vector<SPObject*> StyleSubject::Selection::list(){ +std::vector<SPObject*> StyleSubject::Selection::list() { Inkscape::Selection *selection = _getSelection(); - if(selection) - return selection->list(); - else return std::vector<SPObject*>(); + if(selection) { + return std::vector<SPObject *>(selection->objects().begin(), selection->objects().end()); + } + + return std::vector<SPObject*>(); } Geom::OptRect StyleSubject::Selection::getBounds(SPItem::BBoxType type) { diff --git a/src/uri-references.cpp b/src/uri-references.cpp index d626d0e41..07f2d168b 100644 --- a/src/uri-references.cpp +++ b/src/uri-references.cpp @@ -74,10 +74,11 @@ bool URIReference::_acceptObject(SPObject *obj) const std::vector<int> positions; while (owner->cloned) { int position = 0; - SPObject *c = owner->parent->firstChild(); - while (c != owner && dynamic_cast<SPObject *>(c)) { + for (auto &child: owner->parent->children) { + if(&child == owner) { + break; + } position++; - c = c->next; } positions.push_back(position); owner = owner->parent; @@ -90,7 +91,7 @@ bool URIReference::_acceptObject(SPObject *obj) const g_warning("cloned object with no known type\n"); return false; } - for (int i = positions.size() - 2; i >= 0; i--) + for (int i = (int) (positions.size() - 2); i >= 0; i--) owner = owner->childList(false)[positions[i]]; } // once we have the "original" object (hopefully) we look at who is referencing it diff --git a/src/vanishing-point.cpp b/src/vanishing-point.cpp index 987211edc..d849b35d9 100644 --- a/src/vanishing-point.cpp +++ b/src/vanishing-point.cpp @@ -256,8 +256,8 @@ VanishingPoint::set_pos(Proj::Pt2 const &pt) { std::list<SPBox3D *> VanishingPoint::selectedBoxes(Inkscape::Selection *sel) { std::list<SPBox3D *> sel_boxes; - std::vector<SPItem*> itemlist=sel->itemList(); - for (std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();++i) { + auto itemlist= sel->items(); + for (auto i=itemlist.begin();i!=itemlist.end();++i) { SPItem *item = *i; SPBox3D *box = dynamic_cast<SPBox3D *>(item); if (box && this->hasBox(box)) { @@ -395,8 +395,8 @@ VPDragger::VPsOfSelectedBoxes() { VanishingPoint *vp; // FIXME: Should we take the selection from the parent VPDrag? I guess it shouldn't make a difference. Inkscape::Selection *sel = SP_ACTIVE_DESKTOP->getSelection(); - std::vector<SPItem*> itemlist=sel->itemList(); - for (std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();++i) { + auto itemlist= sel->items(); + for (auto i=itemlist.begin();i!=itemlist.end();++i) { SPItem *item = *i; SPBox3D *box = dynamic_cast<SPBox3D *>(item); if (box) { @@ -573,8 +573,8 @@ VPDrag::updateDraggers () g_return_if_fail (this->selection != NULL); - std::vector<SPItem*> itemlist=this->selection->itemList(); - for (std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();++i) { + auto itemlist= this->selection->items(); + for (auto i=itemlist.begin();i!=itemlist.end();++i) { SPItem *item = *i; SPBox3D *box = dynamic_cast<SPBox3D *>(item); if (box) { @@ -605,8 +605,8 @@ VPDrag::updateLines () g_return_if_fail (this->selection != NULL); - std::vector<SPItem*> itemlist=this->selection->itemList(); - for (std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();++i) { + auto itemlist= this->selection->items(); + for (auto i=itemlist.begin();i!=itemlist.end();++i) { SPItem *item = *i; SPBox3D *box = dynamic_cast<SPBox3D *>(item); if (box) { @@ -623,11 +623,11 @@ VPDrag::updateBoxHandles () // FIXME: Is there a way to update the knots without accessing the // (previously) statically linked function KnotHolder::update_knots? - std::vector<SPItem*> sel = selection->itemList(); + auto sel = selection->items(); if (sel.empty()) return; // no selection - if (sel.size() > 1) { + if (boost::distance(sel) > 1) { // Currently we only show handles if a single box is selected return; } diff --git a/src/verbs.cpp b/src/verbs.cpp index d781442eb..59ad06fa1 100644 --- a/src/verbs.cpp +++ b/src/verbs.cpp @@ -1517,7 +1517,7 @@ void ObjectVerb::perform( SPAction *action, void *data) sp_selection_rotate_90(dt, true); break; case SP_VERB_OBJECT_FLATTEN: - sp_selection_remove_transform(dt); + sp_object_set_remove_transform(dt); break; case SP_VERB_OBJECT_FLOW_TEXT: text_flow_into_shape(); @@ -1529,12 +1529,12 @@ void ObjectVerb::perform( SPAction *action, void *data) flowtext_to_text(); break; case SP_VERB_OBJECT_FLIP_HORIZONTAL: - sp_selection_scale_relative(sel, center, Geom::Scale(-1.0, 1.0)); + sp_object_set_scale_relative(sel, center, Geom::Scale(-1.0, 1.0)); DocumentUndo::done(dt->getDocument(), SP_VERB_OBJECT_FLIP_HORIZONTAL, _("Flip horizontally")); break; case SP_VERB_OBJECT_FLIP_VERTICAL: - sp_selection_scale_relative(sel, center, Geom::Scale(1.0, -1.0)); + sp_object_set_scale_relative(sel, center, Geom::Scale(1.0, -1.0)); DocumentUndo::done(dt->getDocument(), SP_VERB_OBJECT_FLIP_VERTICAL, _("Flip vertically")); break; diff --git a/src/widgets/arc-toolbar.cpp b/src/widgets/arc-toolbar.cpp index 81cde97d4..9b408a7b2 100644 --- a/src/widgets/arc-toolbar.cpp +++ b/src/widgets/arc-toolbar.cpp @@ -96,8 +96,8 @@ sp_arctb_startend_value_changed(GtkAdjustment *adj, GObject *tbl, gchar const *v gchar* namespaced_name = g_strconcat("sodipodi:", value_name, NULL); bool modmade = false; - std::vector<SPItem*> itemlist=desktop->getSelection()->itemList(); - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ + auto itemlist= desktop->getSelection()->items(); + for(auto i=itemlist.begin();i!=itemlist.end();++i){ SPItem *item = *i; if (SP_IS_GENERICELLIPSE(item)) { @@ -162,8 +162,8 @@ static void sp_arctb_open_state_changed( EgeSelectOneAction *act, GObject *tbl ) bool modmade = false; if ( ege_select_one_action_get_active(act) != 0 ) { - std::vector<SPItem*> itemlist=desktop->getSelection()->itemList(); - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ + auto itemlist= desktop->getSelection()->items(); + for(auto i=itemlist.begin();i!=itemlist.end();++i){ SPItem *item = *i; if (SP_IS_GENERICELLIPSE(item)) { Inkscape::XML::Node *repr = item->getRepr(); @@ -173,8 +173,8 @@ static void sp_arctb_open_state_changed( EgeSelectOneAction *act, GObject *tbl ) } } } else { - std::vector<SPItem*> itemlist=desktop->getSelection()->itemList(); - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ + auto itemlist= desktop->getSelection()->items(); + for(auto i=itemlist.begin();i!=itemlist.end();++i){ SPItem *item = *i; if (SP_IS_GENERICELLIPSE(item)) { Inkscape::XML::Node *repr = item->getRepr(); @@ -263,8 +263,8 @@ static void sp_arc_toolbox_selection_changed(Inkscape::Selection *selection, GOb purge_repr_listener( tbl, tbl ); - std::vector<SPItem*> itemlist=selection->itemList(); - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ + auto itemlist= selection->items(); + for(auto i=itemlist.begin();i!=itemlist.end();++i){ SPItem *item = *i; if (SP_IS_GENERICELLIPSE(item)) { n_selected++; diff --git a/src/widgets/connector-toolbar.cpp b/src/widgets/connector-toolbar.cpp index 46493f3ae..a078ecec4 100644 --- a/src/widgets/connector-toolbar.cpp +++ b/src/widgets/connector-toolbar.cpp @@ -94,8 +94,8 @@ static void sp_connector_orthogonal_toggled( GtkToggleAction* act, GObject *tbl gchar *value = is_orthog ? orthog_str : polyline_str ; bool modmade = false; - std::vector<SPItem*> itemlist=desktop->getSelection()->itemList(); - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ + auto itemlist= desktop->getSelection()->items(); + for(auto i=itemlist.begin();i!=itemlist.end();++i){ SPItem *item = *i; if (Inkscape::UI::Tools::cc_item_is_connector(item)) { @@ -141,8 +141,8 @@ static void connector_curvature_changed(GtkAdjustment *adj, GObject* tbl) g_ascii_dtostr(value, G_ASCII_DTOSTR_BUF_SIZE, newValue); bool modmade = false; - std::vector<SPItem*> itemlist=desktop->getSelection()->itemList(); - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ + auto itemlist= desktop->getSelection()->items(); + for(auto i=itemlist.begin();i!=itemlist.end();++i){ SPItem *item = *i; if (Inkscape::UI::Tools::cc_item_is_connector(item)) { @@ -224,7 +224,9 @@ static void sp_connector_graph_layout(void) int saved_compensation = prefs->getInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED); prefs->setInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED); - graphlayout(SP_ACTIVE_DESKTOP->getSelection()->itemList()); + auto tmp = SP_ACTIVE_DESKTOP->getSelection()->items(); + std::vector<SPItem *> vec(tmp.begin(), tmp.end()); + graphlayout(vec); prefs->setInt("/options/clonecompensation/value", saved_compensation); diff --git a/src/widgets/fill-style.cpp b/src/widgets/fill-style.cpp index aff88aca5..c35519b68 100644 --- a/src/widgets/fill-style.cpp +++ b/src/widgets/fill-style.cpp @@ -472,7 +472,7 @@ void FillNStroke::updateFromPaint() SPDocument *document = desktop->getDocument(); Inkscape::Selection *selection = desktop->getSelection(); - std::vector<SPItem*> const items = selection->itemList(); + std::vector<SPItem*> const items(selection->items().begin(), selection->items().end()); switch (psel->mode) { case SPPaintSelector::MODE_EMPTY: diff --git a/src/widgets/gradient-toolbar.cpp b/src/widgets/gradient-toolbar.cpp index fd2eb7efe..8474327ca 100644 --- a/src/widgets/gradient-toolbar.cpp +++ b/src/widgets/gradient-toolbar.cpp @@ -117,8 +117,8 @@ void gr_apply_gradient(Inkscape::Selection *selection, GrDrag *drag, SPGradient } // If no drag or no dragger selected, act on selection - std::vector<SPItem*> itemlist=selection->itemList(); - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ + auto itemlist= selection->items(); + for(auto i=itemlist.begin();i!=itemlist.end();++i){ gr_apply_gradient_to_item(*i, gr, initialType, initialMode, initialMode); } } @@ -217,8 +217,8 @@ void gr_get_dt_selected_gradient(Inkscape::Selection *selection, SPGradient *&gr { SPGradient *gradient = 0; - std::vector<SPItem*> itemlist=selection->itemList(); - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ + auto itemlist= selection->items(); + for(auto i=itemlist.begin();i!=itemlist.end();++i){ SPItem *item = *i;// get the items gradient, not the getVector() version SPStyle *style = item->style; SPPaintServer *server = 0; @@ -285,8 +285,8 @@ void gr_read_selection( Inkscape::Selection *selection, } // If no selected dragger, read desktop selection - std::vector<SPItem*> itemlist=selection->itemList(); - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ + auto itemlist= selection->items(); + for(auto i=itemlist.begin();i!=itemlist.end();++i){ SPItem *item = *i; SPStyle *style = item->style; @@ -721,9 +721,9 @@ static void select_stop_by_drag(GtkWidget *combo_box, SPGradient *gradient, Tool static void select_stop_in_list( GtkWidget *combo_box, SPGradient *gradient, SPStop *new_stop, GtkWidget *data, gboolean block) { int i = 0; - for ( SPObject *ochild = gradient->firstChild() ; ochild ; ochild = ochild->getNext() ) { - if (SP_IS_STOP(ochild)) { - if (ochild == new_stop) { + for (auto& ochild: gradient->children) { + if (SP_IS_STOP(&ochild)) { + if (&ochild == new_stop) { blocked = block; gtk_combo_box_set_active(GTK_COMBO_BOX(combo_box) , i); gr_stop_set_offset(GTK_COMBO_BOX(combo_box), data); @@ -766,9 +766,9 @@ static gboolean update_stop_list( GtkWidget *stop_combo, SPGradient *gradient, S /* Populate the combobox store */ std::vector<SPObject *> sl; if ( gradient->hasStops() ) { - for ( SPObject *ochild = gradient->firstChild() ; ochild ; ochild = ochild->getNext() ) { - if (SP_IS_STOP(ochild)) { - sl.push_back(ochild); + for (auto& ochild: gradient->children) { + if (SP_IS_STOP(&ochild)) { + sl.push_back(&ochild); } } } diff --git a/src/widgets/gradient-vector.cpp b/src/widgets/gradient-vector.cpp index ed88432f1..0c5f3cf47 100644 --- a/src/widgets/gradient-vector.cpp +++ b/src/widgets/gradient-vector.cpp @@ -335,13 +335,13 @@ unsigned long sp_gradient_to_hhssll(SPGradient *gr) static GSList *get_all_doc_items(GSList *list, SPObject *from, bool onlyvisible, bool onlysensitive, bool ingroups, GSList const *exclude) { - for ( SPObject *child = from->firstChild() ; child; child = child->getNext() ) { - if (SP_IS_ITEM(child)) { - list = g_slist_prepend(list, SP_ITEM(child)); + for (auto& child: from->children) { + if (SP_IS_ITEM(&child)) { + list = g_slist_prepend(list, SP_ITEM(&child)); } - if (ingroups || SP_IS_ITEM(child)) { - list = get_all_doc_items(list, child, onlyvisible, onlysensitive, ingroups, exclude); + if (ingroups || SP_IS_ITEM(&child)) { + list = get_all_doc_items(list, &child, onlyvisible, onlysensitive, ingroups, exclude); } } @@ -489,10 +489,10 @@ static void verify_grad(SPGradient *gradient) int i = 0; SPStop *stop = NULL; /* count stops */ - for ( SPObject *ochild = gradient->firstChild() ; ochild ; ochild = ochild->getNext() ) { - if (SP_IS_STOP(ochild)) { + for (auto& ochild: gradient->children) { + if (SP_IS_STOP(&ochild)) { i++; - stop = SP_STOP(ochild); + stop = SP_STOP(&ochild); } } @@ -532,9 +532,9 @@ static void select_stop_in_list( GtkWidget *vb, SPGradient *gradient, SPStop *ne GtkWidget *combo_box = static_cast<GtkWidget *>(g_object_get_data(G_OBJECT(vb), "combo_box")); int i = 0; - for ( SPObject *ochild = gradient->firstChild() ; ochild ; ochild = ochild->getNext() ) { - if (SP_IS_STOP(ochild)) { - if (ochild == new_stop) { + for (auto& ochild: gradient->children) { + if (SP_IS_STOP(&ochild)) { + if (&ochild == new_stop) { gtk_combo_box_set_active (GTK_COMBO_BOX(combo_box) , i); break; } @@ -567,9 +567,9 @@ static void update_stop_list( GtkWidget *vb, SPGradient *gradient, SPStop *new_s /* Populate the combobox store */ GSList *sl = NULL; if ( gradient->hasStops() ) { - for ( SPObject *ochild = gradient->firstChild() ; ochild ; ochild = ochild->getNext() ) { - if (SP_IS_STOP(ochild)) { - sl = g_slist_append(sl, ochild); + for (auto& ochild: gradient->children) { + if (SP_IS_STOP(&ochild)) { + sl = g_slist_append(sl, &ochild); } } } diff --git a/src/widgets/mesh-toolbar.cpp b/src/widgets/mesh-toolbar.cpp index 3bc6cb288..fb540b5f5 100644 --- a/src/widgets/mesh-toolbar.cpp +++ b/src/widgets/mesh-toolbar.cpp @@ -80,8 +80,8 @@ void ms_read_selection( Inkscape::Selection *selection, bool first = true; ms_type = SP_MESH_TYPE_COONS; - std::vector<SPItem*> itemlist=selection->itemList(); - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ + auto itemlist= selection->items(); + for(auto i=itemlist.begin();i!=itemlist.end();++i){ SPItem *item = *i; SPStyle *style = item->style; @@ -207,8 +207,8 @@ void ms_get_dt_selected_gradient(Inkscape::Selection *selection, SPMesh *&ms_sel { SPMesh *gradient = 0; - std::vector<SPItem*> itemlist=selection->itemList(); - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ + auto itemlist= selection->items(); + for(auto i=itemlist.begin();i!=itemlist.end();++i){ SPItem *item = *i;// get the items gradient, not the getVector() version SPStyle *style = item->style; SPPaintServer *server = 0; diff --git a/src/widgets/pencil-toolbar.cpp b/src/widgets/pencil-toolbar.cpp index 32cdb0a7d..582fb66ba 100644 --- a/src/widgets/pencil-toolbar.cpp +++ b/src/widgets/pencil-toolbar.cpp @@ -237,8 +237,8 @@ static void sp_pencil_tb_defaults(GtkWidget * /*widget*/, GObject *obj) static void sp_simplify_flatten(GtkWidget * /*widget*/, GObject *obj) { SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data(obj, "desktop")); - std::vector<SPItem *> selected = desktop->getSelection()->itemList(); - for (std::vector<SPItem *>::iterator it(selected.begin()); it != selected.end(); ++it){ + auto selected = desktop->getSelection()->items(); + for (auto it(selected.begin()); it != selected.end(); ++it){ SPLPEItem* lpeitem = dynamic_cast<SPLPEItem*>(*it); if (lpeitem && lpeitem->hasPathEffect()){ PathEffectList lpelist = lpeitem->getEffectList(); @@ -282,8 +282,8 @@ static void sp_pencil_tb_tolerance_value_changed(GtkAdjustment *adj, GObject *tb gtk_adjustment_get_value(adj)); g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data(tbl, "desktop")); - std::vector<SPItem *> selected = desktop->getSelection()->itemList(); - for (std::vector<SPItem *>::iterator it(selected.begin()); it != selected.end(); ++it){ + auto selected = desktop->getSelection()->items(); + for (auto it(selected.begin()); it != selected.end(); ++it){ SPLPEItem* lpeitem = dynamic_cast<SPLPEItem*>(*it); if (lpeitem && lpeitem->hasPathEffect()){ Inkscape::LivePathEffect::Effect* simplify = lpeitem->getPathEffectOfType(Inkscape::LivePathEffect::SIMPLIFY); diff --git a/src/widgets/rect-toolbar.cpp b/src/widgets/rect-toolbar.cpp index c9b75294b..67947c1fd 100644 --- a/src/widgets/rect-toolbar.cpp +++ b/src/widgets/rect-toolbar.cpp @@ -102,8 +102,8 @@ static void sp_rtb_value_changed(GtkAdjustment *adj, GObject *tbl, gchar const * bool modmade = false; Inkscape::Selection *selection = desktop->getSelection(); - std::vector<SPItem*> itemlist=selection->itemList(); - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ + auto itemlist= selection->items(); + for(auto i=itemlist.begin();i!=itemlist.end();++i){ if (SP_IS_RECT(*i)) { if (gtk_adjustment_get_value(adj) != 0) { (SP_RECT(*i)->*setter)(Quantity::convert(gtk_adjustment_get_value(adj), unit, "px")); @@ -239,8 +239,8 @@ static void sp_rect_toolbox_selection_changed(Inkscape::Selection *selection, GO } purge_repr_listener( tbl, tbl ); - std::vector<SPItem*> itemlist=selection->itemList(); - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ + auto itemlist= selection->items(); + for(auto i=itemlist.begin();i!=itemlist.end();++i){ if (SP_IS_RECT(*i)) { n_selected++; item = *i; diff --git a/src/widgets/select-toolbar.cpp b/src/widgets/select-toolbar.cpp index 81fb2371b..e551c28c3 100644 --- a/src/widgets/select-toolbar.cpp +++ b/src/widgets/select-toolbar.cpp @@ -254,7 +254,7 @@ sp_object_layout_any_value_changed(GtkAdjustment *adj, GObject *tbl) scaler = get_scale_transform_for_uniform_stroke (*bbox_geom, 0, 0, false, false, x0, y0, x1, y1); } - sp_selection_apply_affine(selection, scaler); + sp_object_set_apply_affine(selection, scaler); DocumentUndo::maybeDone(document, actionkey, SP_VERB_CONTEXT_SELECT, _("Transform by toolbar")); diff --git a/src/widgets/spiral-toolbar.cpp b/src/widgets/spiral-toolbar.cpp index 7406be255..98d21c84d 100644 --- a/src/widgets/spiral-toolbar.cpp +++ b/src/widgets/spiral-toolbar.cpp @@ -76,8 +76,8 @@ static void sp_spl_tb_value_changed(GtkAdjustment *adj, GObject *tbl, Glib::ustr gchar* namespaced_name = g_strconcat("sodipodi:", value_name.data(), NULL); bool modmade = false; - std::vector<SPItem*> itemlist=desktop->getSelection()->itemList(); - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end(); ++i){ + auto itemlist= desktop->getSelection()->items(); + for(auto i=itemlist.begin();i!=itemlist.end(); ++i){ SPItem *item = *i; if (SP_IS_SPIRAL(item)) { Inkscape::XML::Node *repr = item->getRepr(); @@ -192,8 +192,8 @@ static void sp_spiral_toolbox_selection_changed(Inkscape::Selection *selection, purge_repr_listener( tbl, tbl ); - std::vector<SPItem*> itemlist=selection->itemList(); - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end(); ++i){ + auto itemlist= selection->items(); + for(auto i=itemlist.begin();i!=itemlist.end(); ++i){ SPItem *item = *i; if (SP_IS_SPIRAL(item)) { n_selected++; diff --git a/src/widgets/star-toolbar.cpp b/src/widgets/star-toolbar.cpp index e06733740..8f667a656 100644 --- a/src/widgets/star-toolbar.cpp +++ b/src/widgets/star-toolbar.cpp @@ -81,8 +81,8 @@ static void sp_stb_magnitude_value_changed( GtkAdjustment *adj, GObject *dataKlu bool modmade = false; Inkscape::Selection *selection = desktop->getSelection(); - std::vector<SPItem*> itemlist=selection->itemList(); - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ + auto itemlist= selection->items(); + for(auto i=itemlist.begin();i!=itemlist.end();++i){ SPItem *item = *i; if (SP_IS_STAR(item)) { Inkscape::XML::Node *repr = item->getRepr(); @@ -126,8 +126,8 @@ static void sp_stb_proportion_value_changed( GtkAdjustment *adj, GObject *dataKl bool modmade = false; Inkscape::Selection *selection = desktop->getSelection(); - std::vector<SPItem*> itemlist=selection->itemList(); - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ + auto itemlist= selection->items(); + for(auto i=itemlist.begin();i!=itemlist.end();++i){ SPItem *item = *i; if (SP_IS_STAR(item)) { Inkscape::XML::Node *repr = item->getRepr(); @@ -183,8 +183,8 @@ static void sp_stb_sides_flat_state_changed( EgeSelectOneAction *act, GObject *d gtk_action_set_visible( prop_action, !flat ); } - std::vector<SPItem*> itemlist=selection->itemList(); - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ + auto itemlist= selection->items(); + for(auto i=itemlist.begin();i!=itemlist.end();++i){ SPItem *item = *i; if (SP_IS_STAR(item)) { Inkscape::XML::Node *repr = item->getRepr(); @@ -222,8 +222,8 @@ static void sp_stb_rounded_value_changed( GtkAdjustment *adj, GObject *dataKludg bool modmade = false; Inkscape::Selection *selection = desktop->getSelection(); - std::vector<SPItem*> itemlist=selection->itemList(); - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ + auto itemlist= selection->items(); + for(auto i=itemlist.begin();i!=itemlist.end();++i){ SPItem *item = *i; if (SP_IS_STAR(item)) { Inkscape::XML::Node *repr = item->getRepr(); @@ -262,8 +262,8 @@ static void sp_stb_randomized_value_changed( GtkAdjustment *adj, GObject *dataKl bool modmade = false; Inkscape::Selection *selection = desktop->getSelection(); - std::vector<SPItem*> itemlist=selection->itemList(); - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ + auto itemlist= selection->items(); + for(auto i=itemlist.begin();i!=itemlist.end();++i){ SPItem *item = *i; if (SP_IS_STAR(item)) { Inkscape::XML::Node *repr = item->getRepr(); @@ -365,8 +365,8 @@ sp_star_toolbox_selection_changed(Inkscape::Selection *selection, GObject *tbl) purge_repr_listener( tbl, tbl ); - std::vector<SPItem*> itemlist=selection->itemList(); - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ + auto itemlist= selection->items(); + for(auto i=itemlist.begin();i!=itemlist.end();++i){ SPItem *item = *i; if (SP_IS_STAR(item)) { n_selected++; diff --git a/src/widgets/stroke-marker-selector.cpp b/src/widgets/stroke-marker-selector.cpp index 2a0a10efa..b0c23a88c 100644 --- a/src/widgets/stroke-marker-selector.cpp +++ b/src/widgets/stroke-marker-selector.cpp @@ -329,10 +329,10 @@ GSList *MarkerComboBox::get_marker_list (SPDocument *source) return NULL; } - for ( SPObject *child = defs->firstChild(); child; child = child->getNext() ) + for (auto& child: defs->children) { - if (SP_IS_MARKER(child)) { - ml = g_slist_prepend (ml, child); + if (SP_IS_MARKER(&child)) { + ml = g_slist_prepend (ml, &child); } } return ml; diff --git a/src/widgets/stroke-style.cpp b/src/widgets/stroke-style.cpp index e6e1a49c9..4a658c5dc 100644 --- a/src/widgets/stroke-style.cpp +++ b/src/widgets/stroke-style.cpp @@ -473,8 +473,8 @@ void StrokeStyle::markerSelectCB(MarkerComboBox *marker_combo, StrokeStyle *spw, //spw->updateMarkerHist(which); Inkscape::Selection *selection = spw->desktop->getSelection(); - std::vector<SPItem*> itemlist=selection->itemList(); - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end();++i){ + auto itemlist= selection->items(); + for(auto i=itemlist.begin();i!=itemlist.end();++i){ SPItem *item = *i; if (!SP_IS_SHAPE(item) || SP_IS_RECT(item)) { // can't set marker to rect, until it's converted to using <path> continue; @@ -934,7 +934,7 @@ StrokeStyle::updateLine() if (!sel || sel->isEmpty()) return; - std::vector<SPItem*> const objects = sel->itemList(); + std::vector<SPItem*> const objects(sel->items().begin(), sel->items().end()); SPObject * const object = objects[0]; SPStyle * const style = object->style; @@ -990,7 +990,7 @@ StrokeStyle::scaleLine() SPDocument *document = desktop->getDocument(); Inkscape::Selection *selection = desktop->getSelection(); - std::vector<SPItem*> items=selection->itemList(); + auto items= selection->items(); /* TODO: Create some standardized method */ SPCSSAttr *css = sp_repr_css_attr_new(); @@ -1005,7 +1005,7 @@ StrokeStyle::scaleLine() int ndash; dashSelector->get_dash(&ndash, &dash, &offset); - for(std::vector<SPItem*>::const_iterator i=items.begin();i!=items.end();++i){ + for(auto i=items.begin();i!=items.end();++i){ /* Set stroke width */ double width; if (unit->type == Inkscape::Util::UNIT_TYPE_LINEAR) { diff --git a/src/widgets/text-toolbar.cpp b/src/widgets/text-toolbar.cpp index 4ab631765..0160bcac7 100644 --- a/src/widgets/text-toolbar.cpp +++ b/src/widgets/text-toolbar.cpp @@ -374,8 +374,8 @@ static void sp_text_align_mode_changed( EgeSelectOneAction *act, GObject *tbl ) // move the x of all texts to preserve the same bbox Inkscape::Selection *selection = desktop->getSelection(); - std::vector<SPItem*> itemlist=selection->itemList(); - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end(); ++i){ + auto itemlist= selection->items(); + for(auto i=itemlist.begin();i!=itemlist.end(); ++i){ if (SP_IS_TEXT(*i)) { SPItem *item = *i; @@ -556,8 +556,8 @@ static void sp_text_lineheight_value_changed( GtkAdjustment *adj, GObject *tbl ) // Only need to save for undo if a text item has been changed. Inkscape::Selection *selection = desktop->getSelection(); bool modmade = false; - std::vector<SPItem*> itemlist=selection->itemList(); - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end(); ++i){ + auto itemlist= selection->items(); + for(auto i=itemlist.begin();i!=itemlist.end(); ++i){ if (SP_IS_TEXT (*i)) { modmade = true; } @@ -621,7 +621,7 @@ static void sp_text_lineheight_unit_changed( gpointer /* */, GObject *tbl ) SPDesktop *desktop = SP_ACTIVE_DESKTOP; Inkscape::Selection *selection = desktop->getSelection(); - std::vector<SPItem*> itemlist=selection->itemList(); + auto itemlist = selection->items(); // Convert between units if ((unit->abbr == "" || unit->abbr == "em") && old_unit == SP_CSS_UNIT_EX) { @@ -640,7 +640,7 @@ static void sp_text_lineheight_unit_changed( gpointer /* */, GObject *tbl ) // Convert absolute to relative... for the moment use average font-size double font_size = 0; int count = 0; - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end(); ++i){ + for(auto i=itemlist.begin();i!=itemlist.end(); ++i){ if (SP_IS_TEXT (*i)) { double doc_scale = Geom::Affine((*i)->i2dt_affine()).descrim(); font_size += (*i)->style->font_size.computed * doc_scale; @@ -669,7 +669,7 @@ static void sp_text_lineheight_unit_changed( gpointer /* */, GObject *tbl ) // Convert relative to absolute... for the moment use average font-size double font_size = 0; int count = 0; - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end(); ++i){ + for(auto i=itemlist.begin();i!=itemlist.end(); ++i){ if (SP_IS_TEXT (*i)) { double doc_scale = Geom::Affine((*i)->i2dt_affine()).descrim(); font_size += (*i)->style->font_size.computed * doc_scale; @@ -712,7 +712,7 @@ static void sp_text_lineheight_unit_changed( gpointer /* */, GObject *tbl ) // Only need to save for undo if a text item has been changed. bool modmade = false; - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end(); ++i){ + for(auto i=itemlist.begin();i!=itemlist.end(); ++i){ if (SP_IS_TEXT (*i)) { modmade = true; } @@ -1116,8 +1116,8 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ // Only flowed text can be justified, only normal text can be kerned... // Find out if we have flowed text now so we can use it several places gboolean isFlow = false; - std::vector<SPItem*> itemlist=SP_ACTIVE_DESKTOP->getSelection()->itemList(); - for(std::vector<SPItem*>::const_iterator i=itemlist.begin();i!=itemlist.end(); ++i){ + auto itemlist= SP_ACTIVE_DESKTOP->getSelection()->items(); + for(auto i=itemlist.begin();i!=itemlist.end(); ++i){ // const gchar* id = reinterpret_cast<SPItem *>(items->data)->getId(); // std::cout << " " << id << std::endl; if( SP_IS_FLOWTEXT(*i)) { |
