From 129f917af4af0324783e3d5316572e603e985783 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Sat, 20 Apr 2019 22:41:48 +0200 Subject: Updating fixes on compiling --- src/ui/dialog/selectordialog.cpp | 244 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 244 insertions(+) (limited to 'src/ui/dialog/selectordialog.cpp') diff --git a/src/ui/dialog/selectordialog.cpp b/src/ui/dialog/selectordialog.cpp index 243a33750..cb7b93cd9 100644 --- a/src/ui/dialog/selectordialog.cpp +++ b/src/ui/dialog/selectordialog.cpp @@ -31,8 +31,13 @@ #include #include +<<<<<<< HEAD //#define DEBUG_SELECTORDIALOG //#define G_LOG_DOMAIN "SELECTORDIALOG" +======= +//#define DEBUG_selectorDialog +//#define G_LOG_DOMAIN "selectorDialog" +>>>>>>> Updating fixes on compiling using Inkscape::DocumentUndo; using Inkscape::Util::List; @@ -53,7 +58,11 @@ namespace Dialog { class SelectorDialog::NodeObserver : public Inkscape::XML::NodeObserver { public: NodeObserver(SelectorDialog* selectorDialog) : +<<<<<<< HEAD _selectorDialog(selectorDialog) +======= + _selectordialog(selectorDialog) +>>>>>>> Updating fixes on compiling { g_debug("SelectorDialog::NodeObserver: Constructor"); }; @@ -62,7 +71,11 @@ public: Inkscape::Util::ptr_shared old_content, Inkscape::Util::ptr_shared new_content) override; +<<<<<<< HEAD SelectorDialog * _selectorDialog; +======= + SelectorDialog * _selectordialog; +>>>>>>> Updating fixes on compiling }; @@ -73,9 +86,15 @@ SelectorDialog::NodeObserver::notifyContentChanged( Inkscape::Util::ptr_shared /*new_content*/ ) { g_debug("SelectorDialog::NodeObserver::notifyContentChanged"); +<<<<<<< HEAD _selectorDialog->_updating = false; _selectorDialog->_readStyleElement(); _selectorDialog->_selectRow(); +======= + _selectordialog->_updating = false; + _selectordialog->_readStyleElement(); + _selectordialog->_selectRow(); +>>>>>>> Updating fixes on compiling } @@ -84,7 +103,11 @@ SelectorDialog::NodeObserver::notifyContentChanged( class SelectorDialog::NodeWatcher : public Inkscape::XML::NodeObserver { public: NodeWatcher(SelectorDialog* selectorDialog, Inkscape::XML::Node *repr) : +<<<<<<< HEAD _selectorDialog(selectorDialog), +======= + _selectordialog(selectorDialog), +>>>>>>> Updating fixes on compiling _repr(repr) { g_debug("SelectorDialog::NodeWatcher: Constructor"); @@ -94,8 +117,13 @@ public: Inkscape::XML::Node &child, Inkscape::XML::Node */*prev*/ ) override { +<<<<<<< HEAD if ( _selectorDialog && _repr ) { _selectorDialog->_nodeAdded( child ); +======= + if ( _selectordialog && _repr ) { + _selectordialog->_nodeAdded( child ); +>>>>>>> Updating fixes on compiling } } @@ -103,8 +131,13 @@ public: Inkscape::XML::Node &child, Inkscape::XML::Node */*prev*/ ) override { +<<<<<<< HEAD if ( _selectorDialog && _repr ) { _selectorDialog->_nodeRemoved( child ); +======= + if ( _selectordialog && _repr ) { + _selectordialog->_nodeRemoved( child ); +>>>>>>> Updating fixes on compiling } } @@ -112,7 +145,11 @@ public: GQuark qname, Util::ptr_shared /*old_value*/, Util::ptr_shared /*new_value*/ ) override { +<<<<<<< HEAD if ( _selectorDialog && _repr ) { +======= + if ( _selectordialog && _repr ) { +>>>>>>> Updating fixes on compiling // For the moment only care about attributes that are directly used in selectors. const gchar * cname = g_quark_to_string (qname ); @@ -122,12 +159,20 @@ public: } if ( name == "id" || name == "class" ) { +<<<<<<< HEAD _selectorDialog->_nodeChanged( node ); +======= + _selectordialog->_nodeChanged( node ); +>>>>>>> Updating fixes on compiling } } } +<<<<<<< HEAD SelectorDialog * _selectorDialog; +======= + SelectorDialog * _selectordialog; +>>>>>>> Updating fixes on compiling Inkscape::XML::Node * _repr; // Need to track if document changes. }; @@ -215,10 +260,17 @@ SelectorDialog::TreeStore::on_row_deleted(const TreeModel::Path& path) } +<<<<<<< HEAD Glib::RefPtr SelectorDialog::TreeStore::create(SelectorDialog *selectordialog) { SelectorDialog::TreeStore * store = new SelectorDialog::TreeStore(); store->_selectordialog = selectordialog; +======= +Glib::RefPtr SelectorDialog::TreeStore::create(SelectorDialog *selectorDialog) +{ + SelectorDialog::TreeStore * store = new SelectorDialog::TreeStore(); + store->_selectordialog = selectorDialog; +>>>>>>> Updating fixes on compiling store->set_column_types( store->_selectordialog->_mColumns ); return Glib::RefPtr( store ); } @@ -229,11 +281,20 @@ Glib::RefPtr SelectorDialog::TreeStore::create(Select * adds selectors to treeview. _delSelector deletes the selector from the dialog. * Any addition/deletion of the selectors updates XML style element accordingly. */ +<<<<<<< HEAD SelectorDialog::SelectorDialog() : UI::Widget::Panel("/dialogs/style", SP_VERB_DIALOG_STYLE), _updating(false), _textNode(nullptr), _desktopTracker() +======= +SelectorDialog::SelectorDialog(bool stylemode) : + UI::Widget::Panel("/dialogs/style", SP_VERB_DIALOG_STYLE), + _updating(false), + _textNode(nullptr), + _desktopTracker(), + _stylemode(stylemode) +>>>>>>> Updating fixes on compiling { g_debug("SelectorDialog::SelectorDialog"); @@ -243,9 +304,17 @@ SelectorDialog::SelectorDialog() : addRenderer->add_icon("edit-delete"); addRenderer->add_icon("list-add"); addRenderer->add_icon("object-locked"); +<<<<<<< HEAD _store = TreeStore::create(this); _treeView.set_model(_store); +======= + + _store = TreeStore::create(this); + _modelfilter = Gtk::TreeModelFilter::create(_store); + _modelfilter->set_visible_column(_mColumns._colVisible); + _treeView.set_model(_modelfilter); +>>>>>>> Updating fixes on compiling _treeView.set_headers_visible(true); _treeView.enable_model_drag_source(); _treeView.enable_model_drag_dest( Gdk::ACTION_MOVE ); @@ -261,6 +330,7 @@ SelectorDialog::SelectorDialog() : _paned.set_orientation(Gtk::ORIENTATION_VERTICAL); _paned.pack1(_mainBox, Gtk::SHRINK); _mainBox.set_orientation(Gtk::ORIENTATION_VERTICAL); +<<<<<<< HEAD _mainBox.pack_start(_scrolledWindow, Gtk::PACK_EXPAND_WIDGET); _scrolledWindow.add(_treeView); _scrolledWindow.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); @@ -279,6 +349,27 @@ SelectorDialog::SelectorDialog() : _buttonBox.pack_start(*create, Gtk::PACK_SHRINK); _buttonBox.pack_start(*del, Gtk::PACK_SHRINK); +======= + if (!_stylemode) { + _mainBox.pack_start(_scrolledWindow, Gtk::PACK_EXPAND_WIDGET); + _scrolledWindow.add(_treeView); + _scrolledWindow.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); + create = manage( new Gtk::Button() ); + _styleButton(*create, "list-add", "Add a new CSS Selector"); + create->signal_clicked().connect(sigc::mem_fun(*this, &SelectorDialog::_addSelector)); + + del = manage( new Gtk::Button() ); + _styleButton(*del, "list-remove", "Remove a CSS Selector"); + del->signal_clicked().connect(sigc::mem_fun(*this, &SelectorDialog::_delSelector)); + del->set_sensitive(false); + _mainBox.pack_end(_buttonBox, Gtk::PACK_SHRINK); + + _buttonBox.pack_start(*create, Gtk::PACK_SHRINK); + _buttonBox.pack_start(*del, Gtk::PACK_SHRINK); + } else { + _mainBox.pack_start(_treeView, Gtk::PACK_EXPAND_WIDGET); + } +>>>>>>> Updating fixes on compiling _getContents()->pack_start(_paned, Gtk::PACK_EXPAND_WIDGET); @@ -313,7 +404,11 @@ SelectorDialog::SelectorDialog() : _readStyleElement(); _selectRow(); +<<<<<<< HEAD if (!_store->children().empty()) { +======= + if (!_stylemode && !_store->children().empty()) { +>>>>>>> Updating fixes on compiling del->set_sensitive(true); } @@ -321,7 +416,10 @@ SelectorDialog::SelectorDialog() : /** +<<<<<<< HEAD * @brief SelectorDialog::~SelectorDialog +======= +>>>>>>> Updating fixes on compiling * Class destructor */ SelectorDialog::~SelectorDialog() @@ -334,7 +432,10 @@ SelectorDialog::~SelectorDialog() /** +<<<<<<< HEAD * @brief SelectorDialog::_styleTextNode +======= +>>>>>>> Updating fixes on compiling * @return Inkscape::XML::Node* pointing to a style element's text node. * Returns the style element's text node. If there is no style element, one is created. * Ditto for text node. @@ -372,11 +473,19 @@ Inkscape::XML::Node* SelectorDialog::_getStyleTextNode() styleNode = SP_ACTIVE_DOCUMENT->getReprDoc()->createElement("svg:style"); textNode = SP_ACTIVE_DOCUMENT->getReprDoc()->createTextNode(""); +<<<<<<< HEAD root->addChild(styleNode, nullptr); Inkscape::GC::release(styleNode); styleNode->appendChild(textNode); Inkscape::GC::release(textNode); +======= + styleNode->appendChild(textNode); + Inkscape::GC::release(textNode); + + root->addChild(styleNode, nullptr); + Inkscape::GC::release(styleNode); +>>>>>>> Updating fixes on compiling } if (_textNode != textNode) { @@ -390,7 +499,10 @@ Inkscape::XML::Node* SelectorDialog::_getStyleTextNode() /** +<<<<<<< HEAD * @brief SelectorDialog::_readStyleElement +======= +>>>>>>> Updating fixes on compiling * Fill the Gtk::TreeStore from the svg:style element. */ void SelectorDialog::_readStyleElement() @@ -429,6 +541,11 @@ void SelectorDialog::_readStyleElement() // regex1->match(content, minfo); // Split on curly brackets. Even tokens are selectors, odd are values. +<<<<<<< HEAD +======= + std::cout << content << std::endl; + std::cout << "aaaaaaaaaaaaaaaaaaaaaaaaaa" << std::endl; +>>>>>>> Updating fixes on compiling std::vector tokens = Glib::Regex::split_simple("[}{]", content); // If text node is empty, return (avoids problem with negative below). @@ -457,8 +574,12 @@ void SelectorDialog::_readStyleElement() coltype colType = SELECTOR; for (auto tok : tokensplus) { REMOVE_SPACES(tok); +<<<<<<< HEAD if (SPAttributeRelSVG::isSVGElement(tok) || tok.find(" ") != -1 || tok[0] == '>' || tok[0] == '+' || tok[0] == '~' || tok[0] == '*' || tok.erase(0, 1).find(".") != -1) { +======= + if (tok.find(" ") != -1 || tok.erase(0, 1).find(".") != -1) { +>>>>>>> Updating fixes on compiling colType = UNHANDLED; } } @@ -486,6 +607,7 @@ void SelectorDialog::_readStyleElement() row[_mColumns._colType] = colType; row[_mColumns._colObj] = objVec; row[_mColumns._colProperties] = properties; +<<<<<<< HEAD // Add as children, objects that match selector. for (auto &obj : objVec) { Gtk::TreeModel::Row childrow = *(_store->append(row->children())); @@ -494,6 +616,20 @@ void SelectorDialog::_readStyleElement() childrow[_mColumns._colType] = colType == UNHANDLED ? UNHANDLED : OBJECT; childrow[_mColumns._colObj] = std::vector(1, obj); childrow[_mColumns._colProperties] = ""; // Unused +======= + row[_mColumns._colVisible] = true; + if (colType == SELECTOR) { + // Add as children, objects that match selector. + for (auto &obj : objVec) { + Gtk::TreeModel::Row childrow = *(_store->append(row->children())); + childrow[_mColumns._colSelector] = "#" + Glib::ustring(obj->getId()); + childrow[_mColumns._colExpand] = false; + childrow[_mColumns._colType] = OBJECT; + childrow[_mColumns._colObj] = std::vector(1, obj); + childrow[_mColumns._colProperties] = ""; // Unused + childrow[_mColumns._colVisible] = true; // Unused + } +>>>>>>> Updating fixes on compiling } } _updating = false; @@ -513,7 +649,10 @@ void SelectorDialog::_rowCollapse(const Gtk::TreeModel::iterator &iter, const Gt row[_mColumns._colExpand] = false; } /** +<<<<<<< HEAD * @brief SelectorDialog::_writeStyleElement +======= +>>>>>>> Updating fixes on compiling * Update the content of the style element as selectors (or objects) are added/removed. */ void SelectorDialog::_writeStyleElement() @@ -562,7 +701,10 @@ void SelectorDialog::_addWatcherRecursive(Inkscape::XML::Node *node) { } /** +<<<<<<< HEAD * @brief SelectorDialog::_updateWatchers +======= +>>>>>>> Updating fixes on compiling * Update the watchers on objects. */ void SelectorDialog::_updateWatchers() @@ -588,7 +730,10 @@ void SelectorDialog::_updateWatchers() /** +<<<<<<< HEAD * @brief SelectorDialog::_addToSelector +======= +>>>>>>> Updating fixes on compiling * @param row * Add selected objects on the desktop to the selector corresponding to 'row'. */ @@ -627,6 +772,10 @@ void SelectorDialog::_addToSelector(Gtk::TreeModel::Row row) childrow[_mColumns._colType] = OBJECT; childrow[_mColumns._colObj] = std::vector(1, obj); childrow[_mColumns._colProperties] = ""; // Unused +<<<<<<< HEAD +======= + childrow[_mColumns._colVisible] = true; // Unused +>>>>>>> Updating fixes on compiling } } } @@ -667,6 +816,10 @@ void SelectorDialog::_addToSelector(Gtk::TreeModel::Row row) childrow[_mColumns._colType] = OBJECT; childrow[_mColumns._colObj] = std::vector(1, obj); childrow[_mColumns._colProperties] = ""; // Unused +<<<<<<< HEAD +======= + childrow[_mColumns._colVisible] = true; // Unused +>>>>>>> Updating fixes on compiling } } } @@ -682,7 +835,10 @@ void SelectorDialog::_addToSelector(Gtk::TreeModel::Row row) /** +<<<<<<< HEAD * @brief SelectorDialog::_removeFromSelector +======= +>>>>>>> Updating fixes on compiling * @param row * Remove the object corresponding to 'row' from the parent selector. */ @@ -692,9 +848,12 @@ void SelectorDialog::_removeFromSelector(Gtk::TreeModel::Row row) if (*row) { Glib::ustring objectLabel = row[_mColumns._colSelector]; +<<<<<<< HEAD if (row[_mColumns._colType] == UNHANDLED) { return; }; +======= +>>>>>>> Updating fixes on compiling Gtk::TreeModel::iterator iter = row->parent(); if (iter) { Gtk::TreeModel::Row parent = *iter; @@ -764,7 +923,10 @@ void SelectorDialog::_removeFromSelector(Gtk::TreeModel::Row row) /** +<<<<<<< HEAD * @brief SelectorDialog::_getIdList +======= +>>>>>>> Updating fixes on compiling * @param sel * @return This function returns a comma separated list of ids for objects in input vector. * It is used in creating an 'id' selector. It relies on objects having 'id's. @@ -783,13 +945,17 @@ Glib::ustring SelectorDialog::_getIdList(std::vector sel) } /** +<<<<<<< HEAD * @brief SelectorDialog::_getObjVec +======= +>>>>>>> Updating fixes on compiling * @param selector: a valid CSS selector string. * @return objVec: a vector of pointers to SPObject's the selector matches. * Return a vector of all objects that selector matches. */ std::vector SelectorDialog::_getObjVec(Glib::ustring selector) { +<<<<<<< HEAD std::vector objVec; std::vector tokensplus = Glib::Regex::split_simple("[,]+", selector); bool unhandled = false; @@ -805,6 +971,10 @@ std::vector SelectorDialog::_getObjVec(Glib::ustring selector) { if (!unhandled) { objVec = SP_ACTIVE_DOCUMENT->getObjectsBySelector(selector); } +======= + std::vector objVec = SP_ACTIVE_DOCUMENT->getObjectsBySelector( selector ); + +>>>>>>> Updating fixes on compiling g_debug("SelectorDialog::_getObjVec: | %s |", selector.c_str()); for (auto& obj: objVec) { g_debug(" %s", obj->getId() ? obj->getId() : "null"); @@ -815,7 +985,10 @@ std::vector SelectorDialog::_getObjVec(Glib::ustring selector) { /** +<<<<<<< HEAD * @brief SelectorDialog::_insertClass +======= +>>>>>>> Updating fixes on compiling * @param objs: list of objects to insert class * @param class: class to insert * Insert a class name into objects' 'class' attribute. @@ -849,7 +1022,10 @@ void SelectorDialog::_insertClass(const std::vector& objVec, const G /** +<<<<<<< HEAD * @brief SelectorDialog::_selectObjects +======= +>>>>>>> Updating fixes on compiling * @param eventX * @param eventY * This function selects objects in the drawing corresponding to the selector @@ -871,7 +1047,11 @@ void SelectorDialog::_selectObjects(int eventX, int eventY) if (iter) { Gtk::TreeModel::Row row = *iter; Gtk::TreeModel::Children children = row.children(); +<<<<<<< HEAD if (children.empty()) { +======= + if (children.empty() && !_stylemode) { +>>>>>>> Updating fixes on compiling del->set_sensitive(true); } std::vector objVec = row[_mColumns._colObj]; @@ -886,8 +1066,11 @@ void SelectorDialog::_selectObjects(int eventX, int eventY) /** +<<<<<<< HEAD * @brief SelectorDialog::_addSelector * +======= +>>>>>>> Updating fixes on compiling * This function opens a dialog to add a selector. The dialog is prefilled * with an 'id' selector containing a list of the id's of selected objects * or with a 'class' selector if no objects are selected. @@ -958,6 +1141,7 @@ void SelectorDialog::_addSelector() * set to ".Class1" */ selectorValue = textEditPtr->get_text(); +<<<<<<< HEAD del->set_sensitive(true); std::vector tokensplus = Glib::Regex::split_simple("[,]+", selectorValue); @@ -996,6 +1180,20 @@ void SelectorDialog::_addSelector() textLabelPtr->show(); } else { invalid = false; +======= + Glib::ustring firstWord = selectorValue.substr(0, selectorValue.find_first_of(" >+~")); + if (firstWord != selectorValue) { + handled = false; + } + if (!_stylemode) { + del->set_sensitive(true); + } + if (selectorValue[0] == '.' || selectorValue[0] == '#' || selectorValue[0] == '*' || + SPAttributeRelSVG::isSVGElement(selectorValue)) { + invalid = false; + } else { + textLabelPtr->show(); +>>>>>>> Updating fixes on compiling } } delete textDialogPtr; @@ -1043,7 +1241,10 @@ void SelectorDialog::_addSelector() void SelectorDialog::_closeDialog(Gtk::Dialog *textDialogPtr) { textDialogPtr->response(Gtk::RESPONSE_OK); } /** +<<<<<<< HEAD * @brief SelectorDialog::_delSelector +======= +>>>>>>> Updating fixes on compiling * This function deletes selector when '-' at the bottom is clicked. * Note: If deleting a class selector, class attributes are NOT changed. */ @@ -1063,12 +1264,21 @@ void SelectorDialog::_delSelector() _store->erase(iter); _updating = false; _writeStyleElement(); +<<<<<<< HEAD del->set_sensitive(false); +======= + if (!_stylemode) { + del->set_sensitive(false); + } +>>>>>>> Updating fixes on compiling } } /** +<<<<<<< HEAD * @brief SelectorDialog::_handleButtonEvent +======= +>>>>>>> Updating fixes on compiling * @param event * @return * Handles the event when '+' button in front of a selector name is clicked or when a '-' button in @@ -1193,7 +1403,10 @@ SelectorDialog::_handleSelectionChanged() { /** +<<<<<<< HEAD * @brief SelectorDialog::_buttonEventsSelectObjs +======= +>>>>>>> Updating fixes on compiling * @param event * This function detects single or double click on a selector in any row. Clicking * on a selector selects the matching objects on the desktop. A double click will @@ -1204,7 +1417,13 @@ void SelectorDialog::_buttonEventsSelectObjs(GdkEventButton* event ) g_debug("SelectorDialog::_buttonEventsSelectObjs"); _treeView.get_selection()->set_mode(Gtk::SELECTION_SINGLE); _updating = true; +<<<<<<< HEAD del->set_sensitive(true); +======= + if (!_stylemode) { + del->set_sensitive(true); + } +>>>>>>> Updating fixes on compiling if (event->type == GDK_BUTTON_RELEASE && event->button == 1) { int x = static_cast(event->x); int y = static_cast(event->y); @@ -1215,14 +1434,23 @@ void SelectorDialog::_buttonEventsSelectObjs(GdkEventButton* event ) /** +<<<<<<< HEAD * @brief SelectorDialog::_selectRow +======= +>>>>>>> Updating fixes on compiling * This function selects the row in treeview corresponding to an object selected * in the drawing. If more than one row matches, the first is chosen. */ void SelectorDialog::_selectRow() { g_debug("SelectorDialog::_selectRow: updating: %s", (_updating ? "true" : "false")); +<<<<<<< HEAD del->set_sensitive(false); +======= + if (!_stylemode) { + del->set_sensitive(false); + } +>>>>>>> Updating fixes on compiling if (_updating || !getDesktop()) return; // Avoid updating if we have set row via dialog. if (SP_ACTIVE_DESKTOP != getDesktop()) { std::cerr << "SelectorDialog::_selectRow: SP_ACTIVE_DESKTOP != getDesktop()" << std::endl; @@ -1241,6 +1469,12 @@ void SelectorDialog::_selectRow() for (auto & i : objVec) { if (obj->getId() == i->getId()) { _treeView.get_selection()->select(row); +<<<<<<< HEAD +======= + row[_mColumns._colVisible] = true; + } else if(_stylemode) { + row[_mColumns._colVisible] = false; +>>>>>>> Updating fixes on compiling } } } @@ -1248,11 +1482,21 @@ void SelectorDialog::_selectRow() _treeView.expand_to_path(Gtk::TreePath(row)); } } +<<<<<<< HEAD } /** * @brief SelectorDialog::_styleButton +======= + if (_stylemode) { + _modelfilter->refilter(); + _treeView.get_selection()->unselect_all(); + } +} + +/** +>>>>>>> Updating fixes on compiling * @param btn * @param iconName * @param tooltip -- cgit v1.2.3 From 6818724008205aa316b4c1faa28c0caef84e9c0e Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Sat, 20 Apr 2019 23:35:53 +0200 Subject: Fix merge --- src/ui/dialog/selectordialog.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'src/ui/dialog/selectordialog.cpp') diff --git a/src/ui/dialog/selectordialog.cpp b/src/ui/dialog/selectordialog.cpp index cb7b93cd9..6e834ffb2 100644 --- a/src/ui/dialog/selectordialog.cpp +++ b/src/ui/dialog/selectordialog.cpp @@ -31,6 +31,7 @@ #include #include +<<<<<<< HEAD <<<<<<< HEAD //#define DEBUG_SELECTORDIALOG //#define G_LOG_DOMAIN "SELECTORDIALOG" @@ -38,6 +39,10 @@ //#define DEBUG_selectorDialog //#define G_LOG_DOMAIN "selectorDialog" >>>>>>> Updating fixes on compiling +======= +//#define DEBUG_SELECTORDIALOG +//#define G_LOG_DOMAIN "SELECTORDIALOG" +>>>>>>> Fix merge using Inkscape::DocumentUndo; using Inkscape::Util::List; @@ -57,12 +62,17 @@ namespace Dialog { // Keeps a watch on style element class SelectorDialog::NodeObserver : public Inkscape::XML::NodeObserver { public: +<<<<<<< HEAD NodeObserver(SelectorDialog* selectorDialog) : <<<<<<< HEAD _selectorDialog(selectorDialog) ======= _selectordialog(selectorDialog) >>>>>>> Updating fixes on compiling +======= + NodeObserver(SelectorDialog* selectordialog) : + _selectordialog(selectordialog) +>>>>>>> Fix merge { g_debug("SelectorDialog::NodeObserver: Constructor"); }; @@ -102,12 +112,17 @@ SelectorDialog::NodeObserver::notifyContentChanged( // (Must update objects that selectors match.) class SelectorDialog::NodeWatcher : public Inkscape::XML::NodeObserver { public: +<<<<<<< HEAD NodeWatcher(SelectorDialog* selectorDialog, Inkscape::XML::Node *repr) : <<<<<<< HEAD _selectorDialog(selectorDialog), ======= _selectordialog(selectorDialog), >>>>>>> Updating fixes on compiling +======= + NodeWatcher(SelectorDialog* selectordialog, Inkscape::XML::Node *repr) : + _selectordialog(selectordialog), +>>>>>>> Fix merge _repr(repr) { g_debug("SelectorDialog::NodeWatcher: Constructor"); @@ -260,6 +275,7 @@ SelectorDialog::TreeStore::on_row_deleted(const TreeModel::Path& path) } +<<<<<<< HEAD <<<<<<< HEAD Glib::RefPtr SelectorDialog::TreeStore::create(SelectorDialog *selectordialog) { @@ -271,6 +287,12 @@ Glib::RefPtr SelectorDialog::TreeStore::create(Select SelectorDialog::TreeStore * store = new SelectorDialog::TreeStore(); store->_selectordialog = selectorDialog; >>>>>>> Updating fixes on compiling +======= +Glib::RefPtr SelectorDialog::TreeStore::create(SelectorDialog *selectordialog) +{ + SelectorDialog::TreeStore * store = new SelectorDialog::TreeStore(); + store->_selectordialog = selectordialog; +>>>>>>> Fix merge store->set_column_types( store->_selectordialog->_mColumns ); return Glib::RefPtr( store ); } -- cgit v1.2.3 From d27a7eb0dbf86e2785c59306ca32bee9632784fb Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Mon, 22 Apr 2019 18:11:23 +0200 Subject: Backup fro full refactor --- src/ui/dialog/selectordialog.cpp | 1551 -------------------------------------- 1 file changed, 1551 deletions(-) delete mode 100644 src/ui/dialog/selectordialog.cpp (limited to 'src/ui/dialog/selectordialog.cpp') diff --git a/src/ui/dialog/selectordialog.cpp b/src/ui/dialog/selectordialog.cpp deleted file mode 100644 index 6e834ffb2..000000000 --- a/src/ui/dialog/selectordialog.cpp +++ /dev/null @@ -1,1551 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/** @file - * @brief A dialog for CSS selectors - */ -/* Authors: - * Kamalpreet Kaur Grewal - * Tavmjong Bah - * - * Copyright (C) Kamalpreet Kaur Grewal 2016 - * Copyright (C) Tavmjong Bah 2017 - * - * Released under GNU GPL v2+, read the file 'COPYING' for more information. - */ - -#include "selectordialog.h" -#include "verbs.h" -#include "selection.h" -#include "attribute-rel-svg.h" -#include "inkscape.h" -#include "document-undo.h" - -#include "ui/icon-loader.h" -#include "ui/widget/iconrenderer.h" - -#include "xml/attribute-record.h" -#include "xml/node-observer.h" - -#include -#include - -#include -#include - -<<<<<<< HEAD -<<<<<<< HEAD -//#define DEBUG_SELECTORDIALOG -//#define G_LOG_DOMAIN "SELECTORDIALOG" -======= -//#define DEBUG_selectorDialog -//#define G_LOG_DOMAIN "selectorDialog" ->>>>>>> Updating fixes on compiling -======= -//#define DEBUG_SELECTORDIALOG -//#define G_LOG_DOMAIN "SELECTORDIALOG" ->>>>>>> Fix merge - -using Inkscape::DocumentUndo; -using Inkscape::Util::List; -using Inkscape::XML::AttributeRecord; - -/** - * This macro is used to remove spaces around selectors or any strings when - * parsing is done to update XML style element or row labels in this dialog. - */ -#define REMOVE_SPACES(x) x.erase(0, x.find_first_not_of(' ')); \ - x.erase(x.find_last_not_of(' ') + 1); - -namespace Inkscape { -namespace UI { -namespace Dialog { - -// Keeps a watch on style element -class SelectorDialog::NodeObserver : public Inkscape::XML::NodeObserver { -public: -<<<<<<< HEAD - NodeObserver(SelectorDialog* selectorDialog) : -<<<<<<< HEAD - _selectorDialog(selectorDialog) -======= - _selectordialog(selectorDialog) ->>>>>>> Updating fixes on compiling -======= - NodeObserver(SelectorDialog* selectordialog) : - _selectordialog(selectordialog) ->>>>>>> Fix merge - { - g_debug("SelectorDialog::NodeObserver: Constructor"); - }; - - void notifyContentChanged(Inkscape::XML::Node &node, - Inkscape::Util::ptr_shared old_content, - Inkscape::Util::ptr_shared new_content) override; - -<<<<<<< HEAD - SelectorDialog * _selectorDialog; -======= - SelectorDialog * _selectordialog; ->>>>>>> Updating fixes on compiling -}; - - -void -SelectorDialog::NodeObserver::notifyContentChanged( - Inkscape::XML::Node &/*node*/, - Inkscape::Util::ptr_shared /*old_content*/, - Inkscape::Util::ptr_shared /*new_content*/ ) { - - g_debug("SelectorDialog::NodeObserver::notifyContentChanged"); -<<<<<<< HEAD - _selectorDialog->_updating = false; - _selectorDialog->_readStyleElement(); - _selectorDialog->_selectRow(); -======= - _selectordialog->_updating = false; - _selectordialog->_readStyleElement(); - _selectordialog->_selectRow(); ->>>>>>> Updating fixes on compiling -} - - -// Keeps a watch for new/removed/changed nodes -// (Must update objects that selectors match.) -class SelectorDialog::NodeWatcher : public Inkscape::XML::NodeObserver { -public: -<<<<<<< HEAD - NodeWatcher(SelectorDialog* selectorDialog, Inkscape::XML::Node *repr) : -<<<<<<< HEAD - _selectorDialog(selectorDialog), -======= - _selectordialog(selectorDialog), ->>>>>>> Updating fixes on compiling -======= - NodeWatcher(SelectorDialog* selectordialog, Inkscape::XML::Node *repr) : - _selectordialog(selectordialog), ->>>>>>> Fix merge - _repr(repr) - { - g_debug("SelectorDialog::NodeWatcher: Constructor"); - }; - - void notifyChildAdded( Inkscape::XML::Node &/*node*/, - Inkscape::XML::Node &child, - Inkscape::XML::Node */*prev*/ ) override - { -<<<<<<< HEAD - if ( _selectorDialog && _repr ) { - _selectorDialog->_nodeAdded( child ); -======= - if ( _selectordialog && _repr ) { - _selectordialog->_nodeAdded( child ); ->>>>>>> Updating fixes on compiling - } - } - - void notifyChildRemoved( Inkscape::XML::Node &/*node*/, - Inkscape::XML::Node &child, - Inkscape::XML::Node */*prev*/ ) override - { -<<<<<<< HEAD - if ( _selectorDialog && _repr ) { - _selectorDialog->_nodeRemoved( child ); -======= - if ( _selectordialog && _repr ) { - _selectordialog->_nodeRemoved( child ); ->>>>>>> Updating fixes on compiling - } - } - - void notifyAttributeChanged( Inkscape::XML::Node &node, - GQuark qname, - Util::ptr_shared /*old_value*/, - Util::ptr_shared /*new_value*/ ) override { -<<<<<<< HEAD - if ( _selectorDialog && _repr ) { -======= - if ( _selectordialog && _repr ) { ->>>>>>> Updating fixes on compiling - - // For the moment only care about attributes that are directly used in selectors. - const gchar * cname = g_quark_to_string (qname ); - Glib::ustring name; - if (cname) { - name = cname; - } - - if ( name == "id" || name == "class" ) { -<<<<<<< HEAD - _selectorDialog->_nodeChanged( node ); -======= - _selectordialog->_nodeChanged( node ); ->>>>>>> Updating fixes on compiling - } - } - } - -<<<<<<< HEAD - SelectorDialog * _selectorDialog; -======= - SelectorDialog * _selectordialog; ->>>>>>> Updating fixes on compiling - Inkscape::XML::Node * _repr; // Need to track if document changes. -}; - -void -SelectorDialog::_nodeAdded( Inkscape::XML::Node &node ) { - - SelectorDialog::NodeWatcher *w = new SelectorDialog::NodeWatcher (this, &node); - node.addObserver (*w); - _nodeWatchers.push_back(w); - - _readStyleElement(); - _selectRow(); -} - -void -SelectorDialog::_nodeRemoved( Inkscape::XML::Node &repr ) { - - for (auto it = _nodeWatchers.begin(); it != _nodeWatchers.end(); ++it) { - if ( (*it)->_repr == &repr ) { - (*it)->_repr->removeObserver (**it); - _nodeWatchers.erase( it ); - break; - } - } - - _readStyleElement(); - _selectRow(); -} - -void -SelectorDialog::_nodeChanged( Inkscape::XML::Node &object ) { - - _readStyleElement(); - _selectRow(); -} - -SelectorDialog::TreeStore::TreeStore() -= default; - - -/** - * Allow dragging only selectors. - */ -bool -SelectorDialog::TreeStore::row_draggable_vfunc(const Gtk::TreeModel::Path& path) const -{ - g_debug("SelectorDialog::TreeStore::row_draggable_vfunc"); - - auto unconstThis = const_cast(this); - const_iterator iter = unconstThis->get_iter(path); - if (iter) { - Gtk::TreeModel::Row row = *iter; - bool is_draggable = - row[_selectordialog->_mColumns._colType] == SELECTOR || row[_selectordialog->_mColumns._colType] == UNHANDLED; - return is_draggable; - } - return Gtk::TreeStore::row_draggable_vfunc(path); -} - - -/** - * Allow dropping only in between other selectors. - */ -bool -SelectorDialog::TreeStore::row_drop_possible_vfunc(const Gtk::TreeModel::Path& dest, - const Gtk::SelectionData& selection_data) const -{ - g_debug("SelectorDialog::TreeStore::row_drop_possible_vfunc"); - - Gtk::TreeModel::Path dest_parent = dest; - dest_parent.up(); - return dest_parent.empty(); -} - - -// This is only here to handle updating style element after a drag and drop. -void -SelectorDialog::TreeStore::on_row_deleted(const TreeModel::Path& path) -{ - if (_selectordialog->_updating) return; // Don't write if we deleted row (other than from DND) - - g_debug("on_row_deleted"); - - _selectordialog->_writeStyleElement(); -} - - -<<<<<<< HEAD -<<<<<<< HEAD -Glib::RefPtr SelectorDialog::TreeStore::create(SelectorDialog *selectordialog) -{ - SelectorDialog::TreeStore * store = new SelectorDialog::TreeStore(); - store->_selectordialog = selectordialog; -======= -Glib::RefPtr SelectorDialog::TreeStore::create(SelectorDialog *selectorDialog) -{ - SelectorDialog::TreeStore * store = new SelectorDialog::TreeStore(); - store->_selectordialog = selectorDialog; ->>>>>>> Updating fixes on compiling -======= -Glib::RefPtr SelectorDialog::TreeStore::create(SelectorDialog *selectordialog) -{ - SelectorDialog::TreeStore * store = new SelectorDialog::TreeStore(); - store->_selectordialog = selectordialog; ->>>>>>> Fix merge - store->set_column_types( store->_selectordialog->_mColumns ); - return Glib::RefPtr( store ); -} - -/** - * Constructor - * A treeview and a set of two buttons are added to the dialog. _addSelector - * adds selectors to treeview. _delSelector deletes the selector from the dialog. - * Any addition/deletion of the selectors updates XML style element accordingly. - */ -<<<<<<< HEAD -SelectorDialog::SelectorDialog() : - UI::Widget::Panel("/dialogs/style", SP_VERB_DIALOG_STYLE), - _updating(false), - _textNode(nullptr), - _desktopTracker() -======= -SelectorDialog::SelectorDialog(bool stylemode) : - UI::Widget::Panel("/dialogs/style", SP_VERB_DIALOG_STYLE), - _updating(false), - _textNode(nullptr), - _desktopTracker(), - _stylemode(stylemode) ->>>>>>> Updating fixes on compiling -{ - g_debug("SelectorDialog::SelectorDialog"); - - // Tree - Inkscape::UI::Widget::IconRenderer * addRenderer = manage( - new Inkscape::UI::Widget::IconRenderer() ); - addRenderer->add_icon("edit-delete"); - addRenderer->add_icon("list-add"); - addRenderer->add_icon("object-locked"); -<<<<<<< HEAD - - _store = TreeStore::create(this); - _treeView.set_model(_store); -======= - - _store = TreeStore::create(this); - _modelfilter = Gtk::TreeModelFilter::create(_store); - _modelfilter->set_visible_column(_mColumns._colVisible); - _treeView.set_model(_modelfilter); ->>>>>>> Updating fixes on compiling - _treeView.set_headers_visible(true); - _treeView.enable_model_drag_source(); - _treeView.enable_model_drag_dest( Gdk::ACTION_MOVE ); - int addCol = _treeView.append_column("", *addRenderer) - 1; - Gtk::TreeViewColumn *col = _treeView.get_column(addCol); - if ( col ) { - col->add_attribute(addRenderer->property_icon(), _mColumns._colType); - } - _treeView.append_column("CSS Selector", _mColumns._colSelector); - _treeView.set_expander_column(*(_treeView.get_column(1))); - - // Pack widgets - _paned.set_orientation(Gtk::ORIENTATION_VERTICAL); - _paned.pack1(_mainBox, Gtk::SHRINK); - _mainBox.set_orientation(Gtk::ORIENTATION_VERTICAL); -<<<<<<< HEAD - _mainBox.pack_start(_scrolledWindow, Gtk::PACK_EXPAND_WIDGET); - _scrolledWindow.add(_treeView); - _scrolledWindow.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); - - create = manage( new Gtk::Button() ); - _styleButton(*create, "list-add", "Add a new CSS Selector"); - create->signal_clicked().connect(sigc::mem_fun(*this, &SelectorDialog::_addSelector)); - - del = manage( new Gtk::Button() ); - _styleButton(*del, "list-remove", "Remove a CSS Selector"); - del->signal_clicked().connect(sigc::mem_fun(*this, &SelectorDialog::_delSelector)); - del->set_sensitive(false); - - _mainBox.pack_end(_buttonBox, Gtk::PACK_SHRINK); - - _buttonBox.pack_start(*create, Gtk::PACK_SHRINK); - _buttonBox.pack_start(*del, Gtk::PACK_SHRINK); - -======= - if (!_stylemode) { - _mainBox.pack_start(_scrolledWindow, Gtk::PACK_EXPAND_WIDGET); - _scrolledWindow.add(_treeView); - _scrolledWindow.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); - create = manage( new Gtk::Button() ); - _styleButton(*create, "list-add", "Add a new CSS Selector"); - create->signal_clicked().connect(sigc::mem_fun(*this, &SelectorDialog::_addSelector)); - - del = manage( new Gtk::Button() ); - _styleButton(*del, "list-remove", "Remove a CSS Selector"); - del->signal_clicked().connect(sigc::mem_fun(*this, &SelectorDialog::_delSelector)); - del->set_sensitive(false); - _mainBox.pack_end(_buttonBox, Gtk::PACK_SHRINK); - - _buttonBox.pack_start(*create, Gtk::PACK_SHRINK); - _buttonBox.pack_start(*del, Gtk::PACK_SHRINK); - } else { - _mainBox.pack_start(_treeView, Gtk::PACK_EXPAND_WIDGET); - } ->>>>>>> Updating fixes on compiling - _getContents()->pack_start(_paned, Gtk::PACK_EXPAND_WIDGET); - - - // Signal handlers - _treeView.signal_button_release_event().connect( // Needs to be release, not press. - sigc::mem_fun(*this, &SelectorDialog::_handleButtonEvent), - false); - - _treeView.signal_button_release_event().connect_notify( - sigc::mem_fun(*this, &SelectorDialog::_buttonEventsSelectObjs), - false); - - _treeView.signal_row_expanded().connect(sigc::mem_fun(*this, &SelectorDialog::_rowExpand)); - - _treeView.signal_row_collapsed().connect(sigc::mem_fun(*this, &SelectorDialog::_rowCollapse)); - - // Document & Desktop - _desktop_changed_connection = _desktopTracker.connectDesktopChanged( - sigc::mem_fun(*this, &SelectorDialog::_handleDesktopChanged) ); - _desktopTracker.connect(GTK_WIDGET(gobj())); - - _document_replaced_connection = getDesktop()->connectDocumentReplaced( - sigc::mem_fun(this, &SelectorDialog::_handleDocumentReplaced)); - - _selection_changed_connection = getDesktop()->getSelection()->connectChanged( - sigc::hide(sigc::mem_fun(this, &SelectorDialog::_handleSelectionChanged))); - - // Add watchers - _updateWatchers(); - - // Load tree - _readStyleElement(); - _selectRow(); - -<<<<<<< HEAD - if (!_store->children().empty()) { -======= - if (!_stylemode && !_store->children().empty()) { ->>>>>>> Updating fixes on compiling - del->set_sensitive(true); - } - -} - - -/** -<<<<<<< HEAD - * @brief SelectorDialog::~SelectorDialog -======= ->>>>>>> Updating fixes on compiling - * Class destructor - */ -SelectorDialog::~SelectorDialog() -{ - g_debug("SelectorDialog::~SelectorDialog"); - _desktop_changed_connection.disconnect(); - _document_replaced_connection.disconnect(); - _selection_changed_connection.disconnect(); -} - - -/** -<<<<<<< HEAD - * @brief SelectorDialog::_styleTextNode -======= ->>>>>>> Updating fixes on compiling - * @return Inkscape::XML::Node* pointing to a style element's text node. - * Returns the style element's text node. If there is no style element, one is created. - * Ditto for text node. - */ -Inkscape::XML::Node* SelectorDialog::_getStyleTextNode() -{ - - Inkscape::XML::Node *styleNode = nullptr; - Inkscape::XML::Node *textNode = nullptr; - - Inkscape::XML::Node *root = SP_ACTIVE_DOCUMENT->getReprRoot(); - for (unsigned i = 0; i < root->childCount(); ++i) { - if (Glib::ustring(root->nthChild(i)->name()) == "svg:style") { - - styleNode = root->nthChild(i); - - for (unsigned j = 0; j < styleNode->childCount(); ++j) { - if (styleNode->nthChild(j)->type() == Inkscape::XML::TEXT_NODE) { - textNode = styleNode->nthChild(j); - } - } - - if (textNode == nullptr) { - // Style element found but does not contain text node! - std::cerr << "SelectorDialog::_getStyleTextNode(): No text node!" << std::endl; - textNode = SP_ACTIVE_DOCUMENT->getReprDoc()->createTextNode(""); - styleNode->appendChild(textNode); - Inkscape::GC::release(textNode); - } - } - } - - if (styleNode == nullptr) { - // Style element not found, create one - styleNode = SP_ACTIVE_DOCUMENT->getReprDoc()->createElement("svg:style"); - textNode = SP_ACTIVE_DOCUMENT->getReprDoc()->createTextNode(""); - -<<<<<<< HEAD - root->addChild(styleNode, nullptr); - Inkscape::GC::release(styleNode); - - styleNode->appendChild(textNode); - Inkscape::GC::release(textNode); -======= - styleNode->appendChild(textNode); - Inkscape::GC::release(textNode); - - root->addChild(styleNode, nullptr); - Inkscape::GC::release(styleNode); ->>>>>>> Updating fixes on compiling - } - - if (_textNode != textNode) { - _textNode = textNode; - NodeObserver *no = new NodeObserver(this); - textNode->addObserver(*no); - } - - return textNode; -} - - -/** -<<<<<<< HEAD - * @brief SelectorDialog::_readStyleElement -======= ->>>>>>> Updating fixes on compiling - * Fill the Gtk::TreeStore from the svg:style element. - */ -void SelectorDialog::_readStyleElement() -{ - g_debug("SelectorDialog::_readStyleElement: updating %s", (_updating ? "true" : "false")); - - if (_updating) return; // Don't read if we wrote style element. - _updating = true; - - Inkscape::XML::Node * textNode = _getStyleTextNode(); - if (textNode == nullptr) { - std::cerr << "SelectorDialog::_readStyleElement: No text node!" << std::endl; - } - - // Get content from style text node. - std::string content = (textNode->content() ? textNode->content() : ""); - - // Remove end-of-lines (check it works on Windoze). - content.erase(std::remove(content.begin(), content.end(), '\n'), content.end()); - - // Remove comments (/* xxx */) - while(content.find("/*") != std::string::npos) { - size_t start = content.find("/*"); - content.erase(start, (content.find("*/", start) - start) +2); - } - - // First split into selector/value chunks. - // An attempt to use Glib::Regex failed. A C++11 version worked but - // reportedly has problems on Windows. Using split_simple() is simpler - // and probably faster. - // - // Glib::RefPtr regex1 = - // Glib::Regex::create("([^\\{]+)\\{([^\\{]+)\\}"); - // - // Glib::MatchInfo minfo; - // regex1->match(content, minfo); - - // Split on curly brackets. Even tokens are selectors, odd are values. -<<<<<<< HEAD -======= - std::cout << content << std::endl; - std::cout << "aaaaaaaaaaaaaaaaaaaaaaaaaa" << std::endl; ->>>>>>> Updating fixes on compiling - std::vector tokens = Glib::Regex::split_simple("[}{]", content); - - // If text node is empty, return (avoids problem with negative below). - if (tokens.size() == 0) { - _updating = false; - return; - } - std::vector> expanderstatus; - for (unsigned i = 0; i < tokens.size() - 1; i += 2) { - Glib::ustring selector = tokens[i]; - REMOVE_SPACES(selector); // Remove leading/trailing spaces - for (auto &row : _store->children()) { - Glib::ustring selectorold = row[_mColumns._colSelector]; - if (selectorold == selector) { - expanderstatus.emplace_back(selector, row[_mColumns._colExpand]); - } - } - } - _store->clear(); - - for (unsigned i = 0; i < tokens.size()-1; i += 2) { - - Glib::ustring selector = tokens[i]; - REMOVE_SPACES(selector); // Remove leading/trailing spaces - std::vector tokensplus = Glib::Regex::split_simple("[,]+", selector); - coltype colType = SELECTOR; - for (auto tok : tokensplus) { - REMOVE_SPACES(tok); -<<<<<<< HEAD - if (SPAttributeRelSVG::isSVGElement(tok) || tok.find(" ") != -1 || tok[0] == '>' || tok[0] == '+' || - tok[0] == '~' || tok[0] == '*' || tok.erase(0, 1).find(".") != -1) { -======= - if (tok.find(" ") != -1 || tok.erase(0, 1).find(".") != -1) { ->>>>>>> Updating fixes on compiling - colType = UNHANDLED; - } - } - // Get list of objects selector matches - std::vector objVec = _getObjVec( selector ); - - Glib::ustring properties; - // Check to make sure we do have a value to match selector. - if ((i+1) < tokens.size()) { - properties = tokens[i+1]; - } else { - std::cerr << "SelectorDialog::_readStyleElement: Missing values " - "for last selector!" << std::endl; - } - REMOVE_SPACES(properties); - bool colExpand = false; - for (auto rowstatus : expanderstatus) { - if (selector == rowstatus.first) { - colExpand = rowstatus.second; - } - } - Gtk::TreeModel::Row row = *(_store->append()); - row[_mColumns._colSelector] = selector; - row[_mColumns._colExpand] = colExpand; - row[_mColumns._colType] = colType; - row[_mColumns._colObj] = objVec; - row[_mColumns._colProperties] = properties; -<<<<<<< HEAD - // Add as children, objects that match selector. - for (auto &obj : objVec) { - Gtk::TreeModel::Row childrow = *(_store->append(row->children())); - childrow[_mColumns._colSelector] = "#" + Glib::ustring(obj->getId()); - childrow[_mColumns._colExpand] = false; - childrow[_mColumns._colType] = colType == UNHANDLED ? UNHANDLED : OBJECT; - childrow[_mColumns._colObj] = std::vector(1, obj); - childrow[_mColumns._colProperties] = ""; // Unused -======= - row[_mColumns._colVisible] = true; - if (colType == SELECTOR) { - // Add as children, objects that match selector. - for (auto &obj : objVec) { - Gtk::TreeModel::Row childrow = *(_store->append(row->children())); - childrow[_mColumns._colSelector] = "#" + Glib::ustring(obj->getId()); - childrow[_mColumns._colExpand] = false; - childrow[_mColumns._colType] = OBJECT; - childrow[_mColumns._colObj] = std::vector(1, obj); - childrow[_mColumns._colProperties] = ""; // Unused - childrow[_mColumns._colVisible] = true; // Unused - } ->>>>>>> Updating fixes on compiling - } - } - _updating = false; -} - -void SelectorDialog::_rowExpand(const Gtk::TreeModel::iterator &iter, const Gtk::TreeModel::Path &path) -{ - g_debug("SelectorDialog::_row_expand()"); - Gtk::TreeModel::Row row = *iter; - row[_mColumns._colExpand] = true; -} - -void SelectorDialog::_rowCollapse(const Gtk::TreeModel::iterator &iter, const Gtk::TreeModel::Path &path) -{ - g_debug("SelectorDialog::_row_collapse()"); - Gtk::TreeModel::Row row = *iter; - row[_mColumns._colExpand] = false; -} -/** -<<<<<<< HEAD - * @brief SelectorDialog::_writeStyleElement -======= ->>>>>>> Updating fixes on compiling - * Update the content of the style element as selectors (or objects) are added/removed. - */ -void SelectorDialog::_writeStyleElement() -{ - if (_updating) { - return; - } - _updating = true; - - Glib::ustring styleContent; - for (auto& row: _store->children()) { - Glib::ustring selector = row[_mColumns._colSelector]; - /* - REMOVE_SPACES(selector); - /* size_t len = selector.size(); - if(selector[len-1] == ','){ - selector.erase(len-1); - } - row[_mColumns._colSelector] = selector; */ - styleContent = styleContent + selector + " { " + row[_mColumns._colProperties] + " }\n"; - } - // We could test if styleContent is empty and then delete the style node here but there is no - // harm in keeping it around ... - - Inkscape::XML::Node *textNode = _getStyleTextNode(); - textNode->setContent(styleContent.c_str()); - - DocumentUndo::done(SP_ACTIVE_DOCUMENT, SP_VERB_DIALOG_STYLE, _("Edited style element.")); - - _updating = false; - g_debug("SelectorDialog::_writeStyleElement(): | %s |", styleContent.c_str()); -} - - -void SelectorDialog::_addWatcherRecursive(Inkscape::XML::Node *node) { - - g_debug("SelectorDialog::_addWatcherRecursive()"); - - SelectorDialog::NodeWatcher *w = new SelectorDialog::NodeWatcher(this, node); - node->addObserver(*w); - _nodeWatchers.push_back(w); - - for (unsigned i = 0; i < node->childCount(); ++i) { - _addWatcherRecursive(node->nthChild(i)); - } -} - -/** -<<<<<<< HEAD - * @brief SelectorDialog::_updateWatchers -======= ->>>>>>> Updating fixes on compiling - * Update the watchers on objects. - */ -void SelectorDialog::_updateWatchers() -{ - _updating = true; - - // Remove old document watchers - while (!_nodeWatchers.empty()) { - SelectorDialog::NodeWatcher *w = _nodeWatchers.back(); - w->_repr->removeObserver(*w); - _nodeWatchers.pop_back(); - delete w; - } - - // Recursively add new watchers - Inkscape::XML::Node *root = SP_ACTIVE_DOCUMENT->getReprRoot(); - _addWatcherRecursive(root); - - g_debug("SelectorDialog::_updateWatchers(): %d", (int)_nodeWatchers.size()); - - _updating = false; -} - - -/** -<<<<<<< HEAD - * @brief SelectorDialog::_addToSelector -======= ->>>>>>> Updating fixes on compiling - * @param row - * Add selected objects on the desktop to the selector corresponding to 'row'. - */ -void SelectorDialog::_addToSelector(Gtk::TreeModel::Row row) -{ - g_debug("SelectorDialog::_addToSelector: Entrance"); - if (*row) { - - Glib::ustring selector = row[_mColumns._colSelector]; - - if (selector[0] == '#') { - // 'id' selector... add selected object's id's to list. - Inkscape::Selection* selection = getDesktop()->getSelection(); - for (auto& obj: selection->objects()) { - - Glib::ustring id = (obj->getId()?obj->getId():""); - - std::vector objVec = row[_mColumns._colObj]; - bool found = false; - for (auto& obj: objVec) { - if (id == obj->getId()) { - found = true; - break; - } - } - - if (!found) { - // Update row - objVec.push_back(obj); // Adding to copy so need to update tree - row[_mColumns._colObj] = objVec; - row[_mColumns._colSelector] = _getIdList( objVec ); - row[_mColumns._colExpand] = true; - // Add child row - Gtk::TreeModel::Row childrow = *(_store->append(row->children())); - childrow[_mColumns._colSelector] = "#" + Glib::ustring(obj->getId()); - childrow[_mColumns._colType] = OBJECT; - childrow[_mColumns._colObj] = std::vector(1, obj); - childrow[_mColumns._colProperties] = ""; // Unused -<<<<<<< HEAD -======= - childrow[_mColumns._colVisible] = true; // Unused ->>>>>>> Updating fixes on compiling - } - } - } - - else if (selector[0] == '.') { - // 'class' selector... add value to class attribute of selected objects. - - // Get first class (split on white space or comma) - std::vector tokens = Glib::Regex::split_simple("[,\\s]+", selector); - Glib::ustring className = tokens[0]; - className.erase(0,1); - Inkscape::Selection* selection = getDesktop()->getSelection(); - std::vector sel_obj(selection->objects().begin(), selection->objects().end()); - _insertClass(sel_obj, className); - std::vector objVec = _getObjVec(selector); - ; - for (auto &obj : sel_obj) { - - Glib::ustring id = (obj->getId() ? obj->getId() : ""); - bool found = false; - for (auto &obj : objVec) { - if (id == obj->getId()) { - found = true; - break; - } - } - - if (!found) { - // Update row - objVec.push_back(obj); // Adding to copy so need to update tree - row[_mColumns._colObj] = objVec; - row[_mColumns._colExpand] = true; - - // Update row - Gtk::TreeModel::Row childrow = *(_store->append(row->children())); - childrow[_mColumns._colSelector] = "#" + Glib::ustring(obj->getId()); - childrow[_mColumns._colExpand] = false; - childrow[_mColumns._colType] = OBJECT; - childrow[_mColumns._colObj] = std::vector(1, obj); - childrow[_mColumns._colProperties] = ""; // Unused -<<<<<<< HEAD -======= - childrow[_mColumns._colVisible] = true; // Unused ->>>>>>> Updating fixes on compiling - } - } - } - - else { - // Do nothing for element selectors. - // std::cout << " Element selector... doing nothing!" << std::endl; - } - } - - _writeStyleElement(); -} - - -/** -<<<<<<< HEAD - * @brief SelectorDialog::_removeFromSelector -======= ->>>>>>> Updating fixes on compiling - * @param row - * Remove the object corresponding to 'row' from the parent selector. - */ -void SelectorDialog::_removeFromSelector(Gtk::TreeModel::Row row) -{ - g_debug("SelectorDialog::_removeFromSelector: Entrance"); - if (*row) { - - Glib::ustring objectLabel = row[_mColumns._colSelector]; -<<<<<<< HEAD - if (row[_mColumns._colType] == UNHANDLED) { - return; - }; -======= ->>>>>>> Updating fixes on compiling - Gtk::TreeModel::iterator iter = row->parent(); - if (iter) { - Gtk::TreeModel::Row parent = *iter; - Glib::ustring selector = parent[_mColumns._colSelector]; - REMOVE_SPACES(selector); - if (selector[0] == '#') { - // 'id' selector... remove selected object's id's to list. - - // Erase from selector label. - auto i = selector.find(objectLabel); - if (i != Glib::ustring::npos) { - selector.erase(i, objectLabel.length()); - } - // Erase any comma/space - REMOVE_SPACES(selector); - if (i != Glib::ustring::npos && selector[i] == ',') { - selector.erase(i, 1); - } - if (i != Glib::ustring::npos && selector[i] == ' ') { - selector.erase(i, 1); - } - REMOVE_SPACES(selector); - if (selector[selector.size() - 1] == ',') { - selector.erase(selector.size() - 1, 1); - } - - // Update store - if (selector.empty()) { - _store->erase(parent); - } else { - // Save new selector and update object vector. - parent[_mColumns._colSelector] = selector; - parent[_mColumns._colObj] = _getObjVec( selector ); - parent[_mColumns._colExpand] = true; - _store->erase(row); - } - } - - else if (selector[0] == '.') { - // 'class' selector... remove value to class attribute of selected objects. - - std::vector objVec = row[_mColumns._colObj]; // Just one - // Get first class (split on white space or comma) - std::vector tokens = Glib::Regex::split_simple("[,\\s]+", selector); - Glib::ustring className = tokens[0]; - className.erase(0, 1); - // Erase class name from 'class' attribute. - Glib::ustring classAttr = objVec[0]->getRepr()->attribute("class"); - auto i = classAttr.find( className ); - if (i != Glib::ustring::npos) { - classAttr.erase(i, className.length()); - } - if (i != Glib::ustring::npos && classAttr[i] == ' ') { - classAttr.erase(i, 1); - } - _store->erase(row); - objVec[0]->getRepr()->setAttribute("class", classAttr); - parent[_mColumns._colExpand] = true; - } else { - // Do nothing for element selectors. - // std::cout << " Element selector... doing nothing!" << std::endl; - } - } - } - _writeStyleElement(); -} - - -/** -<<<<<<< HEAD - * @brief SelectorDialog::_getIdList -======= ->>>>>>> Updating fixes on compiling - * @param sel - * @return This function returns a comma separated list of ids for objects in input vector. - * It is used in creating an 'id' selector. It relies on objects having 'id's. - */ -Glib::ustring SelectorDialog::_getIdList(std::vector sel) -{ - Glib::ustring str; - for (auto& obj: sel) { - str += "#" + Glib::ustring(obj->getId()) + ", "; - } - if (!str.empty()) { - str.erase(str.size()-1); // Remove space at end. c++11 has pop_back() but not ustring. - str.erase(str.size()-1); // Remove comma at end. - } - return str; -} - -/** -<<<<<<< HEAD - * @brief SelectorDialog::_getObjVec -======= ->>>>>>> Updating fixes on compiling - * @param selector: a valid CSS selector string. - * @return objVec: a vector of pointers to SPObject's the selector matches. - * Return a vector of all objects that selector matches. - */ -std::vector SelectorDialog::_getObjVec(Glib::ustring selector) { - -<<<<<<< HEAD - std::vector objVec; - std::vector tokensplus = Glib::Regex::split_simple("[,]+", selector); - bool unhandled = false; - for (auto tok : tokensplus) { - REMOVE_SPACES(tok); - if (SPAttributeRelSVG::isSVGElement(tok) || tok.find(" ") != -1 || tok[0] == '>' || tok[0] == '+' || - tok[0] == '~' || tok[0] == '*' || tok.erase(0, 1).find(".") != -1) { - unhandled = true; - std::vector objVecSplited = SP_ACTIVE_DOCUMENT->getObjectsBySelector(tok); - objVec.insert(objVec.end(), objVecSplited.begin(), objVecSplited.end()); - } - } - if (!unhandled) { - objVec = SP_ACTIVE_DOCUMENT->getObjectsBySelector(selector); - } -======= - std::vector objVec = SP_ACTIVE_DOCUMENT->getObjectsBySelector( selector ); - ->>>>>>> Updating fixes on compiling - g_debug("SelectorDialog::_getObjVec: | %s |", selector.c_str()); - for (auto& obj: objVec) { - g_debug(" %s", obj->getId() ? obj->getId() : "null"); - } - - return objVec; -} - - -/** -<<<<<<< HEAD - * @brief SelectorDialog::_insertClass -======= ->>>>>>> Updating fixes on compiling - * @param objs: list of objects to insert class - * @param class: class to insert - * Insert a class name into objects' 'class' attribute. - */ -void SelectorDialog::_insertClass(const std::vector& objVec, const Glib::ustring& className) { - - for (auto& obj: objVec) { - - if (!obj->getRepr()->attribute("class")) { - // 'class' attribute does not exist, create it. - obj->getRepr()->setAttribute("class", className); - } else { - // 'class' attribute exists, append. - Glib::ustring classAttr = obj->getRepr()->attribute("class"); - - // Split on white space. - std::vector tokens = Glib::Regex::split_simple("\\s+", classAttr); - bool add = true; - for (auto& token: tokens) { - if (token == className) { - add = false; // Might be useful to still add... - break; - } - } - if (add) { - obj->getRepr()->setAttribute("class", classAttr + " " + className ); - } - } - } - } - - -/** -<<<<<<< HEAD - * @brief SelectorDialog::_selectObjects -======= ->>>>>>> Updating fixes on compiling - * @param eventX - * @param eventY - * This function selects objects in the drawing corresponding to the selector - * selected in the treeview. - */ -void SelectorDialog::_selectObjects(int eventX, int eventY) -{ - g_debug("SelectorDialog::_selectObjects: %d, %d", eventX, eventY); - - getDesktop()->selection->clear(); - Gtk::TreeViewColumn *col = _treeView.get_column(1); - Gtk::TreeModel::Path path; - int x2 = 0; - int y2 = 0; - // To do: We should be able to do this via passing in row. - if (_treeView.get_path_at_pos(eventX, eventY, path, col, x2, y2)) { - if (col == _treeView.get_column(1)) { - Gtk::TreeModel::iterator iter = _store->get_iter(path); - if (iter) { - Gtk::TreeModel::Row row = *iter; - Gtk::TreeModel::Children children = row.children(); -<<<<<<< HEAD - if (children.empty()) { -======= - if (children.empty() && !_stylemode) { ->>>>>>> Updating fixes on compiling - del->set_sensitive(true); - } - std::vector objVec = row[_mColumns._colObj]; - - for (auto obj : objVec) { - getDesktop()->selection->add(obj); - } - } - } - } -} - - -/** -<<<<<<< HEAD - * @brief SelectorDialog::_addSelector - * -======= ->>>>>>> Updating fixes on compiling - * This function opens a dialog to add a selector. The dialog is prefilled - * with an 'id' selector containing a list of the id's of selected objects - * or with a 'class' selector if no objects are selected. - */ -void SelectorDialog::_addSelector() -{ - g_debug("SelectorDialog::_addSelector: Entrance"); - - // Store list of selected elements on desktop (not to be confused with selector). - Inkscape::Selection* selection = getDesktop()->getSelection(); - std::vector objVec( selection->objects().begin(), - selection->objects().end() ); - - // ==== Create popup dialog ==== - Gtk::Dialog *textDialogPtr = new Gtk::Dialog(); - textDialogPtr->add_button(_("Cancel"), Gtk::RESPONSE_CANCEL); - textDialogPtr->add_button(_("Add"), Gtk::RESPONSE_OK); - - Gtk::Entry *textEditPtr = manage ( new Gtk::Entry() ); - textEditPtr->signal_activate().connect( - sigc::bind(sigc::mem_fun(*this, &SelectorDialog::_closeDialog), textDialogPtr)); - textDialogPtr->get_content_area()->pack_start(*textEditPtr, Gtk::PACK_SHRINK); - - Gtk::Label *textLabelPtr = manage ( new Gtk::Label( - _("Invalid entry: Not an id (#), class (.), or element CSS selector.") - ) ); - textDialogPtr->get_content_area()->pack_start(*textLabelPtr, Gtk::PACK_SHRINK); - - /** - * By default, the entrybox contains 'Class1' as text. However, if object(s) - * is(are) selected and user clicks '+' at the bottom of dialog, the - * entrybox will have the id(s) of the selected objects as text. - */ - if (getDesktop()->getSelection()->isEmpty()) { - textEditPtr->set_text(".Class1"); - } else { - textEditPtr->set_text(_getIdList(objVec)); - } - - Gtk::Requisition sreq1, sreq2; - textDialogPtr->get_preferred_size(sreq1, sreq2); - int minWidth = 200; - int minHeight = 100; - minWidth = (sreq2.width > minWidth ? sreq2.width : minWidth ); - minHeight = (sreq2.height > minHeight ? sreq2.height : minHeight); - textDialogPtr->set_size_request(minWidth, minHeight); - textEditPtr->show(); - textLabelPtr->hide(); - textDialogPtr->show(); - - - // ==== Get response ==== - int result = -1; - bool invalid = true; - Glib::ustring selectorValue; - bool handled = true; - while (invalid) { - result = textDialogPtr->run(); - if (result != Gtk::RESPONSE_OK) { // Cancel, close dialog, etc. - textDialogPtr->hide(); - delete textDialogPtr; - return; - } - /** - * @brief selectorName - * This string stores selector name. The text from entrybox is saved as name - * for selector. If the entrybox is empty, the text (thus selectorName) is - * set to ".Class1" - */ - selectorValue = textEditPtr->get_text(); -<<<<<<< HEAD - - del->set_sensitive(true); - std::vector tokensplus = Glib::Regex::split_simple("[,]+", selectorValue); - bool unhandled = false; - bool partialinvalid = false; - for (auto tok : tokensplus) { - REMOVE_SPACES(tok); - if (SPAttributeRelSVG::isSVGElement(tok) || tok.find(" ") != -1 || tok[0] == '>' || tok[0] == '+' || - tok[0] == '~' || tok[0] == '*' || tok.erase(0, 1).find(".") != -1) { - unhandled = true; - Glib::ustring firstWord = tok.substr(0, tok.find_first_of(" >+~")); - if (firstWord != tok) { - handled = false; - } - - if (!partialinvalid && - (tok[0] == '.' || tok[0] == '#' || tok[0] == '*' || SPAttributeRelSVG::isSVGElement(tok))) { - partialinvalid = false; - } else { - partialinvalid = true; - } - } - } - if (!unhandled) { - Glib::ustring firstWord = selectorValue.substr(0, selectorValue.find_first_of(" >+~")); - if (firstWord != selectorValue) { - handled = false; - } - if (selectorValue[0] == '.' || selectorValue[0] == '#' || selectorValue[0] == '*' || - SPAttributeRelSVG::isSVGElement(selectorValue)) { - invalid = false; - } else { - textLabelPtr->show(); - } - } else if (partialinvalid) { - textLabelPtr->show(); - } else { - invalid = false; -======= - Glib::ustring firstWord = selectorValue.substr(0, selectorValue.find_first_of(" >+~")); - if (firstWord != selectorValue) { - handled = false; - } - if (!_stylemode) { - del->set_sensitive(true); - } - if (selectorValue[0] == '.' || selectorValue[0] == '#' || selectorValue[0] == '*' || - SPAttributeRelSVG::isSVGElement(selectorValue)) { - invalid = false; - } else { - textLabelPtr->show(); ->>>>>>> Updating fixes on compiling - } - } - delete textDialogPtr; - // ==== Handle response ==== - - // If class selector, add selector name to class attribute for each object - if (selectorValue[0] == '.' && handled) { - std::vector tokens = Glib::Regex::split_simple("[,\\s]+", selectorValue); - Glib::ustring originClassName = tokens[0]; - originClassName.erase(0, 1); - std::vector classes = Glib::Regex::split_simple("[\\.]+", originClassName); - if (classes.size() == 1) { - _insertClass(objVec, classes[0]); - } else { - handled = false; - } - } - - // Generate a new object vector (we could have an element selector, - // the user could have edited the id selector list, etc.). - objVec = _getObjVec( selectorValue ); - - // Add entry to GUI tree - Gtk::TreeModel::Row row = *(_store->append()); - row[_mColumns._colSelector] = selectorValue; - row[_mColumns._colExpand] = true; - row[_mColumns._colType] = handled ? SELECTOR : UNHANDLED; - row[_mColumns._colObj] = objVec; - - // Add as children objects that match selector. - if (handled) { - for (auto &obj : objVec) { - Gtk::TreeModel::Row childrow = *(_store->append(row->children())); - childrow[_mColumns._colSelector] = "#" + Glib::ustring(obj->getId()); - childrow[_mColumns._colExpand] = false; - childrow[_mColumns._colType] = OBJECT; - childrow[_mColumns._colObj] = std::vector(1, obj); - } - } - - // Add entry to style element - _writeStyleElement(); -} - -void SelectorDialog::_closeDialog(Gtk::Dialog *textDialogPtr) { textDialogPtr->response(Gtk::RESPONSE_OK); } - -/** -<<<<<<< HEAD - * @brief SelectorDialog::_delSelector -======= ->>>>>>> Updating fixes on compiling - * This function deletes selector when '-' at the bottom is clicked. - * Note: If deleting a class selector, class attributes are NOT changed. - */ -void SelectorDialog::_delSelector() -{ - g_debug("SelectorDialog::_delSelector"); - - Glib::RefPtr refTreeSelection = _treeView.get_selection(); - _treeView.get_selection()->set_mode(Gtk::SELECTION_SINGLE); - Gtk::TreeModel::iterator iter = refTreeSelection->get_selected(); - if (iter) { - Gtk::TreeModel::Row row = *iter; - if (!row.children().empty()) { - return; - } - _updating = true; - _store->erase(iter); - _updating = false; - _writeStyleElement(); -<<<<<<< HEAD - del->set_sensitive(false); -======= - if (!_stylemode) { - del->set_sensitive(false); - } ->>>>>>> Updating fixes on compiling - } -} - -/** -<<<<<<< HEAD - * @brief SelectorDialog::_handleButtonEvent -======= ->>>>>>> Updating fixes on compiling - * @param event - * @return - * Handles the event when '+' button in front of a selector name is clicked or when a '-' button in - * front of a child object is clicked. In the first case, the selected objects on the desktop (if - * any) are added as children of the selector in the treeview. In the latter case, the object - * corresponding to the row is removed from the selector. - */ -bool SelectorDialog::_handleButtonEvent(GdkEventButton *event) -{ - g_debug("SelectorDialog::_handleButtonEvent: Entrance"); - if (event->type == GDK_BUTTON_RELEASE && event->button == 1) { - Gtk::TreeViewColumn *col = nullptr; - Gtk::TreeModel::Path path; - int x = static_cast(event->x); - int y = static_cast(event->y); - int x2 = 0; - int y2 = 0; - - if (_treeView.get_path_at_pos(x, y, path, col, x2, y2)) { - if (col == _treeView.get_column(0)) { - bool remove_parent = false; - Gtk::TreeModel::iterator iter = _store->get_iter(path); - Gtk::TreeModel::Row row = *iter; - Glib::RefPtr sel = _treeView.get_selection(); - sel->select(row); - // Add or remove objects from a - Gtk::TreeModel::Row row_to_sel; - if (!row.parent()) { - row_to_sel = row; - _addToSelector(row); - } else { - row_to_sel = *row.parent(); - _removeFromSelector(row); - } - } - } - } - return false; -} - -// ------------------------------------------------------------------- - -class PropertyData -{ -public: - PropertyData() = default;; - PropertyData(Glib::ustring name) : _name(std::move(name)) {}; - - void _setSheetValue(Glib::ustring value) { _sheetValue = value; }; - void _setAttrValue(Glib::ustring value) { _attrValue = value; }; - Glib::ustring _getName() { return _name; }; - Glib::ustring _getSheetValue() { return _sheetValue; }; - Glib::ustring _getAttrValue() { return _attrValue; }; - -private: - Glib::ustring _name; - Glib::ustring _sheetValue; - Glib::ustring _attrValue; -}; - -// ------------------------------------------------------------------- - - -/** - * Handle document replaced. (Happens when a default document is immediately replaced by another - * document in a new window.) - */ -void -SelectorDialog::_handleDocumentReplaced(SPDesktop *desktop, SPDocument * /* document */) -{ - g_debug("SelectorDialog::handleDocumentReplaced()"); - - _selection_changed_connection.disconnect(); - - _selection_changed_connection = desktop->getSelection()->connectChanged( - sigc::hide(sigc::mem_fun(this, &SelectorDialog::_handleSelectionChanged))); - - _updateWatchers(); - _readStyleElement(); - _selectRow(); -} - - -/* - * When a dialog is floating, it is connected to the active desktop. - */ -void -SelectorDialog::_handleDesktopChanged(SPDesktop* desktop) { - g_debug("SelectorDialog::handleDesktopReplaced()"); - - if (getDesktop() == desktop) { - // This will happen after construction of dialog. We've already - // set up signals so just return. - return; - } - - _selection_changed_connection.disconnect(); - _document_replaced_connection.disconnect(); - - setDesktop( desktop ); - - _selection_changed_connection = desktop->getSelection()->connectChanged( - sigc::hide(sigc::mem_fun(this, &SelectorDialog::_handleSelectionChanged))); - _document_replaced_connection = desktop->connectDocumentReplaced( - sigc::mem_fun(this, &SelectorDialog::_handleDocumentReplaced)); - - _updateWatchers(); - _readStyleElement(); - _selectRow(); -} - - -/* - * Handle a change in which objects are selected in a document. - */ -void -SelectorDialog::_handleSelectionChanged() { - g_debug("SelectorDialog::_handleSelectionChanged()"); - _treeView.get_selection()->set_mode(Gtk::SELECTION_MULTIPLE); - _selectRow(); -} - - -/** -<<<<<<< HEAD - * @brief SelectorDialog::_buttonEventsSelectObjs -======= ->>>>>>> Updating fixes on compiling - * @param event - * This function detects single or double click on a selector in any row. Clicking - * on a selector selects the matching objects on the desktop. A double click will - * in addition open the CSS dialog. - */ -void SelectorDialog::_buttonEventsSelectObjs(GdkEventButton* event ) -{ - g_debug("SelectorDialog::_buttonEventsSelectObjs"); - _treeView.get_selection()->set_mode(Gtk::SELECTION_SINGLE); - _updating = true; -<<<<<<< HEAD - del->set_sensitive(true); -======= - if (!_stylemode) { - del->set_sensitive(true); - } ->>>>>>> Updating fixes on compiling - if (event->type == GDK_BUTTON_RELEASE && event->button == 1) { - int x = static_cast(event->x); - int y = static_cast(event->y); - _selectObjects(x, y); - } - _updating = false; -} - - -/** -<<<<<<< HEAD - * @brief SelectorDialog::_selectRow -======= ->>>>>>> Updating fixes on compiling - * This function selects the row in treeview corresponding to an object selected - * in the drawing. If more than one row matches, the first is chosen. - */ -void SelectorDialog::_selectRow() -{ - g_debug("SelectorDialog::_selectRow: updating: %s", (_updating ? "true" : "false")); -<<<<<<< HEAD - del->set_sensitive(false); -======= - if (!_stylemode) { - del->set_sensitive(false); - } ->>>>>>> Updating fixes on compiling - if (_updating || !getDesktop()) return; // Avoid updating if we have set row via dialog. - if (SP_ACTIVE_DESKTOP != getDesktop()) { - std::cerr << "SelectorDialog::_selectRow: SP_ACTIVE_DESKTOP != getDesktop()" << std::endl; - return; - } - _treeView.get_selection()->unselect_all(); - Gtk::TreeModel::Children children = _store->children(); - Inkscape::Selection* selection = getDesktop()->getSelection(); - SPObject *obj = nullptr; - if (!selection->isEmpty()) { - obj = selection->objects().back(); - } - for (auto row : children) { - std::vector objVec = row[_mColumns._colObj]; - if (obj) { - for (auto & i : objVec) { - if (obj->getId() == i->getId()) { - _treeView.get_selection()->select(row); -<<<<<<< HEAD -======= - row[_mColumns._colVisible] = true; - } else if(_stylemode) { - row[_mColumns._colVisible] = false; ->>>>>>> Updating fixes on compiling - } - } - } - if (row[_mColumns._colExpand]) { - _treeView.expand_to_path(Gtk::TreePath(row)); - } - } -<<<<<<< HEAD -} - - -/** - * @brief SelectorDialog::_styleButton -======= - if (_stylemode) { - _modelfilter->refilter(); - _treeView.get_selection()->unselect_all(); - } -} - -/** ->>>>>>> Updating fixes on compiling - * @param btn - * @param iconName - * @param tooltip - * Set the style of '+' and '-' buttons at the bottom of dialog. - */ -void SelectorDialog::_styleButton(Gtk::Button& btn, char const* iconName, - char const* tooltip) -{ - GtkWidget *child = sp_get_icon_image(iconName, GTK_ICON_SIZE_SMALL_TOOLBAR); - gtk_widget_show(child); - btn.add(*manage(Glib::wrap(child))); - btn.set_relief(Gtk::RELIEF_NONE); - btn.set_tooltip_text (tooltip); -} - - -} // namespace Dialog -} // namespace UI -} // namespace Inkscape - -/* - Local Variables: - mode:c++ - c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) - indent-tabs-mode:nil - fill-column:99 - End: -*/ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : -- cgit v1.2.3 From cc1d3e4bb71dcc1df631c57e1922b12be331d2c1 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Fri, 26 Apr 2019 22:55:02 +0200 Subject: Working on selectors and unhandled ones --- src/ui/dialog/selectordialog.cpp | 1274 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 1274 insertions(+) create mode 100644 src/ui/dialog/selectordialog.cpp (limited to 'src/ui/dialog/selectordialog.cpp') diff --git a/src/ui/dialog/selectordialog.cpp b/src/ui/dialog/selectordialog.cpp new file mode 100644 index 000000000..70c4388cd --- /dev/null +++ b/src/ui/dialog/selectordialog.cpp @@ -0,0 +1,1274 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/** @file + * @brief A dialog for CSS selectors + */ +/* Authors: + * Kamalpreet Kaur Grewal + * Tavmjong Bah + * + * Copyright (C) Kamalpreet Kaur Grewal 2016 + * Copyright (C) Tavmjong Bah 2017 + * + * Released under GNU GPL v2+, read the file 'COPYING' for more information. + */ + +#include "selectordialog.h" +#include "verbs.h" +#include "selection.h" +#include "attribute-rel-svg.h" +#include "inkscape.h" +#include "document-undo.h" + +#include "ui/icon-loader.h" +#include "ui/widget/iconrenderer.h" + +#include "xml/attribute-record.h" +#include "xml/node-observer.h" + +#include +#include + +#include +#include + +//#define DEBUG_SELECTORDIALOG +//#define G_LOG_DOMAIN "SELECTORDIALOG" + +using Inkscape::DocumentUndo; +using Inkscape::Util::List; +using Inkscape::XML::AttributeRecord; + +/** + * This macro is used to remove spaces around selectors or any strings when + * parsing is done to update XML style element or row labels in this dialog. + */ +#define REMOVE_SPACES(x) x.erase(0, x.find_first_not_of(' ')); \ + x.erase(x.find_last_not_of(' ') + 1); + +namespace Inkscape { +namespace UI { +namespace Dialog { + +// Keeps a watch on style element +class SelectorDialog::NodeObserver : public Inkscape::XML::NodeObserver { +public: + NodeObserver(SelectorDialog* selectordialog) : + _selectordialog(selectordialog) + { + g_debug("SelectorDialog::NodeObserver: Constructor"); + }; + + void notifyContentChanged(Inkscape::XML::Node &node, + Inkscape::Util::ptr_shared old_content, + Inkscape::Util::ptr_shared new_content) override; + + SelectorDialog * _selectordialog; +}; + + +void +SelectorDialog::NodeObserver::notifyContentChanged( + Inkscape::XML::Node &/*node*/, + Inkscape::Util::ptr_shared /*old_content*/, + Inkscape::Util::ptr_shared /*new_content*/ ) { + + g_debug("SelectorDialog::NodeObserver::notifyContentChanged"); + _selectordialog->_updating = false; + _selectordialog->_readStyleElement(); + _selectordialog->_selectRow(); +} + + +// Keeps a watch for new/removed/changed nodes +// (Must update objects that selectors match.) +class SelectorDialog::NodeWatcher : public Inkscape::XML::NodeObserver { +public: + NodeWatcher(SelectorDialog* selectordialog, Inkscape::XML::Node *repr) : + _selectordialog(selectordialog), + _repr(repr) + { + g_debug("SelectorDialog::NodeWatcher: Constructor"); + }; + + void notifyChildAdded( Inkscape::XML::Node &/*node*/, + Inkscape::XML::Node &child, + Inkscape::XML::Node */*prev*/ ) override + { + if ( _selectordialog && _repr ) { + _selectordialog->_nodeAdded( child ); + } + } + + void notifyChildRemoved( Inkscape::XML::Node &/*node*/, + Inkscape::XML::Node &child, + Inkscape::XML::Node */*prev*/ ) override + { + if ( _selectordialog && _repr ) { + _selectordialog->_nodeRemoved( child ); + } + } + + void notifyAttributeChanged( Inkscape::XML::Node &node, + GQuark qname, + Util::ptr_shared /*old_value*/, + Util::ptr_shared /*new_value*/ ) override { + if ( _selectordialog && _repr ) { + + // For the moment only care about attributes that are directly used in selectors. + const gchar * cname = g_quark_to_string (qname ); + Glib::ustring name; + if (cname) { + name = cname; + } + + if ( name == "id" || name == "class" ) { + _selectordialog->_nodeChanged( node ); + } + } + } + + SelectorDialog * _selectordialog; + Inkscape::XML::Node * _repr; // Need to track if document changes. +}; + +void +SelectorDialog::_nodeAdded( Inkscape::XML::Node &node ) { + + SelectorDialog::NodeWatcher *w = new SelectorDialog::NodeWatcher (this, &node); + node.addObserver (*w); + _nodeWatchers.push_back(w); + + _readStyleElement(); + _selectRow(); +} + +void +SelectorDialog::_nodeRemoved( Inkscape::XML::Node &repr ) { + + for (auto it = _nodeWatchers.begin(); it != _nodeWatchers.end(); ++it) { + if ( (*it)->_repr == &repr ) { + (*it)->_repr->removeObserver (**it); + _nodeWatchers.erase( it ); + break; + } + } + + _readStyleElement(); + _selectRow(); +} + +void +SelectorDialog::_nodeChanged( Inkscape::XML::Node &object ) { + + _readStyleElement(); + _selectRow(); +} + +SelectorDialog::TreeStore::TreeStore() += default; + + +/** + * Allow dragging only selectors. + */ +bool +SelectorDialog::TreeStore::row_draggable_vfunc(const Gtk::TreeModel::Path& path) const +{ + g_debug("SelectorDialog::TreeStore::row_draggable_vfunc"); + + auto unconstThis = const_cast(this); + const_iterator iter = unconstThis->get_iter(path); + if (iter) { + Gtk::TreeModel::Row row = *iter; + bool is_draggable = + row[_selectordialog->_mColumns._colType] == SELECTOR || row[_selectordialog->_mColumns._colType] == UNHANDLED; + return is_draggable; + } + return Gtk::TreeStore::row_draggable_vfunc(path); +} + + +/** + * Allow dropping only in between other selectors. + */ +bool +SelectorDialog::TreeStore::row_drop_possible_vfunc(const Gtk::TreeModel::Path& dest, + const Gtk::SelectionData& selection_data) const +{ + g_debug("SelectorDialog::TreeStore::row_drop_possible_vfunc"); + + Gtk::TreeModel::Path dest_parent = dest; + dest_parent.up(); + return dest_parent.empty(); +} + + +// This is only here to handle updating style element after a drag and drop. +void +SelectorDialog::TreeStore::on_row_deleted(const TreeModel::Path& path) +{ + if (_selectordialog->_updating) return; // Don't write if we deleted row (other than from DND) + + g_debug("on_row_deleted"); + + _selectordialog->_writeStyleElement(); +} + + +Glib::RefPtr SelectorDialog::TreeStore::create(SelectorDialog *selectordialog) +{ + SelectorDialog::TreeStore * store = new SelectorDialog::TreeStore(); + store->_selectordialog = selectordialog; + store->set_column_types( store->_selectordialog->_mColumns ); + return Glib::RefPtr( store ); +} + +/** + * Constructor + * A treeview and a set of two buttons are added to the dialog. _addSelector + * adds selectors to treeview. _delSelector deletes the selector from the dialog. + * Any addition/deletion of the selectors updates XML style element accordingly. + */ +SelectorDialog::SelectorDialog(bool stylemode) : + UI::Widget::Panel("/dialogs/style", SP_VERB_DIALOG_STYLE), + _updating(false), + _textNode(nullptr), + _desktopTracker(), + _stylemode(stylemode) +{ + g_debug("SelectorDialog::SelectorDialog"); + + // Tree + Inkscape::UI::Widget::IconRenderer * addRenderer = manage( + new Inkscape::UI::Widget::IconRenderer() ); + addRenderer->add_icon("edit-delete"); + addRenderer->add_icon("list-add"); + addRenderer->add_icon("object-locked"); + + _store = TreeStore::create(this); + if (_stylemode) { + _modelfilter = Gtk::TreeModelFilter::create(_store); + _modelfilter->set_visible_column(_mColumns._colVisible); + _treeView.set_model(_modelfilter); + } else { + _treeView.set_model(_store); + } + if (_stylemode) { + _treeView.set_headers_visible(false); + _treeView.set_grid_lines (Gtk::TREE_VIEW_GRID_LINES_HORIZONTAL); + } else { + _treeView.set_headers_visible(true); + } + _treeView.enable_model_drag_source(); + _treeView.enable_model_drag_dest( Gdk::ACTION_MOVE ); + int addCol = _treeView.append_column("", *addRenderer) - 1; + Gtk::TreeViewColumn *col = _treeView.get_column(addCol); + if ( col ) { + col->add_attribute(addRenderer->property_icon(), _mColumns._colType); + } + _treeView.append_column("CSS Selector", _mColumns._colSelector); + _treeView.set_expander_column(*(_treeView.get_column(1))); + + // Pack widgets + _paned.set_orientation(Gtk::ORIENTATION_VERTICAL); + _paned.pack1(_mainBox, Gtk::SHRINK); + _mainBox.set_orientation(Gtk::ORIENTATION_VERTICAL); + if (!_stylemode) { + _mainBox.pack_start(_scrolledWindow, Gtk::PACK_EXPAND_WIDGET); + _scrolledWindow.add(_treeView); + _scrolledWindow.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); + create = manage( new Gtk::Button() ); + _styleButton(*create, "list-add", "Add a new CSS Selector"); + create->signal_clicked().connect(sigc::mem_fun(*this, &SelectorDialog::_addSelector)); + + del = manage( new Gtk::Button() ); + _styleButton(*del, "list-remove", "Remove a CSS Selector"); + del->signal_clicked().connect(sigc::mem_fun(*this, &SelectorDialog::_delSelector)); + del->set_sensitive(false); + _mainBox.pack_end(_buttonBox, Gtk::PACK_SHRINK); + + _buttonBox.pack_start(*create, Gtk::PACK_SHRINK); + _buttonBox.pack_start(*del, Gtk::PACK_SHRINK); + } else { + _mainBox.pack_start(_treeView, Gtk::PACK_EXPAND_WIDGET); + } + _getContents()->pack_start(_paned, Gtk::PACK_EXPAND_WIDGET); + + + // Signal handlers + _treeView.signal_button_release_event().connect( // Needs to be release, not press. + sigc::mem_fun(*this, &SelectorDialog::_handleButtonEvent), + false); + + _treeView.signal_button_release_event().connect_notify( + sigc::mem_fun(*this, &SelectorDialog::_buttonEventsSelectObjs), + false); + + _treeView.signal_row_expanded().connect(sigc::mem_fun(*this, &SelectorDialog::_rowExpand)); + + _treeView.signal_row_collapsed().connect(sigc::mem_fun(*this, &SelectorDialog::_rowCollapse)); + + // Document & Desktop + _desktop_changed_connection = _desktopTracker.connectDesktopChanged( + sigc::mem_fun(*this, &SelectorDialog::_handleDesktopChanged) ); + _desktopTracker.connect(GTK_WIDGET(gobj())); + + _document_replaced_connection = getDesktop()->connectDocumentReplaced( + sigc::mem_fun(this, &SelectorDialog::_handleDocumentReplaced)); + + _selection_changed_connection = getDesktop()->getSelection()->connectChanged( + sigc::hide(sigc::mem_fun(this, &SelectorDialog::_handleSelectionChanged))); + + // Add watchers + _updateWatchers(); + + // Load tree + _readStyleElement(); + _selectRow(); + + if (!_stylemode && !_store->children().empty()) { + del->set_sensitive(true); + } + +} + + +/** + * Class destructor + */ +SelectorDialog::~SelectorDialog() +{ + g_debug("SelectorDialog::~SelectorDialog"); + _desktop_changed_connection.disconnect(); + _document_replaced_connection.disconnect(); + _selection_changed_connection.disconnect(); +} + + +/** + * @return Inkscape::XML::Node* pointing to a style element's text node. + * Returns the style element's text node. If there is no style element, one is created. + * Ditto for text node. + */ +Inkscape::XML::Node* SelectorDialog::_getStyleTextNode() +{ + + Inkscape::XML::Node *styleNode = nullptr; + Inkscape::XML::Node *textNode = nullptr; + + Inkscape::XML::Node *root = SP_ACTIVE_DOCUMENT->getReprRoot(); + for (unsigned i = 0; i < root->childCount(); ++i) { + if (Glib::ustring(root->nthChild(i)->name()) == "svg:style") { + + styleNode = root->nthChild(i); + + for (unsigned j = 0; j < styleNode->childCount(); ++j) { + if (styleNode->nthChild(j)->type() == Inkscape::XML::TEXT_NODE) { + textNode = styleNode->nthChild(j); + } + } + + if (textNode == nullptr) { + // Style element found but does not contain text node! + std::cerr << "SelectorDialog::_getStyleTextNode(): No text node!" << std::endl; + textNode = SP_ACTIVE_DOCUMENT->getReprDoc()->createTextNode(""); + styleNode->appendChild(textNode); + Inkscape::GC::release(textNode); + } + } + } + + if (styleNode == nullptr) { + // Style element not found, create one + styleNode = SP_ACTIVE_DOCUMENT->getReprDoc()->createElement("svg:style"); + textNode = SP_ACTIVE_DOCUMENT->getReprDoc()->createTextNode(""); + + styleNode->appendChild(textNode); + Inkscape::GC::release(textNode); + + root->addChild(styleNode, nullptr); + Inkscape::GC::release(styleNode); + } + + if (_textNode != textNode) { + _textNode = textNode; + NodeObserver *no = new NodeObserver(this); + textNode->addObserver(*no); + } + + return textNode; +} + + +/** + * Fill the Gtk::TreeStore from the svg:style element. + */ +void SelectorDialog::_readStyleElement() +{ + g_debug("SelectorDialog::_readStyleElement: updating %s", (_updating ? "true" : "false")); + + if (_updating) return; // Don't read if we wrote style element. + _updating = true; + + Inkscape::XML::Node * textNode = _getStyleTextNode(); + if (textNode == nullptr) { + std::cerr << "SelectorDialog::_readStyleElement: No text node!" << std::endl; + } + + // Get content from style text node. + std::string content = (textNode->content() ? textNode->content() : ""); + + // Remove end-of-lines (check it works on Windoze). + content.erase(std::remove(content.begin(), content.end(), '\n'), content.end()); + + // Remove comments (/* xxx */) + while(content.find("/*") != std::string::npos) { + size_t start = content.find("/*"); + content.erase(start, (content.find("*/", start) - start) +2); + } + + // First split into selector/value chunks. + // An attempt to use Glib::Regex failed. A C++11 version worked but + // reportedly has problems on Windows. Using split_simple() is simpler + // and probably faster. + // + // Glib::RefPtr regex1 = + // Glib::Regex::create("([^\\{]+)\\{([^\\{]+)\\}"); + // + // Glib::MatchInfo minfo; + // regex1->match(content, minfo); + + // Split on curly brackets. Even tokens are selectors, odd are values. + std::vector tokens = Glib::Regex::split_simple("[}{]", content); + + // If text node is empty, return (avoids problem with negative below). + if (tokens.size() == 0) { + _updating = false; + return; + } + std::vector> expanderstatus; + for (unsigned i = 0; i < tokens.size() - 1; i += 2) { + Glib::ustring selector = tokens[i]; + REMOVE_SPACES(selector); // Remove leading/trailing spaces + for (auto &row : _store->children()) { + Glib::ustring selectorold = row[_mColumns._colSelector]; + if (selectorold == selector) { + expanderstatus.emplace_back(selector, row[_mColumns._colExpand]); + } + } + } + _store->clear(); + + for (unsigned i = 0; i < tokens.size()-1; i += 2) { + + Glib::ustring selector = tokens[i]; + REMOVE_SPACES(selector); // Remove leading/trailing spaces + std::vector tokensplus = Glib::Regex::split_simple("[,]+", selector); + coltype colType = SELECTOR; + for (auto tok : tokensplus) { + REMOVE_SPACES(tok); + if (tok.find(" ") != -1 || tok.erase(0, 1).find(".") != -1) { + colType = UNHANDLED; + } + } + // Get list of objects selector matches + std::vector objVec = _getObjVec( selector ); + + Glib::ustring properties; + // Check to make sure we do have a value to match selector. + if ((i+1) < tokens.size()) { + properties = tokens[i+1]; + } else { + std::cerr << "SelectorDialog::_readStyleElement: Missing values " + "for last selector!" << std::endl; + } + REMOVE_SPACES(properties); + bool colExpand = false; + for (auto rowstatus : expanderstatus) { + if (selector == rowstatus.first) { + colExpand = rowstatus.second; + } + } + std::vector properties_data = Glib::Regex::split_simple(";", properties); + Gtk::TreeModel::Row row = *(_store->append()); + row[_mColumns._colSelector] = selector; + row[_mColumns._colExpand] = colExpand; + row[_mColumns._colType] = colType; + row[_mColumns._colObj] = objVec; + row[_mColumns._colProperties] = properties; + row[_mColumns._colVisible] = true; + if (!_stylemode) { + // Add as children, objects that match selector. + for (auto &obj : objVec) { + Gtk::TreeModel::Row childrow = *(_store->append(row->children())); + childrow[_mColumns._colSelector] = "#" + Glib::ustring(obj->getId()); + childrow[_mColumns._colExpand] = false; + childrow[_mColumns._colType] = colType == UNHANDLED?UNHANDLED:OBJECT;; + childrow[_mColumns._colObj] = std::vector(1, obj); + childrow[_mColumns._colProperties] = ""; // Unused + childrow[_mColumns._colVisible] = true; // Unused + } + } else { + for (auto property : properties_data) { + Gtk::TreeModel::Row childrow = *(_store->append(row->children())); + childrow[_mColumns._colSelector] = Glib::ustring(property); + childrow[_mColumns._colExpand] = false; + childrow[_mColumns._colType] = 0; + childrow[_mColumns._colObj] = {}; + childrow[_mColumns._colProperties] = ""; // Unused + childrow[_mColumns._colVisible] = true; // Unused + } + } + } + + + _updating = false; +} + +void SelectorDialog::_rowExpand(const Gtk::TreeModel::iterator &iter, const Gtk::TreeModel::Path &path) +{ + g_debug("SelectorDialog::_row_expand()"); + Gtk::TreeModel::Row row = *iter; + row[_mColumns._colExpand] = true; +} + +void SelectorDialog::_rowCollapse(const Gtk::TreeModel::iterator &iter, const Gtk::TreeModel::Path &path) +{ + g_debug("SelectorDialog::_row_collapse()"); + Gtk::TreeModel::Row row = *iter; + row[_mColumns._colExpand] = false; +} +/** + * Update the content of the style element as selectors (or objects) are added/removed. + */ +void SelectorDialog::_writeStyleElement() +{ + if (_updating) { + return; + } + _updating = true; + + Glib::ustring styleContent; + for (auto& row: _store->children()) { + Glib::ustring selector = row[_mColumns._colSelector]; + /* + REMOVE_SPACES(selector); + /* size_t len = selector.size(); + if(selector[len-1] == ','){ + selector.erase(len-1); + } + row[_mColumns._colSelector] = selector; */ + styleContent = styleContent + selector + " { " + row[_mColumns._colProperties] + " }\n"; + } + // We could test if styleContent is empty and then delete the style node here but there is no + // harm in keeping it around ... + + Inkscape::XML::Node *textNode = _getStyleTextNode(); + textNode->setContent(styleContent.c_str()); + + DocumentUndo::done(SP_ACTIVE_DOCUMENT, SP_VERB_DIALOG_STYLE, _("Edited style element.")); + + _updating = false; + g_debug("SelectorDialog::_writeStyleElement(): | %s |", styleContent.c_str()); +} + + +void SelectorDialog::_addWatcherRecursive(Inkscape::XML::Node *node) { + + g_debug("SelectorDialog::_addWatcherRecursive()"); + + SelectorDialog::NodeWatcher *w = new SelectorDialog::NodeWatcher(this, node); + node->addObserver(*w); + _nodeWatchers.push_back(w); + + for (unsigned i = 0; i < node->childCount(); ++i) { + _addWatcherRecursive(node->nthChild(i)); + } +} + +/** + * Update the watchers on objects. + */ +void SelectorDialog::_updateWatchers() +{ + _updating = true; + + // Remove old document watchers + while (!_nodeWatchers.empty()) { + SelectorDialog::NodeWatcher *w = _nodeWatchers.back(); + w->_repr->removeObserver(*w); + _nodeWatchers.pop_back(); + delete w; + } + + // Recursively add new watchers + Inkscape::XML::Node *root = SP_ACTIVE_DOCUMENT->getReprRoot(); + _addWatcherRecursive(root); + + g_debug("SelectorDialog::_updateWatchers(): %d", (int)_nodeWatchers.size()); + + _updating = false; +} + + +/** + * @param row + * Add selected objects on the desktop to the selector corresponding to 'row'. + */ +void SelectorDialog::_addToSelector(Gtk::TreeModel::Row row) +{ + g_debug("SelectorDialog::_addToSelector: Entrance"); + if (*row) { + + Glib::ustring selector = row[_mColumns._colSelector]; + + if (selector[0] == '#') { + // 'id' selector... add selected object's id's to list. + Inkscape::Selection* selection = getDesktop()->getSelection(); + for (auto& obj: selection->objects()) { + + Glib::ustring id = (obj->getId()?obj->getId():""); + + std::vector objVec = row[_mColumns._colObj]; + bool found = false; + for (auto& obj: objVec) { + if (id == obj->getId()) { + found = true; + break; + } + } + + if (!found) { + // Update row + objVec.push_back(obj); // Adding to copy so need to update tree + row[_mColumns._colObj] = objVec; + row[_mColumns._colSelector] = _getIdList( objVec ); + row[_mColumns._colExpand] = true; + // Add child row + Gtk::TreeModel::Row childrow = *(_store->append(row->children())); + childrow[_mColumns._colSelector] = "#" + Glib::ustring(obj->getId()); + childrow[_mColumns._colType] = OBJECT; + childrow[_mColumns._colObj] = std::vector(1, obj); + childrow[_mColumns._colProperties] = ""; // Unused + childrow[_mColumns._colVisible] = true; // Unused + } + } + } + + else if (selector[0] == '.') { + // 'class' selector... add value to class attribute of selected objects. + + // Get first class (split on white space or comma) + std::vector tokens = Glib::Regex::split_simple("[,\\s]+", selector); + Glib::ustring className = tokens[0]; + className.erase(0,1); + Inkscape::Selection* selection = getDesktop()->getSelection(); + std::vector sel_obj(selection->objects().begin(), selection->objects().end()); + _insertClass(sel_obj, className); + std::vector objVec = _getObjVec(selector); + ; + for (auto &obj : sel_obj) { + + Glib::ustring id = (obj->getId() ? obj->getId() : ""); + bool found = false; + for (auto &obj : objVec) { + if (id == obj->getId()) { + found = true; + break; + } + } + + if (!found) { + // Update row + objVec.push_back(obj); // Adding to copy so need to update tree + row[_mColumns._colObj] = objVec; + row[_mColumns._colExpand] = true; + + // Update row + Gtk::TreeModel::Row childrow = *(_store->append(row->children())); + childrow[_mColumns._colSelector] = "#" + Glib::ustring(obj->getId()); + childrow[_mColumns._colExpand] = false; + childrow[_mColumns._colType] = OBJECT; + childrow[_mColumns._colObj] = std::vector(1, obj); + childrow[_mColumns._colProperties] = ""; // Unused + childrow[_mColumns._colVisible] = true; // Unused + } + } + } + + else { + // Do nothing for element selectors. + // std::cout << " Element selector... doing nothing!" << std::endl; + } + } + + _writeStyleElement(); +} + + +/** + * @param row + * Remove the object corresponding to 'row' from the parent selector. + */ +void SelectorDialog::_removeFromSelector(Gtk::TreeModel::Row row) +{ + g_debug("SelectorDialog::_removeFromSelector: Entrance"); + if (*row) { + + Glib::ustring objectLabel = row[_mColumns._colSelector]; + if (row[_mColumns._colType] == UNHANDLED) { + return; + }; + Gtk::TreeModel::iterator iter = row->parent(); + if (iter) { + Gtk::TreeModel::Row parent = *iter; + Glib::ustring selector = parent[_mColumns._colSelector]; + REMOVE_SPACES(selector); + if (selector[0] == '#') { + // 'id' selector... remove selected object's id's to list. + + // Erase from selector label. + auto i = selector.find(objectLabel); + if (i != Glib::ustring::npos) { + selector.erase(i, objectLabel.length()); + } + // Erase any comma/space + REMOVE_SPACES(selector); + if (i != Glib::ustring::npos && selector[i] == ',') { + selector.erase(i, 1); + } + if (i != Glib::ustring::npos && selector[i] == ' ') { + selector.erase(i, 1); + } + REMOVE_SPACES(selector); + if (selector[selector.size() - 1] == ',') { + selector.erase(selector.size() - 1, 1); + } + + // Update store + if (selector.empty()) { + _store->erase(parent); + } else { + // Save new selector and update object vector. + parent[_mColumns._colSelector] = selector; + parent[_mColumns._colObj] = _getObjVec( selector ); + parent[_mColumns._colExpand] = true; + _store->erase(row); + } + } + + else if (selector[0] == '.') { + // 'class' selector... remove value to class attribute of selected objects. + + std::vector objVec = row[_mColumns._colObj]; // Just one + // Get first class (split on white space or comma) + std::vector tokens = Glib::Regex::split_simple("[,\\s]+", selector); + Glib::ustring className = tokens[0]; + className.erase(0, 1); + // Erase class name from 'class' attribute. + Glib::ustring classAttr = objVec[0]->getRepr()->attribute("class"); + auto i = classAttr.find( className ); + if (i != Glib::ustring::npos) { + classAttr.erase(i, className.length()); + } + if (i != Glib::ustring::npos && classAttr[i] == ' ') { + classAttr.erase(i, 1); + } + _store->erase(row); + objVec[0]->getRepr()->setAttribute("class", classAttr); + parent[_mColumns._colExpand] = true; + } else { + // Do nothing for element selectors. + // std::cout << " Element selector... doing nothing!" << std::endl; + } + } + } + _writeStyleElement(); +} + + +/** + * @param sel + * @return This function returns a comma separated list of ids for objects in input vector. + * It is used in creating an 'id' selector. It relies on objects having 'id's. + */ +Glib::ustring SelectorDialog::_getIdList(std::vector sel) +{ + Glib::ustring str; + for (auto& obj: sel) { + str += "#" + Glib::ustring(obj->getId()) + ", "; + } + if (!str.empty()) { + str.erase(str.size()-1); // Remove space at end. c++11 has pop_back() but not ustring. + str.erase(str.size()-1); // Remove comma at end. + } + return str; +} + +/** + * @param selector: a valid CSS selector string. + * @return objVec: a vector of pointers to SPObject's the selector matches. + * Return a vector of all objects that selector matches. + */ +std::vector SelectorDialog::_getObjVec(Glib::ustring selector) { + + std::vector objVec = SP_ACTIVE_DOCUMENT->getObjectsBySelector( selector ); + + g_debug("SelectorDialog::_getObjVec: | %s |", selector.c_str()); + for (auto& obj: objVec) { + g_debug(" %s", obj->getId() ? obj->getId() : "null"); + } + + return objVec; +} + + +/** + * @param objs: list of objects to insert class + * @param class: class to insert + * Insert a class name into objects' 'class' attribute. + */ +void SelectorDialog::_insertClass(const std::vector& objVec, const Glib::ustring& className) { + + for (auto& obj: objVec) { + + if (!obj->getRepr()->attribute("class")) { + // 'class' attribute does not exist, create it. + obj->getRepr()->setAttribute("class", className); + } else { + // 'class' attribute exists, append. + Glib::ustring classAttr = obj->getRepr()->attribute("class"); + + // Split on white space. + std::vector tokens = Glib::Regex::split_simple("\\s+", classAttr); + bool add = true; + for (auto& token: tokens) { + if (token == className) { + add = false; // Might be useful to still add... + break; + } + } + if (add) { + obj->getRepr()->setAttribute("class", classAttr + " " + className ); + } + } + } + } + + +/** + * @param eventX + * @param eventY + * This function selects objects in the drawing corresponding to the selector + * selected in the treeview. + */ +void SelectorDialog::_selectObjects(int eventX, int eventY) +{ + g_debug("SelectorDialog::_selectObjects: %d, %d", eventX, eventY); + if (_stylemode) { + return; + } + getDesktop()->selection->clear(); + Gtk::TreeViewColumn *col = _treeView.get_column(1); + Gtk::TreeModel::Path path; + int x2 = 0; + int y2 = 0; + // To do: We should be able to do this via passing in row. + if (_treeView.get_path_at_pos(eventX, eventY, path, col, x2, y2)) { + if (col == _treeView.get_column(1)) { + Gtk::TreeModel::iterator iter = _store->get_iter(path); + if (iter) { + Gtk::TreeModel::Row row = *iter; + Gtk::TreeModel::Children children = row.children(); + if (children.empty() && !_stylemode) { + del->set_sensitive(true); + } + std::vector objVec = row[_mColumns._colObj]; + + for (auto obj : objVec) { + getDesktop()->selection->add(obj); + } + } + } + } +} + + +/** + * This function opens a dialog to add a selector. The dialog is prefilled + * with an 'id' selector containing a list of the id's of selected objects + * or with a 'class' selector if no objects are selected. + */ +void SelectorDialog::_addSelector() +{ + g_debug("SelectorDialog::_addSelector: Entrance"); + + // Store list of selected elements on desktop (not to be confused with selector). + Inkscape::Selection* selection = getDesktop()->getSelection(); + std::vector objVec( selection->objects().begin(), + selection->objects().end() ); + + // ==== Create popup dialog ==== + Gtk::Dialog *textDialogPtr = new Gtk::Dialog(); + textDialogPtr->add_button(_("Cancel"), Gtk::RESPONSE_CANCEL); + textDialogPtr->add_button(_("Add"), Gtk::RESPONSE_OK); + + Gtk::Entry *textEditPtr = manage ( new Gtk::Entry() ); + textEditPtr->signal_activate().connect( + sigc::bind(sigc::mem_fun(*this, &SelectorDialog::_closeDialog), textDialogPtr)); + textDialogPtr->get_content_area()->pack_start(*textEditPtr, Gtk::PACK_SHRINK); + + Gtk::Label *textLabelPtr = manage ( new Gtk::Label( + _("Invalid entry: Not an id (#), class (.), or element CSS selector.") + ) ); + textDialogPtr->get_content_area()->pack_start(*textLabelPtr, Gtk::PACK_SHRINK); + + /** + * By default, the entrybox contains 'Class1' as text. However, if object(s) + * is(are) selected and user clicks '+' at the bottom of dialog, the + * entrybox will have the id(s) of the selected objects as text. + */ + if (getDesktop()->getSelection()->isEmpty()) { + textEditPtr->set_text(".Class1"); + } else { + textEditPtr->set_text(_getIdList(objVec)); + } + + Gtk::Requisition sreq1, sreq2; + textDialogPtr->get_preferred_size(sreq1, sreq2); + int minWidth = 200; + int minHeight = 100; + minWidth = (sreq2.width > minWidth ? sreq2.width : minWidth ); + minHeight = (sreq2.height > minHeight ? sreq2.height : minHeight); + textDialogPtr->set_size_request(minWidth, minHeight); + textEditPtr->show(); + textLabelPtr->hide(); + textDialogPtr->show(); + + + // ==== Get response ==== + int result = -1; + bool invalid = true; + Glib::ustring selectorValue; + bool handled = true; + while (invalid) { + result = textDialogPtr->run(); + if (result != Gtk::RESPONSE_OK) { // Cancel, close dialog, etc. + textDialogPtr->hide(); + delete textDialogPtr; + return; + } + /** + * @brief selectorName + * This string stores selector name. The text from entrybox is saved as name + * for selector. If the entrybox is empty, the text (thus selectorName) is + * set to ".Class1" + */ + selectorValue = textEditPtr->get_text(); + Glib::ustring firstWord = selectorValue.substr(0, selectorValue.find_first_of(" >+~")); + if (firstWord != selectorValue) { + handled = false; + } + if (!_stylemode) { + del->set_sensitive(true); + } + if (selectorValue[0] == '.' || selectorValue[0] == '#' || selectorValue[0] == '*' || + SPAttributeRelSVG::isSVGElement(selectorValue)) { + invalid = false; + } else { + textLabelPtr->show(); + } + } + delete textDialogPtr; + // ==== Handle response ==== + + // If class selector, add selector name to class attribute for each object + if (selectorValue[0] == '.' && handled) { + std::vector tokens = Glib::Regex::split_simple("[,\\s]+", selectorValue); + Glib::ustring originClassName = tokens[0]; + originClassName.erase(0, 1); + std::vector classes = Glib::Regex::split_simple("[\\.]+", originClassName); + if (classes.size() == 1) { + _insertClass(objVec, classes[0]); + } else { + handled = false; + } + } + + // Generate a new object vector (we could have an element selector, + // the user could have edited the id selector list, etc.). + objVec = _getObjVec( selectorValue ); + + // Add entry to GUI tree + Gtk::TreeModel::Row row = *(_store->append()); + row[_mColumns._colSelector] = selectorValue; + row[_mColumns._colExpand] = true; + row[_mColumns._colType] = handled ? SELECTOR : UNHANDLED; + row[_mColumns._colObj] = objVec; + + // Add as children objects that match selector. + if (handled) { + for (auto &obj : objVec) { + Gtk::TreeModel::Row childrow = *(_store->append(row->children())); + childrow[_mColumns._colSelector] = "#" + Glib::ustring(obj->getId()); + childrow[_mColumns._colExpand] = false; + childrow[_mColumns._colType] = OBJECT; + childrow[_mColumns._colObj] = std::vector(1, obj); + } + } + + // Add entry to style element + _writeStyleElement(); +} + +void SelectorDialog::_closeDialog(Gtk::Dialog *textDialogPtr) { textDialogPtr->response(Gtk::RESPONSE_OK); } + +/** + * This function deletes selector when '-' at the bottom is clicked. + * Note: If deleting a class selector, class attributes are NOT changed. + */ +void SelectorDialog::_delSelector() +{ + g_debug("SelectorDialog::_delSelector"); + + Glib::RefPtr refTreeSelection = _treeView.get_selection(); + _treeView.get_selection()->set_mode(Gtk::SELECTION_SINGLE); + Gtk::TreeModel::iterator iter = refTreeSelection->get_selected(); + if (iter) { + Gtk::TreeModel::Row row = *iter; + if (!row.children().empty()) { + return; + } + _updating = true; + _store->erase(iter); + _updating = false; + _writeStyleElement(); + if (!_stylemode) { + del->set_sensitive(false); + } + } +} + +/** + * @param event + * @return + * Handles the event when '+' button in front of a selector name is clicked or when a '-' button in + * front of a child object is clicked. In the first case, the selected objects on the desktop (if + * any) are added as children of the selector in the treeview. In the latter case, the object + * corresponding to the row is removed from the selector. + */ +bool SelectorDialog::_handleButtonEvent(GdkEventButton *event) +{ + g_debug("SelectorDialog::_handleButtonEvent: Entrance"); + if (event->type == GDK_BUTTON_RELEASE && event->button == 1) { + Gtk::TreeViewColumn *col = nullptr; + Gtk::TreeModel::Path path; + int x = static_cast(event->x); + int y = static_cast(event->y); + int x2 = 0; + int y2 = 0; + + if (_treeView.get_path_at_pos(x, y, path, col, x2, y2)) { + if (col == _treeView.get_column(0)) { + bool remove_parent = false; + Gtk::TreeModel::iterator iter = _store->get_iter(path); + Gtk::TreeModel::Row row = *iter; + Glib::RefPtr sel = _treeView.get_selection(); + sel->select(row); + // Add or remove objects from a + Gtk::TreeModel::Row row_to_sel; + if (!row.parent()) { + row_to_sel = row; + _addToSelector(row); + } else { + row_to_sel = *row.parent(); + _removeFromSelector(row); + } + } + } + } + return false; +} + +// ------------------------------------------------------------------- + +class PropertyData +{ +public: + PropertyData() = default;; + PropertyData(Glib::ustring name) : _name(std::move(name)) {}; + + void _setSheetValue(Glib::ustring value) { _sheetValue = value; }; + void _setAttrValue(Glib::ustring value) { _attrValue = value; }; + Glib::ustring _getName() { return _name; }; + Glib::ustring _getSheetValue() { return _sheetValue; }; + Glib::ustring _getAttrValue() { return _attrValue; }; + +private: + Glib::ustring _name; + Glib::ustring _sheetValue; + Glib::ustring _attrValue; +}; + +// ------------------------------------------------------------------- + + +/** + * Handle document replaced. (Happens when a default document is immediately replaced by another + * document in a new window.) + */ +void +SelectorDialog::_handleDocumentReplaced(SPDesktop *desktop, SPDocument * /* document */) +{ + g_debug("SelectorDialog::handleDocumentReplaced()"); + + _selection_changed_connection.disconnect(); + + _selection_changed_connection = desktop->getSelection()->connectChanged( + sigc::hide(sigc::mem_fun(this, &SelectorDialog::_handleSelectionChanged))); + + _updateWatchers(); + _readStyleElement(); + _selectRow(); +} + + +/* + * When a dialog is floating, it is connected to the active desktop. + */ +void +SelectorDialog::_handleDesktopChanged(SPDesktop* desktop) { + g_debug("SelectorDialog::handleDesktopReplaced()"); + + if (getDesktop() == desktop) { + // This will happen after construction of dialog. We've already + // set up signals so just return. + return; + } + + _selection_changed_connection.disconnect(); + _document_replaced_connection.disconnect(); + + setDesktop( desktop ); + + _selection_changed_connection = desktop->getSelection()->connectChanged( + sigc::hide(sigc::mem_fun(this, &SelectorDialog::_handleSelectionChanged))); + _document_replaced_connection = desktop->connectDocumentReplaced( + sigc::mem_fun(this, &SelectorDialog::_handleDocumentReplaced)); + + _updateWatchers(); + _readStyleElement(); + _selectRow(); +} + + +/* + * Handle a change in which objects are selected in a document. + */ +void +SelectorDialog::_handleSelectionChanged() { + g_debug("SelectorDialog::_handleSelectionChanged()"); + _treeView.get_selection()->set_mode(Gtk::SELECTION_MULTIPLE); + _selectRow(); +} + + +/** + * @param event + * This function detects single or double click on a selector in any row. Clicking + * on a selector selects the matching objects on the desktop. A double click will + * in addition open the CSS dialog. + */ +void SelectorDialog::_buttonEventsSelectObjs(GdkEventButton* event ) +{ + g_debug("SelectorDialog::_buttonEventsSelectObjs"); + _treeView.get_selection()->set_mode(Gtk::SELECTION_SINGLE); + _updating = true; + if (!_stylemode) { + del->set_sensitive(true); + } + if (event->type == GDK_BUTTON_RELEASE && event->button == 1) { + int x = static_cast(event->x); + int y = static_cast(event->y); + _selectObjects(x, y); + } + _updating = false; +} + + +/** + * This function selects the row in treeview corresponding to an object selected + * in the drawing. If more than one row matches, the first is chosen. + */ +void SelectorDialog::_selectRow() +{ + g_debug("SelectorDialog::_selectRow: updating: %s", (_updating ? "true" : "false")); + if (!_stylemode) { + del->set_sensitive(false); + } + if (_updating || !getDesktop()) return; // Avoid updating if we have set row via dialog. + if (SP_ACTIVE_DESKTOP != getDesktop()) { + std::cerr << "SelectorDialog::_selectRow: SP_ACTIVE_DESKTOP != getDesktop()" << std::endl; + return; + } + _treeView.get_selection()->unselect_all(); + Gtk::TreeModel::Children children = _store->children(); + Inkscape::Selection* selection = getDesktop()->getSelection(); + SPObject *obj = nullptr; + if (!selection->isEmpty()) { + obj = selection->objects().back(); + } + for (auto row : children) { + std::vector objVec = row[_mColumns._colObj]; + if (obj) { + for (auto & i : objVec) { + if (obj->getId() == i->getId()) { + _treeView.get_selection()->select(row); + row[_mColumns._colVisible] = true; + break; + } else if(_stylemode) { + row[_mColumns._colVisible] = false; + } + } + } + if (row[_mColumns._colExpand]) { + _treeView.expand_to_path(Gtk::TreePath(row)); + } + } + if (_stylemode) { + _modelfilter->refilter(); + _treeView.get_selection()->unselect_all(); + } +} + +/** + * @param btn + * @param iconName + * @param tooltip + * Set the style of '+' and '-' buttons at the bottom of dialog. + */ +void SelectorDialog::_styleButton(Gtk::Button& btn, char const* iconName, + char const* tooltip) +{ + GtkWidget *child = sp_get_icon_image(iconName, GTK_ICON_SIZE_SMALL_TOOLBAR); + gtk_widget_show(child); + btn.add(*manage(Glib::wrap(child))); + btn.set_relief(Gtk::RELIEF_NONE); + btn.set_tooltip_text (tooltip); +} + + +} // namespace Dialog +} // namespace UI +} // namespace Inkscape + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : -- cgit v1.2.3 From 22ceac00bfe22a63e61af6ea1bbd22e7c7bbe715 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Fri, 26 Apr 2019 23:20:02 +0200 Subject: Merge from master --- src/ui/dialog/selectordialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/ui/dialog/selectordialog.cpp') diff --git a/src/ui/dialog/selectordialog.cpp b/src/ui/dialog/selectordialog.cpp index 70c4388cd..2982ead3a 100644 --- a/src/ui/dialog/selectordialog.cpp +++ b/src/ui/dialog/selectordialog.cpp @@ -503,7 +503,7 @@ void SelectorDialog::_readStyleElement() Gtk::TreeModel::Row childrow = *(_store->append(row->children())); childrow[_mColumns._colSelector] = "#" + Glib::ustring(obj->getId()); childrow[_mColumns._colExpand] = false; - childrow[_mColumns._colType] = colType == UNHANDLED?UNHANDLED:OBJECT;; + childrow[_mColumns._colType] = colType == UNHANDLED ? UNHANDLED : OBJECT;; childrow[_mColumns._colObj] = std::vector(1, obj); childrow[_mColumns._colProperties] = ""; // Unused childrow[_mColumns._colVisible] = true; // Unused -- cgit v1.2.3 From afd54a6c6a696c48d58b25a7a5b00fc9a9d90d26 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Sat, 27 Apr 2019 01:04:52 +0200 Subject: add unhandled multiselector --- src/ui/dialog/selectordialog.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'src/ui/dialog/selectordialog.cpp') diff --git a/src/ui/dialog/selectordialog.cpp b/src/ui/dialog/selectordialog.cpp index 2982ead3a..7d0e0f29d 100644 --- a/src/ui/dialog/selectordialog.cpp +++ b/src/ui/dialog/selectordialog.cpp @@ -812,9 +812,22 @@ Glib::ustring SelectorDialog::_getIdList(std::vector sel) */ std::vector SelectorDialog::_getObjVec(Glib::ustring selector) { - std::vector objVec = SP_ACTIVE_DOCUMENT->getObjectsBySelector( selector ); - g_debug("SelectorDialog::_getObjVec: | %s |", selector.c_str()); + std::vector objVec; + std::vector tokensplus = Glib::Regex::split_simple("[,]+", selector); + bool unhandled = false; + for (auto tok : tokensplus) { + REMOVE_SPACES(tok); + if (tok.find(" ") != -1 || tok.erase(0, 1).find(".") != -1) { + unhandled = true; + std::vector objVecSplited = SP_ACTIVE_DOCUMENT->getObjectsBySelector(tok); + objVec.insert(objVec.end(), objVecSplited.begin(), objVecSplited.end()); + } + } + if (!unhandled) { + objVec = SP_ACTIVE_DOCUMENT->getObjectsBySelector(selector); + } + for (auto& obj: objVec) { g_debug(" %s", obj->getId() ? obj->getId() : "null"); } -- cgit v1.2.3 From e072922d8082660f6fbf3eec3d334ad754bf1681 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Sat, 27 Apr 2019 13:36:28 +0200 Subject: fix merge --- src/ui/dialog/selectordialog.cpp | 50 +++++++++++++++++++++++++++++++--------- 1 file changed, 39 insertions(+), 11 deletions(-) (limited to 'src/ui/dialog/selectordialog.cpp') diff --git a/src/ui/dialog/selectordialog.cpp b/src/ui/dialog/selectordialog.cpp index 7d0e0f29d..b92c0d82a 100644 --- a/src/ui/dialog/selectordialog.cpp +++ b/src/ui/dialog/selectordialog.cpp @@ -467,7 +467,8 @@ void SelectorDialog::_readStyleElement() coltype colType = SELECTOR; for (auto tok : tokensplus) { REMOVE_SPACES(tok); - if (tok.find(" ") != -1 || tok.erase(0, 1).find(".") != -1) { + if (SPAttributeRelSVG::isSVGElement(tok) || tok.find(" ") != -1 || tok[0] == '>' || tok[0] == '+' || ++ tok[0] == '~' || tok[0] == '*' || tok.erase(0, 1).find(".") != -1) { colType = UNHANDLED; } } @@ -818,7 +819,8 @@ std::vector SelectorDialog::_getObjVec(Glib::ustring selector) { bool unhandled = false; for (auto tok : tokensplus) { REMOVE_SPACES(tok); - if (tok.find(" ") != -1 || tok.erase(0, 1).find(".") != -1) { + if (SPAttributeRelSVG::isSVGElement(tok) || tok.find(" ") != -1 || tok[0] == '>' || tok[0] == '+' || + tok[0] == '~' || tok[0] == '*' || tok.erase(0, 1).find(".") != -1) { unhandled = true; std::vector objVecSplited = SP_ACTIVE_DOCUMENT->getObjectsBySelector(tok); objVec.insert(objVec.end(), objVecSplited.begin(), objVecSplited.end()); @@ -978,19 +980,45 @@ void SelectorDialog::_addSelector() * set to ".Class1" */ selectorValue = textEditPtr->get_text(); - Glib::ustring firstWord = selectorValue.substr(0, selectorValue.find_first_of(" >+~")); - if (firstWord != selectorValue) { - handled = false; - } if (!_stylemode) { del->set_sensitive(true); } - if (selectorValue[0] == '.' || selectorValue[0] == '#' || selectorValue[0] == '*' || - SPAttributeRelSVG::isSVGElement(selectorValue)) { - invalid = false; - } else { - textLabelPtr->show(); + std::vector tokensplus = Glib::Regex::split_simple("[,]+", selectorValue); + bool unhandled = false; + bool partialinvalid = false; + for (auto tok : tokensplus) { + REMOVE_SPACES(tok); + if (SPAttributeRelSVG::isSVGElement(tok) || tok.find(" ") != -1 || tok[0] == '>' || tok[0] == '+' || + tok[0] == '~' || tok[0] == '*' || tok.erase(0, 1).find(".") != -1) { + unhandled = true; + Glib::ustring firstWord = tok.substr(0, tok.find_first_of(" >+~")); + if (firstWord != tok) { + handled = false; + } + if (!partialinvalid && + (tok[0] == '.' || tok[0] == '#' || tok[0] == '*' || SPAttributeRelSVG::isSVGElement(tok))) { + partialinvalid = false; + } else { + partialinvalid = true; + } + } } + if (!unhandled) { + Glib::ustring firstWord = selectorValue.substr(0, selectorValue.find_first_of(" >+~")); + if (firstWord != selectorValue) { + handled = false; + } + if (selectorValue[0] == '.' || selectorValue[0] == '#' || selectorValue[0] == '*' || + SPAttributeRelSVG::isSVGElement(selectorValue)) { + invalid = false; + } else { + textLabelPtr->show(); + } + } else if (partialinvalid) { + textLabelPtr->show(); + } else { + invalid = false; + } } delete textDialogPtr; // ==== Handle response ==== -- cgit v1.2.3 From ef02728bee2e3011ad09f405db348a3c053ff4f9 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Wed, 15 May 2019 01:45:48 +0200 Subject: Fix a bug on undo, backpoer from master --- src/ui/dialog/selectordialog.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/ui/dialog/selectordialog.cpp') diff --git a/src/ui/dialog/selectordialog.cpp b/src/ui/dialog/selectordialog.cpp index b92c0d82a..529b7c06c 100644 --- a/src/ui/dialog/selectordialog.cpp +++ b/src/ui/dialog/selectordialog.cpp @@ -383,11 +383,11 @@ Inkscape::XML::Node* SelectorDialog::_getStyleTextNode() styleNode = SP_ACTIVE_DOCUMENT->getReprDoc()->createElement("svg:style"); textNode = SP_ACTIVE_DOCUMENT->getReprDoc()->createTextNode(""); - styleNode->appendChild(textNode); - Inkscape::GC::release(textNode); - root->addChild(styleNode, nullptr); Inkscape::GC::release(styleNode); + + styleNode->appendChild(textNode); + Inkscape::GC::release(textNode); } if (_textNode != textNode) { @@ -468,7 +468,7 @@ void SelectorDialog::_readStyleElement() for (auto tok : tokensplus) { REMOVE_SPACES(tok); if (SPAttributeRelSVG::isSVGElement(tok) || tok.find(" ") != -1 || tok[0] == '>' || tok[0] == '+' || -+ tok[0] == '~' || tok[0] == '*' || tok.erase(0, 1).find(".") != -1) { + tok[0] == '~' || tok[0] == '*' || tok.erase(0, 1).find(".") != -1) { colType = UNHANDLED; } } -- cgit v1.2.3 From 39a54755e1a46bf7107d382ae2975b01d894f201 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Mon, 27 May 2019 17:40:53 +0200 Subject: add improvements pointed by Thomas Holder --- src/ui/dialog/selectordialog.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/ui/dialog/selectordialog.cpp') diff --git a/src/ui/dialog/selectordialog.cpp b/src/ui/dialog/selectordialog.cpp index 529b7c06c..319ed1bda 100644 --- a/src/ui/dialog/selectordialog.cpp +++ b/src/ui/dialog/selectordialog.cpp @@ -422,10 +422,10 @@ void SelectorDialog::_readStyleElement() content.erase(std::remove(content.begin(), content.end(), '\n'), content.end()); // Remove comments (/* xxx */) - while(content.find("/*") != std::string::npos) { +/* while(content.find("/*") != std::string::npos) { size_t start = content.find("/*"); - content.erase(start, (content.find("*/", start) - start) +2); - } + content.erase(start, (content.find("*\/", start) - start) +2); + } */ // First split into selector/value chunks. // An attempt to use Glib::Regex failed. A C++11 version worked but -- cgit v1.2.3 From 817e61de278c79c005b3970fe4acaebcda20aabb Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Tue, 28 May 2019 11:13:27 +0200 Subject: working on selector dialog --- src/ui/dialog/selectordialog.cpp | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'src/ui/dialog/selectordialog.cpp') diff --git a/src/ui/dialog/selectordialog.cpp b/src/ui/dialog/selectordialog.cpp index 319ed1bda..4dedd02df 100644 --- a/src/ui/dialog/selectordialog.cpp +++ b/src/ui/dialog/selectordialog.cpp @@ -284,7 +284,7 @@ SelectorDialog::SelectorDialog(bool stylemode) : del = manage( new Gtk::Button() ); _styleButton(*del, "list-remove", "Remove a CSS Selector"); del->signal_clicked().connect(sigc::mem_fun(*this, &SelectorDialog::_delSelector)); - del->set_sensitive(false); + del->hide(); _mainBox.pack_end(_buttonBox, Gtk::PACK_SHRINK); _buttonBox.pack_start(*create, Gtk::PACK_SHRINK); @@ -327,7 +327,7 @@ SelectorDialog::SelectorDialog(bool stylemode) : _selectRow(); if (!_stylemode && !_store->children().empty()) { - del->set_sensitive(true); + del->show(); } } @@ -895,8 +895,8 @@ void SelectorDialog::_selectObjects(int eventX, int eventY) if (iter) { Gtk::TreeModel::Row row = *iter; Gtk::TreeModel::Children children = row.children(); - if (children.empty() && !_stylemode) { - del->set_sensitive(true); + if ((children.empty() || children.size() == 1) && !_stylemode) { + del->show(); } std::vector objVec = row[_mColumns._colObj]; @@ -981,7 +981,7 @@ void SelectorDialog::_addSelector() */ selectorValue = textEditPtr->get_text(); if (!_stylemode) { - del->set_sensitive(true); + del->show(); } std::vector tokensplus = Glib::Regex::split_simple("[,]+", selectorValue); bool unhandled = false; @@ -1077,7 +1077,7 @@ void SelectorDialog::_delSelector() Gtk::TreeModel::iterator iter = refTreeSelection->get_selected(); if (iter) { Gtk::TreeModel::Row row = *iter; - if (!row.children().empty()) { + if (row.children().size() > 2) { return; } _updating = true; @@ -1085,7 +1085,7 @@ void SelectorDialog::_delSelector() _updating = false; _writeStyleElement(); if (!_stylemode) { - del->set_sensitive(false); + del->hide(); } } } @@ -1226,7 +1226,7 @@ void SelectorDialog::_buttonEventsSelectObjs(GdkEventButton* event ) _treeView.get_selection()->set_mode(Gtk::SELECTION_SINGLE); _updating = true; if (!_stylemode) { - del->set_sensitive(true); + del->show(); } if (event->type == GDK_BUTTON_RELEASE && event->button == 1) { int x = static_cast(event->x); @@ -1245,7 +1245,9 @@ void SelectorDialog::_selectRow() { g_debug("SelectorDialog::_selectRow: updating: %s", (_updating ? "true" : "false")); if (!_stylemode) { - del->set_sensitive(false); + del->hide(); + } else { + del->show(); } if (_updating || !getDesktop()) return; // Avoid updating if we have set row via dialog. if (SP_ACTIVE_DESKTOP != getDesktop()) { -- cgit v1.2.3 From a2aa66acf986f27198468ba99e7fa6fd5307372f Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Wed, 29 May 2019 10:16:32 +0200 Subject: Improvements to hadle whols CSS file --- src/ui/dialog/selectordialog.cpp | 127 ++++++++++++++------------------------- 1 file changed, 46 insertions(+), 81 deletions(-) (limited to 'src/ui/dialog/selectordialog.cpp') diff --git a/src/ui/dialog/selectordialog.cpp b/src/ui/dialog/selectordialog.cpp index 4dedd02df..81130e61a 100644 --- a/src/ui/dialog/selectordialog.cpp +++ b/src/ui/dialog/selectordialog.cpp @@ -229,12 +229,11 @@ Glib::RefPtr SelectorDialog::TreeStore::create(Select * adds selectors to treeview. _delSelector deletes the selector from the dialog. * Any addition/deletion of the selectors updates XML style element accordingly. */ -SelectorDialog::SelectorDialog(bool stylemode) : +SelectorDialog::SelectorDialog() : UI::Widget::Panel("/dialogs/style", SP_VERB_DIALOG_STYLE), _updating(false), _textNode(nullptr), - _desktopTracker(), - _stylemode(stylemode) + _desktopTracker() { g_debug("SelectorDialog::SelectorDialog"); @@ -246,19 +245,9 @@ SelectorDialog::SelectorDialog(bool stylemode) : addRenderer->add_icon("object-locked"); _store = TreeStore::create(this); - if (_stylemode) { - _modelfilter = Gtk::TreeModelFilter::create(_store); - _modelfilter->set_visible_column(_mColumns._colVisible); - _treeView.set_model(_modelfilter); - } else { - _treeView.set_model(_store); - } - if (_stylemode) { - _treeView.set_headers_visible(false); - _treeView.set_grid_lines (Gtk::TREE_VIEW_GRID_LINES_HORIZONTAL); - } else { - _treeView.set_headers_visible(true); - } + _treeView.set_model(_store); + + _treeView.set_headers_visible(true); _treeView.enable_model_drag_source(); _treeView.enable_model_drag_dest( Gdk::ACTION_MOVE ); int addCol = _treeView.append_column("", *addRenderer) - 1; @@ -273,25 +262,21 @@ SelectorDialog::SelectorDialog(bool stylemode) : _paned.set_orientation(Gtk::ORIENTATION_VERTICAL); _paned.pack1(_mainBox, Gtk::SHRINK); _mainBox.set_orientation(Gtk::ORIENTATION_VERTICAL); - if (!_stylemode) { - _mainBox.pack_start(_scrolledWindow, Gtk::PACK_EXPAND_WIDGET); - _scrolledWindow.add(_treeView); - _scrolledWindow.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); - create = manage( new Gtk::Button() ); - _styleButton(*create, "list-add", "Add a new CSS Selector"); - create->signal_clicked().connect(sigc::mem_fun(*this, &SelectorDialog::_addSelector)); - - del = manage( new Gtk::Button() ); - _styleButton(*del, "list-remove", "Remove a CSS Selector"); - del->signal_clicked().connect(sigc::mem_fun(*this, &SelectorDialog::_delSelector)); - del->hide(); - _mainBox.pack_end(_buttonBox, Gtk::PACK_SHRINK); - - _buttonBox.pack_start(*create, Gtk::PACK_SHRINK); - _buttonBox.pack_start(*del, Gtk::PACK_SHRINK); - } else { - _mainBox.pack_start(_treeView, Gtk::PACK_EXPAND_WIDGET); - } + _mainBox.pack_start(_scrolledWindow, Gtk::PACK_EXPAND_WIDGET); + _scrolledWindow.add(_treeView); + _scrolledWindow.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); + create = manage( new Gtk::Button() ); + _styleButton(*create, "list-add", "Add a new CSS Selector"); + create->signal_clicked().connect(sigc::mem_fun(*this, &SelectorDialog::_addSelector)); + + del = manage( new Gtk::Button() ); + _styleButton(*del, "list-remove", "Remove a CSS Selector"); + del->signal_clicked().connect(sigc::mem_fun(*this, &SelectorDialog::_delSelector)); + del->hide(); + _mainBox.pack_end(_buttonBox, Gtk::PACK_SHRINK); + + _buttonBox.pack_start(*create, Gtk::PACK_SHRINK); + _buttonBox.pack_start(*del, Gtk::PACK_SHRINK); _getContents()->pack_start(_paned, Gtk::PACK_EXPAND_WIDGET); @@ -326,7 +311,7 @@ SelectorDialog::SelectorDialog(bool stylemode) : _readStyleElement(); _selectRow(); - if (!_stylemode && !_store->children().empty()) { + if (!_store->children().empty()) { del->show(); } @@ -498,29 +483,17 @@ void SelectorDialog::_readStyleElement() row[_mColumns._colObj] = objVec; row[_mColumns._colProperties] = properties; row[_mColumns._colVisible] = true; - if (!_stylemode) { - // Add as children, objects that match selector. - for (auto &obj : objVec) { - Gtk::TreeModel::Row childrow = *(_store->append(row->children())); - childrow[_mColumns._colSelector] = "#" + Glib::ustring(obj->getId()); - childrow[_mColumns._colExpand] = false; - childrow[_mColumns._colType] = colType == UNHANDLED ? UNHANDLED : OBJECT;; - childrow[_mColumns._colObj] = std::vector(1, obj); - childrow[_mColumns._colProperties] = ""; // Unused - childrow[_mColumns._colVisible] = true; // Unused - } - } else { - for (auto property : properties_data) { - Gtk::TreeModel::Row childrow = *(_store->append(row->children())); - childrow[_mColumns._colSelector] = Glib::ustring(property); - childrow[_mColumns._colExpand] = false; - childrow[_mColumns._colType] = 0; - childrow[_mColumns._colObj] = {}; - childrow[_mColumns._colProperties] = ""; // Unused - childrow[_mColumns._colVisible] = true; // Unused - } + // Add as children, objects that match selector. + for (auto &obj : objVec) { + Gtk::TreeModel::Row childrow = *(_store->append(row->children())); + childrow[_mColumns._colSelector] = "#" + Glib::ustring(obj->getId()); + childrow[_mColumns._colExpand] = false; + childrow[_mColumns._colType] = colType == UNHANDLED ? UNHANDLED : OBJECT;; + childrow[_mColumns._colObj] = std::vector(1, obj); + childrow[_mColumns._colProperties] = ""; // Unused + childrow[_mColumns._colVisible] = true; // Unused } - } +} _updating = false; @@ -880,9 +853,6 @@ void SelectorDialog::_insertClass(const std::vector& objVec, const G void SelectorDialog::_selectObjects(int eventX, int eventY) { g_debug("SelectorDialog::_selectObjects: %d, %d", eventX, eventY); - if (_stylemode) { - return; - } getDesktop()->selection->clear(); Gtk::TreeViewColumn *col = _treeView.get_column(1); Gtk::TreeModel::Path path; @@ -895,7 +865,7 @@ void SelectorDialog::_selectObjects(int eventX, int eventY) if (iter) { Gtk::TreeModel::Row row = *iter; Gtk::TreeModel::Children children = row.children(); - if ((children.empty() || children.size() == 1) && !_stylemode) { + if (children.empty() || children.size() == 1) { del->show(); } std::vector objVec = row[_mColumns._colObj]; @@ -980,9 +950,7 @@ void SelectorDialog::_addSelector() * set to ".Class1" */ selectorValue = textEditPtr->get_text(); - if (!_stylemode) { - del->show(); - } + del->show(); std::vector tokensplus = Glib::Regex::split_simple("[,]+", selectorValue); bool unhandled = false; bool partialinvalid = false; @@ -1084,9 +1052,7 @@ void SelectorDialog::_delSelector() _store->erase(iter); _updating = false; _writeStyleElement(); - if (!_stylemode) { - del->hide(); - } + del->hide(); } } @@ -1225,9 +1191,7 @@ void SelectorDialog::_buttonEventsSelectObjs(GdkEventButton* event ) g_debug("SelectorDialog::_buttonEventsSelectObjs"); _treeView.get_selection()->set_mode(Gtk::SELECTION_SINGLE); _updating = true; - if (!_stylemode) { - del->show(); - } + del->show(); if (event->type == GDK_BUTTON_RELEASE && event->button == 1) { int x = static_cast(event->x); int y = static_cast(event->y); @@ -1244,16 +1208,22 @@ void SelectorDialog::_buttonEventsSelectObjs(GdkEventButton* event ) void SelectorDialog::_selectRow() { g_debug("SelectorDialog::_selectRow: updating: %s", (_updating ? "true" : "false")); - if (!_stylemode) { - del->hide(); - } else { - del->show(); + del->hide(); + std::vector< Gtk::TreeModel::Path > selectedrows = _treeView.get_selection()->get_selected_rows(); + if(selectedrows.size() == 1) { + Gtk::TreeModel::Row row = *_store->get_iter(selectedrows[0]); + if (!row->parent() && row->children().size() < 2 ) { + del->show(); + } + } else if(selectedrows.size() == 0) { + del->show(); } if (_updating || !getDesktop()) return; // Avoid updating if we have set row via dialog. if (SP_ACTIVE_DESKTOP != getDesktop()) { std::cerr << "SelectorDialog::_selectRow: SP_ACTIVE_DESKTOP != getDesktop()" << std::endl; return; } + _treeView.get_selection()->unselect_all(); Gtk::TreeModel::Children children = _store->children(); Inkscape::Selection* selection = getDesktop()->getSelection(); @@ -1261,6 +1231,7 @@ void SelectorDialog::_selectRow() if (!selection->isEmpty()) { obj = selection->objects().back(); } + for (auto row : children) { std::vector objVec = row[_mColumns._colObj]; if (obj) { @@ -1269,8 +1240,6 @@ void SelectorDialog::_selectRow() _treeView.get_selection()->select(row); row[_mColumns._colVisible] = true; break; - } else if(_stylemode) { - row[_mColumns._colVisible] = false; } } } @@ -1278,10 +1247,6 @@ void SelectorDialog::_selectRow() _treeView.expand_to_path(Gtk::TreePath(row)); } } - if (_stylemode) { - _modelfilter->refilter(); - _treeView.get_selection()->unselect_all(); - } } /** -- cgit v1.2.3 From 930ca25606ddefe59afa37f32c823bedcea8ed30 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Wed, 29 May 2019 11:20:37 +0200 Subject: Fixing coding style --- src/ui/dialog/selectordialog.cpp | 71 ++++++++++++++++++++-------------------- 1 file changed, 36 insertions(+), 35 deletions(-) (limited to 'src/ui/dialog/selectordialog.cpp') diff --git a/src/ui/dialog/selectordialog.cpp b/src/ui/dialog/selectordialog.cpp index 81130e61a..2501214c5 100644 --- a/src/ui/dialog/selectordialog.cpp +++ b/src/ui/dialog/selectordialog.cpp @@ -52,17 +52,17 @@ namespace Dialog { // Keeps a watch on style element class SelectorDialog::NodeObserver : public Inkscape::XML::NodeObserver { public: - NodeObserver(SelectorDialog* selectordialog) : - _selectordialog(selectordialog) - { - g_debug("SelectorDialog::NodeObserver: Constructor"); + NodeObserver(SelectorDialog *selectordialog) + : _selectordialog(selectordialog) + { + g_debug("SelectorDialog::NodeObserver: Constructor"); }; void notifyContentChanged(Inkscape::XML::Node &node, Inkscape::Util::ptr_shared old_content, Inkscape::Util::ptr_shared new_content) override; - SelectorDialog * _selectordialog; + SelectorDialog *_selectordialog; }; @@ -83,19 +83,19 @@ SelectorDialog::NodeObserver::notifyContentChanged( // (Must update objects that selectors match.) class SelectorDialog::NodeWatcher : public Inkscape::XML::NodeObserver { public: - NodeWatcher(SelectorDialog* selectordialog, Inkscape::XML::Node *repr) : - _selectordialog(selectordialog), - _repr(repr) - { - g_debug("SelectorDialog::NodeWatcher: Constructor"); + NodeWatcher(SelectorDialog *selectordialog, Inkscape::XML::Node *repr) + : _selectordialog(selectordialog) + , _repr(repr) + { + g_debug("SelectorDialog::NodeWatcher: Constructor"); }; void notifyChildAdded( Inkscape::XML::Node &/*node*/, Inkscape::XML::Node &child, Inkscape::XML::Node */*prev*/ ) override { - if ( _selectordialog && _repr ) { - _selectordialog->_nodeAdded( child ); + if (_selectordialog && _repr) { + _selectordialog->_nodeAdded(child); } } @@ -103,8 +103,8 @@ public: Inkscape::XML::Node &child, Inkscape::XML::Node */*prev*/ ) override { - if ( _selectordialog && _repr ) { - _selectordialog->_nodeRemoved( child ); + if (_selectordialog && _repr) { + _selectordialog->_nodeRemoved(child); } } @@ -112,7 +112,7 @@ public: GQuark qname, Util::ptr_shared /*old_value*/, Util::ptr_shared /*new_value*/ ) override { - if ( _selectordialog && _repr ) { + if (_selectordialog && _repr) { // For the moment only care about attributes that are directly used in selectors. const gchar * cname = g_quark_to_string (qname ); @@ -122,12 +122,12 @@ public: } if ( name == "id" || name == "class" ) { - _selectordialog->_nodeChanged( node ); + _selectordialog->_nodeChanged(node); } } } - SelectorDialog * _selectordialog; + SelectorDialog *_selectordialog; Inkscape::XML::Node * _repr; // Need to track if document changes. }; @@ -243,7 +243,7 @@ SelectorDialog::SelectorDialog() : addRenderer->add_icon("edit-delete"); addRenderer->add_icon("list-add"); addRenderer->add_icon("object-locked"); - + _store = TreeStore::create(this); _treeView.set_model(_store); @@ -407,10 +407,10 @@ void SelectorDialog::_readStyleElement() content.erase(std::remove(content.begin(), content.end(), '\n'), content.end()); // Remove comments (/* xxx */) -/* while(content.find("/*") != std::string::npos) { - size_t start = content.find("/*"); - content.erase(start, (content.find("*\/", start) - start) +2); - } */ + /* while(content.find("/*") != std::string::npos) { + size_t start = content.find("/*"); + content.erase(start, (content.find("*\/", start) - start) +2); + } */ // First split into selector/value chunks. // An attempt to use Glib::Regex failed. A C++11 version worked but @@ -453,7 +453,7 @@ void SelectorDialog::_readStyleElement() for (auto tok : tokensplus) { REMOVE_SPACES(tok); if (SPAttributeRelSVG::isSVGElement(tok) || tok.find(" ") != -1 || tok[0] == '>' || tok[0] == '+' || - tok[0] == '~' || tok[0] == '*' || tok.erase(0, 1).find(".") != -1) { + tok[0] == '~' || tok[0] == '*' || tok.erase(0, 1).find(".") != -1) { colType = UNHANDLED; } } @@ -488,14 +488,15 @@ void SelectorDialog::_readStyleElement() Gtk::TreeModel::Row childrow = *(_store->append(row->children())); childrow[_mColumns._colSelector] = "#" + Glib::ustring(obj->getId()); childrow[_mColumns._colExpand] = false; - childrow[_mColumns._colType] = colType == UNHANDLED ? UNHANDLED : OBJECT;; + childrow[_mColumns._colType] = colType == UNHANDLED ? UNHANDLED : OBJECT; + ; childrow[_mColumns._colObj] = std::vector(1, obj); childrow[_mColumns._colProperties] = ""; // Unused - childrow[_mColumns._colVisible] = true; // Unused + childrow[_mColumns._colVisible] = true; // Unused } -} + } + - _updating = false; } @@ -624,7 +625,7 @@ void SelectorDialog::_addToSelector(Gtk::TreeModel::Row row) childrow[_mColumns._colType] = OBJECT; childrow[_mColumns._colObj] = std::vector(1, obj); childrow[_mColumns._colProperties] = ""; // Unused - childrow[_mColumns._colVisible] = true; // Unused + childrow[_mColumns._colVisible] = true; // Unused } } } @@ -665,7 +666,7 @@ void SelectorDialog::_addToSelector(Gtk::TreeModel::Row row) childrow[_mColumns._colType] = OBJECT; childrow[_mColumns._colObj] = std::vector(1, obj); childrow[_mColumns._colProperties] = ""; // Unused - childrow[_mColumns._colVisible] = true; // Unused + childrow[_mColumns._colVisible] = true; // Unused } } } @@ -986,7 +987,7 @@ void SelectorDialog::_addSelector() textLabelPtr->show(); } else { invalid = false; - } + } } delete textDialogPtr; // ==== Handle response ==== @@ -1209,13 +1210,13 @@ void SelectorDialog::_selectRow() { g_debug("SelectorDialog::_selectRow: updating: %s", (_updating ? "true" : "false")); del->hide(); - std::vector< Gtk::TreeModel::Path > selectedrows = _treeView.get_selection()->get_selected_rows(); - if(selectedrows.size() == 1) { + std::vector selectedrows = _treeView.get_selection()->get_selected_rows(); + if (selectedrows.size() == 1) { Gtk::TreeModel::Row row = *_store->get_iter(selectedrows[0]); - if (!row->parent() && row->children().size() < 2 ) { + if (!row->parent() && row->children().size() < 2) { del->show(); } - } else if(selectedrows.size() == 0) { + } else if (selectedrows.size() == 0) { del->show(); } if (_updating || !getDesktop()) return; // Avoid updating if we have set row via dialog. @@ -1231,7 +1232,7 @@ void SelectorDialog::_selectRow() if (!selection->isEmpty()) { obj = selection->objects().back(); } - + for (auto row : children) { std::vector objVec = row[_mColumns._colObj]; if (obj) { -- cgit v1.2.3 From 4ee33795749b46cd4e0b8c84ab336b7cb8d18faa Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Date: Wed, 29 May 2019 15:46:40 +0200 Subject: fix coding style --- src/ui/dialog/selectordialog.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/ui/dialog/selectordialog.cpp') diff --git a/src/ui/dialog/selectordialog.cpp b/src/ui/dialog/selectordialog.cpp index 2501214c5..fefd23e51 100644 --- a/src/ui/dialog/selectordialog.cpp +++ b/src/ui/dialog/selectordialog.cpp @@ -56,7 +56,7 @@ public: : _selectordialog(selectordialog) { g_debug("SelectorDialog::NodeObserver: Constructor"); - }; + }; void notifyContentChanged(Inkscape::XML::Node &node, Inkscape::Util::ptr_shared old_content, @@ -88,7 +88,7 @@ public: , _repr(repr) { g_debug("SelectorDialog::NodeWatcher: Constructor"); - }; + }; void notifyChildAdded( Inkscape::XML::Node &/*node*/, Inkscape::XML::Node &child, -- cgit v1.2.3