summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJabier Arraiza <jabier.arraiza@marker.es>2019-04-20 16:40:55 +0000
committerJabier Arraiza <jabier.arraiza@marker.es>2019-06-02 09:50:16 +0000
commit35a635e53826eecdf3b5932dffbcaab708770771 (patch)
treea791fe4f6d7727c3f151a83176ae12a208517a7f /src
parentminor fixes (diff)
downloadinkscape-35a635e53826eecdf3b5932dffbcaab708770771.tar.gz
inkscape-35a635e53826eecdf3b5932dffbcaab708770771.zip
reorder dialogs
Diffstat (limited to 'src')
-rw-r--r--src/ui/CMakeLists.txt8
-rw-r--r--src/ui/dialog/dialog-manager.cpp6
-rw-r--r--src/ui/dialog/selectordialog.h16
-rw-r--r--src/ui/dialog/styledialog.cpp510
-rw-r--r--src/ui/dialog/styledialog.h153
-rw-r--r--src/ui/dialog/xml-tree.h6
6 files changed, 144 insertions, 555 deletions
diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt
index bf773ba6f..fab824699 100644
--- a/src/ui/CMakeLists.txt
+++ b/src/ui/CMakeLists.txt
@@ -133,9 +133,9 @@ set(ui_SRC
dialog/print-colors-preview-dialog.cpp
dialog/print.cpp
dialog/prototype.cpp
- dialog/selectordialog.cpp
+ dialog/selectordialog.cpp
dialog/spellcheck.cpp
- dialog/styledialog.cpp
+ dialog/styledialog.cpp
dialog/svg-fonts-dialog.cpp
dialog/svg-preview.cpp
dialog/swatches.cpp
@@ -300,9 +300,9 @@ set(ui_SRC
dialog/print-colors-preview-dialog.h
dialog/print.h
dialog/prototype.h
- dialog/selectordialog.h
+ dialog/selectordialog.h
dialog/spellcheck.h
- dialog/styledialog.h
+ dialog/styledialog.h
dialog/svg-fonts-dialog.h
dialog/svg-preview.h
dialog/swatches.h
diff --git a/src/ui/dialog/dialog-manager.cpp b/src/ui/dialog/dialog-manager.cpp
index 00bcedd62..158071e18 100644
--- a/src/ui/dialog/dialog-manager.cpp
+++ b/src/ui/dialog/dialog-manager.cpp
@@ -125,8 +125,8 @@ DialogManager::DialogManager() {
registerFactory("Swatches", &create<SwatchesPanel, FloatingBehavior>);
registerFactory("TileDialog", &create<ArrangeDialog, FloatingBehavior>);
registerFactory("Symbols", &create<SymbolsDialog, FloatingBehavior>);
- registerFactory("StyleDialog", &create<StyleDialog, FloatingBehavior>);
- registerFactory("SelectorDialog", &create<SelectorDialog, FloatingBehavior>);
+ registerFactory("SelectorDialog", &create<SelectorDialog, FloatingBehavior>);
+ registerFactory("StyleDialog", &create<StyleDialog, FloatingBehavior>);
#if HAVE_POTRACE
registerFactory("Trace", &create<TraceDialog, FloatingBehavior>);
@@ -167,8 +167,8 @@ DialogManager::DialogManager() {
registerFactory("Swatches", &create<SwatchesPanel, DockBehavior>);
registerFactory("TileDialog", &create<ArrangeDialog, DockBehavior>);
registerFactory("Symbols", &create<SymbolsDialog, DockBehavior>);
- registerFactory("StyleDialog", &create<StyleDialog, DockBehavior>);
registerFactory("SelectorDialog", &create<SelectorDialog, DockBehavior>);
+ registerFactory("StyleDialog", &create<StyleDialog, DockBehavior>);
#if HAVE_POTRACE
registerFactory("Trace", &create<TraceDialog, DockBehavior>);
diff --git a/src/ui/dialog/selectordialog.h b/src/ui/dialog/selectordialog.h
index 306169611..96a5dc6f4 100644
--- a/src/ui/dialog/selectordialog.h
+++ b/src/ui/dialog/selectordialog.h
@@ -18,6 +18,7 @@
#include <ui/widget/panel.h>
#include <gtkmm/treeview.h>
#include <gtkmm/treestore.h>
+#include <gtkmm/treemodelfilter.h>
#include <gtkmm/scrolledwindow.h>
#include <gtkmm/dialog.h>
#include <gtkmm/treeselection.h>
@@ -47,12 +48,11 @@ class SelectorDialog : public Widget::Panel {
public:
~SelectorDialog() override;
// No default constructor, noncopyable, nonassignable
- SelectorDialog();
+ SelectorDialog(bool stylemode = false);
SelectorDialog(SelectorDialog const &d) = delete;
SelectorDialog operator=(SelectorDialog const &d) = delete;
- static SelectorDialog &getInstance() { return *new SelectorDialog(); }
-
+ static SelectorDialog &getInstance() { return *new SelectorDialog(false); }
private:
// Monitor <style> element for changes.
class NodeObserver;
@@ -74,12 +74,14 @@ public:
add(_colType);
add(_colObj);
add(_colProperties);
+ add(_colVisible);
}
Gtk::TreeModelColumn<Glib::ustring> _colSelector; // Selector or matching object id.
Gtk::TreeModelColumn<bool> _colExpand; // Open/Close store row.
Gtk::TreeModelColumn<gint> _colType; // Selector row or child object row.
Gtk::TreeModelColumn<std::vector<SPObject *> > _colObj; // List of matching objects.
Gtk::TreeModelColumn<Glib::ustring> _colProperties; // List of properties.
+ Gtk::TreeModelColumn<bool> _colVisible; // Make visible or not.
};
ModelColumns _mColumns;
@@ -98,16 +100,16 @@ public:
void on_row_deleted(const TreeModel::Path& path) override;
public:
- static Glib::RefPtr<SelectorDialog::TreeStore> create(SelectorDialog *selectordialog);
+ static Glib::RefPtr<SelectorDialog::TreeStore> create(SelectorDialog *styledialog);
private:
SelectorDialog *_selectordialog;
};
// TreeView
- Gtk::TreeView _treeView;
+ Glib::RefPtr<Gtk::TreeModelFilter> _modelfilter;
Glib::RefPtr<TreeStore> _store;
-
+ Gtk::TreeView _treeView;
// Widgets
Gtk::Paned _paned;
Gtk::Box _mainBox;
@@ -135,6 +137,7 @@ public:
// Variables
bool _updating; // Prevent cyclic actions: read <-> write, select via dialog <-> via desktop
+ bool _stylemode; // Show dialog of items in selector widget or in css styles in CSS dialog
Inkscape::XML::Node *_textNode; // Track so we know when to add a NodeObserver.
// Signals and handlers - External
@@ -157,6 +160,7 @@ public:
void _addSelector();
void _delSelector();
bool _handleButtonEvent(GdkEventButton *event);
+ //bool _showStyleSelectors(const Gtk::TreeModel::iterator& iter, std::vector<Gtk::TreeModel::Row> toshow);
void _buttonEventsSelectObjs(GdkEventButton *event);
void _selectRow(); // Select row in tree when selection changed.
diff --git a/src/ui/dialog/styledialog.cpp b/src/ui/dialog/styledialog.cpp
index cc1c6acb8..08e5117b5 100644
--- a/src/ui/dialog/styledialog.cpp
+++ b/src/ui/dialog/styledialog.cpp
@@ -32,8 +32,7 @@
static void on_attr_changed(Inkscape::XML::Node *repr, const gchar *name, const gchar * /*old_value*/,
const gchar *new_value, bool /*is_interactive*/, gpointer data)
{
- CSS_DIALOG(data)->onAttrChanged(repr, name, new_value);
- CSS_DIALOG(data)->styledialog = new Inkscape::UI::Dialog::StyleDialog();
+ STYLE_DIALOG(data)->onAttrChanged(repr, name, new_value);
}
Inkscape::XML::NodeEventVector css_repr_events = {
@@ -56,97 +55,33 @@ namespace Dialog {
* and clicking 'Enter' updates the property with changes reflected in the
* drawing.
*/
-StyleDialog::StyleDialog(bool stylemode) :
- UI::Widget::Panel("/dialogs/style", SP_VERB_DIALOG_STYLE),
- _updating(false),
- _textNode(nullptr),
- _desktopTracker(),
- _stylemode(stylemode)
+StyleDialog::StyleDialog()
+ : UI::Widget::Panel("/dialogs/css", SP_VERB_DIALOG_CSS)
+ , _desktop(nullptr)
+ , _repr(nullptr)
{
- g_debug("StyleDialog::StyleDialog");
-
- // 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);
- _modelfilter = Gtk::TreeModelFilter::create(_store);
- _modelfilter->set_visible_column(_mColumns._colVisible);
- _treeView.set_model(_modelfilter);
+ set_size_request(20, 15);
_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, &StyleDialog::_addSelector));
-
- del = manage( new Gtk::Button() );
- _styleButton(*del, "list-remove", "Remove a CSS Selector");
- del->signal_clicked().connect(sigc::mem_fun(*this, &StyleDialog::_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, &StyleDialog::_handleButtonEvent),
- false);
-
- _treeView.signal_button_release_event().connect_notify(
- sigc::mem_fun(*this, &StyleDialog::_buttonEventsSelectObjs),
- false);
-
- _treeView.signal_row_expanded().connect(sigc::mem_fun(*this, &StyleDialog::_rowExpand));
-
- _treeView.signal_row_collapsed().connect(sigc::mem_fun(*this, &StyleDialog::_rowCollapse));
-
- // Document & Desktop
- _desktop_changed_connection = _desktopTracker.connectDesktopChanged(
- sigc::mem_fun(*this, &StyleDialog::_handleDesktopChanged) );
- _desktopTracker.connect(GTK_WIDGET(gobj()));
-
- _document_replaced_connection = getDesktop()->connectDocumentReplaced(
- sigc::mem_fun(this, &StyleDialog::_handleDocumentReplaced));
-
- _selection_changed_connection = getDesktop()->getSelection()->connectChanged(
- sigc::hide(sigc::mem_fun(this, &StyleDialog::_handleSelectionChanged)));
-
- // Add watchers
- _updateWatchers();
+ auto _scrolledWindow = new Gtk::ScrolledWindow();
+ _selectordialog = new Inkscape::UI::Dialog::SelectorDialog(true);
+ Gtk::Box *css_box = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_VERTICAL));
+ css_box->set_homogeneous(false);
+ css_box->pack_start(_treeView, Gtk::PACK_SHRINK);
+ css_box->pack_start(*_selectordialog, Gtk::PACK_EXPAND_WIDGET);
+ _scrolledWindow->add(*css_box);
+ _scrolledWindow->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
+
+ _store = Gtk::ListStore::create(_cssColumns);
+ _treeView.set_model(_store);
Inkscape::UI::Widget::IconRenderer *addRenderer = manage(new Inkscape::UI::Widget::IconRenderer());
addRenderer->add_icon("edit-delete");
addRenderer->signal_activated().connect(sigc::mem_fun(*this, &StyleDialog::onPropertyDelete));
- if (!_stylemode && !_store->children().empty()) {
- del->set_sensitive(true);
- }
+ _message_stack = std::make_shared<Inkscape::MessageStack>();
+ _message_context = std::unique_ptr<Inkscape::MessageContext>(new Inkscape::MessageContext(_message_stack));
+ _message_changed_connection =
+ _message_stack->connectChanged(sigc::bind(sigc::ptr_fun(_set_status_message), GTK_WIDGET(status.gobj())));
int addCol = _treeView.append_column("", *addRenderer) - 1;
Gtk::TreeViewColumn *col = _treeView.get_column(addCol);
@@ -173,7 +108,7 @@ StyleDialog::StyleDialog(bool stylemode) :
_propCol->add_attribute(renderer->property_text(), _cssColumns.label);
_propCol->add_attribute(renderer->property_foreground_rgba(), _cssColumns.label_color);
}
- renderer->signal_edited().connect(sigc::mem_fun(*this, &CssDialog::nameEdited));
+ renderer->signal_edited().connect(sigc::mem_fun(*this, &StyleDialog::nameEdited));
renderer = Gtk::manage(new Gtk::CellRendererText());
renderer->property_editable() = true;
int attrColNum = _treeView.append_column("Value", *renderer) - 1;
@@ -182,7 +117,7 @@ StyleDialog::StyleDialog(bool stylemode) :
_attrCol->add_attribute(renderer->property_text(), _cssColumns._styleAttrVal);
_attrCol->add_attribute(renderer->property_foreground_rgba(), _cssColumns.attr_color);
}
- renderer->signal_edited().connect(sigc::mem_fun(*this, &CssDialog::valueEdited));
+ renderer->signal_edited().connect(sigc::mem_fun(*this, &StyleDialog::valueEdited));
renderer = Gtk::manage(new Gtk::CellRendererText());
renderer->property_editable() = true;
@@ -224,113 +159,7 @@ void StyleDialog::_set_status_message(Inkscape::MessageType /*type*/, const gcha
*/
void StyleDialog::setDesktop(SPDesktop* desktop)
{
- g_debug("StyleDialog::_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 << "StyleDialog::_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<Glib::Regex> regex1 =
- // Glib::Regex::create("([^\\{]+)\\{([^\\{]+)\\}");
- //
- // Glib::MatchInfo minfo;
- // regex1->match(content, minfo);
-
- // Split on curly brackets. Even tokens are selectors, odd are values.
- std::cout << content << std::endl;
- std::cout << "aaaaaaaaaaaaaaaaaaaaaaaaaa" << std::endl;
- std::vector<Glib::ustring> 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<std::pair<Glib::ustring, bool>> 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<Glib::ustring> 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<SPObject *> 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 << "StyleDialog::_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;
- 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<SPObject *>(1, obj);
- childrow[_mColumns._colProperties] = ""; // Unused
- childrow[_mColumns._colVisible] = true; // Unused
- }
- }
- }
- _updating = false;
+ _desktop = desktop;
}
/**
@@ -369,63 +198,10 @@ std::map<Glib::ustring, Glib::ustring> StyleDialog::parseStyle(Glib::ustring sty
REMOVE_SPACES(style_string); // We'd use const, but we need to trip spaces
std::vector<Glib::ustring> props = r_props->split(style_string);
- 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<SPObject *>(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<Glib::ustring> tokens = Glib::Regex::split_simple("[,\\s]+", selector);
- Glib::ustring className = tokens[0];
- className.erase(0,1);
- Inkscape::Selection* selection = getDesktop()->getSelection();
- std::vector<SPObject *> sel_obj(selection->objects().begin(), selection->objects().end());
- _insertClass(sel_obj, className);
- std::vector<SPObject *> 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<SPObject *>(1, obj);
- childrow[_mColumns._colProperties] = ""; // Unused
- childrow[_mColumns._colVisible] = true; // Unused
- }
- }
- }
+ for (auto const token : props) {
+ if (token.empty())
+ break;
+ std::vector<Glib::ustring> pair = r_pair->split(token);
if (pair.size() > 1) {
ret[pair[0]] = pair[1];
@@ -507,30 +283,13 @@ void StyleDialog::onAttrChanged(Inkscape::XML::Node *repr, const gchar *name, co
*/
void StyleDialog::css_reset_context(gint css)
{
- g_debug("StyleDialog::_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();
- if (children.empty() && !_stylemode) {
- del->set_sensitive(true);
- }
- std::vector<SPObject *> objVec = row[_mColumns._colObj];
-
- for (auto obj : objVec) {
- getDesktop()->selection->add(obj);
- }
- }
- }
+ if (css == 0) {
+ _message_context->set(Inkscape::NORMAL_MESSAGE, _("<b>Click</b> CSS property to edit."));
+ } else {
+ const gchar *name = g_quark_to_string(css);
+ _message_context->setF(
+ Inkscape::NORMAL_MESSAGE,
+ _("Property <b>%s</b> selected. Press <b>Ctrl+Enter</b> when done editing to commit changes."), name);
}
}
@@ -541,82 +300,15 @@ void StyleDialog::css_reset_context(gint css)
*/
bool StyleDialog::setStyleProperty(Glib::ustring name, Glib::ustring value)
{
- g_debug("StyleDialog::_addSelector: Entrance");
-
- // Store list of selected elements on desktop (not to be confused with selector).
- Inkscape::Selection* selection = getDesktop()->getSelection();
- std::vector<SPObject *> 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<Gtk::Dialog *>(sigc::mem_fun(*this, &StyleDialog::_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();
+ auto original = this->_repr->attribute("style");
+ std::map<Glib::ustring, Glib::ustring> properties = parseStyle(original);
+
+ bool updated = false;
+ if (!value.empty()) {
+ if (properties[name] != value) {
+ // Set value (create or update)
+ properties[name] = value;
+ updated = true;
}
} else if (properties.count(name)) {
// Delete value
@@ -639,23 +331,9 @@ bool StyleDialog::setStyleProperty(Glib::ustring name, Glib::ustring value)
*/
void StyleDialog::onPropertyDelete(Glib::ustring path)
{
- g_debug("StyleDialog::_delSelector");
-
- Glib::RefPtr<Gtk::TreeSelection> 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);
- }
+ Gtk::TreeModel::Row row = *_store->get_iter(path);
+ if (row) {
+ this->setStyleProperty(row[_cssColumns.label], "");
}
}
@@ -676,109 +354,49 @@ bool StyleDialog::onPropertyCreate(GdkEventButton *event)
}
/**
- * @brief CssDialog::onKeyPressed
+ * @brief StyleDialog::onKeyPressed
* @param event_description
* @return
* Send an undo message and mark this point for undo
*/
-void CssDialog::setUndo(Glib::ustring const &event_description)
+void StyleDialog::setUndo(Glib::ustring const &event_description)
{
SPDocument *document = this->_desktop->doc();
DocumentUndo::done(document, SP_VERB_DIALOG_XML_EDITOR, event_description);
}
/**
- * @brief CssDialog::nameEdited
+ * @brief StyleDialog::nameEdited
* @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 StyleDialog::_buttonEventsSelectObjs(GdkEventButton* event )
-{
- g_debug("StyleDialog::_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<int>(event->x);
- int y = static_cast<int>(event->y);
- _selectObjects(x, y);
- }
- _updating = false;
-}
-
-
-/**
- * @brief StyleDialog::_selectRow
- * 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.
+ * @return
+ * Called when the name is edited in the TreeView editable column
*/
-void CssDialog::nameEdited (const Glib::ustring& path, const Glib::ustring& name)
+void StyleDialog::nameEdited (const Glib::ustring& path, const Glib::ustring& name)
{
- g_debug("StyleDialog::_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 << "StyleDialog::_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<SPObject *> objVec = row[_mColumns._colObj];
- if (obj) {
- for (auto & i : objVec) {
- if (obj->getId() == i->getId()) {
- _treeView.get_selection()->select(row);
- row[_mColumns._colVisible] = true;
- } else if(_stylemode) {
- row[_mColumns._colVisible] = false;
- }
- }
+ Gtk::TreeModel::Row row = *_store->get_iter(path);
+ if(row && this->_repr) {
+ Glib::ustring old_name = row[_cssColumns.label];
+ Glib::ustring value = row[_cssColumns._styleAttrVal];
+ // Move to editing value, we set the name as a temporary store value
+ if (!old_name.empty()) {
+ // Remove old named value
+ onPropertyDelete(path);
+ setStyleProperty(name, " ");
}
if (!name.empty()) {
row[_cssColumns.label] = name;
}
this->setUndo(_("Rename CSS attribute"));
}
- if (_stylemode) {
- _modelfilter->refilter();
- _treeView.get_selection()->unselect_all();
- }
-/* if (_stylemode) {
- _store->foreach_iter(sigc::bind<std::vector<Gtk::TreeModel::Row> >(sigc::mem_fun(*this, &StyleDialog::_showStyleSelectors), toshow));
- } */
}
-/* bool StyleDialog::_showStyleSelectors(const Gtk::TreeModel::iterator& iter, std::vector<Gtk::TreeModel::Row> toshow)
-{
- Gtk::TreeModel::Row row = *iter;
- if (std::find(toshow.begin(), toshow.end(), row)!= toshow.end()) {
- std::cout << "fasdsfaasfasfasfasfasf" << std::endl;
- } else {
-
- }
- _store->erase(row);
- std::cout << "1111111111111111111" << std::endl;
- return true;
-} */
/**
- * @brief CssDialog::valueEdited
+ * @brief StyleDialog::valueEdited
* @param event
* @return
* Called when the value is edited in the TreeView editable column
*/
-void CssDialog::valueEdited (const Glib::ustring& path, const Glib::ustring& value)
+void StyleDialog::valueEdited (const Glib::ustring& path, const Glib::ustring& value)
{
Gtk::TreeModel::Row row = *_store->get_iter(path);
if(row && this->_repr) {
diff --git a/src/ui/dialog/styledialog.h b/src/ui/dialog/styledialog.h
index b06ea3065..8467c6683 100644
--- a/src/ui/dialog/styledialog.h
+++ b/src/ui/dialog/styledialog.h
@@ -15,20 +15,15 @@
#ifndef SEEN_UI_DIALOGS_STYLEDIALOG_H
#define SEEN_UI_DIALOGS_STYLEDIALOG_H
-#include <ui/widget/panel.h>
-#include <gtkmm/treeview.h>
-#include <gtkmm/treestore.h>
-#include <gtkmm/treemodelfilter.h>
-#include <gtkmm/scrolledwindow.h>
-#include <gtkmm/dialog.h>
-#include <gtkmm/treeselection.h>
-#include <gtkmm/paned.h>
+#include "desktop.h"
+#include "message.h"
#include <glibmm/regex.h>
#include <gtkmm/dialog.h>
#include <gtkmm/liststore.h>
#include <gtkmm/scrolledwindow.h>
#include <gtkmm/treeview.h>
+#include "ui/dialog/selectordialog.h"
#include <ui/widget/panel.h>
#define STYLE_DIALOG(obj) (dynamic_cast<Inkscape::UI::Dialog::StyleDialog *>((Inkscape::UI::Dialog::StyleDialog *)obj))
@@ -52,41 +47,26 @@ namespace Dialog {
class StyleDialog : public UI::Widget::Panel
{
public:
+ StyleDialog();
~StyleDialog() override;
- // No default constructor, noncopyable, nonassignable
- StyleDialog(bool stylemode = false);
- StyleDialog(StyleDialog const &d) = delete;
- StyleDialog operator=(StyleDialog const &d) = delete;
- static StyleDialog &getInstance() { return *new StyleDialog(false); }
- private:
- // Monitor <style> element for changes.
- class NodeObserver;
+ static StyleDialog &getInstance() { return *new StyleDialog(); }
- // Monitor all objects for addition/removal/attribute change
- class NodeWatcher;
-
- std::vector<StyleDialog::NodeWatcher*> _nodeWatchers;
- void _nodeAdded( Inkscape::XML::Node &repr );
- void _nodeRemoved( Inkscape::XML::Node &repr );
- void _nodeChanged( Inkscape::XML::Node &repr );
// Data structure
class CssColumns : public Gtk::TreeModel::ColumnRecord {
public:
- ModelColumns() {
- add(_colSelector);
- add(_colExpand);
- add(_colType);
- add(_colObj);
- add(_colProperties);
- add(_colVisible);
+ CssColumns() {
+ add(deleteButton);
+ add(label);
+ add(_styleAttrVal);
+ add(label_color);
+ add(attr_color);
}
- Gtk::TreeModelColumn<Glib::ustring> _colSelector; // Selector or matching object id.
- Gtk::TreeModelColumn<bool> _colExpand; // Open/Close store row.
- Gtk::TreeModelColumn<gint> _colType; // Selector row or child object row.
- Gtk::TreeModelColumn<std::vector<SPObject *> > _colObj; // List of matching objects.
- Gtk::TreeModelColumn<Glib::ustring> _colProperties; // List of properties.
- Gtk::TreeModelColumn<bool> _colVisible; // Make visible or not.
+ Gtk::TreeModelColumn<bool> deleteButton;
+ Gtk::TreeModelColumn<Glib::ustring> label;
+ Gtk::TreeModelColumn<Glib::ustring> _styleAttrVal;
+ Gtk::TreeModelColumn<Gdk::RGBA> label_color;
+ Gtk::TreeModelColumn<Gdk::RGBA> attr_color;
};
CssColumns _cssColumns;
@@ -97,65 +77,50 @@ public:
std::unique_ptr<Inkscape::MessageContext> _message_context;
// TreeView
- Glib::RefPtr<Gtk::TreeModelFilter> _modelfilter;
- Glib::RefPtr<TreeStore> _store;
Gtk::TreeView _treeView;
- // Widgets
- Gtk::Paned _paned;
- Gtk::Box _mainBox;
- Gtk::Box _buttonBox;
- Gtk::ScrolledWindow _scrolledWindow;
- Gtk::Button* del;
- Gtk::Button* create;
-
- // Reading and writing the style element.
- Inkscape::XML::Node *_getStyleTextNode();
- void _readStyleElement();
- void _writeStyleElement();
-
- // Update watchers
- void _addWatcherRecursive(Inkscape::XML::Node *node);
- void _updateWatchers();
-
- // Manipulate Tree
- void _addToSelector(Gtk::TreeModel::Row row);
- void _removeFromSelector(Gtk::TreeModel::Row row);
- Glib::ustring _getIdList(std::vector<SPObject *>);
- std::vector<SPObject *> _getObjVec(Glib::ustring selector);
- void _insertClass(const std::vector<SPObject *>& objVec, const Glib::ustring& className);
- void _selectObjects(int, int);
-
- // Variables
- bool _updating; // Prevent cyclic actions: read <-> write, select via dialog <-> via desktop
- bool _stylemode; // Show dialog of items in selector widget or in css styles in CSS dialog
- Inkscape::XML::Node *_textNode; // Track so we know when to add a NodeObserver.
-
- // Signals and handlers - External
- sigc::connection _document_replaced_connection;
- sigc::connection _desktop_changed_connection;
- sigc::connection _selection_changed_connection;
-
- void _handleDocumentReplaced(SPDesktop* desktop, SPDocument *document);
- void _handleDesktopChanged(SPDesktop* desktop);
- void _handleSelectionChanged();
- void _rowExpand(const Gtk::TreeModel::iterator &iter, const Gtk::TreeModel::Path &path);
- void _rowCollapse(const Gtk::TreeModel::iterator &iter, const Gtk::TreeModel::Path &path);
- void _closeDialog(Gtk::Dialog *textDialogPtr);
-
- DesktopTracker _desktopTracker;
-
- Inkscape::XML::SignalObserver _objObserver; // Track object in selected row (for style change).
-
- // Signal and handlers - Internal
- void _addSelector();
- void _delSelector();
- bool _handleButtonEvent(GdkEventButton *event);
- //bool _showStyleSelectors(const Gtk::TreeModel::iterator& iter, std::vector<Gtk::TreeModel::Row> toshow);
- void _buttonEventsSelectObjs(GdkEventButton *event);
- void _selectRow(); // Select row in tree when selection changed.
-
- // GUI
- void _styleButton(Gtk::Button& btn, char const* iconName, char const* tooltip);
+ Glib::RefPtr<Gtk::ListStore> _store;
+ Gtk::TreeModel::Row _propRow;
+ Gtk::TreeViewColumn *_propCol;
+ Gtk::TreeViewColumn *_attrCol;
+ Gtk::HBox status_box;
+ Gtk::Label status;
+
+ /**
+ * Sets the XML status bar, depending on which attr is selected.
+ */
+ void css_reset_context(gint css);
+ static void _set_status_message(Inkscape::MessageType type, const gchar *message, GtkWidget *dialog);
+
+
+ // Variables - Inkscape
+ SPDesktop* _desktop;
+ Inkscape::XML::Node *_repr;
+
+ // Helper functions
+ void setDesktop(SPDesktop* desktop) override;
+ void setRepr(Inkscape::XML::Node *repr);
+
+ // Parsing functions
+ std::map<Glib::ustring, Glib::ustring> parseStyle(Glib::ustring style_string);
+ Glib::ustring compileStyle(std::map<Glib::ustring, Glib::ustring> props);
+ // Signal handlers
+ void onAttrChanged(Inkscape::XML::Node *repr, const gchar *name, const gchar *new_value);
+
+ private:
+ Glib::RefPtr<Glib::Regex> r_props = Glib::Regex::create("\\s*;\\s*");
+ Glib::RefPtr<Glib::Regex> r_pair = Glib::Regex::create("\\s*:\\s*");
+ void setUndo(Glib::ustring const &event_description);
+ void valueEdited (const Glib::ustring& path, const Glib::ustring& value);
+ void nameEdited (const Glib::ustring& path, const Glib::ustring& name);
+ bool onPropertyCreate(GdkEventButton *event);
+ void onPropertyDelete(Glib::ustring path);
+ bool setStyleProperty(Glib::ustring name, Glib::ustring value);
+ Inkscape::UI::Dialog::SelectorDialog *_selectordialog;
+ /**
+ * Signal handlers
+ */
+ sigc::connection _message_changed_connection;
+ bool _addProperty(GdkEventButton *event);
};
diff --git a/src/ui/dialog/xml-tree.h b/src/ui/dialog/xml-tree.h
index 9aa96a9a2..71930ae42 100644
--- a/src/ui/dialog/xml-tree.h
+++ b/src/ui/dialog/xml-tree.h
@@ -26,10 +26,12 @@
#include <gtkmm/toolbar.h>
#include "message.h"
-#include "ui/dialog/attrdialog.h"
+
#include "ui/dialog/selectordialog.h"
-#include "ui/dialog/desktop-tracker.h"
+#include "ui/dialog/attrdialog.h"
#include "ui/dialog/styledialog.h"
+#include "ui/dialog/desktop-tracker.h"
+
class SPDesktop;
class SPObject;