summaryrefslogtreecommitdiffstats
path: root/src/ui/dialog/styledialog.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui/dialog/styledialog.h')
-rw-r--r--src/ui/dialog/styledialog.h199
1 files changed, 199 insertions, 0 deletions
diff --git a/src/ui/dialog/styledialog.h b/src/ui/dialog/styledialog.h
new file mode 100644
index 0000000..dd2171e
--- /dev/null
+++ b/src/ui/dialog/styledialog.h
@@ -0,0 +1,199 @@
+// 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 <grewalkamal005@gmail.com>
+ * Copyright (C) Tavmjong Bah 2017 <tavmjong@free.fr>
+ *
+ * Released under GNU GPL v2+, read the file 'COPYING' for more information.
+ */
+
+#ifndef STYLEDIALOG_H
+#define STYLEDIALOG_H
+
+#include <glibmm/regex.h>
+#include <gtkmm/adjustment.h>
+#include <gtkmm/builder.h>
+#include <gtkmm/celleditable.h>
+#include <gtkmm/cellrenderercombo.h>
+#include <gtkmm/dialog.h>
+#include <gtkmm/entry.h>
+#include <gtkmm/entrycompletion.h>
+#include <gtkmm/eventbox.h>
+#include <gtkmm/liststore.h>
+#include <gtkmm/paned.h>
+#include <gtkmm/scrolledwindow.h>
+#include <gtkmm/switch.h>
+#include <gtkmm/tooltip.h>
+#include <gtkmm/treemodelfilter.h>
+#include <gtkmm/treeselection.h>
+#include <gtkmm/treestore.h>
+#include <gtkmm/treeview.h>
+#include <gtkmm/viewport.h>
+#include <memory>
+#include <vector>
+
+#include "style-enums.h"
+#include "ui/dialog/dialog-base.h"
+#include "xml/helper-observer.h"
+
+namespace Inkscape {
+
+XML::Node *get_first_style_text_node(XML::Node *root, bool create_if_missing);
+
+namespace UI {
+namespace Dialog {
+
+/**
+ * @brief The StyleDialog class
+ * A list of CSS selectors will show up in this dialog. This dialog allows one to
+ * add and delete selectors. Elements can be added to and removed from the selectors
+ * in the dialog. Selection of any selector row selects the matching objects in
+ * the drawing and vice-versa. (Only simple selectors supported for now.)
+ *
+ * This class must keep two things in sync:
+ * 1. The text node of the style element.
+ * 2. The Gtk::TreeModel.
+ */
+class StyleDialog : public DialogBase
+{
+public:
+ // No default constructor, noncopyable, nonassignable
+ StyleDialog();
+ ~StyleDialog() override;
+ StyleDialog(StyleDialog const &d) = delete;
+ StyleDialog operator=(StyleDialog const &d) = delete;
+
+ void documentReplaced() override;
+ void selectionChanged(Selection *selection) override;
+
+ static StyleDialog &getInstance() { return *new StyleDialog(); }
+ void setCurrentSelector(Glib::ustring current_selector);
+ Gtk::TreeView *_current_css_tree;
+ Gtk::TreeViewColumn *_current_value_col;
+ Gtk::TreeModel::Path _current_path;
+ bool _deletion;
+ Glib::ustring fixCSSSelectors(Glib::ustring selector);
+ void readStyleElement();
+
+ private:
+ // Monitor <style> element for changes.
+ class NodeObserver;
+ // Monitor all objects for addition/removal/attribute change
+ class NodeWatcher;
+ Glib::RefPtr<Glib::Regex> r_props = Glib::Regex::create("\\s*;\\s*");
+ Glib::RefPtr<Glib::Regex> r_pair = Glib::Regex::create("\\s*:\\s*");
+ void _nodeAdded(Inkscape::XML::Node &repr);
+ void _nodeRemoved(Inkscape::XML::Node &repr);
+ void _nodeChanged(Inkscape::XML::Node &repr);
+ void removeObservers();
+ /* void _stylesheetChanged( Inkscape::XML::Node &repr ); */
+ // Data structure
+ class ModelColumns : public Gtk::TreeModel::ColumnRecord {
+ public:
+ ModelColumns()
+ {
+ add(_colActive);
+ add(_colName);
+ add(_colValue);
+ add(_colStrike);
+ add(_colSelector);
+ add(_colSelectorPos);
+ add(_colOwner);
+ add(_colLinked);
+ add(_colHref);
+ }
+ Gtk::TreeModelColumn<bool> _colActive; // Active or inactive property
+ Gtk::TreeModelColumn<Glib::ustring> _colName; // Name of the property.
+ Gtk::TreeModelColumn<Glib::ustring> _colValue; // Value of the property.
+ Gtk::TreeModelColumn<bool> _colStrike; // Property not used, overloaded
+ Gtk::TreeModelColumn<Glib::ustring> _colSelector; // Style or matching object id.
+ Gtk::TreeModelColumn<gint> _colSelectorPos; // Position of the selector to handle dup selectors
+ Gtk::TreeModelColumn<Glib::ustring> _colOwner; // Store the owner of the property for popup
+ Gtk::TreeModelColumn<bool> _colLinked; // Other object linked
+ Gtk::TreeModelColumn<SPObject *> _colHref; // Is going to another object
+ };
+ ModelColumns _mColumns;
+
+ class CSSData : public Gtk::TreeModel::ColumnRecord {
+ public:
+ CSSData() { add(_colCSSData); }
+ Gtk::TreeModelColumn<Glib::ustring> _colCSSData; // Name of the property.
+ };
+ CSSData _mCSSData;
+ guint _deleted_pos;
+ // Widgets
+ Gtk::ScrolledWindow _scrolledWindow;
+ Glib::RefPtr<Gtk::Adjustment> _vadj;
+ Gtk::Box _mainBox;
+ Gtk::Box _styleBox;
+ // Reading and writing the style element.
+ Inkscape::XML::Node *_getStyleTextNode(bool create_if_missing = false);
+ Glib::RefPtr<Gtk::TreeModel> _selectTree(Glib::ustring selector);
+ void _writeStyleElement(Glib::RefPtr<Gtk::TreeStore> store, Glib::ustring selector,
+ Glib::ustring new_selector = "");
+ // void _selectorActivate(Glib::RefPtr<Gtk::TreeStore> store, Gtk::Label *selector, Gtk::Entry *selector_edit);
+ bool _selectorEditKeyPress(GdkEventKey *event, Glib::RefPtr<Gtk::TreeStore> store, Gtk::Label *selector,
+ Gtk::Entry *selector_edit);
+ bool _selectorStartEdit(GdkEventButton *event, Gtk::Label *selector, Gtk::Entry *selector_edit);
+ void _activeToggled(const Glib::ustring &path, Glib::RefPtr<Gtk::TreeStore> store);
+ bool _addRow(GdkEventButton *evt, Glib::RefPtr<Gtk::TreeStore> store, Gtk::TreeView *css_tree,
+ Glib::ustring selector, gint pos);
+ void _onPropDelete(Glib::ustring path, Glib::RefPtr<Gtk::TreeStore> store);
+ void _nameEdited(const Glib::ustring &path, const Glib::ustring &name, Glib::RefPtr<Gtk::TreeStore> store,
+ Gtk::TreeView *css_tree);
+ bool _onNameKeyReleased(GdkEventKey *event, Gtk::Entry *entry);
+ bool _onValueKeyReleased(GdkEventKey *event, Gtk::Entry *entry);
+ bool _onNameKeyPressed(GdkEventKey *event, Gtk::Entry *entry);
+ bool _onValueKeyPressed(GdkEventKey *event, Gtk::Entry *entry);
+ void _onLinkObj(Glib::ustring path, Glib::RefPtr<Gtk::TreeStore> store);
+ void _valueEdited(const Glib::ustring &path, const Glib::ustring &value, Glib::RefPtr<Gtk::TreeStore> store);
+ void _startNameEdit(Gtk::CellEditable *cell, const Glib::ustring &path);
+
+ void _startValueEdit(Gtk::CellEditable *cell, const Glib::ustring &path, Glib::RefPtr<Gtk::TreeStore> store);
+ void _setAutocompletion(Gtk::Entry *entry, SPStyleEnum const cssenum[]);
+ void _setAutocompletion(Gtk::Entry *entry, Glib::ustring name);
+ bool _on_foreach_iter(const Gtk::TreeModel::iterator &iter);
+ void _reload();
+ void _vscroll();
+ bool _scrollock;
+ double _scrollpos;
+ Glib::ustring _current_selector;
+
+ // Update watchers
+ std::unique_ptr<Inkscape::XML::NodeObserver> m_nodewatcher;
+ std::unique_ptr<Inkscape::XML::NodeObserver> m_styletextwatcher;
+
+ // Manipulate Tree
+ std::vector<SPObject *> _getObjVec(Glib::ustring selector);
+ std::map<Glib::ustring, Glib::ustring> parseStyle(Glib::ustring style_string);
+ std::map<Glib::ustring, Glib::ustring> _owner_style;
+ void _addOwnerStyle(Glib::ustring name, Glib::ustring selector);
+ // Variables
+ Inkscape::XML::Node *m_root = nullptr;
+ Inkscape::XML::Node *_textNode; // Track so we know when to add a NodeObserver.
+ bool _updating; // Prevent cyclic actions: read <-> write, select via dialog <-> via desktop
+
+ void _closeDialog(Gtk::Dialog *textDialogPtr);
+};
+
+} // namespace Dialog
+} // namespace UI
+} // namespace Inkscape
+
+#endif // STYLEDIALOG_H
+
+/*
+ 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 :