diff options
| author | Tavmjong Bah <tavmjong@free.fr> | 2017-02-18 08:42:01 +0000 |
|---|---|---|
| committer | tavmjong-free <tavmjong@free.fr> | 2017-02-18 08:42:01 +0000 |
| commit | 7494443a3f6c759f615e4e98676c0ed027e3ad47 (patch) | |
| tree | 7bc8f4df1e06b38199cb38269ee5091670c9194a /src/ui/dialog/styledialog.cpp | |
| parent | partial fix bug 1640899 (diff) | |
| download | inkscape-7494443a3f6c759f615e4e98676c0ed027e3ad47.tar.gz inkscape-7494443a3f6c759f615e4e98676c0ed027e3ad47.zip | |
Implement Undo. Respond to external changes to <style> element.
(bzr r15528)
Diffstat (limited to 'src/ui/dialog/styledialog.cpp')
| -rw-r--r-- | src/ui/dialog/styledialog.cpp | 151 |
1 files changed, 113 insertions, 38 deletions
diff --git a/src/ui/dialog/styledialog.cpp b/src/ui/dialog/styledialog.cpp index 581911a1b..09fca0074 100644 --- a/src/ui/dialog/styledialog.cpp +++ b/src/ui/dialog/styledialog.cpp @@ -18,13 +18,16 @@ #include "sp-object.h" #include "selection.h" #include "xml/attribute-record.h" +#include "xml/node-observer.h" #include "attribute-rel-svg.h" +#include "document-undo.h" #include <glibmm/i18n.h> #include <glibmm/regex.h> //#define DEBUG_STYLEDIALOG +using Inkscape::DocumentUndo; using Inkscape::Util::List; using Inkscape::XML::AttributeRecord; @@ -39,6 +42,38 @@ namespace Inkscape { namespace UI { namespace Dialog { +class StyleDialog::NodeObserver : public Inkscape::XML::NodeObserver { +public: + NodeObserver(StyleDialog* styleDialog) : + _styleDialog(styleDialog) + { +#ifdef DEBUG_STYLEDIALOG + std::cout << "StyleDialog::NodeObserver: Constructor" << std::endl; +#endif + }; + + virtual void notifyContentChanged(Inkscape::XML::Node &node, + Inkscape::Util::ptr_shared<char> old_content, + Inkscape::Util::ptr_shared<char> new_content); + + StyleDialog * _styleDialog; +}; + + +void +StyleDialog::NodeObserver::notifyContentChanged( + Inkscape::XML::Node &/*node*/, + Inkscape::Util::ptr_shared<char> /*old_content*/, + Inkscape::Util::ptr_shared<char> /*new_content*/ ) { + +#ifdef DEBUG_STYLEDIALOG + std::cout << "StyleDialog::NodeObserver::notifyContentChanged" << std::endl; +#endif + + _styleDialog->_readStyleElement(); + _styleDialog->_selectRow(NULL); +} + /** * Constructor @@ -49,8 +84,12 @@ namespace Dialog { StyleDialog::StyleDialog() : UI::Widget::Panel("", "/dialogs/style", SP_VERB_DIALOG_STYLE), _desktop(0), - _updating(false) + _updating(false), + _textNode(NULL) { +#ifdef DEBUG_STYLEDIALOG + std::cout << "StyleDialog::StyleDialog" << std::endl; +#endif // Tree Inkscape::UI::Widget::AddToIcon * addRenderer = manage( @@ -134,6 +173,7 @@ StyleDialog::StyleDialog() : _document = _desktop->doc(); _readStyleElement(); + _selectRow(NULL); if (!_store->children().empty()) { del->set_sensitive(true); @@ -148,6 +188,9 @@ StyleDialog::StyleDialog() : */ StyleDialog::~StyleDialog() { +#ifdef DEBUG_STYLEDIALOOG + std::cout << "StyleDialog::~StyleDialog" << std::endl; +#endif setDesktop(NULL); } @@ -176,36 +219,49 @@ void StyleDialog::setDesktop( SPDesktop* desktop ) */ Inkscape::XML::Node* StyleDialog::_getStyleTextNode() { + + Inkscape::XML::Node *styleNode = NULL; + Inkscape::XML::Node *textNode = NULL; + Inkscape::XML::Node *root = _document->getReprRoot(); for (unsigned i = 0; i < root->childCount(); ++i) { if (Glib::ustring(root->nthChild(i)->name()) == "svg:style") { - Inkscape::XML::Node * styleNode = root->nthChild(i); + + styleNode = root->nthChild(i); for (unsigned j = 0; j < styleNode->childCount(); ++j) { if (styleNode->nthChild(j)->type() == Inkscape::XML::TEXT_NODE) { - return styleNode->nthChild(j); + textNode = styleNode->nthChild(j); } } - // Style element found but does not contain text node! - std::cerr << "StyleDialog::_getStyleTextNode(): No text node!" << std::endl; - Inkscape::XML::Node *textNode = _document->getReprDoc()->createTextNode(""); - styleNode->appendChild(textNode); - Inkscape::GC::release(textNode); - - return textNode; + if (textNode == NULL) { + // Style element found but does not contain text node! + std::cerr << "StyleDialog::_getStyleTextNode(): No text node!" << std::endl; + textNode = _document->getReprDoc()->createTextNode(""); + styleNode->appendChild(textNode); + Inkscape::GC::release(textNode); + } } } - // Style element not found, create one - Inkscape::XML::Node *styleNode = _document->getReprDoc()->createElement("svg:style"); - Inkscape::XML::Node *textNode = _document->getReprDoc()->createTextNode(""); + if (styleNode == NULL) { + // Style element not found, create one + styleNode = _document->getReprDoc()->createElement("svg:style"); + textNode = _document->getReprDoc()->createTextNode(""); + + styleNode->appendChild(textNode); + Inkscape::GC::release(textNode); - styleNode->appendChild(textNode); - Inkscape::GC::release(textNode); + root->addChild(styleNode, NULL); + Inkscape::GC::release(styleNode); + } - root->addChild(styleNode, NULL); - Inkscape::GC::release(styleNode); + if (_textNode != textNode) { + _textNode = textNode; + NodeObserver *no = new NodeObserver(this); + textNode->addObserver(*no); + } return textNode; } @@ -213,11 +269,11 @@ Inkscape::XML::Node* StyleDialog::_getStyleTextNode() /** * @brief StyleDialog::_readStyleElement - * @return selVec * Fill the Gtk::TreeStore from the svg:style element. */ void StyleDialog::_readStyleElement() { + _store->clear(); Inkscape::XML::Node * textNode = _getStyleTextNode(); if (textNode == NULL) { @@ -302,6 +358,8 @@ void StyleDialog::_writeStyleElement() Inkscape::XML::Node *textNode = _getStyleTextNode(); textNode->setContent(styleContent.c_str()); + DocumentUndo::done(_document, SP_VERB_DIALOG_STYLE, _("Edited style element.")); + #ifdef DEBUG_STYLEDIALOG std::cout << "StyleDialog::_writeStyleElement(): |" << styleContent << "|" << std::endl; #endif @@ -789,6 +847,37 @@ bool StyleDialog::_handleButtonEvent(GdkEventButton *event) return false; } +/** + * @brief StyleDialog::_updateCSSPanel + * Updates CSS panel according to row in Style panel. + */ +void StyleDialog::_updateCSSPanel() +{ +#ifdef DEBUG_STYLEDIALOG + std::cout << "StyleDialog::_updateCSSPanel" << std::endl; +#endif + // This should probably be in a member function of CSSDialog. + _cssPane->_store->clear(); + + Glib::RefPtr<Gtk::TreeSelection> refTreeSelection = _treeView.get_selection(); + Gtk::TreeModel::iterator iter = refTreeSelection->get_selected(); + if (iter) { + Gtk::TreeModel::Row row = *iter; + Glib::ustring properties = row[_mColumns._colProperties]; + REMOVE_SPACES(properties); // Remove leading/trailing spaces + + std::vector<Glib::ustring> tokens = + Glib::Regex::split_simple("\\s*;\\s*", properties); + for (auto& token: tokens) { + if (!token.empty()) { + _cssPane->_propRow = *(_cssPane->_store->append()); + _cssPane->_propRow[_cssPane->_cssColumns._colUnsetProp] = false; + _cssPane->_propRow[_cssPane->_cssColumns._propertyLabel] = token; + } + } + } +} + /** * @brief StyleDialog::_buttonEventsSelectObjs @@ -814,26 +903,7 @@ void StyleDialog::_buttonEventsSelectObjs(GdkEventButton* event ) //int y = static_cast<int>(event->y); //_selectObjects(x, y); - _cssPane->_store->clear(); - - // This should probably be in a member function of CSSDialog. - Glib::RefPtr<Gtk::TreeSelection> refTreeSelection = _treeView.get_selection(); - Gtk::TreeModel::iterator iter = refTreeSelection->get_selected(); - if (iter) { - Gtk::TreeModel::Row row = *iter; - Glib::ustring properties = row[_mColumns._colProperties]; - REMOVE_SPACES(properties); // Remove leading/trailing spaces - - std::vector<Glib::ustring> tokens = - Glib::Regex::split_simple("\\s*;\\s*", properties); - for (auto& token: tokens) { - if (!token.empty()) { - _cssPane->_propRow = *(_cssPane->_store->append()); - _cssPane->_propRow[_cssPane->_cssColumns._colUnsetProp] = false; - _cssPane->_propRow[_cssPane->_cssColumns._propertyLabel] = token; - } - } - } + _updateCSSPanel(); } _updating = false; } @@ -846,6 +916,9 @@ void StyleDialog::_buttonEventsSelectObjs(GdkEventButton* event ) */ void StyleDialog::_selectRow(Selection */*sel*/) { +#ifdef DEBUG_STYLEDIALOG + std::cout << "StyleDialog::_selectRow: updating: " << (_updating?"true":"false") << std::endl; +#endif if (_updating) return; // Avoid updating if we have set row via dialog. Inkscape::Selection* selection = _desktop->getSelection(); @@ -861,6 +934,7 @@ void StyleDialog::_selectRow(Selection */*sel*/) for (unsigned i = 0; i < objVec.size(); ++i) { if (obj->getId() == objVec[i]->getId()) { _treeView.get_selection()->select(row); + _updateCSSPanel(); return; } } @@ -869,6 +943,7 @@ void StyleDialog::_selectRow(Selection */*sel*/) // Selection empty or no row matches. _treeView.get_selection()->unselect_all(); + _updateCSSPanel(); } |
