=== modified file 'src/desktop.cpp'
--- src/desktop.cpp 2016-07-25 05:27:21 +0000
+++ src/desktop.cpp 2017-05-30 23:44:28 +0000
@@ -123,6 +123,7 @@
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 ),
@@ -557,6 +558,25 @@
}
}
+void SPDesktop::setOverlay(bool set, bool freeze, double opacity){
+ if (opacity > 0.0 && opacity <= 1.0) {
+ if (set) {
+ getCanvas()->setOverlay(true, opacity);
+ } else {
+ getCanvas()->setOverlay(false, opacity);
+ }
+ }
+ if (freeze) {
+ if ( interaction_disabled_counter == 0) {
+ disableInteraction();
+ }
+ } else {
+ if ( interaction_disabled_counter > 0) {
+ enableInteraction();
+ }
+ }
+}
+
// Pass-through LayerModel functions
SPObject *SPDesktop::currentRoot() const
{
@@ -1436,12 +1456,14 @@
void
SPDesktop::enableInteraction()
{
- _widget->enableInteraction();
+ _widget->enableInteraction();
+ interaction_disabled_counter --;
}
void SPDesktop::disableInteraction()
{
- _widget->disableInteraction();
+ _widget->disableInteraction();
+ interaction_disabled_counter ++;
}
void SPDesktop::setWaitingCursor()
=== modified file 'src/desktop.h'
--- src/desktop.h 2016-07-25 05:27:21 +0000
+++ src/desktop.h 2017-05-30 23:55:16 +0000
@@ -194,6 +194,8 @@
/// \todo fixme: This has to be implemented in different way */
guint guides_active : 1;
+ bool on_live_extension;
+ void setOverlay(bool set, bool freeze = true, double opacity = 0.2);
// storage for selected dragger used by GrDrag as it's
// created and deleted by tools
=== modified file 'src/display/sp-canvas.cpp'
--- src/display/sp-canvas.cpp 2016-08-18 18:55:56 +0000
+++ src/display/sp-canvas.cpp 2017-05-30 21:15:29 +0000
@@ -937,7 +937,8 @@
gtk_widget_set_has_window (GTK_WIDGET (canvas), TRUE);
gtk_widget_set_double_buffered (GTK_WIDGET (canvas), FALSE);
gtk_widget_set_can_focus (GTK_WIDGET (canvas), TRUE);
-
+ canvas->_opacity = 0.2;
+ canvas->_overlay = false;
canvas->_pick_event.type = GDK_LEAVE_NOTIFY;
canvas->_pick_event.crossing.x = 0;
canvas->_pick_event.crossing.y = 0;
@@ -959,7 +960,6 @@
canvas->_tiles=NULL;
canvas->_tLeft=canvas->_tTop=canvas->_tRight=canvas->_tBottom=0;
canvas->_tile_h=canvas->_tile_w=0;
-
canvas->_forced_redraw_count = 0;
canvas->_forced_redraw_limit = -1;
@@ -1034,6 +1034,21 @@
return GTK_WIDGET(canvas);
}
+void SPCanvas::setOverlay(bool set, double opacity)
+{
+ if (opacity == 0.0 || opacity > 1.0){
+ return;
+ }
+ if(set) {
+ _opacity = opacity;
+ _overlay = true;
+ updateNow();
+ } else {
+ _overlay = false;
+ updateNow();
+ }
+}
+
void SPCanvas::handle_realize(GtkWidget *widget)
{
GdkWindowAttr attributes;
@@ -1607,6 +1622,12 @@
cairo_set_source_surface(xct, imgs, 0, 0);
cairo_set_operator(xct, CAIRO_OPERATOR_SOURCE);
cairo_paint(xct);
+ if (_overlay && _opacity > 0.0 && _opacity <= 1.0) {
+ cairo_set_operator(buf.ct, CAIRO_OPERATOR_OVER);
+ cairo_rectangle(xct, 0, 0, paint_rect.width(), paint_rect.height());
+ cairo_set_source_rgba (xct, 0.0, 0.0, 0.0, _opacity);
+ cairo_fill(xct);
+ }
cairo_destroy(xct);
cairo_surface_destroy(imgs);
}
=== modified file 'src/display/sp-canvas.h'
--- src/display/sp-canvas.h 2016-07-25 05:27:21 +0000
+++ src/display/sp-canvas.h 2017-05-30 21:15:29 +0000
@@ -84,7 +84,7 @@
Geom::Rect getViewbox() const;
Geom::IntRect getViewboxIntegers() const;
SPCanvasGroup *getRoot();
-
+ void setOverlay(bool set = true, double opacity = 0.0);
/// Returns new canvas as widget.
static GtkWidget *createAA();
@@ -173,6 +173,9 @@
SPCanvasItem *_root;
+ bool _overlay;
+ double _opacity;
+
bool _is_dragging;
double _dx0;
double _dy0;
=== modified file 'src/extension/execution-env.cpp'
--- src/extension/execution-env.cpp 2016-04-12 10:35:15 +0000
+++ src/extension/execution-env.cpp 2017-05-31 00:21:54 +0000
@@ -23,6 +23,8 @@
#include "selection.h"
#include "effect.h"
#include "document.h"
+#include "desktop.h"
+#include "inkscape.h"
#include "document-undo.h"
#include "desktop.h"
#include "ui/view/view.h"
@@ -54,19 +56,6 @@
_show_working(show_working),
_show_errors(show_errors)
{
- SPDesktop *desktop = (SPDesktop *)_doc;
- sp_namedview_document_from_window(desktop);
-
- if (desktop != NULL) {
- std::vector<SPItem*> selected = desktop->getSelection()->itemList();
- for(std::vector<SPItem*>::const_iterator x = selected.begin(); x != selected.end(); ++x){
- Glib::ustring selected_id;
- selected_id = (*x)->getId();
- _selected.insert(_selected.end(), selected_id);
- //std::cout << "Selected: " << selected_id << std::endl;
- }
- }
-
genDocCache();
return;
@@ -183,24 +172,14 @@
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<Glib::ustring>::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;
}
=== modified file 'src/extension/execution-env.h'
--- src/extension/execution-env.h 2014-03-27 01:33:44 +0000
+++ src/extension/execution-env.h 2017-05-30 21:15:29 +0000
@@ -54,9 +54,6 @@
Glib::RefPtr<Glib::MainLoop> _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<Glib::ustring> _selected;
/** \brief A document cache if we were passed one. */
Implementation::ImplementationDocumentCache * _docCache;
=== modified file 'src/extension/implementation/script.cpp'
--- src/extension/implementation/script.cpp 2016-06-03 07:50:21 +0000
+++ src/extension/implementation/script.cpp 2017-05-31 00:24:00 +0000
@@ -422,11 +422,29 @@
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;
}
@@ -688,59 +706,14 @@
/// \todo Popup dialog here
return;
}
-
- std::vector<SPItem*> selected =
- desktop->getSelection()->itemList(); //desktop should not be NULL since doc was checked and desktop is a casted pointer
- for(std::vector<SPItem*>::const_iterator x = selected.begin(); x != selected.end(); ++x){
- 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<Inkscape::UI::Tools::NodeTool*>(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<Inkscape::UI::Node*>(*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
-
+ if (desktop) {
+ Inkscape::Selection * selection = desktop->getSelection();
+ if (!selection->isEmpty()) {
+ selection->setBackup();
+ }
+ params = selection->params;
+ module->paramListString(params);
+ }
file_listener fileout;
int data_read = execute(command, params, dc->_filename, fileout);
fileout.toFile(tempfilename_out);
@@ -784,6 +757,7 @@
layer = document->getObjectById(g_quark_to_string(nv->default_layer_id));
}
}
+ desktop->showGrids(nv->grids_visible);
}
sp_namedview_update_layers_from_document(desktop);
@@ -792,6 +766,14 @@
//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();
}
@@ -827,12 +809,10 @@
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<gchar const *> 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.
@@ -853,80 +833,33 @@
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<Inkscape::XML::Node *> 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<AttributeRecord const> 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<gchar const *>::const_iterator it = attribs.begin(); it != attribs.end(); ++it) {
- oldroot_namedview->setAttribute(*it, NULL);
- }
-
- // Set the new attributes.
- for (List<AttributeRecord const> 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,
=== modified file 'src/extension/internal/bitmap/imagemagick.cpp'
--- src/extension/internal/bitmap/imagemagick.cpp 2015-12-09 20:01:20 +0000
+++ src/extension/internal/bitmap/imagemagick.cpp 2017-05-31 00:25:18 +0000
@@ -65,6 +65,16 @@
_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();
+ }
+ }
+ }
const std::vector<SPItem*> selectedItemList = desktop->selection->itemList();
int selectCount = selectedItemList.size();
=== modified file 'src/extension/internal/bluredge.cpp'
--- src/extension/internal/bluredge.cpp 2016-06-11 17:25:23 +0000
+++ src/extension/internal/bluredge.cpp 2017-05-31 00:25:13 +0000
@@ -53,7 +53,7 @@
void
BlurEdge::effect (Inkscape::Extension::Effect *module, Inkscape::UI::View::View *desktop, Inkscape::Extension::Implementation::ImplementationDocumentCache * /*docCache*/)
{
- Inkscape::Selection * selection = static_cast<SPDesktop *>(desktop)->selection;
+
float width = module->get_param_float("blur-width");
int steps = module->get_param_int("num-steps");
@@ -62,6 +62,17 @@
double old_offset = prefs->getDouble("/options/defaultoffsetwidth/value", 1.0, "px");
// TODO need to properly refcount the items, at least
+ SPDesktop *deskt = static_cast<SPDesktop *>(desktop);
+ Inkscape::Selection * selection = NULL;
+ if (deskt) {
+ selection = deskt->selection;
+ if (selection && !selection->params.empty()) {
+ selection->restoreBackup();
+ if (!deskt->on_live_extension) {
+ selection->emptyBackup();
+ }
+ }
+ }
std::vector<SPItem*> items(selection->itemList());
selection->clear();
=== modified file 'src/extension/internal/filter/filter.cpp'
--- src/extension/internal/filter/filter.cpp 2016-11-11 20:30:37 +0000
+++ src/extension/internal/filter/filter.cpp 2017-05-31 00:25:26 +0000
@@ -122,8 +122,17 @@
}
//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<SPItem*> items(selection->itemList());
=== modified file 'src/extension/internal/grid.cpp'
--- src/extension/internal/grid.cpp 2016-06-11 17:25:23 +0000
+++ src/extension/internal/grid.cpp 2017-05-31 00:25:34 +0000
@@ -87,7 +87,17 @@
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()) {
=== modified file 'src/extension/prefdialog.cpp'
--- src/extension/prefdialog.cpp 2016-06-11 17:25:23 +0000
+++ src/extension/prefdialog.cpp 2017-05-31 00:22:52 +0000
@@ -64,7 +64,13 @@
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, 6);
hbox->show();
@@ -196,19 +202,42 @@
void
PrefDialog::preview_toggle (void) {
+ SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+ Inkscape::Selection * selection = NULL;
+ if(desktop) {
+ selection = desktop->getSelection();
+ }
+ desktop->getSelection();
+ desktop->setOverlay(false, false, 0.0);
+ desktop->on_live_extension = false;
+ set_modal(false);
if(_param_preview->get_bool(NULL, NULL)) {
- set_modal(true);
if (_exEnv == NULL) {
+ if (desktop && selection) {
+ desktop->setOverlay(false, true, 0.0);
+ desktop->on_live_extension = true;
+ if (!selection->isEmpty()) {
+ selection->setBackup();
+ }
+ }
_exEnv = new ExecutionEnv(_effect, SP_ACTIVE_DESKTOP, NULL, false, false);
_exEnv->run();
+ if (desktop && selection) {
+ selection->clear();
+ }
}
} else {
- set_modal(false);
+ if (desktop) {
+ desktop->setOverlay(false);
+ }
if (_exEnv != NULL) {
_exEnv->cancel();
_exEnv->undo();
delete _exEnv;
_exEnv = NULL;
+ if (desktop && selection) {
+ selection->restoreBackup();
+ }
}
}
}
@@ -243,12 +272,12 @@
PrefDialog::on_response (int signal) {
if (signal == Gtk::RESPONSE_OK) {
if (_exEnv == NULL) {
- if (_effect != NULL) {
- _effect->effect(SP_ACTIVE_DESKTOP);
- } else {
- // Shutdown run()
- return;
- }
+ if (_effect != NULL) {
+ _effect->effect(SP_ACTIVE_DESKTOP);
+ } else {
+ // Shutdown run()
+ return;
+ }
} else {
if (_exEnv->wait()) {
_exEnv->commit();
@@ -257,6 +286,7 @@
}
delete _exEnv;
_exEnv = NULL;
+
}
}
@@ -267,7 +297,15 @@
if ((signal == Gtk::RESPONSE_CANCEL || signal == Gtk::RESPONSE_DELETE_EVENT) && _effect != NULL) {
delete this;
}
-
+ SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+ Inkscape::Selection * selection = NULL;
+ if(desktop) {
+ selection = desktop->getSelection();
+ desktop->on_live_extension = false;
+ desktop->setOverlay(false);
+ selection->restoreBackup();
+ selection->emptyBackup();
+ }
return;
}
=== modified file 'src/selection.cpp'
--- src/selection.cpp 2016-02-08 07:32:51 +0000
+++ src/selection.cpp 2017-05-31 00:20:43 +0000
@@ -22,6 +22,7 @@
#include "macros.h"
#include "inkscape.h"
#include "document.h"
+#include "desktop.h"
#include "layer-model.h"
#include "selection.h"
#include <2geom/rect.h>
@@ -34,6 +35,12 @@
#include "box3d.h"
#include "box3d.h"
#include "persp3d.h"
+#include "ui/tools/node-tool.h"
+#include "ui/tool/multi-path-manipulator.h"
+#include "ui/tool/path-manipulator.h"
+#include "ui/tool/control-point-selection.h"
+#include "sp-path.h"
+#include "sp-defs.h"
#include <sigc++/functors/mem_fun.h>
@@ -541,6 +548,140 @@
return parents.size();
}
+void
+Selection::emptyBackup(){
+ _selected_ids.clear();
+ _seldata.clear();
+ params.clear();
+}
+
+void
+Selection::setBackup ()
+{
+ SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+ if (desktop) {
+ std::vector<SPItem*> selected_items = itemList();
+ _selected_ids.clear();
+ _seldata.clear();
+ params.clear();
+ for(std::vector<SPItem*>::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<Inkscape::UI::Tools::NodeTool*>(ec);
+ }
+ if(tool){
+ Inkscape::UI::ControlPointSelection *cps = tool->_selected_nodes;
+ std::list<Inkscape::UI::SelectableControlPoint *> points_list = cps->_points_list;
+ for (std::list<Inkscape::UI::SelectableControlPoint *>::iterator i = points_list.begin(); i != points_list.end(); ++i) {
+ Inkscape::UI::Node *node = dynamic_cast<Inkscape::UI::Node*>(*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_front(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<Inkscape::UI::Tools::NodeTool*>(ec);
+ }
+ clear();
+ std::vector<std::string>::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<Inkscape::UI::SelectableControlPoint *> points_list = cps->_points_list;
+ cps->clear();
+ std::vector<Inkscape::UI::Node *> nodes (_seldata.size(), NULL);
+ for (std::list<Inkscape::UI::SelectableControlPoint *>::iterator i = points_list.begin(); i != points_list.end(); ++i) {
+ Inkscape::UI::Node *node = dynamic_cast<Inkscape::UI::Node*>(*i);
+ if (node) {
+ SPPath * item = node->nodeList().subpathList().pm().item();
+ if(!item || !includes(item->getRepr())) {
+ continue;
+ }
+ std::string id = item->getId();
+ int sp=0;
+ bool found_sp = false;
+ for(Inkscape::UI::SubpathList::iterator j = node->nodeList().subpathList().begin(); j != node->nodeList().subpathList().end(); ++j,++sp){
+ if(&**j == &(node->nodeList())){
+ found_sp = true;
+ break;
+ }
+ }
+ int nl=0;
+ for (Inkscape::UI::NodeList::iterator k = node->nodeList().begin(); k != node->nodeList().end(); ++k, ++nl){
+ if(&*k==node){
+ guint count = 0;
+ for (std::vector<std::pair<std::string, std::pair<int, int> > >::iterator l = _seldata.begin(); l != _seldata.end(); ++l, ++count) {
+ if(l->first == id && l->second.first == sp && l->second.second == nl && found_sp){
+ nodes[count] = node;
+ break;
+ }
+ }
+ break;
+ }
+ }
+ }
+ }
+ for (std::vector<Inkscape::UI::Node *>::iterator m = nodes.begin(); m != nodes.end(); ++m){
+ if (*m) {
+ (*m)->select(true);
+ }
+ }
+ }
+ }
+}
+
}
/*
=== modified file 'src/selection.h'
--- src/selection.h 2015-04-29 22:29:17 +0000
+++ src/selection.h 2017-05-31 00:21:11 +0000
@@ -328,13 +328,29 @@
{
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<std::string> params;
private:
/** no copy. */
Selection(Selection const &);
/** no assign. */
void operator=(Selection const &);
-
+
/** Issues modification notification signals. */
static int _emit_modified(Selection *selection);
/** Schedules an item modification signal to be sent. */
@@ -381,7 +397,8 @@
SPObject* _selection_context;
unsigned int _flags;
unsigned int _idle;
-
+ std::vector<std::pair<std::string, std::pair<int, int> > > _seldata;
+ std::vector<std::string> _selected_ids;
std::map<SPObject *, sigc::connection> _modified_connections;
std::map<SPObject *, sigc::connection> _release_connections;
sigc::connection _context_release_connection;
=== modified file 'src/ui/tool/control-point-selection.h'
--- src/ui/tool/control-point-selection.h 2016-03-13 23:50:24 +0000
+++ src/ui/tool/control-point-selection.h 2017-05-30 21:15:29 +0000
@@ -118,6 +118,8 @@
void getOriginalPoints(std::vector<Inkscape::SnapCandidatePoint> &pts);
void getUnselectedPoints(std::vector<Inkscape::SnapCandidatePoint> &pts);
void setOriginalPoints();
+ //the purpose of this list is to keep track of first and last selected
+ std::list<SelectableControlPoint *> _points_list;
private:
// The functions below are invoked from SelectableControlPoint.
@@ -141,8 +143,7 @@
double _rotationRadius(Geom::Point const &);
set_type _points;
- //the purpose of this list is to keep track of first and last selected
- std::list<SelectableControlPoint *> _points_list;
+
set_type _all_points;
INK_UNORDERED_MAP<SelectableControlPoint *, Geom::Point> _original_positions;
INK_UNORDERED_MAP<SelectableControlPoint *, Geom::Affine> _last_trans;
=== modified file 'src/ui/tool/selectable-control-point.cpp'
--- src/ui/tool/selectable-control-point.cpp 2014-03-27 01:33:44 +0000
+++ src/ui/tool/selectable-control-point.cpp 2017-05-30 21:15:29 +0000
@@ -87,6 +87,15 @@
return true;
}
+void SelectableControlPoint::select(bool toselect)
+{
+ if (toselect) {
+ _selection.insert(this);
+ } else {
+ _selection.erase(this);
+ }
+}
+
void SelectableControlPoint::_takeSelection()
{
_selection.clear();
=== modified file 'src/ui/tool/selectable-control-point.h'
--- src/ui/tool/selectable-control-point.h 2014-08-08 20:20:44 +0000
+++ src/ui/tool/selectable-control-point.h 2017-05-30 21:15:29 +0000
@@ -28,8 +28,10 @@
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,
=== modified file 'src/xml/node.h'
--- src/xml/node.h 2014-12-16 14:05:47 +0000
+++ src/xml/node.h 2017-05-30 21:15:29 +0000
@@ -384,6 +384,20 @@
*/
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 @@
*
* @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;
/*@}*/
=== modified file 'src/xml/simple-node.cpp'
--- src/xml/simple-node.cpp 2014-12-16 14:05:47 +0000
+++ src/xml/simple-node.cpp 2017-05-30 21:15:29 +0000
@@ -318,7 +318,7 @@
// 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.
@@ -648,28 +648,112 @@
}
}
-void SimpleNode::mergeFrom(Node const *src, gchar const *key) {
+void SimpleNode::cleanOriginal(Node *src, gchar const *key){
+ std::vector<Node *> 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<Node *>::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<AttributeRecord const> orig_attr = attributeList(); orig_attr; ++orig_attr) {
+ for (List<AttributeRecord const> 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<Node *>(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();
}
}
=== modified file 'src/xml/simple-node.h'
--- src/xml/simple-node.h 2014-12-16 14:05:47 +0000
+++ src/xml/simple-node.h 2017-05-30 21:15:29 +0000
@@ -91,7 +91,9 @@
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<AttributeRecord const> attributeList() const {
return _attributes;
-
请登录后发言!