diff options
| author | Jabier Arraiza <jabier.arraiza@marker.es> | 2017-09-09 01:54:39 +0000 |
|---|---|---|
| committer | Jabier Arraiza <jabier.arraiza@marker.es> | 2017-09-09 01:54:39 +0000 |
| commit | 30faf29165b1bcd936e9e0ca3ecc8b4bad4c94d2 (patch) | |
| tree | ff87b28b4f76e4b2ae947bd1bc28696cece68ce5 /src | |
| parent | Fix for bug: 1715433 :: Clone original LPE can no longer be used to fill a po... (diff) | |
| download | inkscape-30faf29165b1bcd936e9e0ca3ecc8b4bad4c94d2.tar.gz inkscape-30faf29165b1bcd936e9e0ca3ecc8b4bad4c94d2.zip | |
This commit is based on a coment on bug #1670644. And allow to fill the fill between many LPE widget that allow
attach all paths on the clipboard instead only one
Also added to this widget the option visible, to allow work with multiples paths wigout getting full cracy
Diffstat (limited to 'src')
| -rw-r--r-- | src/live_effects/lpe-fill-between-many.cpp | 15 | ||||
| -rw-r--r-- | src/live_effects/lpe-fill-between-many.h | 2 | ||||
| -rw-r--r-- | src/live_effects/parameter/originalpatharray.cpp | 134 | ||||
| -rw-r--r-- | src/live_effects/parameter/originalpatharray.h | 28 | ||||
| -rw-r--r-- | src/selection-chemistry.cpp | 1 | ||||
| -rw-r--r-- | src/ui/clipboard.cpp | 49 | ||||
| -rw-r--r-- | src/ui/clipboard.h | 1 |
7 files changed, 165 insertions, 65 deletions
diff --git a/src/live_effects/lpe-fill-between-many.cpp b/src/live_effects/lpe-fill-between-many.cpp index ded8819fc..8b5cb9b95 100644 --- a/src/live_effects/lpe-fill-between-many.cpp +++ b/src/live_effects/lpe-fill-between-many.cpp @@ -20,12 +20,16 @@ namespace LivePathEffect { LPEFillBetweenMany::LPEFillBetweenMany(LivePathEffectObject *lpeobject) : Effect(lpeobject), linked_paths(_("Linked path:"), _("Paths from which to take the original path data"), "linkedpaths", &wr, this), + original_visible(_("Original path visible"), _("Original path visibled"), "original_visible", &wr, this, true), + original_reversed(_("Original path reversed"), _("Reverse original path"), "original_reversed", &wr, this, false), fuse(_("Fuse coincident points"), _("Fuse coincident points"), "fuse", &wr, this, false), allow_transforms(_("Allow transforms"), _("Allow transforms"), "allow_transforms", &wr, this, false), join(_("Join subpaths"), _("Join subpaths"), "join", &wr, this, true), close(_("Close"), _("Close path"), "close", &wr, this, true) { registerParameter(&linked_paths); + registerParameter(&original_visible); + registerParameter(&original_reversed); registerParameter(&fuse); registerParameter(&allow_transforms); registerParameter(&join); @@ -43,9 +47,16 @@ void LPEFillBetweenMany::doEffect (SPCurve * curve) { Geom::PathVector res_pathv; SPItem * firstObj = NULL; - for (std::vector<PathAndDirection*>::iterator iter = linked_paths._vector.begin(); iter != linked_paths._vector.end(); ++iter) { + if (original_visible) { + Geom::PathVector original = curve->get_pathvector(); + if (original_reversed) { + original = original.reversed(); + } + res_pathv = original; + } + for (std::vector<PathAndDirectionAndVisible*>::iterator iter = linked_paths._vector.begin(); iter != linked_paths._vector.end(); ++iter) { SPObject *obj; - if ((*iter)->ref.isAttached() && (obj = (*iter)->ref.getObject()) && SP_IS_ITEM(obj) && !(*iter)->_pathvector.empty()) { + if ((*iter)->ref.isAttached() && (obj = (*iter)->ref.getObject()) && SP_IS_ITEM(obj) && !(*iter)->_pathvector.empty() && (*iter)->visibled) { Geom::Path linked_path; if ((*iter)->reversed) { linked_path = (*iter)->_pathvector.front().reversed(); diff --git a/src/live_effects/lpe-fill-between-many.h b/src/live_effects/lpe-fill-between-many.h index fe824e936..5bea53aba 100644 --- a/src/live_effects/lpe-fill-between-many.h +++ b/src/live_effects/lpe-fill-between-many.h @@ -24,6 +24,8 @@ public: private: OriginalPathArrayParam linked_paths; + BoolParam original_visible; + BoolParam original_reversed; BoolParam fuse; BoolParam allow_transforms; BoolParam join; diff --git a/src/live_effects/parameter/originalpatharray.cpp b/src/live_effects/parameter/originalpatharray.cpp index 2513a0d5e..13bd23634 100644 --- a/src/live_effects/parameter/originalpatharray.cpp +++ b/src/live_effects/parameter/originalpatharray.cpp @@ -54,12 +54,14 @@ public: add(_colObject); add(_colLabel); add(_colReverse); + add(_colVisible); } virtual ~ModelColumns() {} - Gtk::TreeModelColumn<PathAndDirection*> _colObject; + Gtk::TreeModelColumn<PathAndDirectionAndVisible*> _colObject; Gtk::TreeModelColumn<Glib::ustring> _colLabel; Gtk::TreeModelColumn<bool> _colReverse; + Gtk::TreeModelColumn<bool> _colVisible; }; OriginalPathArrayParam::OriginalPathArrayParam( const Glib::ustring& label, @@ -72,6 +74,7 @@ OriginalPathArrayParam::OriginalPathArrayParam( const Glib::ustring& label, _tree(), _text_renderer(), _toggle_renderer(), + _toggle_visible(), _scroller() { _model = new ModelColumns(); @@ -81,13 +84,6 @@ OriginalPathArrayParam::OriginalPathArrayParam( const Glib::ustring& label, _tree.set_reorderable(true); _tree.enable_model_drag_dest (Gdk::ACTION_MOVE); - _text_renderer = manage(new Gtk::CellRendererText()); - int nameColNum = _tree.append_column(_("Name"), *_text_renderer) - 1; - _name_column = _tree.get_column(nameColNum); - _name_column->add_attribute(_text_renderer->property_text(), _model->_colLabel); - - _tree.set_expander_column( *_tree.get_column(nameColNum) ); - _tree.set_search_column(_model->_colLabel); Gtk::CellRendererToggle * _toggle_renderer = manage(new Gtk::CellRendererToggle()); int toggleColNum = _tree.append_column(_("Reverse"), *_toggle_renderer) - 1; @@ -96,6 +92,22 @@ OriginalPathArrayParam::OriginalPathArrayParam( const Glib::ustring& label, _toggle_renderer->signal_toggled().connect(sigc::mem_fun(*this, &OriginalPathArrayParam::on_reverse_toggled)); col->add_attribute(_toggle_renderer->property_active(), _model->_colReverse); + + Gtk::CellRendererToggle * _toggle_visible = manage(new Gtk::CellRendererToggle()); + int toggleColNum2 = _tree.append_column(_("Visible"), *_toggle_visible) - 1; + Gtk::TreeViewColumn* col2 = _tree.get_column(toggleColNum2); + _toggle_visible->set_activatable(true); + _toggle_visible->signal_toggled().connect(sigc::mem_fun(*this, &OriginalPathArrayParam::on_visible_toggled)); + col2->add_attribute(_toggle_visible->property_active(), _model->_colVisible); + + _text_renderer = manage(new Gtk::CellRendererText()); + int nameColNum = _tree.append_column(_("Name"), *_text_renderer) - 1; + _name_column = _tree.get_column(nameColNum); + _name_column->add_attribute(_text_renderer->property_text(), _model->_colLabel); + + _tree.set_expander_column( *_tree.get_column(nameColNum) ); + _tree.set_search_column(_model->_colLabel); + //quick little hack -- newer versions of gtk gave the item zero space allotment _scroller.set_size_request(-1, 120); @@ -112,7 +124,7 @@ OriginalPathArrayParam::OriginalPathArrayParam( const Glib::ustring& label, OriginalPathArrayParam::~OriginalPathArrayParam() { while (!_vector.empty()) { - PathAndDirection *w = _vector.back(); + PathAndDirectionAndVisible *w = _vector.back(); _vector.pop_back(); unlink(w); delete w; @@ -124,7 +136,7 @@ void OriginalPathArrayParam::on_reverse_toggled(const Glib::ustring& path) { Gtk::TreeModel::iterator iter = _store->get_iter(path); Gtk::TreeModel::Row row = *iter; - PathAndDirection *w = row[_model->_colObject]; + PathAndDirectionAndVisible *w = row[_model->_colObject]; row[_model->_colReverse] = !row[_model->_colReverse]; w->reversed = row[_model->_colReverse]; @@ -135,6 +147,21 @@ void OriginalPathArrayParam::on_reverse_toggled(const Glib::ustring& path) _("Link path parameter to path")); } +void OriginalPathArrayParam::on_visible_toggled(const Glib::ustring& path) +{ + Gtk::TreeModel::iterator iter = _store->get_iter(path); + Gtk::TreeModel::Row row = *iter; + PathAndDirectionAndVisible *w = row[_model->_colObject]; + row[_model->_colVisible] = !row[_model->_colVisible]; + w->visibled = row[_model->_colVisible]; + + gchar * full = param_getSVGValue(); + param_write_to_repr(full); + g_free(full); + DocumentUndo::done(param_effect->getSPDoc(), SP_VERB_DIALOG_LIVE_PATH_EFFECT, + _("Toggle path parameter to path")); +} + void OriginalPathArrayParam::param_set_default() { @@ -223,8 +250,8 @@ void OriginalPathArrayParam::on_up_button_click() Gtk::TreeModel::Row row = *iter; int i = -1; - std::vector<PathAndDirection*>::iterator piter = _vector.begin(); - for (std::vector<PathAndDirection*>::iterator iter = _vector.begin(); iter != _vector.end(); piter = iter, i++, ++iter) { + std::vector<PathAndDirectionAndVisible*>::iterator piter = _vector.begin(); + for (std::vector<PathAndDirectionAndVisible*>::iterator iter = _vector.begin(); iter != _vector.end(); piter = iter, i++, ++iter) { if (*iter == row[_model->_colObject]) { _vector.erase(iter); _vector.insert(piter, row[_model->_colObject]); @@ -250,9 +277,9 @@ void OriginalPathArrayParam::on_down_button_click() Gtk::TreeModel::Row row = *iter; int i = 0; - for (std::vector<PathAndDirection*>::iterator iter = _vector.begin(); iter != _vector.end(); i++, ++iter) { + for (std::vector<PathAndDirectionAndVisible*>::iterator iter = _vector.begin(); iter != _vector.end(); i++, ++iter) { if (*iter == row[_model->_colObject]) { - std::vector<PathAndDirection*>::iterator niter = _vector.erase(iter); + std::vector<PathAndDirectionAndVisible*>::iterator niter = _vector.erase(iter); if (niter != _vector.end()) { ++niter; i++; @@ -294,37 +321,40 @@ void OriginalPathArrayParam::on_link_button_click() { Inkscape::UI::ClipboardManager *cm = Inkscape::UI::ClipboardManager::get(); - Glib::ustring pathid = cm->getShapeOrTextObjectId(SP_ACTIVE_DESKTOP); + std::vector<Glib::ustring> pathsid = cm->getElementsOfType(SP_ACTIVE_DESKTOP, "svg:path"); - if (pathid == "") { + if (pathsid.empty()) { return; } - // add '#' at start to make it an uri. - pathid.insert(pathid.begin(), '#'); - Inkscape::SVGOStringStream os; - bool foundOne = false; - for (std::vector<PathAndDirection*>::const_iterator iter = _vector.begin(); iter != _vector.end(); ++iter) { + for (auto i=pathsid.begin();i!=pathsid.end();++i) { + Glib::ustring pathid = *i; + // add '#' at start to make it an uri. + pathid.insert(pathid.begin(), '#'); + bool foundOne = false; + for (std::vector<PathAndDirectionAndVisible*>::const_iterator iter = _vector.begin(); iter != _vector.end(); ++iter) { + if (foundOne) { + os << "|"; + } else { + foundOne = true; + } + os << (*iter)->href << "," << ((*iter)->reversed ? "1" : "0") << "," << ((*iter)->visibled ? "1" : "0"); + } + if (foundOne) { os << "|"; - } else { - foundOne = true; } - os << (*iter)->href << "," << ((*iter)->reversed ? "1" : "0"); - } - - if (foundOne) { - os << "|"; + os << pathid.c_str() << ",0"; + if (*i != *(--pathsid.end())) { + os << "|"; + } } - - os << pathid.c_str() << ",0"; - param_write_to_repr(os.str().c_str()); DocumentUndo::done(param_effect->getSPDoc(), SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Link path parameter to path")); } -void OriginalPathArrayParam::unlink(PathAndDirection* to) +void OriginalPathArrayParam::unlink(PathAndDirectionAndVisible* to) { to->linked_modified_connection.disconnect(); to->linked_delete_connection.disconnect(); @@ -336,12 +366,12 @@ void OriginalPathArrayParam::unlink(PathAndDirection* to) } } -void OriginalPathArrayParam::remove_link(PathAndDirection* to) +void OriginalPathArrayParam::remove_link(PathAndDirectionAndVisible* to) { unlink(to); - for (std::vector<PathAndDirection*>::iterator iter = _vector.begin(); iter != _vector.end(); ++iter) { + for (std::vector<PathAndDirectionAndVisible*>::iterator iter = _vector.begin(); iter != _vector.end(); ++iter) { if (*iter == to) { - PathAndDirection *w = *iter; + PathAndDirectionAndVisible *w = *iter; _vector.erase(iter); delete w; return; @@ -349,7 +379,7 @@ void OriginalPathArrayParam::remove_link(PathAndDirection* to) } } -void OriginalPathArrayParam::linked_delete(SPObject */*deleted*/, PathAndDirection* /*to*/) +void OriginalPathArrayParam::linked_delete(SPObject */*deleted*/, PathAndDirectionAndVisible* /*to*/) { //remove_link(to); @@ -358,7 +388,7 @@ void OriginalPathArrayParam::linked_delete(SPObject */*deleted*/, PathAndDirecti g_free(full); } -bool OriginalPathArrayParam::_updateLink(const Gtk::TreeIter& iter, PathAndDirection* pd) +bool OriginalPathArrayParam::_updateLink(const Gtk::TreeIter& iter, PathAndDirectionAndVisible* pd) { Gtk::TreeModel::Row row = *iter; if (row[_model->_colObject] == pd) { @@ -369,26 +399,26 @@ bool OriginalPathArrayParam::_updateLink(const Gtk::TreeIter& iter, PathAndDirec return false; } -void OriginalPathArrayParam::linked_changed(SPObject */*old_obj*/, SPObject *new_obj, PathAndDirection* to) +void OriginalPathArrayParam::linked_changed(SPObject */*old_obj*/, SPObject *new_obj, PathAndDirectionAndVisible* to) { to->linked_delete_connection.disconnect(); to->linked_modified_connection.disconnect(); to->linked_transformed_connection.disconnect(); if (new_obj && SP_IS_ITEM(new_obj)) { - to->linked_delete_connection = new_obj->connectDelete(sigc::bind<PathAndDirection*>(sigc::mem_fun(*this, &OriginalPathArrayParam::linked_delete), to)); - to->linked_modified_connection = new_obj->connectModified(sigc::bind<PathAndDirection*>(sigc::mem_fun(*this, &OriginalPathArrayParam::linked_modified), to)); - to->linked_transformed_connection = SP_ITEM(new_obj)->connectTransformed(sigc::bind<PathAndDirection*>(sigc::mem_fun(*this, &OriginalPathArrayParam::linked_transformed), to)); + to->linked_delete_connection = new_obj->connectDelete(sigc::bind<PathAndDirectionAndVisible*>(sigc::mem_fun(*this, &OriginalPathArrayParam::linked_delete), to)); + to->linked_modified_connection = new_obj->connectModified(sigc::bind<PathAndDirectionAndVisible*>(sigc::mem_fun(*this, &OriginalPathArrayParam::linked_modified), to)); + to->linked_transformed_connection = SP_ITEM(new_obj)->connectTransformed(sigc::bind<PathAndDirectionAndVisible*>(sigc::mem_fun(*this, &OriginalPathArrayParam::linked_transformed), to)); linked_modified(new_obj, SP_OBJECT_MODIFIED_FLAG, to); } else { to->_pathvector = Geom::PathVector(); SP_OBJECT(param_effect->getLPEObj())->requestModified(SP_OBJECT_MODIFIED_FLAG); - _store->foreach_iter(sigc::bind<PathAndDirection*>(sigc::mem_fun(*this, &OriginalPathArrayParam::_updateLink), to)); + _store->foreach_iter(sigc::bind<PathAndDirectionAndVisible*>(sigc::mem_fun(*this, &OriginalPathArrayParam::_updateLink), to)); } } -void OriginalPathArrayParam::setPathVector(SPObject *linked_obj, guint /*flags*/, PathAndDirection* to) +void OriginalPathArrayParam::setPathVector(SPObject *linked_obj, guint /*flags*/, PathAndDirectionAndVisible* to) { if (!to) { return; @@ -430,21 +460,21 @@ void OriginalPathArrayParam::setPathVector(SPObject *linked_obj, guint /*flags*/ } } -void OriginalPathArrayParam::linked_modified(SPObject *linked_obj, guint flags, PathAndDirection* to) +void OriginalPathArrayParam::linked_modified(SPObject *linked_obj, guint flags, PathAndDirectionAndVisible* to) { if (!to) { return; } setPathVector(linked_obj, flags, to); SP_OBJECT(param_effect->getLPEObj())->requestModified(SP_OBJECT_MODIFIED_FLAG); - _store->foreach_iter(sigc::bind<PathAndDirection*>(sigc::mem_fun(*this, &OriginalPathArrayParam::_updateLink), to)); + _store->foreach_iter(sigc::bind<PathAndDirectionAndVisible*>(sigc::mem_fun(*this, &OriginalPathArrayParam::_updateLink), to)); } bool OriginalPathArrayParam::param_readSVGValue(const gchar* strvalue) { if (strvalue) { while (!_vector.empty()) { - PathAndDirection *w = _vector.back(); + PathAndDirectionAndVisible *w = _vector.back(); unlink(w); _vector.pop_back(); delete w; @@ -455,11 +485,12 @@ bool OriginalPathArrayParam::param_readSVGValue(const gchar* strvalue) for (gchar ** iter = strarray; *iter != NULL; iter++) { if ((*iter)[0] == '#') { gchar ** substrarray = g_strsplit(*iter, ",", 0); - PathAndDirection* w = new PathAndDirection((SPObject *)param_effect->getLPEObj()); + PathAndDirectionAndVisible* w = new PathAndDirectionAndVisible((SPObject *)param_effect->getLPEObj()); w->href = g_strdup(*substrarray); w->reversed = *(substrarray+1) != NULL && (*(substrarray+1))[0] == '1'; - - w->linked_changed_connection = w->ref.changedSignal().connect(sigc::bind<PathAndDirection *>(sigc::mem_fun(*this, &OriginalPathArrayParam::linked_changed), w)); + //Like this to make backwards compatible, new value added in 0.93 + w->visibled = *(substrarray+2) == NULL || (*(substrarray+2))[0] == '1'; + w->linked_changed_connection = w->ref.changedSignal().connect(sigc::bind<PathAndDirectionAndVisible *>(sigc::mem_fun(*this, &OriginalPathArrayParam::linked_changed), w)); w->ref.attach(URI(w->href)); _vector.push_back(w); @@ -471,6 +502,7 @@ bool OriginalPathArrayParam::param_readSVGValue(const gchar* strvalue) row[_model->_colObject] = w; row[_model->_colLabel] = obj ? ( obj->label() ? obj->label() : obj->getId() ) : w->href; row[_model->_colReverse] = w->reversed; + row[_model->_colVisible] = w->visibled; g_strfreev (substrarray); } } @@ -484,13 +516,13 @@ gchar * OriginalPathArrayParam::param_getSVGValue() const { Inkscape::SVGOStringStream os; bool foundOne = false; - for (std::vector<PathAndDirection*>::const_iterator iter = _vector.begin(); iter != _vector.end(); ++iter) { + for (std::vector<PathAndDirectionAndVisible*>::const_iterator iter = _vector.begin(); iter != _vector.end(); ++iter) { if (foundOne) { os << "|"; } else { foundOne = true; } - os << (*iter)->href << "," << ((*iter)->reversed ? "1" : "0"); + os << (*iter)->href << "," << ((*iter)->reversed ? "1" : "0") << "," << ((*iter)->visibled ? "1" : "0"); } gchar * str = g_strdup(os.str().c_str()); return str; diff --git a/src/live_effects/parameter/originalpatharray.h b/src/live_effects/parameter/originalpatharray.h index eb1114c3f..51810a5cf 100644 --- a/src/live_effects/parameter/originalpatharray.h +++ b/src/live_effects/parameter/originalpatharray.h @@ -28,13 +28,14 @@ namespace Inkscape { namespace LivePathEffect { -class PathAndDirection { +class PathAndDirectionAndVisible { public: - PathAndDirection(SPObject *owner) + PathAndDirectionAndVisible(SPObject *owner) : href(NULL), ref(owner), _pathvector(Geom::PathVector()), - reversed(false) + reversed(false), + visibled(true) { } @@ -42,6 +43,7 @@ public: URIReference ref; Geom::PathVector _pathvector; bool reversed; + bool visibled; sigc::connection linked_changed_connection; sigc::connection linked_delete_connection; @@ -73,25 +75,26 @@ public: void setFromOriginalD(bool from_original_d){ _from_original_d = from_original_d; }; void allowOnlyBsplineSpiro(bool allow_only_bspline_spiro){ _allow_only_bspline_spiro = allow_only_bspline_spiro; }; - std::vector<PathAndDirection*> _vector; + std::vector<PathAndDirectionAndVisible*> _vector; protected: - bool _updateLink(const Gtk::TreeIter& iter, PathAndDirection* pd); + bool _updateLink(const Gtk::TreeIter& iter, PathAndDirectionAndVisible* pd); bool _selectIndex(const Gtk::TreeIter& iter, int* i); - void unlink(PathAndDirection* to); - void remove_link(PathAndDirection* to); - void setPathVector(SPObject *linked_obj, guint flags, PathAndDirection* to); + void unlink(PathAndDirectionAndVisible* to); + void remove_link(PathAndDirectionAndVisible* to); + void setPathVector(SPObject *linked_obj, guint flags, PathAndDirectionAndVisible* to); - void linked_changed(SPObject *old_obj, SPObject *new_obj, PathAndDirection* to); - void linked_modified(SPObject *linked_obj, guint flags, PathAndDirection* to); - void linked_transformed(Geom::Affine const *, SPItem *, PathAndDirection*) {} - void linked_delete(SPObject *deleted, PathAndDirection* to); + void linked_changed(SPObject *old_obj, SPObject *new_obj, PathAndDirectionAndVisible* to); + void linked_modified(SPObject *linked_obj, guint flags, PathAndDirectionAndVisible* to); + void linked_transformed(Geom::Affine const *, SPItem *, PathAndDirectionAndVisible*) {} + void linked_delete(SPObject *deleted, PathAndDirectionAndVisible* to); ModelColumns *_model; Glib::RefPtr<Gtk::TreeStore> _store; Gtk::TreeView _tree; Gtk::CellRendererText *_text_renderer; Gtk::CellRendererToggle *_toggle_renderer; + Gtk::CellRendererToggle *_toggle_visible; Gtk::TreeView::Column *_name_column; Gtk::ScrolledWindow _scroller; @@ -100,6 +103,7 @@ protected: void on_up_button_click(); void on_down_button_click(); void on_reverse_toggled(const Glib::ustring& path); + void on_visible_toggled(const Glib::ustring& path); private: bool _from_original_d; diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index bac924980..f4e37d7e9 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -2942,6 +2942,7 @@ void ObjectSet::cloneOriginalPathLPE() { lpe_repr->setAttribute("effect", "fill_between_many"); lpe_repr->setAttribute("linkedpaths", os.str()); + lpe_repr->setAttribute("retain_original", "false"); document()->getDefs()->getRepr()->addChild(lpe_repr, NULL); // adds to <defs> and assigns the 'id' attribute } std::string lpe_id_href = std::string("#") + lpe_repr->attribute("id"); diff --git a/src/ui/clipboard.cpp b/src/ui/clipboard.cpp index 3cc8ac098..202c8d922 100644 --- a/src/ui/clipboard.cpp +++ b/src/ui/clipboard.cpp @@ -105,6 +105,7 @@ public: virtual bool pastePathEffect(ObjectSet *set); virtual Glib::ustring getPathParameter(SPDesktop* desktop); virtual Glib::ustring getShapeOrTextObjectId(SPDesktop *desktop); + virtual std::vector<Glib::ustring> getElementsOfType(SPDesktop *desktop, gchar const *type); virtual const gchar *getFirstObjectID(); ClipboardManagerImpl(); @@ -653,6 +654,54 @@ Glib::ustring ClipboardManagerImpl::getShapeOrTextObjectId(SPDesktop *desktop) } /** + * Get all objects id from the clipboard. + * @return A vector containing all IDs or empty if no shape or text item was found. + * type. Set to "*" to retrive all elements of the types vector inside, feel free to populate more + */ +std::vector<Glib::ustring> ClipboardManagerImpl::getElementsOfType(SPDesktop *desktop, gchar const *type) +{ + std::vector<Glib::ustring> result; + SPDocument *tempdoc = _retrieveClipboard(); // any target will do here + if ( tempdoc == NULL ) { + _userWarn(desktop, _("Nothing on the clipboard.")); + return result; + } + Inkscape::XML::Node *root = tempdoc->getReprRoot(); + + // 1293979: strip out the defs of the document + root->removeChild(tempdoc->getDefs()->getRepr()); + std::vector<Inkscape::XML::Node const *> reprs; + if (strcmp(type, "*") == 0){ + //TODO:Fill vector with all posible elements + std::vector<Glib::ustring> types; + types.push_back((Glib::ustring)"svg:path"); + types.push_back((Glib::ustring)"svg:circle"); + types.push_back((Glib::ustring)"svg:rect"); + types.push_back((Glib::ustring)"svg:ellipse"); + types.push_back((Glib::ustring)"svg:text"); + types.push_back((Glib::ustring)"svg:g"); + types.push_back((Glib::ustring)"svg:image"); + for (auto i=types.begin();i!=types.end();++i) { + Glib::ustring type_elem = *i; + std::vector<Inkscape::XML::Node const *> reprs_found = sp_repr_lookup_name_many(root, type_elem.c_str(), -1); // unlimited search depth + reprs.insert(reprs.end(), reprs_found.begin(), reprs_found.end()); + } + } else { + reprs = sp_repr_lookup_name_many(root, type, -1); // unlimited search depth + } + for (auto i=reprs.begin();i!=reprs.end();++i) { + Inkscape::XML::Node const * node = *i; + result.push_back(node->attribute("id")); + } + if ( result.empty() ) { + _userWarn(desktop, ((Glib::ustring)_("Clipboard does not contain any.") + (Glib::ustring)type).c_str()); + tempdoc->doUnref(); + return result; + } + return result; +} + +/** * Iterate over a list of items and copy them to the clipboard. */ void ClipboardManagerImpl::_copySelection(ObjectSet *selection) diff --git a/src/ui/clipboard.h b/src/ui/clipboard.h index 32a49867c..12dbd51df 100644 --- a/src/ui/clipboard.h +++ b/src/ui/clipboard.h @@ -51,6 +51,7 @@ public: virtual bool pastePathEffect(ObjectSet *set) = 0; virtual Glib::ustring getPathParameter(SPDesktop* desktop) = 0; virtual Glib::ustring getShapeOrTextObjectId(SPDesktop *desktop) = 0; + virtual std::vector<Glib::ustring> getElementsOfType(SPDesktop *desktop, gchar const *type = "*") = 0; virtual const gchar *getFirstObjectID() = 0; static ClipboardManager *get(); |
