From d23636aa5eb0748908df4546a11649209f83bae7 Mon Sep 17 00:00:00 2001 From: joncruz Date: Mon, 28 Apr 2008 07:34:35 +0000 Subject: [PATCH] Refining eraser --- src/eraser-context.cpp | 57 ++++++++++++++++++++++++++---------------- 1 file changed, 36 insertions(+), 21 deletions(-) diff --git a/src/eraser-context.cpp b/src/eraser-context.cpp index c787f0799..b787a965c 100644 --- a/src/eraser-context.cpp +++ b/src/eraser-context.cpp @@ -819,45 +819,60 @@ set_to_accumulated(SPEraserContext *dc) g_free(str); if ( dc->repr ) { + bool wasSelection = false; Inkscape::Selection *selection = sp_desktop_selection(desktop); gint eraserMode = (prefs_get_int_attribute("tools.eraser", "mode", 0) != 0) ? 1 : 0; Inkscape::XML::Document *xml_doc = sp_document_repr_doc(desktop->doc()); - if (!selection->isEmpty()) { - // Do selection-limited - if ( eraserMode == 0 ) { - // Nuke - } else { - // Cut-out - std::vector putBacks; - GSList const *selected = g_slist_copy(const_cast(selection->itemList())); - for (GSList const *i = selected ; i ; i = i->next ) { - SPItem *item = SP_ITEM(i->data); + + SPItem* acid = SP_ITEM(desktop->doc()->getObjectByRepr(dc->repr)); + NR::Maybe eraserBbox = acid->getBounds(NR::identity()); + NR::Rect bounds = (*eraserBbox) * desktop->doc2dt(); + std::vector remainingItems; + GSList* toWorkOn = 0; + if (selection->isEmpty()) { + toWorkOn = sp_document_partial_items_in_box(sp_desktop_document(desktop), desktop->dkey, bounds); + toWorkOn = g_slist_remove( toWorkOn, acid ); + } else { + toWorkOn = g_slist_copy(const_cast(selection->itemList())); + wasSelection = true; + } + + if ( g_slist_length(toWorkOn) > 0 ) { + for (GSList *i = toWorkOn ; i ; i = i->next ) { + SPItem *item = SP_ITEM(i->data); + NR::Maybe bbox = item->getBounds(NR::identity()); + if (bbox && bbox->intersects(*eraserBbox)) { Inkscape::XML::Node* dup = dc->repr->duplicate(xml_doc); dc->repr->parent()->appendChild(dup); - Inkscape::GC::release(dup); + Inkscape::GC::release(dup); // parent takes over selection->set(item); selection->add(dup); sp_selected_path_diff_skip_undo(); workDone = true; // TODO set this only if something was cut. if ( !selection->isEmpty() ) { - // If the item was not completely erased, add it back to the selection. - GSList const *selected2 = g_slist_copy(const_cast(selection->itemList())); - for (GSList const *i2 = selected2 ; i2 ; i2 = i2->next ) { - putBacks.push_back(SP_ITEM(i2->data)); + // If the item was not completely erased, track the new remainder. + GSList *nowSel = g_slist_copy(const_cast(selection->itemList())); + for (GSList const *i2 = nowSel ; i2 ; i2 = i2->next ) { + remainingItems.push_back(SP_ITEM(i2->data)); } + g_slist_free(nowSel); } + } else { + remainingItems.push_back(item); } - g_slist_free ((GSList *) selected); + } - selection->clear(); - selection->add(putBacks.begin(), putBacks.end()); + g_slist_free(toWorkOn); + + selection->clear(); + if ( wasSelection ) { + if ( !remainingItems.empty() ) { + selection->add(remainingItems.begin(), remainingItems.end()); + } } - } else { - // TODO finish } - // Remove the eraser stroke itself: sp_repr_unparent( dc->repr ); dc->repr = 0; -- 2.30.2