From 61cbbcbe02f11d67e4fe9f3c4f452442d2e9f778 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Fri, 3 Nov 2017 01:55:01 +0100 Subject: [PATCH 01/14] Start migrating 0.92 patch to master --- src/desktop.cpp | 1 + src/desktop.h | 2 +- src/extension/execution-env.cpp | 37 +---- src/extension/execution-env.h | 3 - src/extension/implementation/script.cpp | 137 +++++------------- src/extension/internal/bitmap/imagemagick.cpp | 10 ++ src/extension/internal/bluredge.cpp | 13 +- src/extension/internal/filter/filter.cpp | 13 +- src/extension/internal/grid.cpp | 12 +- src/extension/prefdialog.cpp | 28 +++- src/selection.cpp | 122 +++++++++++++++- src/selection.h | 20 ++- src/ui/tool/control-point-selection.h | 5 +- src/ui/tool/selectable-control-point.cpp | 9 ++ src/ui/tool/selectable-control-point.h | 2 + src/xml/node.h | 19 ++- src/xml/simple-node.cpp | 92 +++++++++++- src/xml/simple-node.h | 4 +- 18 files changed, 379 insertions(+), 150 deletions(-) diff --git a/src/desktop.cpp b/src/desktop.cpp index 47c82b6d93..72739305ae 100644 --- a/src/desktop.cpp +++ b/src/desktop.cpp @@ -117,6 +117,7 @@ SPDesktop::SPDesktop() : waiting_cursor( false ), showing_dialogs ( false ), guides_active( false ), + on_live_extension(false), gr_item( NULL ), gr_point_type( POINT_LG_BEGIN ), gr_point_i( 0 ), diff --git a/src/desktop.h b/src/desktop.h index f4eecf8b71..8b20195db1 100644 --- a/src/desktop.h +++ b/src/desktop.h @@ -188,9 +188,9 @@ public: unsigned int interaction_disabled_counter; bool waiting_cursor; bool showing_dialogs; - /// \todo fixme: This has to be implemented in different way */ guint guides_active : 1; + bool on_live_extension; // storage for selected dragger used by GrDrag as it's // created and deleted by tools diff --git a/src/extension/execution-env.cpp b/src/extension/execution-env.cpp index 7e233d2151..bde04d924f 100644 --- a/src/extension/execution-env.cpp +++ b/src/extension/execution-env.cpp @@ -22,6 +22,8 @@ #include "selection.h" #include "effect.h" #include "document.h" +#include "desktop.h" +#include "inkscape.h" #include "document-undo.h" #include "desktop.h" #include "object/sp-namedview.h" @@ -52,19 +54,6 @@ ExecutionEnv::ExecutionEnv (Effect * effect, Inkscape::UI::View::View * doc, Imp _show_working(show_working), _show_errors(show_errors) { - SPDesktop *desktop = (SPDesktop *)_doc; - sp_namedview_document_from_window(desktop); - - if (desktop != NULL) { - 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); - //std::cout << "Selected: " << selected_id << std::endl; - } - } - genDocCache(); return; @@ -189,24 +178,14 @@ ExecutionEnv::commit (void) { void ExecutionEnv::reselect (void) { - if (_doc == NULL) { return; } - SPDocument * doc = _doc->doc(); - if (doc == NULL) { return; } - - SPDesktop *desktop = (SPDesktop *)_doc; - sp_namedview_document_from_window(desktop); - - if (desktop == NULL) { return; } - - Inkscape::Selection * selection = desktop->getSelection(); - - for (std::list::iterator i = _selected.begin(); i != _selected.end(); ++i) { - SPObject * obj = doc->getObjectById(i->c_str()); - if (obj != NULL) { - selection->add(obj); + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + Inkscape::Selection * selection = NULL; + if(desktop) { + selection = desktop->getSelection(); + if (!desktop->on_live_extension) { + selection->restoreBackup(); } } - return; } diff --git a/src/extension/execution-env.h b/src/extension/execution-env.h index b1a3a8ea22..8af97cd923 100644 --- a/src/extension/execution-env.h +++ b/src/extension/execution-env.h @@ -54,9 +54,6 @@ private: Glib::RefPtr _mainloop; /** \brief The document that we're working on. */ Inkscape::UI::View::View * _doc; - /** \brief A list of the IDs of all the selected objects before - we started to work on this document. */ - std::list _selected; /** \brief A document cache if we were passed one. */ Implementation::ImplementationDocumentCache * _docCache; diff --git a/src/extension/implementation/script.cpp b/src/extension/implementation/script.cpp index f25c8a5d69..42867b8236 100644 --- a/src/extension/implementation/script.cpp +++ b/src/extension/implementation/script.cpp @@ -417,11 +417,29 @@ ScriptDocCache::ScriptDocCache (Inkscape::UI::View::View * view) : SPDesktop *desktop = (SPDesktop *) view; sp_namedview_document_from_window(desktop); - + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + bool sort_attributes = prefs->getBool("/options/svgoutput/sort_attributes", false); + bool incorrect_style_properties_remove = prefs->getBool("/options/svgoutput/incorrect_style_properties_remove", false); + bool incorrect_attributes_remove = prefs->getBool("/options/svgoutput/incorrect_attributes_remove", false); + bool usenamedcolors = prefs->getBool("/options/svgoutput/usenamedcolors", false); + bool forcerepeatcommands = prefs->getBool("/options/svgoutput/forcerepeatcommands", false); + bool style_defaults_remove = prefs->getBool("/options/svgoutput/style_defaults_remove", false); + prefs->setBool("/options/svgoutput/sort_attributes", false); + prefs->setBool("/options/svgoutput/incorrect_style_properties_remove", false); + prefs->setBool("/options/svgoutput/incorrect_attributes_remove", false); + prefs->setBool("/options/svgoutput/usenamedcolors", false); + prefs->setBool("/options/svgoutput/forcerepeatcommands", false); + prefs->setBool("/options/svgoutput/style_defaults_remove", false); Inkscape::Extension::save( Inkscape::Extension::db.get(SP_MODULE_KEY_OUTPUT_SVG_INKSCAPE), view->doc(), _filename.c_str(), false, false, false, Inkscape::Extension::FILE_SAVE_METHOD_TEMPORARY); + prefs->setBool("/options/svgoutput/sort_attributes", sort_attributes); + prefs->setBool("/options/svgoutput/incorrect_style_properties_remove", incorrect_style_properties_remove); + prefs->setBool("/options/svgoutput/incorrect_attributes_remove", incorrect_attributes_remove); + prefs->setBool("/options/svgoutput/usenamedcolors", usenamedcolors); + prefs->setBool("/options/svgoutput/forcerepeatcommands", forcerepeatcommands); + prefs->setBool("/options/svgoutput/style_defaults_remove", style_defaults_remove); return; } @@ -686,57 +704,14 @@ void Script::effect(Inkscape::Extension::Effect *module, return; } - 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(); - params.push_front(selected_id); - } - - {//add selected nodes - Inkscape::UI::Tools::NodeTool *tool = 0; - if (SP_ACTIVE_DESKTOP ) { - Inkscape::UI::Tools::ToolBase *ec = SP_ACTIVE_DESKTOP->event_context; - if (INK_IS_NODE_TOOL(ec)) { - tool = static_cast(ec); - } - } - - if(tool){ - Inkscape::UI::ControlPointSelection *cps = tool->_selected_nodes; - for (Inkscape::UI::ControlPointSelection::iterator i = cps->begin(); i != cps->end(); ++i) { - Inkscape::UI::Node *node = dynamic_cast(*i); - if (node) { - std::string id = node->nodeList().subpathList().pm().item()->getId(); - - int sp = 0; - bool found_sp = false; - for(Inkscape::UI::SubpathList::iterator i = node->nodeList().subpathList().begin(); i != node->nodeList().subpathList().end(); ++i,++sp){ - if(&**i == &(node->nodeList())){ - found_sp = true; - break; - } - } - int nl=0; - bool found_nl = false; - for (Inkscape::UI::NodeList::iterator j = node->nodeList().begin(); j != node->nodeList().end(); ++j, ++nl){ - if(&*j==node){ - found_nl = true; - break; - } - } - std::ostringstream ss; - ss<< "--selected-nodes=" << id << ":" << sp << ":" << nl; - Glib::ustring selected = ss.str(); - - if(found_nl && found_sp)params.push_front(selected); - else g_warning("Something went wrong while trying to pass selected nodes to extension. Please report a bug."); - } + if (desktop) { + Inkscape::Selection * selection = desktop->getSelection(); + if (!selection->isEmpty()) { + selection->setBackup(); } + params = selection->params; + module->paramListString(params); } - }//end add selected nodes file_listener fileout; int data_read = execute(command, params, dc->_filename, fileout); @@ -790,6 +765,7 @@ void Script::effect(Inkscape::Extension::Effect *module, layer = document->getObjectById(g_quark_to_string(nv->default_layer_id)); } } + desktop->showGrids(nv->grids_visible); } sp_namedview_update_layers_from_document(desktop); @@ -798,6 +774,14 @@ void Script::effect(Inkscape::Extension::Effect *module, //set the current layer desktop->setCurrentLayer(layer); } + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if (desktop) { + Inkscape::Selection * selection = desktop->getSelection(); + if (selection && selection->isEmpty() && !desktop->on_live_extension) { + selection->restoreBackup(); + selection->emptyBackup(); + } + } } mydoc->release(); } @@ -833,12 +817,10 @@ void Script::copy_doc (Inkscape::XML::Node * oldroot, Inkscape::XML::Node * newr g_warning("Error on copy_doc: NULL pointer input."); return; } - // For copying attributes in root and in namedview using Inkscape::Util::List; using Inkscape::XML::AttributeRecord; std::vector attribs; - // Must explicitly copy root attributes. This must be done first since // copying grid lines calls "SPGuide::set()" which needs to know the // width, height, and viewBox of the root element. @@ -859,80 +841,33 @@ void Script::copy_doc (Inkscape::XML::Node * oldroot, Inkscape::XML::Node * newr oldroot->setAttribute(name, newroot->attribute(name)); } - // Question: Why is the "sodipodi:namedview" special? Treating it as a normal // elmement results in crashes. // Seems to be a bug: // http://inkscape.13.x6.nabble.com/Effect-that-modifies-the-document-properties-tt2822126.html std::vector delete_list; - Inkscape::XML::Node * oldroot_namedview = NULL; - Inkscape::XML::Node * newroot_namedview = NULL; // Make list for (Inkscape::XML::Node * child = oldroot->firstChild(); child != NULL; child = child->next()) { if (!strcmp("sodipodi:namedview", child->name())) { - oldroot_namedview = child; for (Inkscape::XML::Node * oldroot_namedview_child = child->firstChild(); oldroot_namedview_child != NULL; oldroot_namedview_child = oldroot_namedview_child->next()) { delete_list.push_back(oldroot_namedview_child); } - } else { - delete_list.push_back(child); + break; } } - if(!oldroot_namedview) - { - g_warning("Error on copy_doc: No namedview on destination document."); - return; - } - // Unparent (delete) for (unsigned int i = 0; i < delete_list.size(); i++) { sp_repr_unparent(delete_list[i]); } - - // Copy - for (Inkscape::XML::Node * child = newroot->firstChild(); - child != NULL; - child = child->next()) { - if (!strcmp("sodipodi:namedview", child->name())) { - newroot_namedview = child; - for (Inkscape::XML::Node * newroot_namedview_child = child->firstChild(); - newroot_namedview_child != NULL; - newroot_namedview_child = newroot_namedview_child->next()) { - oldroot_namedview->appendChild(newroot_namedview_child->duplicate(oldroot->document())); - } - } else { - oldroot->appendChild(child->duplicate(oldroot->document())); - } - } - attribs.clear(); - - // Must explicitly copy namedview attributes. - // Make a list of all attributes of the old namedview node. - for (List iter = oldroot_namedview->attributeList(); iter; ++iter) { - attribs.push_back(g_quark_to_string(iter->key)); - } - - // Delete the attributes of the old namedview node. - for (std::vector::const_iterator it = attribs.begin(); it != attribs.end(); ++it) { - oldroot_namedview->setAttribute(*it, NULL); - } - - // Set the new attributes. - for (List iter = newroot_namedview->attributeList(); iter; ++iter) { - gchar const *name = g_quark_to_string(iter->key); - oldroot_namedview->setAttribute(name, newroot_namedview->attribute(name)); - } - - /** \todo Restore correct layer */ - /** \todo Restore correct selection */ + oldroot->mergeFrom(newroot, "id", true, true); } /** \brief This function checks the stderr file, and if it has data, diff --git a/src/extension/internal/bitmap/imagemagick.cpp b/src/extension/internal/bitmap/imagemagick.cpp index 636b9d6a41..32d6f59e3f 100644 --- a/src/extension/internal/bitmap/imagemagick.cpp +++ b/src/extension/internal/bitmap/imagemagick.cpp @@ -64,6 +64,16 @@ ImageMagickDocCache::ImageMagickDocCache(Inkscape::UI::View::View * view) : _imageItems(NULL) { SPDesktop *desktop = (SPDesktop*)view; + Inkscape::Selection * selection = NULL; + if (desktop) { + selection = desktop->getSelection(); + if (selection && !selection->params.empty()) { + selection->restoreBackup(); + if (!desktop->on_live_extension) { + selection->emptyBackup(); + } + } + } auto selectedItemList = desktop->selection->items(); int selectCount = (int) boost::distance(selectedItemList); diff --git a/src/extension/internal/bluredge.cpp b/src/extension/internal/bluredge.cpp index f04007d00f..c086405e50 100644 --- a/src/extension/internal/bluredge.cpp +++ b/src/extension/internal/bluredge.cpp @@ -53,7 +53,7 @@ BlurEdge::load (Inkscape::Extension::Extension */*module*/) void BlurEdge::effect (Inkscape::Extension::Effect *module, Inkscape::UI::View::View *desktop, Inkscape::Extension::Implementation::ImplementationDocumentCache * /*docCache*/) { - Inkscape::Selection * selection = static_cast(desktop)->selection; + float width = module->get_param_float("blur-width"); int steps = module->get_param_int("num-steps"); @@ -61,6 +61,17 @@ BlurEdge::effect (Inkscape::Extension::Effect *module, Inkscape::UI::View::View Inkscape::Preferences *prefs = Inkscape::Preferences::get(); double old_offset = prefs->getDouble("/options/defaultoffsetwidth/value", 1.0, "px"); + SPDesktop *deskt = static_cast(desktop); + Inkscape::Selection * selection = NULL; + if (deskt) { + selection = deskt->selection; + if (selection && !selection->params.empty()) { + selection->restoreBackup(); + if (!deskt->on_live_extension) { + selection->emptyBackup(); + } + } + } // TODO need to properly refcount the items, at least std::vector items(selection->items().begin(), selection->items().end()); selection->clear(); diff --git a/src/extension/internal/filter/filter.cpp b/src/extension/internal/filter/filter.cpp index 166e5406fb..af4997ebac 100644 --- a/src/extension/internal/filter/filter.cpp +++ b/src/extension/internal/filter/filter.cpp @@ -122,8 +122,17 @@ void Filter::effect(Inkscape::Extension::Effect *module, Inkscape::UI::View::Vie } //printf("Calling filter effect\n"); - Inkscape::Selection * selection = ((SPDesktop *)document)->selection; - + SPDesktop *desktop = (SPDesktop *)document; + Inkscape::Selection * selection = NULL; + if (desktop) { + selection = desktop->selection; + if (selection && !selection->params.empty()) { + selection->restoreBackup(); + if (!desktop->on_live_extension) { + selection->emptyBackup(); + } + } + } // TODO need to properly refcount the items, at least std::vector items(selection->items().begin(), selection->items().end()); diff --git a/src/extension/internal/grid.cpp b/src/extension/internal/grid.cpp index c7ebf2494d..6b3f2efe39 100644 --- a/src/extension/internal/grid.cpp +++ b/src/extension/internal/grid.cpp @@ -86,7 +86,17 @@ Glib::ustring build_lines(Geom::Rect bounding_area, void Grid::effect (Inkscape::Extension::Effect *module, Inkscape::UI::View::View *document, Inkscape::Extension::Implementation::ImplementationDocumentCache * /*docCache*/) { - Inkscape::Selection * selection = ((SPDesktop *)document)->selection; + SPDesktop *desktop = ((SPDesktop *)document); + Inkscape::Selection * selection = NULL; + if (desktop) { + selection = desktop->getSelection(); + if (selection && !selection->params.empty()) { + selection->restoreBackup(); + if (!desktop->on_live_extension) { + selection->emptyBackup(); + } + } + } Geom::Rect bounding_area = Geom::Rect(Geom::Point(0,0), Geom::Point(100,100)); if (selection->isEmpty()) { diff --git a/src/extension/prefdialog.cpp b/src/extension/prefdialog.cpp index 0247e18e90..4c799eb686 100644 --- a/src/extension/prefdialog.cpp +++ b/src/extension/prefdialog.cpp @@ -18,6 +18,8 @@ // Used to get SP_ACTIVE_DESKTOP #include "inkscape.h" #include "desktop.h" +#include "document.h" +#include "document-undo.h" #include "effect.h" #include "implementation/implementation.h" @@ -61,6 +63,13 @@ PrefDialog::PrefDialog (Glib::ustring name, gchar const * help, Gtk::Widget * co controls = _effect->get_imp()->prefs_effect(_effect, SP_ACTIVE_DESKTOP, &_signal_param_change, NULL); _signal_param_change.connect(sigc::mem_fun(this, &PrefDialog::param_change)); } + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if (desktop) { + Inkscape::Selection * selection = desktop->getSelection(); + if (selection) { + selection->emptyBackup(); + } + } hbox->pack_start(*controls, true, true, 0); hbox->show(); @@ -170,12 +179,29 @@ PrefDialog::run (void) { void PrefDialog::preview_toggle (void) { + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + SPDocument *document = SP_ACTIVE_DOCUMENT; + Inkscape::Selection * selection = NULL; + bool modified = document->isModifiedSinceSave(); + if(desktop) { + selection = desktop->getSelection(); + if (!selection->isEmpty()) { + selection->setBackup(); + } + } if(_param_preview->get_bool(NULL, NULL)) { - set_modal(true); if (_exEnv == NULL) { + set_modal(true); + if (desktop && selection) { + desktop->on_live_extension = true; + + } _exEnv = new ExecutionEnv(_effect, SP_ACTIVE_DESKTOP, NULL, false, false); _effect->set_execution_env(_exEnv); _exEnv->run(); + if (desktop && selection) { + selection->clear(); + } } } else { set_modal(false); diff --git a/src/selection.cpp b/src/selection.cpp index b8dffb4aee..6c791f10fa 100644 --- a/src/selection.cpp +++ b/src/selection.cpp @@ -28,8 +28,7 @@ #include "object/sp-shape.h" #include "object/sp-path.h" - -#include "xml/repr.h" +#include "object/sp-defs.h" #define SP_SELECTION_UPDATE_PRIORITY (G_PRIORITY_HIGH_IDLE + 1) @@ -179,6 +178,125 @@ void Selection::_releaseSignals(SPObject *object) { _modified_connections.erase(object); } +void +Selection::emptyBackup(){ + _selected_ids.clear(); + _seldata.clear(); + params.clear(); +} + +void +Selection::setBackup () +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if (desktop) { + std::vector selected_items = itemList(); + _selected_ids.clear(); + _seldata.clear(); + params.clear(); + for(std::vector::const_iterator x = selected_items.begin(); x != selected_items.end(); ++x){ + std::string selected_id; + selected_id += "--id="; + selected_id += (*x)->getId(); + params.push_front(selected_id); + _selected_ids.push_back((*x)->getId()); + } + Inkscape::UI::Tools::NodeTool *tool = 0; + + Inkscape::UI::Tools::ToolBase *ec = desktop->event_context; + if (INK_IS_NODE_TOOL(ec)) { + tool = static_cast(ec); + } + if(tool){ + Inkscape::UI::ControlPointSelection *cps = tool->_selected_nodes; + std::list points_list = cps->_points_list; + for (std::list::iterator i = points_list.begin(); i != points_list.end(); ++i) { + Inkscape::UI::Node *node = dynamic_cast(*i); + if (node) { + std::string id = node->nodeList().subpathList().pm().item()->getId(); + + int sp = 0; + bool found_sp = false; + for(Inkscape::UI::SubpathList::iterator i = node->nodeList().subpathList().begin(); i != node->nodeList().subpathList().end(); ++i,++sp){ + if(&**i == &(node->nodeList())){ + found_sp = true; + break; + } + } + int nl=0; + bool found_nl = false; + for (Inkscape::UI::NodeList::iterator j = node->nodeList().begin(); j != node->nodeList().end(); ++j, ++nl){ + if(&*j==node){ + found_nl = true; + break; + } + } + std::ostringstream ss; + ss<< "--selected-nodes=" << id << ":" << sp << ":" << nl; + Glib::ustring selected_nodes = ss.str(); + + if(found_nl && found_sp) { + _seldata.push_back(std::make_pair(id,std::make_pair(sp,nl))); + params.push_back(selected_nodes); + } else { + g_warning("Something went wrong while trying to pass selected nodes to extension. Please report a bug."); + } + } + } + } + }//end add selected nodes +} + +void +Selection::restoreBackup() +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if (desktop) { + Inkscape::UI::Tools::NodeTool *tool = 0; + Inkscape::UI::Tools::ToolBase *ec = desktop->event_context; + if (INK_IS_NODE_TOOL(ec)) { + tool = static_cast(ec); + } + clear(); + std::vector::reverse_iterator rit = _selected_ids.rbegin(); + for (; rit!= _selected_ids.rend(); ++rit){ + SPObject * obj = desktop->doc()->getObjectById(rit->c_str()); + SPDefs * defs = desktop->getDocument()->getDefs(); + if (obj && !defs->isAncestorOf(obj)) { + add(obj); + } + } + if (tool) { + Inkscape::UI::ControlPointSelection *cps = tool->_selected_nodes; + cps->selectAll(); + std::list points_list = cps->_points_list; + cps->clear(); + Inkscape::UI::Node * node = dynamic_cast(*points_list.begin()); + if (node) { + Inkscape::UI::SubpathList sp = node->nodeList().subpathList(); + for (std::vector > >::iterator l = _seldata.begin(); l != _seldata.end(); ++l) { + SPPath * path = dynamic_cast(desktop->doc()->getObjectById(l->first)); + gint sp_count = 0; + for (Inkscape::UI::SubpathList::iterator j = sp.begin(); j != sp.end(); ++j, ++sp_count) { + if(sp_count == l->second.first) { + gint nt_count = 0; + for (Inkscape::UI::NodeList::iterator k = (*j)->begin(); k != (*j)->end(); ++k, ++nt_count) { + if(nt_count == l->second.second) { + k->select(true); + break; + } + } + break; + } + } + } + } + points_list.clear(); + } + } +} + + } /* diff --git a/src/selection.h b/src/selection.h index 2b454e9474..989adf6b0e 100644 --- a/src/selection.h +++ b/src/selection.h @@ -183,6 +183,23 @@ public: return _modified_signal.slots().insert(_modified_signal.slots().begin(), slot); } + /** + * Set a backup of current selection and store it also to be command line readable by extension system + */ + void setBackup(); + /** + * Clear backup of current selection + */ + void emptyBackup(); + /** + * Restore a selection from a existing backup + */ + void restoreBackup(); + /** + * Here store a paramlist when set backup + */ + std::list params; + protected: void _emitSignals(); void _connectSignals(SPObject* object); @@ -212,7 +229,8 @@ private: SPObject* _selection_context; unsigned int _flags; unsigned int _idle; - + std::vector > > _seldata; + std::vector _selected_ids; std::map _modified_connections; sigc::connection _context_release_connection; diff --git a/src/ui/tool/control-point-selection.h b/src/ui/tool/control-point-selection.h index ec845b1b39..d0cfce8d2f 100644 --- a/src/ui/tool/control-point-selection.h +++ b/src/ui/tool/control-point-selection.h @@ -117,6 +117,8 @@ public: void getOriginalPoints(std::vector &pts); void getUnselectedPoints(std::vector &pts); void setOriginalPoints(); + //the purpose of this list is to keep track of first and last selected + std::list _points_list; private: // The functions below are invoked from SelectableControlPoint. @@ -140,8 +142,7 @@ private: double _rotationRadius(Geom::Point const &); set_type _points; - //the purpose of this list is to keep track of first and last selected - std::list _points_list; + set_type _all_points; INK_UNORDERED_MAP _original_positions; INK_UNORDERED_MAP _last_trans; diff --git a/src/ui/tool/selectable-control-point.cpp b/src/ui/tool/selectable-control-point.cpp index f3f9c0e1e4..83ed7d38b1 100644 --- a/src/ui/tool/selectable-control-point.cpp +++ b/src/ui/tool/selectable-control-point.cpp @@ -87,6 +87,15 @@ bool SelectableControlPoint::clicked(GdkEventButton *event) return true; } +void SelectableControlPoint::select(bool toselect) +{ + if (toselect) { + _selection.insert(this); + } else { + _selection.erase(this); + } +} + void SelectableControlPoint::_takeSelection() { _selection.clear(); diff --git a/src/ui/tool/selectable-control-point.h b/src/ui/tool/selectable-control-point.h index 362d4addca..c16f639b1e 100644 --- a/src/ui/tool/selectable-control-point.h +++ b/src/ui/tool/selectable-control-point.h @@ -28,8 +28,10 @@ public: virtual Geom::Rect bounds() const { return Geom::Rect(position(), position()); } + virtual void select(bool toselect); friend class NodeList; + protected: SelectableControlPoint(SPDesktop *d, Geom::Point const &initial_pos, SPAnchorType anchor, diff --git a/src/xml/node.h b/src/xml/node.h index 29cfdab468..8d9fc19e4a 100644 --- a/src/xml/node.h +++ b/src/xml/node.h @@ -384,6 +384,20 @@ public: */ virtual void changeOrder(Node *child, Node *after)=0; + /** + * @brief Remove all elements that not in src node + * @param src The node to check for elemments into this node + * @param key The attribute to use as the identity attribute + */ + virtual void cleanOriginal(Node *src, gchar const *key)=0; + + + /** + * @brief Compare 2 nodes equality + * @param other The other node to compare + * @param recursive Recursive mode check + */ + virtual bool equal(Node const *other, bool recursive)=0; /** * @brief Merge all children of another node with the current * @@ -397,8 +411,11 @@ public: * * @param src The node to merge into this node * @param key The attribute to use as the identity attribute + * @param noid If true process noid items + * @param key If clean callback to cleanOriginal */ - virtual void mergeFrom(Node const *src, char const *key)=0; + + virtual void mergeFrom(Node const *src, char const *key, bool extension = false, bool clean = false)=0; /*@}*/ diff --git a/src/xml/simple-node.cpp b/src/xml/simple-node.cpp index 78fc52a279..a1a7127cca 100644 --- a/src/xml/simple-node.cpp +++ b/src/xml/simple-node.cpp @@ -315,7 +315,7 @@ SimpleNode::setAttribute(gchar const *name, gchar const *value, bool const /*is_ // Check usefulness of attributes on elements in the svg namespace, optionally don't add them to tree. Glib::ustring element = g_quark_to_string(_name); - // g_message("setAttribute: %s: %s: %s", element.c_str(), name, value); + //g_message("setAttribute: %s: %s: %s", element.c_str(), name, value); gchar* cleaned_value = g_strdup( value ); // Only check elements in SVG name space and don't block setting attribute to NULL. @@ -645,28 +645,112 @@ Node *SimpleNode::root() { } } -void SimpleNode::mergeFrom(Node const *src, gchar const *key) { +void SimpleNode::cleanOriginal(Node *src, gchar const *key){ + std::vector to_delete; + for ( Node *child = this->firstChild() ; child != NULL ; child = child->next() ) + { + gchar const *id = child->attribute(key); + if (id) { + Node *rch = sp_repr_lookup_child(src, key, id); + if (rch) { + child->cleanOriginal(rch, key); + } else { + to_delete.push_back(child); + } + } else { + to_delete.push_back(child); + } + } + for ( std::vector::iterator i = to_delete.begin(); i != to_delete.end(); ++i) { + removeChild(*i); + } +} + +bool SimpleNode::equal(Node const *other, bool recursive) { + if(strcmp(name(),other->name())!= 0){ + return false; + } + if (!(strcmp("sodipodi:namedview", name()))) { + return true; + } + guint orig_length = 0; + guint other_length = 0; + + if(content() && other->content() && strcmp(content(), other->content()) != 0){ + return false; + } + for (List orig_attr = attributeList(); orig_attr; ++orig_attr) { + for (List other_attr = other->attributeList(); other_attr; ++other_attr) { + const gchar * key_orig = g_quark_to_string(orig_attr->key); + const gchar * key_other = g_quark_to_string(other_attr->key); + if (!strcmp(key_orig, key_other) && + !strcmp(orig_attr->value, other_attr->value)) + { + other_length++; + break; + } + } + orig_length++; + } + if (orig_length != other_length) { + return false; + } + if (recursive) { + //NOTE: for faster the childs need to be in the same order + Node const *other_child = other->firstChild(); + for ( Node *child = firstChild(); + child; + child = child->next()) + { + if (!child->equal(other_child, recursive)) { + return false; + } + other_child = other_child->next(); + if(!other_child) { + return false; + } + } + } + return true; +} + +void SimpleNode::mergeFrom(Node const *src, gchar const *key, bool extension, bool clean) { g_return_if_fail(src != NULL); g_return_if_fail(key != NULL); g_assert(src != this); setContent(src->content()); + if(_parent) { + setPosition(src->position()); + } + + if (clean) { + Node * srcp = const_cast(src); + cleanOriginal(srcp, key); + } for ( Node const *child = src->firstChild() ; child != NULL ; child = child->next() ) { gchar const *id = child->attribute(key); if (id) { Node *rch=sp_repr_lookup_child(this, key, id); - if (rch) { - rch->mergeFrom(child, key); + if (rch && (!extension || rch->equal(child, false))) { + rch->mergeFrom(child, key, extension); } else { + if(rch) { + removeChild(rch); + } + guint pos = child->position(); rch = child->duplicate(_document); appendChild(rch); + rch->setPosition(pos); rch->release(); } } else { + guint pos = child->position(); Node *rch=child->duplicate(_document); appendChild(rch); + rch->setPosition(pos); rch->release(); } } diff --git a/src/xml/simple-node.h b/src/xml/simple-node.h index f2cfa953c9..fd41e53a88 100644 --- a/src/xml/simple-node.h +++ b/src/xml/simple-node.h @@ -91,7 +91,9 @@ public: char const *content() const; void setContent(char const *value); - void mergeFrom(Node const *src, char const *key); + void cleanOriginal(Node *src, gchar const *key); + bool equal(Node const *other, bool recursive); + void mergeFrom(Node const *src, char const *key, bool extension = false, bool clean = false); Inkscape::Util::List attributeList() const { return _attributes; -- GitLab From 94c489c75dc15b7e8ebe2524af57a3e451b961d2 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Fri, 3 Nov 2017 03:14:36 +0100 Subject: [PATCH 02/14] Tweak to force CI --- src/attribute-rel-css.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/attribute-rel-css.cpp b/src/attribute-rel-css.cpp index f8483d538b..325af092d7 100644 --- a/src/attribute-rel-css.cpp +++ b/src/attribute-rel-css.cpp @@ -25,6 +25,7 @@ #include "path-prefix.h" #include "preferences.h" + SPAttributeRelCSS * SPAttributeRelCSS::instance = NULL; bool SPAttributeRelCSS::foundFileProp = false; bool SPAttributeRelCSS::foundFileDefault = false; -- GitLab From 8137246af4857ed0b75442ed378663f7bc688e8e Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Fri, 3 Nov 2017 03:15:18 +0100 Subject: [PATCH 03/14] Tweak to force CI --- src/attribute-rel-css.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/attribute-rel-css.cpp b/src/attribute-rel-css.cpp index 325af092d7..f8483d538b 100644 --- a/src/attribute-rel-css.cpp +++ b/src/attribute-rel-css.cpp @@ -25,7 +25,6 @@ #include "path-prefix.h" #include "preferences.h" - SPAttributeRelCSS * SPAttributeRelCSS::instance = NULL; bool SPAttributeRelCSS::foundFileProp = false; bool SPAttributeRelCSS::foundFileDefault = false; -- GitLab From aead9ac60e981d5cf11e49d245eb3d96c64589d7 Mon Sep 17 00:00:00 2001 From: Jabiertxo Arraiza Cenoz Date: Fri, 3 Nov 2017 22:25:53 +0100 Subject: [PATCH 04/14] fix compiling problems on selection --- src/selection.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/selection.cpp b/src/selection.cpp index 6c791f10fa..f4a76365e8 100644 --- a/src/selection.cpp +++ b/src/selection.cpp @@ -190,16 +190,17 @@ Selection::setBackup () { SPDesktop *desktop = SP_ACTIVE_DESKTOP; if (desktop) { - std::vector selected_items = itemList(); _selected_ids.clear(); _seldata.clear(); params.clear(); - for(std::vector::const_iterator x = selected_items.begin(); x != selected_items.end(); ++x){ + auto items = const_cast(this)->items(); + for (auto iter = items.begin(); iter != items.end(); ++iter) { + SPItem *item = *iter; std::string selected_id; selected_id += "--id="; - selected_id += (*x)->getId(); + selected_id += item->getId(); params.push_front(selected_id); - _selected_ids.push_back((*x)->getId()); + _selected_ids.push_back(item->getId()); } Inkscape::UI::Tools::NodeTool *tool = 0; -- GitLab From ae4c0eb49fe82e38ed782430e69190ff374389c7 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Mon, 26 Feb 2018 22:29:38 +0100 Subject: [PATCH 05/14] Add patch to branch https://inkscape.org/en/paste/10993/ --- src/extension/prefdialog.cpp | 5 ++ src/selection.cpp | 153 ++++++++++++++++++----------------- 2 files changed, 82 insertions(+), 76 deletions(-) diff --git a/src/extension/prefdialog.cpp b/src/extension/prefdialog.cpp index 4c799eb686..0861f1dc33 100644 --- a/src/extension/prefdialog.cpp +++ b/src/extension/prefdialog.cpp @@ -211,8 +211,13 @@ PrefDialog::preview_toggle (void) { delete _exEnv; _exEnv = NULL; _effect->set_execution_env(_exEnv); + if (desktop && selection) { + selection->restoreBackup(); + desktop->on_live_extension = false; + } } } + document->setModifiedSinceSave(modified); } void diff --git a/src/selection.cpp b/src/selection.cpp index f4a76365e8..230073bcd1 100644 --- a/src/selection.cpp +++ b/src/selection.cpp @@ -189,60 +189,60 @@ void Selection::setBackup () { SPDesktop *desktop = SP_ACTIVE_DESKTOP; + SPDocument *document = SP_ACTIVE_DOCUMENT; + Inkscape::UI::Tools::NodeTool *tool = 0; if (desktop) { - _selected_ids.clear(); - _seldata.clear(); - params.clear(); - auto items = const_cast(this)->items(); - for (auto iter = items.begin(); iter != items.end(); ++iter) { - SPItem *item = *iter; - std::string selected_id; - selected_id += "--id="; - selected_id += item->getId(); - params.push_front(selected_id); - _selected_ids.push_back(item->getId()); - } - Inkscape::UI::Tools::NodeTool *tool = 0; - Inkscape::UI::Tools::ToolBase *ec = desktop->event_context; if (INK_IS_NODE_TOOL(ec)) { tool = static_cast(ec); } - if(tool){ - Inkscape::UI::ControlPointSelection *cps = tool->_selected_nodes; - std::list points_list = cps->_points_list; - for (std::list::iterator i = points_list.begin(); i != points_list.end(); ++i) { - Inkscape::UI::Node *node = dynamic_cast(*i); - if (node) { - std::string id = node->nodeList().subpathList().pm().item()->getId(); - - int sp = 0; - bool found_sp = false; - for(Inkscape::UI::SubpathList::iterator i = node->nodeList().subpathList().begin(); i != node->nodeList().subpathList().end(); ++i,++sp){ - if(&**i == &(node->nodeList())){ - found_sp = true; - break; - } - } - int nl=0; - bool found_nl = false; - for (Inkscape::UI::NodeList::iterator j = node->nodeList().begin(); j != node->nodeList().end(); ++j, ++nl){ - if(&*j==node){ - found_nl = true; - break; - } + } + _selected_ids.clear(); + _seldata.clear(); + params.clear(); + auto items = const_cast(this)->items(); + for (auto iter = items.begin(); iter != items.end(); ++iter) { + SPItem *item = *iter; + std::string selected_id; + selected_id += "--id="; + selected_id += item->getId(); + params.push_back(selected_id); + _selected_ids.push_back(item->getId()); + } + if(tool){ + Inkscape::UI::ControlPointSelection *cps = tool->_selected_nodes; + std::list points_list = cps->_points_list; + for (std::list::iterator i = points_list.begin(); i != points_list.end(); ++i) { + Inkscape::UI::Node *node = dynamic_cast(*i); + if (node) { + std::string id = node->nodeList().subpathList().pm().item()->getId(); + + int sp = 0; + bool found_sp = false; + for(Inkscape::UI::SubpathList::iterator i = node->nodeList().subpathList().begin(); i != node->nodeList().subpathList().end(); ++i,++sp){ + if(&**i == &(node->nodeList())){ + found_sp = true; + break; } - std::ostringstream ss; - ss<< "--selected-nodes=" << id << ":" << sp << ":" << nl; - Glib::ustring selected_nodes = ss.str(); - - if(found_nl && found_sp) { - _seldata.push_back(std::make_pair(id,std::make_pair(sp,nl))); - params.push_back(selected_nodes); - } else { - g_warning("Something went wrong while trying to pass selected nodes to extension. Please report a bug."); + } + int nl=0; + bool found_nl = false; + for (Inkscape::UI::NodeList::iterator j = node->nodeList().begin(); j != node->nodeList().end(); ++j, ++nl){ + if(&*j==node){ + found_nl = true; + break; } } + std::ostringstream ss; + ss<< "--selected-nodes=" << id << ":" << sp << ":" << nl; + Glib::ustring selected_nodes = ss.str(); + + if(found_nl && found_sp) { + _seldata.push_back(std::make_pair(id,std::make_pair(sp,nl))); + params.push_back(selected_nodes); + } else { + g_warning("Something went wrong while trying to pass selected nodes to extension. Please report a bug."); + } } } }//end add selected nodes @@ -252,48 +252,49 @@ void Selection::restoreBackup() { SPDesktop *desktop = SP_ACTIVE_DESKTOP; + SPDocument *document = SP_ACTIVE_DOCUMENT; + Inkscape::UI::Tools::NodeTool *tool = 0; if (desktop) { - Inkscape::UI::Tools::NodeTool *tool = 0; Inkscape::UI::Tools::ToolBase *ec = desktop->event_context; if (INK_IS_NODE_TOOL(ec)) { tool = static_cast(ec); } - clear(); - std::vector::reverse_iterator rit = _selected_ids.rbegin(); - for (; rit!= _selected_ids.rend(); ++rit){ - SPObject * obj = desktop->doc()->getObjectById(rit->c_str()); - SPDefs * defs = desktop->getDocument()->getDefs(); - if (obj && !defs->isAncestorOf(obj)) { - add(obj); - } + } + clear(); + std::vector::iterator it = _selected_ids.begin(); + for (; it!= _selected_ids.end(); ++it){ + SPItem * item = dynamic_cast(document->getObjectById(it->c_str())); + SPDefs * defs = document->getDefs(); + if (item && !defs->isAncestorOf(item)) { + add(item); } - if (tool) { - Inkscape::UI::ControlPointSelection *cps = tool->_selected_nodes; - cps->selectAll(); - std::list points_list = cps->_points_list; - cps->clear(); - Inkscape::UI::Node * node = dynamic_cast(*points_list.begin()); - if (node) { - Inkscape::UI::SubpathList sp = node->nodeList().subpathList(); - for (std::vector > >::iterator l = _seldata.begin(); l != _seldata.end(); ++l) { - SPPath * path = dynamic_cast(desktop->doc()->getObjectById(l->first)); - gint sp_count = 0; - for (Inkscape::UI::SubpathList::iterator j = sp.begin(); j != sp.end(); ++j, ++sp_count) { - if(sp_count == l->second.first) { - gint nt_count = 0; - for (Inkscape::UI::NodeList::iterator k = (*j)->begin(); k != (*j)->end(); ++k, ++nt_count) { - if(nt_count == l->second.second) { - k->select(true); - break; - } + } + if (tool) { + Inkscape::UI::ControlPointSelection *cps = tool->_selected_nodes; + cps->selectAll(); + std::list points_list = cps->_points_list; + cps->clear(); + Inkscape::UI::Node * node = dynamic_cast(*points_list.begin()); + if (node) { + Inkscape::UI::SubpathList sp = node->nodeList().subpathList(); + for (std::vector > >::iterator l = _seldata.begin(); l != _seldata.end(); ++l) { + SPPath * path = dynamic_cast(document->getObjectById(l->first)); + gint sp_count = 0; + for (Inkscape::UI::SubpathList::iterator j = sp.begin(); j != sp.end(); ++j, ++sp_count) { + if(sp_count == l->second.first) { + gint nt_count = 0; + for (Inkscape::UI::NodeList::iterator k = (*j)->begin(); k != (*j)->end(); ++k, ++nt_count) { + if(nt_count == l->second.second) { + cps->insert(k.ptr()); + break; } - break; } + break; } } } - points_list.clear(); } + points_list.clear(); } } -- GitLab From 0624d93323c24936b9bc83c9836e87c6645b8582 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Tue, 27 Feb 2018 00:19:22 +0100 Subject: [PATCH 06/14] Fix https://gitlab.com/inkscape/inkscape/merge_requests/208#note_60693688 --- src/attribute-rel-util.cpp | 9 ++++++--- src/extension/implementation/script.cpp | 21 ++------------------- src/preferences-skeleton.h | 1 + src/svg/path-string.cpp | 7 +++++-- src/svg/svg-color.cpp | 3 ++- src/xml/repr-io.cpp | 5 ++++- 6 files changed, 20 insertions(+), 26 deletions(-) diff --git a/src/attribute-rel-util.cpp b/src/attribute-rel-util.cpp index 42b6bebf25..d377e5edb3 100644 --- a/src/attribute-rel-util.cpp +++ b/src/attribute-rel-util.cpp @@ -34,11 +34,14 @@ unsigned int sp_attribute_clean_get_prefs() { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); unsigned int flags = 0; if( prefs->getBool("/options/svgoutput/incorrect_attributes_warn") ) flags += SP_ATTR_CLEAN_ATTR_WARN; - if( prefs->getBool("/options/svgoutput/incorrect_attributes_remove") ) flags += SP_ATTR_CLEAN_ATTR_REMOVE; + if( prefs->getBool("/options/svgoutput/incorrect_attributes_remove") && + !prefs->getBool("/options/svgoutput/disable_optimizations" ) ) flags += SP_ATTR_CLEAN_ATTR_REMOVE; if( prefs->getBool("/options/svgoutput/incorrect_style_properties_warn") ) flags += SP_ATTR_CLEAN_STYLE_WARN; - if( prefs->getBool("/options/svgoutput/incorrect_style_properties_remove" ) ) flags += SP_ATTR_CLEAN_STYLE_REMOVE; + if( prefs->getBool("/options/svgoutput/incorrect_style_properties_remove" ) && + !prefs->getBool("/options/svgoutput/disable_optimizations" ) ) flags += SP_ATTR_CLEAN_STYLE_REMOVE; if( prefs->getBool("/options/svgoutput/style_defaults_warn") ) flags += SP_ATTR_CLEAN_DEFAULT_WARN; - if( prefs->getBool("/options/svgoutput/style_defaults_remove") ) flags += SP_ATTR_CLEAN_DEFAULT_REMOVE; + if( prefs->getBool("/options/svgoutput/style_defaults_remove") && + !prefs->getBool("/options/svgoutput/disable_optimizations" ) ) flags += SP_ATTR_CLEAN_DEFAULT_REMOVE; return flags; } diff --git a/src/extension/implementation/script.cpp b/src/extension/implementation/script.cpp index 42867b8236..f1b46e8ac4 100644 --- a/src/extension/implementation/script.cpp +++ b/src/extension/implementation/script.cpp @@ -418,28 +418,11 @@ ScriptDocCache::ScriptDocCache (Inkscape::UI::View::View * view) : SPDesktop *desktop = (SPDesktop *) view; sp_namedview_document_from_window(desktop); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - bool sort_attributes = prefs->getBool("/options/svgoutput/sort_attributes", false); - bool incorrect_style_properties_remove = prefs->getBool("/options/svgoutput/incorrect_style_properties_remove", false); - bool incorrect_attributes_remove = prefs->getBool("/options/svgoutput/incorrect_attributes_remove", false); - bool usenamedcolors = prefs->getBool("/options/svgoutput/usenamedcolors", false); - bool forcerepeatcommands = prefs->getBool("/options/svgoutput/forcerepeatcommands", false); - bool style_defaults_remove = prefs->getBool("/options/svgoutput/style_defaults_remove", false); - prefs->setBool("/options/svgoutput/sort_attributes", false); - prefs->setBool("/options/svgoutput/incorrect_style_properties_remove", false); - prefs->setBool("/options/svgoutput/incorrect_attributes_remove", false); - prefs->setBool("/options/svgoutput/usenamedcolors", false); - prefs->setBool("/options/svgoutput/forcerepeatcommands", false); - prefs->setBool("/options/svgoutput/style_defaults_remove", false); + prefs->setBool("/options/svgoutput/disable_optimizations", true); Inkscape::Extension::save( Inkscape::Extension::db.get(SP_MODULE_KEY_OUTPUT_SVG_INKSCAPE), view->doc(), _filename.c_str(), false, false, false, Inkscape::Extension::FILE_SAVE_METHOD_TEMPORARY); - - prefs->setBool("/options/svgoutput/sort_attributes", sort_attributes); - prefs->setBool("/options/svgoutput/incorrect_style_properties_remove", incorrect_style_properties_remove); - prefs->setBool("/options/svgoutput/incorrect_attributes_remove", incorrect_attributes_remove); - prefs->setBool("/options/svgoutput/usenamedcolors", usenamedcolors); - prefs->setBool("/options/svgoutput/forcerepeatcommands", forcerepeatcommands); - prefs->setBool("/options/svgoutput/style_defaults_remove", style_defaults_remove); + prefs->setBool("/options/svgoutput/disable_optimizations", false); return; } diff --git a/src/preferences-skeleton.h b/src/preferences-skeleton.h index ed00092b2c..23040fcfd4 100644 --- a/src/preferences-skeleton.h +++ b/src/preferences-skeleton.h @@ -323,6 +323,7 @@ static char const preferences_skeleton[] = " clips=\"16711935\"" // 00ff00ff " masks=\"65535\"/>\n" // 0x0000ffff " getBool("/options/svgoutput/disable_optimizations" ); +if (!forcerepeatcommands) { + forcerepeatcommands = Inkscape::Preferences::get()->getBool("/options/svgoutput/forcerepeatcommands"); +} Inkscape::SVG::PathString::PathString() : - force_repeat_commands(Inkscape::Preferences::get()->getBool("/options/svgoutput/forcerepeatcommands")) + force_repeat_commands(forcerepeatcommands) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); format = (PATHSTRING_FORMAT)prefs->getIntLimited("/options/svgoutput/pathstring_format", 1, 0, PATHSTRING_FORMAT_SIZE - 1 ); diff --git a/src/svg/svg-color.cpp b/src/svg/svg-color.cpp index d1e91ace12..1f26d02b12 100644 --- a/src/svg/svg-color.cpp +++ b/src/svg/svg-color.cpp @@ -491,7 +491,8 @@ void sp_svg_write_color(gchar *buf, unsigned const buflen, guint32 const rgba32) Inkscape::Preferences *prefs = Inkscape::Preferences::get(); unsigned const rgb24 = rgba32 >> 8; - if (prefs->getBool("/options/svgoutput/usenamedcolors")) { + if ( prefs->getBool("/options/svgoutput/usenamedcolors") && + !prefs->getBool("/options/svgoutput/disable_optimizations" )) { rgb24_to_css(buf, rgb24); } else { g_snprintf(buf, buflen, "#%06x", rgb24); diff --git a/src/xml/repr-io.cpp b/src/xml/repr-io.cpp index 2ff9d47769..c7b483dcb3 100644 --- a/src/xml/repr-io.cpp +++ b/src/xml/repr-io.cpp @@ -872,7 +872,10 @@ static void sp_repr_write_stream_root_element(Node *repr, Writer &out, if (clean) sp_attribute_clean_tree( repr ); // Sort attributes in a canonical order (helps with "diffing" SVG files). - bool sort = prefs->getBool("/options/svgoutput/sort_attributes"); + bool sort = prefs->getBool("/options/svgoutput/disable_optimizations"); + if (!sort) { + sort = prefs->getBool("/options/svgoutput/sort_attributes"); + } if (sort) sp_attribute_sort_tree( repr ); Glib::QueryQuark xml_prefix=g_quark_from_static_string("xml"); -- GitLab From cf0e762fa380de08b8f3043b4e9c0b3c33fd817b Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Tue, 27 Feb 2018 00:35:45 +0100 Subject: [PATCH 07/14] fix https://gitlab.com/inkscape/inkscape/merge_requests/208#note_60694271 --- src/extension/implementation/implementation.h | 11 +++++++++++ src/extension/internal/bitmap/imagemagick.cpp | 10 ---------- src/extension/internal/bluredge.cpp | 12 +----------- src/extension/internal/filter/filter.cpp | 14 ++------------ src/extension/internal/grid.cpp | 12 +----------- 5 files changed, 15 insertions(+), 44 deletions(-) diff --git a/src/extension/implementation/implementation.h b/src/extension/implementation/implementation.h index 1232ae0c87..fa4a647253 100644 --- a/src/extension/implementation/implementation.h +++ b/src/extension/implementation/implementation.h @@ -59,6 +59,17 @@ public: ImplementationDocumentCache (Inkscape::UI::View::View * view) : _view(view) { + SPDesktop *desktop = (SPDesktop*)view; + Inkscape::Selection * selection = NULL; + if (desktop) { + selection = desktop->getSelection(); + if (selection && !selection->params.empty()) { + selection->restoreBackup(); + if (!desktop->on_live_extension) { + selection->emptyBackup(); + } + } + } return; }; virtual ~ImplementationDocumentCache ( ) { return; }; diff --git a/src/extension/internal/bitmap/imagemagick.cpp b/src/extension/internal/bitmap/imagemagick.cpp index 32d6f59e3f..636b9d6a41 100644 --- a/src/extension/internal/bitmap/imagemagick.cpp +++ b/src/extension/internal/bitmap/imagemagick.cpp @@ -64,16 +64,6 @@ ImageMagickDocCache::ImageMagickDocCache(Inkscape::UI::View::View * view) : _imageItems(NULL) { SPDesktop *desktop = (SPDesktop*)view; - Inkscape::Selection * selection = NULL; - if (desktop) { - selection = desktop->getSelection(); - if (selection && !selection->params.empty()) { - selection->restoreBackup(); - if (!desktop->on_live_extension) { - selection->emptyBackup(); - } - } - } auto selectedItemList = desktop->selection->items(); int selectCount = (int) boost::distance(selectedItemList); diff --git a/src/extension/internal/bluredge.cpp b/src/extension/internal/bluredge.cpp index c086405e50..4bcc5d715e 100644 --- a/src/extension/internal/bluredge.cpp +++ b/src/extension/internal/bluredge.cpp @@ -54,6 +54,7 @@ void BlurEdge::effect (Inkscape::Extension::Effect *module, Inkscape::UI::View::View *desktop, Inkscape::Extension::Implementation::ImplementationDocumentCache * /*docCache*/) { + Inkscape::Selection * selection = static_cast(desktop)->selection; float width = module->get_param_float("blur-width"); int steps = module->get_param_int("num-steps"); @@ -61,17 +62,6 @@ BlurEdge::effect (Inkscape::Extension::Effect *module, Inkscape::UI::View::View Inkscape::Preferences *prefs = Inkscape::Preferences::get(); double old_offset = prefs->getDouble("/options/defaultoffsetwidth/value", 1.0, "px"); - SPDesktop *deskt = static_cast(desktop); - Inkscape::Selection * selection = NULL; - if (deskt) { - selection = deskt->selection; - if (selection && !selection->params.empty()) { - selection->restoreBackup(); - if (!deskt->on_live_extension) { - selection->emptyBackup(); - } - } - } // TODO need to properly refcount the items, at least std::vector items(selection->items().begin(), selection->items().end()); selection->clear(); diff --git a/src/extension/internal/filter/filter.cpp b/src/extension/internal/filter/filter.cpp index af4997ebac..69aec15956 100644 --- a/src/extension/internal/filter/filter.cpp +++ b/src/extension/internal/filter/filter.cpp @@ -120,19 +120,9 @@ void Filter::effect(Inkscape::Extension::Effect *module, Inkscape::UI::View::Vie if (filterdoc == NULL) { return; // could not parse the XML source of the filter; typically parser will stderr a warning } - //printf("Calling filter effect\n"); - SPDesktop *desktop = (SPDesktop *)document; - Inkscape::Selection * selection = NULL; - if (desktop) { - selection = desktop->selection; - if (selection && !selection->params.empty()) { - selection->restoreBackup(); - if (!desktop->on_live_extension) { - selection->emptyBackup(); - } - } - } + Inkscape::Selection * selection = ((SPDesktop *)document)->selection; + // TODO need to properly refcount the items, at least std::vector items(selection->items().begin(), selection->items().end()); diff --git a/src/extension/internal/grid.cpp b/src/extension/internal/grid.cpp index 6b3f2efe39..c7ebf2494d 100644 --- a/src/extension/internal/grid.cpp +++ b/src/extension/internal/grid.cpp @@ -86,17 +86,7 @@ Glib::ustring build_lines(Geom::Rect bounding_area, void Grid::effect (Inkscape::Extension::Effect *module, Inkscape::UI::View::View *document, Inkscape::Extension::Implementation::ImplementationDocumentCache * /*docCache*/) { - SPDesktop *desktop = ((SPDesktop *)document); - Inkscape::Selection * selection = NULL; - if (desktop) { - selection = desktop->getSelection(); - if (selection && !selection->params.empty()) { - selection->restoreBackup(); - if (!desktop->on_live_extension) { - selection->emptyBackup(); - } - } - } + Inkscape::Selection * selection = ((SPDesktop *)document)->selection; Geom::Rect bounding_area = Geom::Rect(Geom::Point(0,0), Geom::Point(100,100)); if (selection->isEmpty()) { -- GitLab From a45afbdbffb81b567de372741f1f08c70244dc53 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Tue, 27 Feb 2018 01:01:23 +0100 Subject: [PATCH 08/14] fix compiling bugs --- .../implementation/implementation.cpp | 17 +++++++++++++++++ src/extension/implementation/implementation.h | 18 ++---------------- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/src/extension/implementation/implementation.cpp b/src/extension/implementation/implementation.cpp index 6e6100d2b6..38a6c11620 100644 --- a/src/extension/implementation/implementation.cpp +++ b/src/extension/implementation/implementation.cpp @@ -27,6 +27,23 @@ namespace Inkscape { namespace Extension { namespace Implementation { +void +ImplementationDocumentCache::ImplementationDocumentCache (Inkscape::UI::View::View * view) + : _view(view) +{ + SPDesktop *desktop = (SPDesktop*)view; + Inkscape::Selection * selection = NULL; + if (desktop) { + selection = desktop->getSelection(); + if (selection && !selection->params.empty()) { + selection->restoreBackup(); + if (!desktop->on_live_extension) { + selection->emptyBackup(); + } + } + } +} + Gtk::Widget * Implementation::prefs_input(Inkscape::Extension::Input *module, gchar const */*filename*/) { return module->autogui(NULL, NULL); diff --git a/src/extension/implementation/implementation.h b/src/extension/implementation/implementation.h index fa4a647253..5bb909ef26 100644 --- a/src/extension/implementation/implementation.h +++ b/src/extension/implementation/implementation.h @@ -56,22 +56,8 @@ class ImplementationDocumentCache { */ Inkscape::UI::View::View * _view; public: - ImplementationDocumentCache (Inkscape::UI::View::View * view) : - _view(view) - { - SPDesktop *desktop = (SPDesktop*)view; - Inkscape::Selection * selection = NULL; - if (desktop) { - selection = desktop->getSelection(); - if (selection && !selection->params.empty()) { - selection->restoreBackup(); - if (!desktop->on_live_extension) { - selection->emptyBackup(); - } - } - } - return; - }; + ImplementationDocumentCache (Inkscape::UI::View::View * view); + virtual ~ImplementationDocumentCache ( ) { return; }; Inkscape::UI::View::View const * view ( ) { return _view; }; }; -- GitLab From 844f91c73c41679ac53e57611a1df46475b09bfc Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Tue, 27 Feb 2018 01:08:34 +0100 Subject: [PATCH 09/14] fix compiling bugs --- src/extension/implementation/implementation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/extension/implementation/implementation.cpp b/src/extension/implementation/implementation.cpp index 38a6c11620..e05dbf3c43 100644 --- a/src/extension/implementation/implementation.cpp +++ b/src/extension/implementation/implementation.cpp @@ -27,7 +27,6 @@ namespace Inkscape { namespace Extension { namespace Implementation { -void ImplementationDocumentCache::ImplementationDocumentCache (Inkscape::UI::View::View * view) : _view(view) { @@ -42,6 +41,7 @@ ImplementationDocumentCache::ImplementationDocumentCache (Inkscape::UI::View::Vi } } } + return; } Gtk::Widget * -- GitLab From fa705a24dc4af5fb9f3bca2c3f52896a0466b694 Mon Sep 17 00:00:00 2001 From: Jabiertxo Arraiza Cenoz Date: Tue, 27 Feb 2018 10:38:03 +0100 Subject: [PATCH 10/14] fix bug compiling --- src/svg/path-string.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/svg/path-string.cpp b/src/svg/path-string.cpp index a1dd3e49cf..2fa2c8f026 100644 --- a/src/svg/path-string.cpp +++ b/src/svg/path-string.cpp @@ -26,12 +26,9 @@ static int const maxprec = 16; int Inkscape::SVG::PathString::numericprecision; int Inkscape::SVG::PathString::minimumexponent; Inkscape::SVG::PATHSTRING_FORMAT Inkscape::SVG::PathString::format; -bool forcerepeatcommands = prefs->getBool("/options/svgoutput/disable_optimizations" ); -if (!forcerepeatcommands) { - forcerepeatcommands = Inkscape::Preferences::get()->getBool("/options/svgoutput/forcerepeatcommands"); -} + Inkscape::SVG::PathString::PathString() : - force_repeat_commands(forcerepeatcommands) + force_repeat_commands(!Inkscape::Preferences::get()->getBool("/options/svgoutput/disable_optimizations" ) && Inkscape::Preferences::get()->getBool("/options/svgoutput/forcerepeatcommands")) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); format = (PATHSTRING_FORMAT)prefs->getIntLimited("/options/svgoutput/pathstring_format", 1, 0, PATHSTRING_FORMAT_SIZE - 1 ); -- GitLab From b85b43a64e3d3d7e623b4bcd99b08ef8f6fc7a43 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Wed, 9 May 2018 21:38:45 +0200 Subject: [PATCH 11/14] Reset old code to reaply fixed --- src/attribute-rel-util.cpp | 9 +- src/desktop.cpp | 1 - src/desktop.h | 2 +- src/extension/execution-env.cpp | 37 ++++-- src/extension/execution-env.h | 3 + .../implementation/implementation.cpp | 17 --- src/extension/implementation/implementation.h | 7 +- src/extension/implementation/script.cpp | 122 ++++++++++++++--- src/extension/internal/bluredge.cpp | 1 - src/extension/internal/filter/filter.cpp | 1 + src/extension/prefdialog.cpp | 33 +---- src/preferences-skeleton.h | 1 - src/selection.cpp | 123 +----------------- src/selection.h | 20 +-- src/svg/path-string.cpp | 2 +- src/svg/svg-color.cpp | 3 +- src/ui/tool/control-point-selection.h | 5 +- src/ui/tool/selectable-control-point.cpp | 9 -- src/ui/tool/selectable-control-point.h | 2 - src/xml/node.h | 19 +-- src/xml/repr-io.cpp | 5 +- src/xml/simple-node.cpp | 92 +------------ src/xml/simple-node.h | 4 +- 23 files changed, 159 insertions(+), 359 deletions(-) diff --git a/src/attribute-rel-util.cpp b/src/attribute-rel-util.cpp index d377e5edb3..42b6bebf25 100644 --- a/src/attribute-rel-util.cpp +++ b/src/attribute-rel-util.cpp @@ -34,14 +34,11 @@ unsigned int sp_attribute_clean_get_prefs() { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); unsigned int flags = 0; if( prefs->getBool("/options/svgoutput/incorrect_attributes_warn") ) flags += SP_ATTR_CLEAN_ATTR_WARN; - if( prefs->getBool("/options/svgoutput/incorrect_attributes_remove") && - !prefs->getBool("/options/svgoutput/disable_optimizations" ) ) flags += SP_ATTR_CLEAN_ATTR_REMOVE; + if( prefs->getBool("/options/svgoutput/incorrect_attributes_remove") ) flags += SP_ATTR_CLEAN_ATTR_REMOVE; if( prefs->getBool("/options/svgoutput/incorrect_style_properties_warn") ) flags += SP_ATTR_CLEAN_STYLE_WARN; - if( prefs->getBool("/options/svgoutput/incorrect_style_properties_remove" ) && - !prefs->getBool("/options/svgoutput/disable_optimizations" ) ) flags += SP_ATTR_CLEAN_STYLE_REMOVE; + if( prefs->getBool("/options/svgoutput/incorrect_style_properties_remove" ) ) flags += SP_ATTR_CLEAN_STYLE_REMOVE; if( prefs->getBool("/options/svgoutput/style_defaults_warn") ) flags += SP_ATTR_CLEAN_DEFAULT_WARN; - if( prefs->getBool("/options/svgoutput/style_defaults_remove") && - !prefs->getBool("/options/svgoutput/disable_optimizations" ) ) flags += SP_ATTR_CLEAN_DEFAULT_REMOVE; + if( prefs->getBool("/options/svgoutput/style_defaults_remove") ) flags += SP_ATTR_CLEAN_DEFAULT_REMOVE; return flags; } diff --git a/src/desktop.cpp b/src/desktop.cpp index 72739305ae..47c82b6d93 100644 --- a/src/desktop.cpp +++ b/src/desktop.cpp @@ -117,7 +117,6 @@ SPDesktop::SPDesktop() : waiting_cursor( false ), showing_dialogs ( false ), guides_active( false ), - on_live_extension(false), gr_item( NULL ), gr_point_type( POINT_LG_BEGIN ), gr_point_i( 0 ), diff --git a/src/desktop.h b/src/desktop.h index 8b20195db1..f4eecf8b71 100644 --- a/src/desktop.h +++ b/src/desktop.h @@ -188,9 +188,9 @@ public: unsigned int interaction_disabled_counter; bool waiting_cursor; bool showing_dialogs; + /// \todo fixme: This has to be implemented in different way */ guint guides_active : 1; - bool on_live_extension; // storage for selected dragger used by GrDrag as it's // created and deleted by tools diff --git a/src/extension/execution-env.cpp b/src/extension/execution-env.cpp index bde04d924f..7e233d2151 100644 --- a/src/extension/execution-env.cpp +++ b/src/extension/execution-env.cpp @@ -22,8 +22,6 @@ #include "selection.h" #include "effect.h" #include "document.h" -#include "desktop.h" -#include "inkscape.h" #include "document-undo.h" #include "desktop.h" #include "object/sp-namedview.h" @@ -54,6 +52,19 @@ ExecutionEnv::ExecutionEnv (Effect * effect, Inkscape::UI::View::View * doc, Imp _show_working(show_working), _show_errors(show_errors) { + SPDesktop *desktop = (SPDesktop *)_doc; + sp_namedview_document_from_window(desktop); + + if (desktop != NULL) { + 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); + //std::cout << "Selected: " << selected_id << std::endl; + } + } + genDocCache(); return; @@ -178,14 +189,24 @@ ExecutionEnv::commit (void) { void ExecutionEnv::reselect (void) { - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - Inkscape::Selection * selection = NULL; - if(desktop) { - selection = desktop->getSelection(); - if (!desktop->on_live_extension) { - selection->restoreBackup(); + if (_doc == NULL) { return; } + SPDocument * doc = _doc->doc(); + if (doc == NULL) { return; } + + SPDesktop *desktop = (SPDesktop *)_doc; + sp_namedview_document_from_window(desktop); + + if (desktop == NULL) { return; } + + Inkscape::Selection * selection = desktop->getSelection(); + + for (std::list::iterator i = _selected.begin(); i != _selected.end(); ++i) { + SPObject * obj = doc->getObjectById(i->c_str()); + if (obj != NULL) { + selection->add(obj); } } + return; } diff --git a/src/extension/execution-env.h b/src/extension/execution-env.h index 8af97cd923..b1a3a8ea22 100644 --- a/src/extension/execution-env.h +++ b/src/extension/execution-env.h @@ -54,6 +54,9 @@ private: Glib::RefPtr _mainloop; /** \brief The document that we're working on. */ Inkscape::UI::View::View * _doc; + /** \brief A list of the IDs of all the selected objects before + we started to work on this document. */ + std::list _selected; /** \brief A document cache if we were passed one. */ Implementation::ImplementationDocumentCache * _docCache; diff --git a/src/extension/implementation/implementation.cpp b/src/extension/implementation/implementation.cpp index e05dbf3c43..6e6100d2b6 100644 --- a/src/extension/implementation/implementation.cpp +++ b/src/extension/implementation/implementation.cpp @@ -27,23 +27,6 @@ namespace Inkscape { namespace Extension { namespace Implementation { -ImplementationDocumentCache::ImplementationDocumentCache (Inkscape::UI::View::View * view) - : _view(view) -{ - SPDesktop *desktop = (SPDesktop*)view; - Inkscape::Selection * selection = NULL; - if (desktop) { - selection = desktop->getSelection(); - if (selection && !selection->params.empty()) { - selection->restoreBackup(); - if (!desktop->on_live_extension) { - selection->emptyBackup(); - } - } - } - return; -} - Gtk::Widget * Implementation::prefs_input(Inkscape::Extension::Input *module, gchar const */*filename*/) { return module->autogui(NULL, NULL); diff --git a/src/extension/implementation/implementation.h b/src/extension/implementation/implementation.h index 5bb909ef26..1232ae0c87 100644 --- a/src/extension/implementation/implementation.h +++ b/src/extension/implementation/implementation.h @@ -56,8 +56,11 @@ class ImplementationDocumentCache { */ Inkscape::UI::View::View * _view; public: - ImplementationDocumentCache (Inkscape::UI::View::View * view); - + ImplementationDocumentCache (Inkscape::UI::View::View * view) : + _view(view) + { + return; + }; virtual ~ImplementationDocumentCache ( ) { return; }; Inkscape::UI::View::View const * view ( ) { return _view; }; }; diff --git a/src/extension/implementation/script.cpp b/src/extension/implementation/script.cpp index f1b46e8ac4..f25c8a5d69 100644 --- a/src/extension/implementation/script.cpp +++ b/src/extension/implementation/script.cpp @@ -417,12 +417,11 @@ ScriptDocCache::ScriptDocCache (Inkscape::UI::View::View * view) : SPDesktop *desktop = (SPDesktop *) view; sp_namedview_document_from_window(desktop); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setBool("/options/svgoutput/disable_optimizations", true); + Inkscape::Extension::save( Inkscape::Extension::db.get(SP_MODULE_KEY_OUTPUT_SVG_INKSCAPE), view->doc(), _filename.c_str(), false, false, false, Inkscape::Extension::FILE_SAVE_METHOD_TEMPORARY); - prefs->setBool("/options/svgoutput/disable_optimizations", false); + return; } @@ -687,14 +686,57 @@ void Script::effect(Inkscape::Extension::Effect *module, return; } - if (desktop) { - Inkscape::Selection * selection = desktop->getSelection(); - if (!selection->isEmpty()) { - selection->setBackup(); + 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(); + params.push_front(selected_id); + } + + {//add selected nodes + Inkscape::UI::Tools::NodeTool *tool = 0; + if (SP_ACTIVE_DESKTOP ) { + Inkscape::UI::Tools::ToolBase *ec = SP_ACTIVE_DESKTOP->event_context; + if (INK_IS_NODE_TOOL(ec)) { + tool = static_cast(ec); + } + } + + if(tool){ + Inkscape::UI::ControlPointSelection *cps = tool->_selected_nodes; + for (Inkscape::UI::ControlPointSelection::iterator i = cps->begin(); i != cps->end(); ++i) { + Inkscape::UI::Node *node = dynamic_cast(*i); + if (node) { + std::string id = node->nodeList().subpathList().pm().item()->getId(); + + int sp = 0; + bool found_sp = false; + for(Inkscape::UI::SubpathList::iterator i = node->nodeList().subpathList().begin(); i != node->nodeList().subpathList().end(); ++i,++sp){ + if(&**i == &(node->nodeList())){ + found_sp = true; + break; + } + } + int nl=0; + bool found_nl = false; + for (Inkscape::UI::NodeList::iterator j = node->nodeList().begin(); j != node->nodeList().end(); ++j, ++nl){ + if(&*j==node){ + found_nl = true; + break; + } + } + std::ostringstream ss; + ss<< "--selected-nodes=" << id << ":" << sp << ":" << nl; + Glib::ustring selected = ss.str(); + + if(found_nl && found_sp)params.push_front(selected); + else g_warning("Something went wrong while trying to pass selected nodes to extension. Please report a bug."); + } } - params = selection->params; - module->paramListString(params); } + }//end add selected nodes file_listener fileout; int data_read = execute(command, params, dc->_filename, fileout); @@ -748,7 +790,6 @@ void Script::effect(Inkscape::Extension::Effect *module, layer = document->getObjectById(g_quark_to_string(nv->default_layer_id)); } } - desktop->showGrids(nv->grids_visible); } sp_namedview_update_layers_from_document(desktop); @@ -757,14 +798,6 @@ void Script::effect(Inkscape::Extension::Effect *module, //set the current layer desktop->setCurrentLayer(layer); } - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - if (desktop) { - Inkscape::Selection * selection = desktop->getSelection(); - if (selection && selection->isEmpty() && !desktop->on_live_extension) { - selection->restoreBackup(); - selection->emptyBackup(); - } - } } mydoc->release(); } @@ -800,10 +833,12 @@ void Script::copy_doc (Inkscape::XML::Node * oldroot, Inkscape::XML::Node * newr g_warning("Error on copy_doc: NULL pointer input."); return; } + // For copying attributes in root and in namedview using Inkscape::Util::List; using Inkscape::XML::AttributeRecord; std::vector attribs; + // Must explicitly copy root attributes. This must be done first since // copying grid lines calls "SPGuide::set()" which needs to know the // width, height, and viewBox of the root element. @@ -824,33 +859,80 @@ void Script::copy_doc (Inkscape::XML::Node * oldroot, Inkscape::XML::Node * newr oldroot->setAttribute(name, newroot->attribute(name)); } + // Question: Why is the "sodipodi:namedview" special? Treating it as a normal // elmement results in crashes. // Seems to be a bug: // http://inkscape.13.x6.nabble.com/Effect-that-modifies-the-document-properties-tt2822126.html std::vector delete_list; + Inkscape::XML::Node * oldroot_namedview = NULL; + Inkscape::XML::Node * newroot_namedview = NULL; // Make list for (Inkscape::XML::Node * child = oldroot->firstChild(); child != NULL; child = child->next()) { if (!strcmp("sodipodi:namedview", child->name())) { + oldroot_namedview = child; for (Inkscape::XML::Node * oldroot_namedview_child = child->firstChild(); oldroot_namedview_child != NULL; oldroot_namedview_child = oldroot_namedview_child->next()) { delete_list.push_back(oldroot_namedview_child); } - break; + } else { + delete_list.push_back(child); } } + if(!oldroot_namedview) + { + g_warning("Error on copy_doc: No namedview on destination document."); + return; + } + // Unparent (delete) for (unsigned int i = 0; i < delete_list.size(); i++) { sp_repr_unparent(delete_list[i]); } + + // Copy + for (Inkscape::XML::Node * child = newroot->firstChild(); + child != NULL; + child = child->next()) { + if (!strcmp("sodipodi:namedview", child->name())) { + newroot_namedview = child; + for (Inkscape::XML::Node * newroot_namedview_child = child->firstChild(); + newroot_namedview_child != NULL; + newroot_namedview_child = newroot_namedview_child->next()) { + oldroot_namedview->appendChild(newroot_namedview_child->duplicate(oldroot->document())); + } + } else { + oldroot->appendChild(child->duplicate(oldroot->document())); + } + } + attribs.clear(); - oldroot->mergeFrom(newroot, "id", true, true); + + // Must explicitly copy namedview attributes. + // Make a list of all attributes of the old namedview node. + for (List iter = oldroot_namedview->attributeList(); iter; ++iter) { + attribs.push_back(g_quark_to_string(iter->key)); + } + + // Delete the attributes of the old namedview node. + for (std::vector::const_iterator it = attribs.begin(); it != attribs.end(); ++it) { + oldroot_namedview->setAttribute(*it, NULL); + } + + // Set the new attributes. + for (List iter = newroot_namedview->attributeList(); iter; ++iter) { + gchar const *name = g_quark_to_string(iter->key); + oldroot_namedview->setAttribute(name, newroot_namedview->attribute(name)); + } + + /** \todo Restore correct layer */ + /** \todo Restore correct selection */ } /** \brief This function checks the stderr file, and if it has data, diff --git a/src/extension/internal/bluredge.cpp b/src/extension/internal/bluredge.cpp index 4bcc5d715e..f04007d00f 100644 --- a/src/extension/internal/bluredge.cpp +++ b/src/extension/internal/bluredge.cpp @@ -53,7 +53,6 @@ BlurEdge::load (Inkscape::Extension::Extension */*module*/) void BlurEdge::effect (Inkscape::Extension::Effect *module, Inkscape::UI::View::View *desktop, Inkscape::Extension::Implementation::ImplementationDocumentCache * /*docCache*/) { - Inkscape::Selection * selection = static_cast(desktop)->selection; float width = module->get_param_float("blur-width"); diff --git a/src/extension/internal/filter/filter.cpp b/src/extension/internal/filter/filter.cpp index 69aec15956..166e5406fb 100644 --- a/src/extension/internal/filter/filter.cpp +++ b/src/extension/internal/filter/filter.cpp @@ -120,6 +120,7 @@ void Filter::effect(Inkscape::Extension::Effect *module, Inkscape::UI::View::Vie if (filterdoc == NULL) { return; // could not parse the XML source of the filter; typically parser will stderr a warning } + //printf("Calling filter effect\n"); Inkscape::Selection * selection = ((SPDesktop *)document)->selection; diff --git a/src/extension/prefdialog.cpp b/src/extension/prefdialog.cpp index 0861f1dc33..0247e18e90 100644 --- a/src/extension/prefdialog.cpp +++ b/src/extension/prefdialog.cpp @@ -18,8 +18,6 @@ // Used to get SP_ACTIVE_DESKTOP #include "inkscape.h" #include "desktop.h" -#include "document.h" -#include "document-undo.h" #include "effect.h" #include "implementation/implementation.h" @@ -63,13 +61,6 @@ PrefDialog::PrefDialog (Glib::ustring name, gchar const * help, Gtk::Widget * co controls = _effect->get_imp()->prefs_effect(_effect, SP_ACTIVE_DESKTOP, &_signal_param_change, NULL); _signal_param_change.connect(sigc::mem_fun(this, &PrefDialog::param_change)); } - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - if (desktop) { - Inkscape::Selection * selection = desktop->getSelection(); - if (selection) { - selection->emptyBackup(); - } - } hbox->pack_start(*controls, true, true, 0); hbox->show(); @@ -179,29 +170,12 @@ PrefDialog::run (void) { void PrefDialog::preview_toggle (void) { - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - SPDocument *document = SP_ACTIVE_DOCUMENT; - Inkscape::Selection * selection = NULL; - bool modified = document->isModifiedSinceSave(); - if(desktop) { - selection = desktop->getSelection(); - if (!selection->isEmpty()) { - selection->setBackup(); - } - } if(_param_preview->get_bool(NULL, NULL)) { + set_modal(true); if (_exEnv == NULL) { - set_modal(true); - if (desktop && selection) { - desktop->on_live_extension = true; - - } _exEnv = new ExecutionEnv(_effect, SP_ACTIVE_DESKTOP, NULL, false, false); _effect->set_execution_env(_exEnv); _exEnv->run(); - if (desktop && selection) { - selection->clear(); - } } } else { set_modal(false); @@ -211,13 +185,8 @@ PrefDialog::preview_toggle (void) { delete _exEnv; _exEnv = NULL; _effect->set_execution_env(_exEnv); - if (desktop && selection) { - selection->restoreBackup(); - desktop->on_live_extension = false; - } } } - document->setModifiedSinceSave(modified); } void diff --git a/src/preferences-skeleton.h b/src/preferences-skeleton.h index 23040fcfd4..ed00092b2c 100644 --- a/src/preferences-skeleton.h +++ b/src/preferences-skeleton.h @@ -323,7 +323,6 @@ static char const preferences_skeleton[] = " clips=\"16711935\"" // 00ff00ff " masks=\"65535\"/>\n" // 0x0000ffff " event_context; - if (INK_IS_NODE_TOOL(ec)) { - tool = static_cast(ec); - } - } - _selected_ids.clear(); - _seldata.clear(); - params.clear(); - auto items = const_cast(this)->items(); - for (auto iter = items.begin(); iter != items.end(); ++iter) { - SPItem *item = *iter; - std::string selected_id; - selected_id += "--id="; - selected_id += item->getId(); - params.push_back(selected_id); - _selected_ids.push_back(item->getId()); - } - if(tool){ - Inkscape::UI::ControlPointSelection *cps = tool->_selected_nodes; - std::list points_list = cps->_points_list; - for (std::list::iterator i = points_list.begin(); i != points_list.end(); ++i) { - Inkscape::UI::Node *node = dynamic_cast(*i); - if (node) { - std::string id = node->nodeList().subpathList().pm().item()->getId(); - - int sp = 0; - bool found_sp = false; - for(Inkscape::UI::SubpathList::iterator i = node->nodeList().subpathList().begin(); i != node->nodeList().subpathList().end(); ++i,++sp){ - if(&**i == &(node->nodeList())){ - found_sp = true; - break; - } - } - int nl=0; - bool found_nl = false; - for (Inkscape::UI::NodeList::iterator j = node->nodeList().begin(); j != node->nodeList().end(); ++j, ++nl){ - if(&*j==node){ - found_nl = true; - break; - } - } - std::ostringstream ss; - ss<< "--selected-nodes=" << id << ":" << sp << ":" << nl; - Glib::ustring selected_nodes = ss.str(); - - if(found_nl && found_sp) { - _seldata.push_back(std::make_pair(id,std::make_pair(sp,nl))); - params.push_back(selected_nodes); - } else { - g_warning("Something went wrong while trying to pass selected nodes to extension. Please report a bug."); - } - } - } - }//end add selected nodes -} - -void -Selection::restoreBackup() -{ - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - SPDocument *document = SP_ACTIVE_DOCUMENT; - Inkscape::UI::Tools::NodeTool *tool = 0; - if (desktop) { - Inkscape::UI::Tools::ToolBase *ec = desktop->event_context; - if (INK_IS_NODE_TOOL(ec)) { - tool = static_cast(ec); - } - } - clear(); - std::vector::iterator it = _selected_ids.begin(); - for (; it!= _selected_ids.end(); ++it){ - SPItem * item = dynamic_cast(document->getObjectById(it->c_str())); - SPDefs * defs = document->getDefs(); - if (item && !defs->isAncestorOf(item)) { - add(item); - } - } - if (tool) { - Inkscape::UI::ControlPointSelection *cps = tool->_selected_nodes; - cps->selectAll(); - std::list points_list = cps->_points_list; - cps->clear(); - Inkscape::UI::Node * node = dynamic_cast(*points_list.begin()); - if (node) { - Inkscape::UI::SubpathList sp = node->nodeList().subpathList(); - for (std::vector > >::iterator l = _seldata.begin(); l != _seldata.end(); ++l) { - SPPath * path = dynamic_cast(document->getObjectById(l->first)); - gint sp_count = 0; - for (Inkscape::UI::SubpathList::iterator j = sp.begin(); j != sp.end(); ++j, ++sp_count) { - if(sp_count == l->second.first) { - gint nt_count = 0; - for (Inkscape::UI::NodeList::iterator k = (*j)->begin(); k != (*j)->end(); ++k, ++nt_count) { - if(nt_count == l->second.second) { - cps->insert(k.ptr()); - break; - } - } - break; - } - } - } - } - points_list.clear(); - } -} - - } /* diff --git a/src/selection.h b/src/selection.h index 989adf6b0e..2b454e9474 100644 --- a/src/selection.h +++ b/src/selection.h @@ -183,23 +183,6 @@ public: return _modified_signal.slots().insert(_modified_signal.slots().begin(), slot); } - /** - * Set a backup of current selection and store it also to be command line readable by extension system - */ - void setBackup(); - /** - * Clear backup of current selection - */ - void emptyBackup(); - /** - * Restore a selection from a existing backup - */ - void restoreBackup(); - /** - * Here store a paramlist when set backup - */ - std::list params; - protected: void _emitSignals(); void _connectSignals(SPObject* object); @@ -229,8 +212,7 @@ private: SPObject* _selection_context; unsigned int _flags; unsigned int _idle; - std::vector > > _seldata; - std::vector _selected_ids; + std::map _modified_connections; sigc::connection _context_release_connection; diff --git a/src/svg/path-string.cpp b/src/svg/path-string.cpp index 2fa2c8f026..7d0092dfaa 100644 --- a/src/svg/path-string.cpp +++ b/src/svg/path-string.cpp @@ -28,7 +28,7 @@ int Inkscape::SVG::PathString::minimumexponent; Inkscape::SVG::PATHSTRING_FORMAT Inkscape::SVG::PathString::format; Inkscape::SVG::PathString::PathString() : - force_repeat_commands(!Inkscape::Preferences::get()->getBool("/options/svgoutput/disable_optimizations" ) && Inkscape::Preferences::get()->getBool("/options/svgoutput/forcerepeatcommands")) + force_repeat_commands(Inkscape::Preferences::get()->getBool("/options/svgoutput/forcerepeatcommands")) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); format = (PATHSTRING_FORMAT)prefs->getIntLimited("/options/svgoutput/pathstring_format", 1, 0, PATHSTRING_FORMAT_SIZE - 1 ); diff --git a/src/svg/svg-color.cpp b/src/svg/svg-color.cpp index 1f26d02b12..d1e91ace12 100644 --- a/src/svg/svg-color.cpp +++ b/src/svg/svg-color.cpp @@ -491,8 +491,7 @@ void sp_svg_write_color(gchar *buf, unsigned const buflen, guint32 const rgba32) Inkscape::Preferences *prefs = Inkscape::Preferences::get(); unsigned const rgb24 = rgba32 >> 8; - if ( prefs->getBool("/options/svgoutput/usenamedcolors") && - !prefs->getBool("/options/svgoutput/disable_optimizations" )) { + if (prefs->getBool("/options/svgoutput/usenamedcolors")) { rgb24_to_css(buf, rgb24); } else { g_snprintf(buf, buflen, "#%06x", rgb24); diff --git a/src/ui/tool/control-point-selection.h b/src/ui/tool/control-point-selection.h index d0cfce8d2f..ec845b1b39 100644 --- a/src/ui/tool/control-point-selection.h +++ b/src/ui/tool/control-point-selection.h @@ -117,8 +117,6 @@ public: void getOriginalPoints(std::vector &pts); void getUnselectedPoints(std::vector &pts); void setOriginalPoints(); - //the purpose of this list is to keep track of first and last selected - std::list _points_list; private: // The functions below are invoked from SelectableControlPoint. @@ -142,7 +140,8 @@ private: double _rotationRadius(Geom::Point const &); set_type _points; - + //the purpose of this list is to keep track of first and last selected + std::list _points_list; set_type _all_points; INK_UNORDERED_MAP _original_positions; INK_UNORDERED_MAP _last_trans; diff --git a/src/ui/tool/selectable-control-point.cpp b/src/ui/tool/selectable-control-point.cpp index 83ed7d38b1..f3f9c0e1e4 100644 --- a/src/ui/tool/selectable-control-point.cpp +++ b/src/ui/tool/selectable-control-point.cpp @@ -87,15 +87,6 @@ bool SelectableControlPoint::clicked(GdkEventButton *event) return true; } -void SelectableControlPoint::select(bool toselect) -{ - if (toselect) { - _selection.insert(this); - } else { - _selection.erase(this); - } -} - void SelectableControlPoint::_takeSelection() { _selection.clear(); diff --git a/src/ui/tool/selectable-control-point.h b/src/ui/tool/selectable-control-point.h index c16f639b1e..362d4addca 100644 --- a/src/ui/tool/selectable-control-point.h +++ b/src/ui/tool/selectable-control-point.h @@ -28,10 +28,8 @@ public: virtual Geom::Rect bounds() const { return Geom::Rect(position(), position()); } - virtual void select(bool toselect); friend class NodeList; - protected: SelectableControlPoint(SPDesktop *d, Geom::Point const &initial_pos, SPAnchorType anchor, diff --git a/src/xml/node.h b/src/xml/node.h index 8d9fc19e4a..29cfdab468 100644 --- a/src/xml/node.h +++ b/src/xml/node.h @@ -384,20 +384,6 @@ public: */ virtual void changeOrder(Node *child, Node *after)=0; - /** - * @brief Remove all elements that not in src node - * @param src The node to check for elemments into this node - * @param key The attribute to use as the identity attribute - */ - virtual void cleanOriginal(Node *src, gchar const *key)=0; - - - /** - * @brief Compare 2 nodes equality - * @param other The other node to compare - * @param recursive Recursive mode check - */ - virtual bool equal(Node const *other, bool recursive)=0; /** * @brief Merge all children of another node with the current * @@ -411,11 +397,8 @@ public: * * @param src The node to merge into this node * @param key The attribute to use as the identity attribute - * @param noid If true process noid items - * @param key If clean callback to cleanOriginal */ - - virtual void mergeFrom(Node const *src, char const *key, bool extension = false, bool clean = false)=0; + virtual void mergeFrom(Node const *src, char const *key)=0; /*@}*/ diff --git a/src/xml/repr-io.cpp b/src/xml/repr-io.cpp index c7b483dcb3..2ff9d47769 100644 --- a/src/xml/repr-io.cpp +++ b/src/xml/repr-io.cpp @@ -872,10 +872,7 @@ static void sp_repr_write_stream_root_element(Node *repr, Writer &out, if (clean) sp_attribute_clean_tree( repr ); // Sort attributes in a canonical order (helps with "diffing" SVG files). - bool sort = prefs->getBool("/options/svgoutput/disable_optimizations"); - if (!sort) { - sort = prefs->getBool("/options/svgoutput/sort_attributes"); - } + bool sort = prefs->getBool("/options/svgoutput/sort_attributes"); if (sort) sp_attribute_sort_tree( repr ); Glib::QueryQuark xml_prefix=g_quark_from_static_string("xml"); diff --git a/src/xml/simple-node.cpp b/src/xml/simple-node.cpp index a1a7127cca..78fc52a279 100644 --- a/src/xml/simple-node.cpp +++ b/src/xml/simple-node.cpp @@ -315,7 +315,7 @@ SimpleNode::setAttribute(gchar const *name, gchar const *value, bool const /*is_ // Check usefulness of attributes on elements in the svg namespace, optionally don't add them to tree. Glib::ustring element = g_quark_to_string(_name); - //g_message("setAttribute: %s: %s: %s", element.c_str(), name, value); + // g_message("setAttribute: %s: %s: %s", element.c_str(), name, value); gchar* cleaned_value = g_strdup( value ); // Only check elements in SVG name space and don't block setting attribute to NULL. @@ -645,112 +645,28 @@ Node *SimpleNode::root() { } } -void SimpleNode::cleanOriginal(Node *src, gchar const *key){ - std::vector to_delete; - for ( Node *child = this->firstChild() ; child != NULL ; child = child->next() ) - { - gchar const *id = child->attribute(key); - if (id) { - Node *rch = sp_repr_lookup_child(src, key, id); - if (rch) { - child->cleanOriginal(rch, key); - } else { - to_delete.push_back(child); - } - } else { - to_delete.push_back(child); - } - } - for ( std::vector::iterator i = to_delete.begin(); i != to_delete.end(); ++i) { - removeChild(*i); - } -} - -bool SimpleNode::equal(Node const *other, bool recursive) { - if(strcmp(name(),other->name())!= 0){ - return false; - } - if (!(strcmp("sodipodi:namedview", name()))) { - return true; - } - guint orig_length = 0; - guint other_length = 0; - - if(content() && other->content() && strcmp(content(), other->content()) != 0){ - return false; - } - for (List orig_attr = attributeList(); orig_attr; ++orig_attr) { - for (List other_attr = other->attributeList(); other_attr; ++other_attr) { - const gchar * key_orig = g_quark_to_string(orig_attr->key); - const gchar * key_other = g_quark_to_string(other_attr->key); - if (!strcmp(key_orig, key_other) && - !strcmp(orig_attr->value, other_attr->value)) - { - other_length++; - break; - } - } - orig_length++; - } - if (orig_length != other_length) { - return false; - } - if (recursive) { - //NOTE: for faster the childs need to be in the same order - Node const *other_child = other->firstChild(); - for ( Node *child = firstChild(); - child; - child = child->next()) - { - if (!child->equal(other_child, recursive)) { - return false; - } - other_child = other_child->next(); - if(!other_child) { - return false; - } - } - } - return true; -} - -void SimpleNode::mergeFrom(Node const *src, gchar const *key, bool extension, bool clean) { +void SimpleNode::mergeFrom(Node const *src, gchar const *key) { g_return_if_fail(src != NULL); g_return_if_fail(key != NULL); g_assert(src != this); setContent(src->content()); - if(_parent) { - setPosition(src->position()); - } - - if (clean) { - Node * srcp = const_cast(src); - cleanOriginal(srcp, key); - } for ( Node const *child = src->firstChild() ; child != NULL ; child = child->next() ) { gchar const *id = child->attribute(key); if (id) { Node *rch=sp_repr_lookup_child(this, key, id); - if (rch && (!extension || rch->equal(child, false))) { - rch->mergeFrom(child, key, extension); + if (rch) { + rch->mergeFrom(child, key); } else { - if(rch) { - removeChild(rch); - } - guint pos = child->position(); rch = child->duplicate(_document); appendChild(rch); - rch->setPosition(pos); rch->release(); } } else { - guint pos = child->position(); Node *rch=child->duplicate(_document); appendChild(rch); - rch->setPosition(pos); rch->release(); } } diff --git a/src/xml/simple-node.h b/src/xml/simple-node.h index fd41e53a88..f2cfa953c9 100644 --- a/src/xml/simple-node.h +++ b/src/xml/simple-node.h @@ -91,9 +91,7 @@ public: char const *content() const; void setContent(char const *value); - void cleanOriginal(Node *src, gchar const *key); - bool equal(Node const *other, bool recursive); - void mergeFrom(Node const *src, char const *key, bool extension = false, bool clean = false); + void mergeFrom(Node const *src, char const *key); Inkscape::Util::List attributeList() const { return _attributes; -- GitLab From 88e4d87b141e9552b1bc58cbd708b7f9c6693d1a Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Wed, 9 May 2018 21:45:52 +0200 Subject: [PATCH 12/14] Reset code to reaply --- src/selection.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/selection.cpp b/src/selection.cpp index a2080e6fb2..b8dffb4aee 100644 --- a/src/selection.cpp +++ b/src/selection.cpp @@ -28,7 +28,6 @@ #include "object/sp-shape.h" #include "object/sp-path.h" -#include "object/sp-defs.h" #include "xml/repr.h" -- GitLab From e312c345ba946b59dcd228d1e4d382b51aa37e9d Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Wed, 9 May 2018 21:47:33 +0200 Subject: [PATCH 13/14] Apply fixed --- src/attribute-rel-util.cpp | 9 +- src/desktop.cpp | 1 + src/desktop.h | 2 +- src/extension/execution-env.cpp | 37 ++--- src/extension/execution-env.h | 3 - .../implementation/implementation.cpp | 17 +++ src/extension/implementation/implementation.h | 7 +- src/extension/implementation/script.cpp | 119 +++------------- src/extension/prefdialog.cpp | 33 ++++- src/preferences-skeleton.h | 1 + src/selection.cpp | 130 +++++++++++++++++- src/selection.h | 20 ++- src/svg/path-string.cpp | 2 +- src/svg/svg-color.cpp | 3 +- src/ui/tool/control-point-selection.h | 5 +- src/ui/tool/selectable-control-point.cpp | 9 ++ src/ui/tool/selectable-control-point.h | 2 + src/xml/node.h | 19 ++- src/xml/repr-io.cpp | 3 + src/xml/simple-node.cpp | 92 ++++++++++++- src/xml/simple-node.h | 4 +- 21 files changed, 363 insertions(+), 155 deletions(-) diff --git a/src/attribute-rel-util.cpp b/src/attribute-rel-util.cpp index 42b6bebf25..d377e5edb3 100644 --- a/src/attribute-rel-util.cpp +++ b/src/attribute-rel-util.cpp @@ -34,11 +34,14 @@ unsigned int sp_attribute_clean_get_prefs() { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); unsigned int flags = 0; if( prefs->getBool("/options/svgoutput/incorrect_attributes_warn") ) flags += SP_ATTR_CLEAN_ATTR_WARN; - if( prefs->getBool("/options/svgoutput/incorrect_attributes_remove") ) flags += SP_ATTR_CLEAN_ATTR_REMOVE; + if( prefs->getBool("/options/svgoutput/incorrect_attributes_remove") && + !prefs->getBool("/options/svgoutput/disable_optimizations" ) ) flags += SP_ATTR_CLEAN_ATTR_REMOVE; if( prefs->getBool("/options/svgoutput/incorrect_style_properties_warn") ) flags += SP_ATTR_CLEAN_STYLE_WARN; - if( prefs->getBool("/options/svgoutput/incorrect_style_properties_remove" ) ) flags += SP_ATTR_CLEAN_STYLE_REMOVE; + if( prefs->getBool("/options/svgoutput/incorrect_style_properties_remove" ) && + !prefs->getBool("/options/svgoutput/disable_optimizations" ) ) flags += SP_ATTR_CLEAN_STYLE_REMOVE; if( prefs->getBool("/options/svgoutput/style_defaults_warn") ) flags += SP_ATTR_CLEAN_DEFAULT_WARN; - if( prefs->getBool("/options/svgoutput/style_defaults_remove") ) flags += SP_ATTR_CLEAN_DEFAULT_REMOVE; + if( prefs->getBool("/options/svgoutput/style_defaults_remove") && + !prefs->getBool("/options/svgoutput/disable_optimizations" ) ) flags += SP_ATTR_CLEAN_DEFAULT_REMOVE; return flags; } diff --git a/src/desktop.cpp b/src/desktop.cpp index 47c82b6d93..72739305ae 100644 --- a/src/desktop.cpp +++ b/src/desktop.cpp @@ -117,6 +117,7 @@ SPDesktop::SPDesktop() : waiting_cursor( false ), showing_dialogs ( false ), guides_active( false ), + on_live_extension(false), gr_item( NULL ), gr_point_type( POINT_LG_BEGIN ), gr_point_i( 0 ), diff --git a/src/desktop.h b/src/desktop.h index f4eecf8b71..8b20195db1 100644 --- a/src/desktop.h +++ b/src/desktop.h @@ -188,9 +188,9 @@ public: unsigned int interaction_disabled_counter; bool waiting_cursor; bool showing_dialogs; - /// \todo fixme: This has to be implemented in different way */ guint guides_active : 1; + bool on_live_extension; // storage for selected dragger used by GrDrag as it's // created and deleted by tools diff --git a/src/extension/execution-env.cpp b/src/extension/execution-env.cpp index 7e233d2151..bde04d924f 100644 --- a/src/extension/execution-env.cpp +++ b/src/extension/execution-env.cpp @@ -22,6 +22,8 @@ #include "selection.h" #include "effect.h" #include "document.h" +#include "desktop.h" +#include "inkscape.h" #include "document-undo.h" #include "desktop.h" #include "object/sp-namedview.h" @@ -52,19 +54,6 @@ ExecutionEnv::ExecutionEnv (Effect * effect, Inkscape::UI::View::View * doc, Imp _show_working(show_working), _show_errors(show_errors) { - SPDesktop *desktop = (SPDesktop *)_doc; - sp_namedview_document_from_window(desktop); - - if (desktop != NULL) { - 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); - //std::cout << "Selected: " << selected_id << std::endl; - } - } - genDocCache(); return; @@ -189,24 +178,14 @@ ExecutionEnv::commit (void) { void ExecutionEnv::reselect (void) { - if (_doc == NULL) { return; } - SPDocument * doc = _doc->doc(); - if (doc == NULL) { return; } - - SPDesktop *desktop = (SPDesktop *)_doc; - sp_namedview_document_from_window(desktop); - - if (desktop == NULL) { return; } - - Inkscape::Selection * selection = desktop->getSelection(); - - for (std::list::iterator i = _selected.begin(); i != _selected.end(); ++i) { - SPObject * obj = doc->getObjectById(i->c_str()); - if (obj != NULL) { - selection->add(obj); + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + Inkscape::Selection * selection = NULL; + if(desktop) { + selection = desktop->getSelection(); + if (!desktop->on_live_extension) { + selection->restoreBackup(); } } - return; } diff --git a/src/extension/execution-env.h b/src/extension/execution-env.h index b1a3a8ea22..8af97cd923 100644 --- a/src/extension/execution-env.h +++ b/src/extension/execution-env.h @@ -54,9 +54,6 @@ private: Glib::RefPtr _mainloop; /** \brief The document that we're working on. */ Inkscape::UI::View::View * _doc; - /** \brief A list of the IDs of all the selected objects before - we started to work on this document. */ - std::list _selected; /** \brief A document cache if we were passed one. */ Implementation::ImplementationDocumentCache * _docCache; diff --git a/src/extension/implementation/implementation.cpp b/src/extension/implementation/implementation.cpp index 6e6100d2b6..e05dbf3c43 100644 --- a/src/extension/implementation/implementation.cpp +++ b/src/extension/implementation/implementation.cpp @@ -27,6 +27,23 @@ namespace Inkscape { namespace Extension { namespace Implementation { +ImplementationDocumentCache::ImplementationDocumentCache (Inkscape::UI::View::View * view) + : _view(view) +{ + SPDesktop *desktop = (SPDesktop*)view; + Inkscape::Selection * selection = NULL; + if (desktop) { + selection = desktop->getSelection(); + if (selection && !selection->params.empty()) { + selection->restoreBackup(); + if (!desktop->on_live_extension) { + selection->emptyBackup(); + } + } + } + return; +} + Gtk::Widget * Implementation::prefs_input(Inkscape::Extension::Input *module, gchar const */*filename*/) { return module->autogui(NULL, NULL); diff --git a/src/extension/implementation/implementation.h b/src/extension/implementation/implementation.h index 1232ae0c87..5bb909ef26 100644 --- a/src/extension/implementation/implementation.h +++ b/src/extension/implementation/implementation.h @@ -56,11 +56,8 @@ class ImplementationDocumentCache { */ Inkscape::UI::View::View * _view; public: - ImplementationDocumentCache (Inkscape::UI::View::View * view) : - _view(view) - { - return; - }; + ImplementationDocumentCache (Inkscape::UI::View::View * view); + virtual ~ImplementationDocumentCache ( ) { return; }; Inkscape::UI::View::View const * view ( ) { return _view; }; }; diff --git a/src/extension/implementation/script.cpp b/src/extension/implementation/script.cpp index f25c8a5d69..1e8556de77 100644 --- a/src/extension/implementation/script.cpp +++ b/src/extension/implementation/script.cpp @@ -418,10 +418,12 @@ ScriptDocCache::ScriptDocCache (Inkscape::UI::View::View * view) : SPDesktop *desktop = (SPDesktop *) view; sp_namedview_document_from_window(desktop); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setBool("/options/svgoutput/disable_optimizations", true); Inkscape::Extension::save( Inkscape::Extension::db.get(SP_MODULE_KEY_OUTPUT_SVG_INKSCAPE), view->doc(), _filename.c_str(), false, false, false, Inkscape::Extension::FILE_SAVE_METHOD_TEMPORARY); - + prefs->setBool("/options/svgoutput/disable_optimizations", false); return; } @@ -686,57 +688,14 @@ void Script::effect(Inkscape::Extension::Effect *module, return; } - 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(); - params.push_front(selected_id); - } - - {//add selected nodes - Inkscape::UI::Tools::NodeTool *tool = 0; - if (SP_ACTIVE_DESKTOP ) { - Inkscape::UI::Tools::ToolBase *ec = SP_ACTIVE_DESKTOP->event_context; - if (INK_IS_NODE_TOOL(ec)) { - tool = static_cast(ec); + if (desktop) { + Inkscape::Selection * selection = desktop->getSelection(); + if (!selection->isEmpty()) { + selection->setBackup(); } + params = selection->params; + module->paramListString(params); } - - if(tool){ - Inkscape::UI::ControlPointSelection *cps = tool->_selected_nodes; - for (Inkscape::UI::ControlPointSelection::iterator i = cps->begin(); i != cps->end(); ++i) { - Inkscape::UI::Node *node = dynamic_cast(*i); - if (node) { - std::string id = node->nodeList().subpathList().pm().item()->getId(); - - int sp = 0; - bool found_sp = false; - for(Inkscape::UI::SubpathList::iterator i = node->nodeList().subpathList().begin(); i != node->nodeList().subpathList().end(); ++i,++sp){ - if(&**i == &(node->nodeList())){ - found_sp = true; - break; - } - } - int nl=0; - bool found_nl = false; - for (Inkscape::UI::NodeList::iterator j = node->nodeList().begin(); j != node->nodeList().end(); ++j, ++nl){ - if(&*j==node){ - found_nl = true; - break; - } - } - std::ostringstream ss; - ss<< "--selected-nodes=" << id << ":" << sp << ":" << nl; - Glib::ustring selected = ss.str(); - - if(found_nl && found_sp)params.push_front(selected); - else g_warning("Something went wrong while trying to pass selected nodes to extension. Please report a bug."); - } - } - } - }//end add selected nodes file_listener fileout; int data_read = execute(command, params, dc->_filename, fileout); @@ -790,6 +749,7 @@ void Script::effect(Inkscape::Extension::Effect *module, layer = document->getObjectById(g_quark_to_string(nv->default_layer_id)); } } + desktop->showGrids(nv->grids_visible); } sp_namedview_update_layers_from_document(desktop); @@ -798,6 +758,14 @@ void Script::effect(Inkscape::Extension::Effect *module, //set the current layer desktop->setCurrentLayer(layer); } + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if (desktop) { + Inkscape::Selection * selection = desktop->getSelection(); + if (selection && selection->isEmpty() && !desktop->on_live_extension) { + selection->restoreBackup(); + selection->emptyBackup(); + } + } } mydoc->release(); } @@ -859,80 +827,33 @@ void Script::copy_doc (Inkscape::XML::Node * oldroot, Inkscape::XML::Node * newr oldroot->setAttribute(name, newroot->attribute(name)); } - // Question: Why is the "sodipodi:namedview" special? Treating it as a normal // elmement results in crashes. // Seems to be a bug: // http://inkscape.13.x6.nabble.com/Effect-that-modifies-the-document-properties-tt2822126.html std::vector delete_list; - Inkscape::XML::Node * oldroot_namedview = NULL; - Inkscape::XML::Node * newroot_namedview = NULL; // Make list for (Inkscape::XML::Node * child = oldroot->firstChild(); child != NULL; child = child->next()) { if (!strcmp("sodipodi:namedview", child->name())) { - oldroot_namedview = child; for (Inkscape::XML::Node * oldroot_namedview_child = child->firstChild(); oldroot_namedview_child != NULL; oldroot_namedview_child = oldroot_namedview_child->next()) { delete_list.push_back(oldroot_namedview_child); } - } else { - delete_list.push_back(child); + break; } } - if(!oldroot_namedview) - { - g_warning("Error on copy_doc: No namedview on destination document."); - return; - } - // Unparent (delete) for (unsigned int i = 0; i < delete_list.size(); i++) { sp_repr_unparent(delete_list[i]); } - - // Copy - for (Inkscape::XML::Node * child = newroot->firstChild(); - child != NULL; - child = child->next()) { - if (!strcmp("sodipodi:namedview", child->name())) { - newroot_namedview = child; - for (Inkscape::XML::Node * newroot_namedview_child = child->firstChild(); - newroot_namedview_child != NULL; - newroot_namedview_child = newroot_namedview_child->next()) { - oldroot_namedview->appendChild(newroot_namedview_child->duplicate(oldroot->document())); - } - } else { - oldroot->appendChild(child->duplicate(oldroot->document())); - } - } - attribs.clear(); - - // Must explicitly copy namedview attributes. - // Make a list of all attributes of the old namedview node. - for (List iter = oldroot_namedview->attributeList(); iter; ++iter) { - attribs.push_back(g_quark_to_string(iter->key)); - } - - // Delete the attributes of the old namedview node. - for (std::vector::const_iterator it = attribs.begin(); it != attribs.end(); ++it) { - oldroot_namedview->setAttribute(*it, NULL); - } - - // Set the new attributes. - for (List iter = newroot_namedview->attributeList(); iter; ++iter) { - gchar const *name = g_quark_to_string(iter->key); - oldroot_namedview->setAttribute(name, newroot_namedview->attribute(name)); - } - - /** \todo Restore correct layer */ - /** \todo Restore correct selection */ + oldroot->mergeFrom(newroot, "id", true, true); } /** \brief This function checks the stderr file, and if it has data, diff --git a/src/extension/prefdialog.cpp b/src/extension/prefdialog.cpp index 0247e18e90..0861f1dc33 100644 --- a/src/extension/prefdialog.cpp +++ b/src/extension/prefdialog.cpp @@ -18,6 +18,8 @@ // Used to get SP_ACTIVE_DESKTOP #include "inkscape.h" #include "desktop.h" +#include "document.h" +#include "document-undo.h" #include "effect.h" #include "implementation/implementation.h" @@ -61,6 +63,13 @@ PrefDialog::PrefDialog (Glib::ustring name, gchar const * help, Gtk::Widget * co controls = _effect->get_imp()->prefs_effect(_effect, SP_ACTIVE_DESKTOP, &_signal_param_change, NULL); _signal_param_change.connect(sigc::mem_fun(this, &PrefDialog::param_change)); } + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if (desktop) { + Inkscape::Selection * selection = desktop->getSelection(); + if (selection) { + selection->emptyBackup(); + } + } hbox->pack_start(*controls, true, true, 0); hbox->show(); @@ -170,12 +179,29 @@ PrefDialog::run (void) { void PrefDialog::preview_toggle (void) { + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + SPDocument *document = SP_ACTIVE_DOCUMENT; + Inkscape::Selection * selection = NULL; + bool modified = document->isModifiedSinceSave(); + if(desktop) { + selection = desktop->getSelection(); + if (!selection->isEmpty()) { + selection->setBackup(); + } + } if(_param_preview->get_bool(NULL, NULL)) { - set_modal(true); if (_exEnv == NULL) { + set_modal(true); + if (desktop && selection) { + desktop->on_live_extension = true; + + } _exEnv = new ExecutionEnv(_effect, SP_ACTIVE_DESKTOP, NULL, false, false); _effect->set_execution_env(_exEnv); _exEnv->run(); + if (desktop && selection) { + selection->clear(); + } } } else { set_modal(false); @@ -185,8 +211,13 @@ PrefDialog::preview_toggle (void) { delete _exEnv; _exEnv = NULL; _effect->set_execution_env(_exEnv); + if (desktop && selection) { + selection->restoreBackup(); + desktop->on_live_extension = false; + } } } + document->setModifiedSinceSave(modified); } void diff --git a/src/preferences-skeleton.h b/src/preferences-skeleton.h index ed00092b2c..23040fcfd4 100644 --- a/src/preferences-skeleton.h +++ b/src/preferences-skeleton.h @@ -323,6 +323,7 @@ static char const preferences_skeleton[] = " clips=\"16711935\"" // 00ff00ff " masks=\"65535\"/>\n" // 0x0000ffff " event_context; + if (INK_IS_NODE_TOOL(ec)) { + tool = static_cast(ec); + } + } + _selected_ids.clear(); + _seldata.clear(); + params.clear(); + auto items = const_cast(this)->items(); + for (auto iter = items.begin(); iter != items.end(); ++iter) { + SPItem *item = *iter; + std::string selected_id; + selected_id += "--id="; + selected_id += item->getId(); + params.push_back(selected_id); + _selected_ids.push_back(item->getId()); + } + if(tool){ + Inkscape::UI::ControlPointSelection *cps = tool->_selected_nodes; + std::list points_list = cps->_points_list; + for (std::list::iterator i = points_list.begin(); i != points_list.end(); ++i) { + Inkscape::UI::Node *node = dynamic_cast(*i); + if (node) { + std::string id = node->nodeList().subpathList().pm().item()->getId(); + + int sp = 0; + bool found_sp = false; + for(Inkscape::UI::SubpathList::iterator i = node->nodeList().subpathList().begin(); i != node->nodeList().subpathList().end(); ++i,++sp){ + if(&**i == &(node->nodeList())){ + found_sp = true; + break; + } + } + int nl=0; + bool found_nl = false; + for (Inkscape::UI::NodeList::iterator j = node->nodeList().begin(); j != node->nodeList().end(); ++j, ++nl){ + if(&*j==node){ + found_nl = true; + break; + } + } + std::ostringstream ss; + ss<< "--selected-nodes=" << id << ":" << sp << ":" << nl; + Glib::ustring selected_nodes = ss.str(); + + if(found_nl && found_sp) { + _seldata.push_back(std::make_pair(id,std::make_pair(sp,nl))); + params.push_back(selected_nodes); + } else { + g_warning("Something went wrong while trying to pass selected nodes to extension. Please report a bug."); + } + } + } + }//end add selected nodes +} + +void +Selection::restoreBackup() +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + SPDocument *document = SP_ACTIVE_DOCUMENT; + Inkscape::UI::Tools::NodeTool *tool = 0; + if (desktop) { + Inkscape::UI::Tools::ToolBase *ec = desktop->event_context; + if (INK_IS_NODE_TOOL(ec)) { + tool = static_cast(ec); + } + } + clear(); + std::vector::iterator it = _selected_ids.begin(); + for (; it!= _selected_ids.end(); ++it){ + SPItem * item = dynamic_cast(document->getObjectById(it->c_str())); + SPDefs * defs = document->getDefs(); + if (item && !defs->isAncestorOf(item)) { + add(item); + } + } + if (tool) { + Inkscape::UI::ControlPointSelection *cps = tool->_selected_nodes; + cps->selectAll(); + std::list points_list = cps->_points_list; + cps->clear(); + Inkscape::UI::Node * node = dynamic_cast(*points_list.begin()); + if (node) { + Inkscape::UI::SubpathList sp = node->nodeList().subpathList(); + for (std::vector > >::iterator l = _seldata.begin(); l != _seldata.end(); ++l) { + SPPath * path = dynamic_cast(document->getObjectById(l->first)); + gint sp_count = 0; + for (Inkscape::UI::SubpathList::iterator j = sp.begin(); j != sp.end(); ++j, ++sp_count) { + if(sp_count == l->second.first) { + gint nt_count = 0; + for (Inkscape::UI::NodeList::iterator k = (*j)->begin(); k != (*j)->end(); ++k, ++nt_count) { + if(nt_count == l->second.second) { + cps->insert(k.ptr()); + break; + } + } + break; + } + } + } + } + points_list.clear(); + } +} + + } /* diff --git a/src/selection.h b/src/selection.h index 2b454e9474..989adf6b0e 100644 --- a/src/selection.h +++ b/src/selection.h @@ -183,6 +183,23 @@ public: return _modified_signal.slots().insert(_modified_signal.slots().begin(), slot); } + /** + * Set a backup of current selection and store it also to be command line readable by extension system + */ + void setBackup(); + /** + * Clear backup of current selection + */ + void emptyBackup(); + /** + * Restore a selection from a existing backup + */ + void restoreBackup(); + /** + * Here store a paramlist when set backup + */ + std::list params; + protected: void _emitSignals(); void _connectSignals(SPObject* object); @@ -212,7 +229,8 @@ private: SPObject* _selection_context; unsigned int _flags; unsigned int _idle; - + std::vector > > _seldata; + std::vector _selected_ids; std::map _modified_connections; sigc::connection _context_release_connection; diff --git a/src/svg/path-string.cpp b/src/svg/path-string.cpp index 7d0092dfaa..2fa2c8f026 100644 --- a/src/svg/path-string.cpp +++ b/src/svg/path-string.cpp @@ -28,7 +28,7 @@ int Inkscape::SVG::PathString::minimumexponent; Inkscape::SVG::PATHSTRING_FORMAT Inkscape::SVG::PathString::format; Inkscape::SVG::PathString::PathString() : - force_repeat_commands(Inkscape::Preferences::get()->getBool("/options/svgoutput/forcerepeatcommands")) + force_repeat_commands(!Inkscape::Preferences::get()->getBool("/options/svgoutput/disable_optimizations" ) && Inkscape::Preferences::get()->getBool("/options/svgoutput/forcerepeatcommands")) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); format = (PATHSTRING_FORMAT)prefs->getIntLimited("/options/svgoutput/pathstring_format", 1, 0, PATHSTRING_FORMAT_SIZE - 1 ); diff --git a/src/svg/svg-color.cpp b/src/svg/svg-color.cpp index d1e91ace12..1f26d02b12 100644 --- a/src/svg/svg-color.cpp +++ b/src/svg/svg-color.cpp @@ -491,7 +491,8 @@ void sp_svg_write_color(gchar *buf, unsigned const buflen, guint32 const rgba32) Inkscape::Preferences *prefs = Inkscape::Preferences::get(); unsigned const rgb24 = rgba32 >> 8; - if (prefs->getBool("/options/svgoutput/usenamedcolors")) { + if ( prefs->getBool("/options/svgoutput/usenamedcolors") && + !prefs->getBool("/options/svgoutput/disable_optimizations" )) { rgb24_to_css(buf, rgb24); } else { g_snprintf(buf, buflen, "#%06x", rgb24); diff --git a/src/ui/tool/control-point-selection.h b/src/ui/tool/control-point-selection.h index ec845b1b39..d0cfce8d2f 100644 --- a/src/ui/tool/control-point-selection.h +++ b/src/ui/tool/control-point-selection.h @@ -117,6 +117,8 @@ public: void getOriginalPoints(std::vector &pts); void getUnselectedPoints(std::vector &pts); void setOriginalPoints(); + //the purpose of this list is to keep track of first and last selected + std::list _points_list; private: // The functions below are invoked from SelectableControlPoint. @@ -140,8 +142,7 @@ private: double _rotationRadius(Geom::Point const &); set_type _points; - //the purpose of this list is to keep track of first and last selected - std::list _points_list; + set_type _all_points; INK_UNORDERED_MAP _original_positions; INK_UNORDERED_MAP _last_trans; diff --git a/src/ui/tool/selectable-control-point.cpp b/src/ui/tool/selectable-control-point.cpp index f3f9c0e1e4..83ed7d38b1 100644 --- a/src/ui/tool/selectable-control-point.cpp +++ b/src/ui/tool/selectable-control-point.cpp @@ -87,6 +87,15 @@ bool SelectableControlPoint::clicked(GdkEventButton *event) return true; } +void SelectableControlPoint::select(bool toselect) +{ + if (toselect) { + _selection.insert(this); + } else { + _selection.erase(this); + } +} + void SelectableControlPoint::_takeSelection() { _selection.clear(); diff --git a/src/ui/tool/selectable-control-point.h b/src/ui/tool/selectable-control-point.h index 362d4addca..c16f639b1e 100644 --- a/src/ui/tool/selectable-control-point.h +++ b/src/ui/tool/selectable-control-point.h @@ -28,8 +28,10 @@ public: virtual Geom::Rect bounds() const { return Geom::Rect(position(), position()); } + virtual void select(bool toselect); friend class NodeList; + protected: SelectableControlPoint(SPDesktop *d, Geom::Point const &initial_pos, SPAnchorType anchor, diff --git a/src/xml/node.h b/src/xml/node.h index 29cfdab468..8d9fc19e4a 100644 --- a/src/xml/node.h +++ b/src/xml/node.h @@ -384,6 +384,20 @@ public: */ virtual void changeOrder(Node *child, Node *after)=0; + /** + * @brief Remove all elements that not in src node + * @param src The node to check for elemments into this node + * @param key The attribute to use as the identity attribute + */ + virtual void cleanOriginal(Node *src, gchar const *key)=0; + + + /** + * @brief Compare 2 nodes equality + * @param other The other node to compare + * @param recursive Recursive mode check + */ + virtual bool equal(Node const *other, bool recursive)=0; /** * @brief Merge all children of another node with the current * @@ -397,8 +411,11 @@ public: * * @param src The node to merge into this node * @param key The attribute to use as the identity attribute + * @param noid If true process noid items + * @param key If clean callback to cleanOriginal */ - virtual void mergeFrom(Node const *src, char const *key)=0; + + virtual void mergeFrom(Node const *src, char const *key, bool extension = false, bool clean = false)=0; /*@}*/ diff --git a/src/xml/repr-io.cpp b/src/xml/repr-io.cpp index 2ff9d47769..4873fd4e95 100644 --- a/src/xml/repr-io.cpp +++ b/src/xml/repr-io.cpp @@ -873,6 +873,9 @@ static void sp_repr_write_stream_root_element(Node *repr, Writer &out, // Sort attributes in a canonical order (helps with "diffing" SVG files). bool sort = prefs->getBool("/options/svgoutput/sort_attributes"); + if (sort) { + sort = !prefs->getBool("/options/svgoutput/disable_optimizations"); + } if (sort) sp_attribute_sort_tree( repr ); Glib::QueryQuark xml_prefix=g_quark_from_static_string("xml"); diff --git a/src/xml/simple-node.cpp b/src/xml/simple-node.cpp index 78fc52a279..a1a7127cca 100644 --- a/src/xml/simple-node.cpp +++ b/src/xml/simple-node.cpp @@ -315,7 +315,7 @@ SimpleNode::setAttribute(gchar const *name, gchar const *value, bool const /*is_ // Check usefulness of attributes on elements in the svg namespace, optionally don't add them to tree. Glib::ustring element = g_quark_to_string(_name); - // g_message("setAttribute: %s: %s: %s", element.c_str(), name, value); + //g_message("setAttribute: %s: %s: %s", element.c_str(), name, value); gchar* cleaned_value = g_strdup( value ); // Only check elements in SVG name space and don't block setting attribute to NULL. @@ -645,28 +645,112 @@ Node *SimpleNode::root() { } } -void SimpleNode::mergeFrom(Node const *src, gchar const *key) { +void SimpleNode::cleanOriginal(Node *src, gchar const *key){ + std::vector to_delete; + for ( Node *child = this->firstChild() ; child != NULL ; child = child->next() ) + { + gchar const *id = child->attribute(key); + if (id) { + Node *rch = sp_repr_lookup_child(src, key, id); + if (rch) { + child->cleanOriginal(rch, key); + } else { + to_delete.push_back(child); + } + } else { + to_delete.push_back(child); + } + } + for ( std::vector::iterator i = to_delete.begin(); i != to_delete.end(); ++i) { + removeChild(*i); + } +} + +bool SimpleNode::equal(Node const *other, bool recursive) { + if(strcmp(name(),other->name())!= 0){ + return false; + } + if (!(strcmp("sodipodi:namedview", name()))) { + return true; + } + guint orig_length = 0; + guint other_length = 0; + + if(content() && other->content() && strcmp(content(), other->content()) != 0){ + return false; + } + for (List orig_attr = attributeList(); orig_attr; ++orig_attr) { + for (List other_attr = other->attributeList(); other_attr; ++other_attr) { + const gchar * key_orig = g_quark_to_string(orig_attr->key); + const gchar * key_other = g_quark_to_string(other_attr->key); + if (!strcmp(key_orig, key_other) && + !strcmp(orig_attr->value, other_attr->value)) + { + other_length++; + break; + } + } + orig_length++; + } + if (orig_length != other_length) { + return false; + } + if (recursive) { + //NOTE: for faster the childs need to be in the same order + Node const *other_child = other->firstChild(); + for ( Node *child = firstChild(); + child; + child = child->next()) + { + if (!child->equal(other_child, recursive)) { + return false; + } + other_child = other_child->next(); + if(!other_child) { + return false; + } + } + } + return true; +} + +void SimpleNode::mergeFrom(Node const *src, gchar const *key, bool extension, bool clean) { g_return_if_fail(src != NULL); g_return_if_fail(key != NULL); g_assert(src != this); setContent(src->content()); + if(_parent) { + setPosition(src->position()); + } + + if (clean) { + Node * srcp = const_cast(src); + cleanOriginal(srcp, key); + } for ( Node const *child = src->firstChild() ; child != NULL ; child = child->next() ) { gchar const *id = child->attribute(key); if (id) { Node *rch=sp_repr_lookup_child(this, key, id); - if (rch) { - rch->mergeFrom(child, key); + if (rch && (!extension || rch->equal(child, false))) { + rch->mergeFrom(child, key, extension); } else { + if(rch) { + removeChild(rch); + } + guint pos = child->position(); rch = child->duplicate(_document); appendChild(rch); + rch->setPosition(pos); rch->release(); } } else { + guint pos = child->position(); Node *rch=child->duplicate(_document); appendChild(rch); + rch->setPosition(pos); rch->release(); } } diff --git a/src/xml/simple-node.h b/src/xml/simple-node.h index f2cfa953c9..fd41e53a88 100644 --- a/src/xml/simple-node.h +++ b/src/xml/simple-node.h @@ -91,7 +91,9 @@ public: char const *content() const; void setContent(char const *value); - void mergeFrom(Node const *src, char const *key); + void cleanOriginal(Node *src, gchar const *key); + bool equal(Node const *other, bool recursive); + void mergeFrom(Node const *src, char const *key, bool extension = false, bool clean = false); Inkscape::Util::List attributeList() const { return _attributes; -- GitLab From 99f25194657838f3bac55c38dc7edde802c9d2b1 Mon Sep 17 00:00:00 2001 From: Jabiertxo Arraiza Cenoz Date: Thu, 10 May 2018 17:22:10 +0200 Subject: [PATCH 14/14] Improve sort handling in XML --- src/xml/repr-io.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/xml/repr-io.cpp b/src/xml/repr-io.cpp index 4873fd4e95..519b30cd44 100644 --- a/src/xml/repr-io.cpp +++ b/src/xml/repr-io.cpp @@ -871,11 +871,8 @@ static void sp_repr_write_stream_root_element(Node *repr, Writer &out, bool clean = prefs->getBool("/options/svgoutput/check_on_writing"); if (clean) sp_attribute_clean_tree( repr ); - // Sort attributes in a canonical order (helps with "diffing" SVG files). - bool sort = prefs->getBool("/options/svgoutput/sort_attributes"); - if (sort) { - sort = !prefs->getBool("/options/svgoutput/disable_optimizations"); - } + // Sort attributes in a canonical order (helps with "diffing" SVG files).only if not set disable optimizations + bool sort = !prefs->getBool("/options/svgoutput/disable_optimizations") && prefs->getBool("/options/svgoutput/sort_attributes"); if (sort) sp_attribute_sort_tree( repr ); Glib::QueryQuark xml_prefix=g_quark_from_static_string("xml"); -- GitLab