summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Owens <doctormo@gmail.com>2018-09-14 16:58:18 +0000
committerMartin Owens <doctormo@gmail.com>2018-09-14 16:58:18 +0000
commitb92e577ea62c2a94ba38390fa67d9dcea3db88af (patch)
tree3b48af7caf1e7fd14fd0015f6113a6545f11e9b7
parentMerge branch 'master' of gitlab.com:jordim/inkscape (diff)
downloadinkscape-b92e577ea62c2a94ba38390fa67d9dcea3db88af.tar.gz
inkscape-b92e577ea62c2a94ba38390fa67d9dcea3db88af.zip
Remove sp-xmlview-attr with attrdialog (C++) and improve interface
-rw-r--r--src/ui/CMakeLists.txt2
-rw-r--r--src/ui/dialog/attrdialog.cpp272
-rw-r--r--src/ui/dialog/attrdialog.h92
-rw-r--r--src/ui/dialog/cssdialog.cpp25
-rw-r--r--src/ui/dialog/cssdialog.h1
-rw-r--r--src/ui/dialog/xml-tree.cpp38
-rw-r--r--src/ui/dialog/xml-tree.h10
-rw-r--r--src/widgets/CMakeLists.txt2
-rw-r--r--src/widgets/sp-xmlview-attr-list.cpp280
-rw-r--r--src/widgets/sp-xmlview-attr-list.h57
10 files changed, 391 insertions, 388 deletions
diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt
index 0ae3b8624..6d1ebb785 100644
--- a/src/ui/CMakeLists.txt
+++ b/src/ui/CMakeLists.txt
@@ -82,6 +82,7 @@ set(ui_SRC
dialog/calligraphic-profile-rename.cpp
dialog/clonetiler.cpp
dialog/color-item.cpp
+ dialog/attrdialog.cpp
dialog/cssdialog.cpp
dialog/debug.cpp
dialog/desktop-tracker.cpp
@@ -233,6 +234,7 @@ set(ui_SRC
dialog/calligraphic-profile-rename.h
dialog/clonetiler.h
dialog/color-item.h
+ dialog/attrdialog.h
dialog/cssdialog.h
dialog/debug.h
dialog/desktop-tracker.h
diff --git a/src/ui/dialog/attrdialog.cpp b/src/ui/dialog/attrdialog.cpp
new file mode 100644
index 000000000..529a59720
--- /dev/null
+++ b/src/ui/dialog/attrdialog.cpp
@@ -0,0 +1,272 @@
+/** @file
+ * @brief A dialog for XML attributes
+ */
+/* Authors:
+ * Martin Owens
+ *
+ * Copyright (C) Martin Owens 2018 <doctormo@gmail.com>
+ *
+ * Released under GNU GPLv2 or later, read the file 'COPYING' for more information
+ */
+
+#include "attrdialog.h"
+
+#include "verbs.h"
+#include "selection.h"
+
+#include "helper/icon-loader.h"
+#include "ui/widget/addtoicon.h"
+
+#include "xml/node-event-vector.h"
+#include "xml/attribute-record.h"
+
+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)
+{
+ ATTR_DIALOG(data)->onAttrChanged(repr, name, new_value);
+}
+Inkscape::XML::NodeEventVector _repr_events = {
+ nullptr, /* child_added */
+ nullptr, /* child_removed */
+ on_attr_changed,
+ nullptr, /* content_changed */
+ nullptr /* order_changed */
+};
+
+namespace Inkscape {
+namespace UI {
+namespace Dialog {
+
+
+/**
+ * Constructor
+ * A treeview whose each row corresponds to an XML attribute of a selected node
+ * New attribute can be added by clicking '+' at bottom of the attr pane. '-'
+ */
+AttrDialog::AttrDialog():
+ UI::Widget::Panel("/dialogs/attr", SP_VERB_DIALOG_CSS),
+ _desktop(nullptr),
+ _repr(nullptr)
+{
+ set_size_request(20, 15);
+ _mainBox.pack_start(_scrolledWindow, Gtk::PACK_EXPAND_WIDGET);
+ _treeView.set_headers_visible(true);
+ _scrolledWindow.add(_treeView);
+ _scrolledWindow.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
+
+ _store = Gtk::ListStore::create(_attrColumns);
+ _treeView.set_model(_store);
+
+ Inkscape::UI::Widget::AddToIcon * addRenderer = manage(new Inkscape::UI::Widget::AddToIcon());
+ addRenderer->property_active() = false;
+
+ int addCol = _treeView.append_column("", *addRenderer) - 1;
+ Gtk::TreeViewColumn *col = _treeView.get_column(addCol);
+ if (col) {
+ auto add_icon = Gtk::manage(sp_get_icon_image("list-add", GTK_ICON_SIZE_SMALL_TOOLBAR));
+ col->add_attribute(addRenderer->property_active(), _attrColumns._colUnsetAttr);
+ col->set_clickable(true);
+ col->set_widget(*add_icon);
+ add_icon->set_tooltip_text("Add a new attribute");
+ add_icon->show();
+ // This gets the GtkButton inside the GtkBox, inside the GtkAlignment, inside the GtkImage icon.
+ auto button = add_icon->get_parent()->get_parent()->get_parent();
+ // Assign the button event so that create happens BEFORE delete. If this code
+ // isn't in this exact way, the onAttrDelete is called when the header lines are pressed.
+ button->signal_button_release_event().connect(sigc::mem_fun(*this, &AttrDialog::onAttrCreate), false);
+ }
+ _treeView.signal_button_release_event().connect(sigc::mem_fun(*this, &AttrDialog::onAttrDelete));
+
+ _nameRenderer = Gtk::manage(new Gtk::CellRendererText());
+ _nameRenderer->property_editable() = true;
+ _nameRenderer->property_placeholder_text().set_value("Attribute Name");
+ _nameRenderer->signal_edited().connect(sigc::mem_fun(*this, &AttrDialog::nameEdited));
+ int nameColNum = _treeView.append_column("Name", *_nameRenderer) - 1;
+ _nameCol = _treeView.get_column(nameColNum);
+ if (_nameCol) {
+ _nameCol->add_attribute(_nameRenderer->property_text(), _attrColumns._attributeName);
+ }
+
+ _valueRenderer = Gtk::manage(new Gtk::CellRendererText());
+ _valueRenderer->property_editable() = true;
+ _valueRenderer->property_placeholder_text().set_value("Attribute Value");
+ _valueRenderer->property_ellipsize().set_value(Pango::ELLIPSIZE_MIDDLE);
+ _valueRenderer->signal_edited().connect(sigc::mem_fun(*this, &AttrDialog::valueEdited));
+ int valueColNum = _treeView.append_column("Value", *_valueRenderer) - 1;
+ _valueCol = _treeView.get_column(valueColNum);
+ if (_valueCol) {
+ _valueCol->add_attribute(_valueRenderer->property_text(), _attrColumns._attributeValue);
+ }
+
+ _getContents()->pack_start(_mainBox, Gtk::PACK_EXPAND_WIDGET);
+
+ setDesktop(getDesktop());
+}
+
+
+/**
+ * @brief AttrDialog::~AttrDialog
+ * Class destructor
+ */
+AttrDialog::~AttrDialog()
+{
+ setDesktop(nullptr);
+}
+
+
+/**
+ * @brief AttrDialog::setDesktop
+ * @param desktop
+ * This function sets the 'desktop' for the CSS pane.
+ */
+void AttrDialog::setDesktop(SPDesktop* desktop)
+{
+ _desktop = desktop;
+}
+
+/**
+ * @brief AttrDialog::setRepr
+ * Set the internal xml object that I'm working on right now.
+ */
+void AttrDialog::setRepr(Inkscape::XML::Node * repr)
+{
+ if ( repr == _repr ) return;
+ if (_repr) {
+ _store->clear();
+ _repr->removeListenerByData(this);
+ Inkscape::GC::release(_repr);
+ }
+ _repr = repr;
+ if (repr) {
+ Inkscape::GC::anchor(_repr);
+ _repr->addListener(&_repr_events, this);
+ _repr->synthesizeEvents(&_repr_events, this);
+ }
+}
+
+/**
+ * @brief AttrDialog::onAttrChanged
+ * This is called when the XML has an updated attribute
+ */
+void AttrDialog::onAttrChanged(Inkscape::XML::Node *repr, const gchar * name, const gchar * new_value)
+{
+ for(auto iter: this->_store->children())
+ {
+ Gtk::TreeModel::Row row = *iter;
+ Glib::ustring col_name = row[_attrColumns._attributeName];
+ if(name == col_name) {
+ if(new_value) {
+ row[_attrColumns._attributeValue] = new_value;
+ new_value = nullptr; // Don't make a new one
+ } else {
+ _store->erase(iter);
+ }
+ }
+ }
+ if(new_value) {
+ Gtk::TreeModel::Row row = *(_store->append());
+ row[_attrColumns._attributeName] = name;
+ row[_attrColumns._attributeValue] = new_value;
+ }
+}
+
+/**
+ * @brief AttrDialog::onAttrCreate
+ * This function is a slot to signal_clicked for '+' button panel.
+ */
+bool AttrDialog::onAttrCreate(GdkEventButton *event)
+{
+ if(event->type == GDK_BUTTON_RELEASE && event->button == 1 && this->_repr) {
+ Gtk::TreeIter iter = _store->append();
+ Gtk::TreeModel::Path path = (Gtk::TreeModel::Path)iter;
+ _treeView.set_cursor(path, *_nameCol, true);
+ grab_focus();
+ return true;
+ }
+ return false;
+}
+
+/**
+ * @brief AttrDialog::onAttrDelete
+ * @param event
+ * @return
+ * Delete the attribute from the xml
+ */
+bool AttrDialog::onAttrDelete(GdkEventButton *event)
+{
+ if (event->type == GDK_BUTTON_RELEASE && event->button == 1 && this->_repr) {
+ if(!this->_treeView.has_focus()) {
+ // If the treeView doesn't have focus, then it's probably the edit
+ // input box or some other widget that propergates to the same click
+ return false;
+ }
+ int x = static_cast<int>(event->x);
+ int y = static_cast<int>(event->y);
+ Gtk::TreeModel::Path path;
+ Gtk::TreeViewColumn *col = nullptr;
+ int x2, y2 = 0;
+ if (_treeView.get_path_at_pos(x, y, path, col, x2, y2)) {
+ Gtk::TreeModel::Row row = *_store->get_iter(path);
+ if (col == _treeView.get_column(0) && row) {
+ Glib::ustring name = row[_attrColumns._attributeName];
+ this->_repr->setAttribute(name.c_str(), nullptr, false);
+ // Return true to prevent propergation
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+
+/**
+ * @brief AttrDialog::nameEdited
+ * @param event
+ * @return
+ * Called when the name is edited in the TreeView editable column
+ */
+void AttrDialog::nameEdited (const Glib::ustring& path, const Glib::ustring& name)
+{
+
+ Gtk::TreeModel::Row row = *_store->get_iter(path);
+ if(row) {
+ Glib::ustring old_name = row[_attrColumns._attributeName];
+ Glib::ustring value = row[_attrColumns._attributeValue];
+ if(!old_name.empty()) {
+ // Remove named value
+ _repr->setAttribute(old_name, nullptr, false);
+ _repr->setAttribute(name, value, false);
+ } else {
+ // Move to editing value, we set the name as a temporary store value
+ row[_attrColumns._attributeName] = name;
+ Gtk::TreeModel::Path _path = (Gtk::TreeModel::Path)row;
+ _treeView.set_cursor(_path, *_valueCol, true);
+ grab_focus();
+ }
+ }
+}
+
+/**
+ * @brief AttrDialog::valueEdited
+ * @param event
+ * @return
+ * Called when the value is edited in the TreeView editable column
+ */
+void AttrDialog::valueEdited (const Glib::ustring& path, const Glib::ustring& value)
+{
+
+ Gtk::TreeModel::Row row = *_store->get_iter(path);
+ if(row) {
+ Glib::ustring name = row[_attrColumns._attributeName];
+ if(name.empty()) return;
+ _repr->setAttribute(name, value, false);
+ }
+}
+
+} // namespace Dialog
+} // namespace UI
+} // namespace Inkscape
diff --git a/src/ui/dialog/attrdialog.h b/src/ui/dialog/attrdialog.h
new file mode 100644
index 000000000..23ba8f321
--- /dev/null
+++ b/src/ui/dialog/attrdialog.h
@@ -0,0 +1,92 @@
+/** @file
+ * @brief A dialog for XML attributes based on Gtk TreeView
+ */
+/* Authors:
+ * Martin Owens
+ *
+ * Copyright (C) Martin Owens 2018 <doctormo@gmail.com>
+ *
+ * Released under GNU GPLv2 or later, read the file 'COPYING' for more information
+ */
+
+#ifndef ATTRDIALOG_H
+#define ATTRDIALOG_H
+
+#include <gtkmm/treeview.h>
+#include <gtkmm/liststore.h>
+#include <gtkmm/scrolledwindow.h>
+#include <gtkmm/dialog.h>
+#include <ui/widget/panel.h>
+
+#include "desktop.h"
+
+#define ATTR_DIALOG(obj) (dynamic_cast<Inkscape::UI::Dialog::AttrDialog*>((Inkscape::UI::Dialog::AttrDialog*)obj))
+
+namespace Inkscape {
+namespace UI {
+namespace Dialog {
+
+/**
+ * @brief The AttrDialog class
+ * This dialog allows to add, delete and modify XML attributes created in the
+ * xml editor.
+ */
+class AttrDialog : public UI::Widget::Panel
+{
+public:
+ AttrDialog();
+ ~AttrDialog() override;
+
+ static AttrDialog &getInstance() { return *new AttrDialog(); }
+
+ // Data structure
+ class AttrColumns : public Gtk::TreeModel::ColumnRecord {
+ public:
+ AttrColumns() {
+ add(_colUnsetAttr);
+ add(_attributeName);
+ add(_attributeValue);
+ }
+ Gtk::TreeModelColumn<bool> _colUnsetAttr;
+ Gtk::TreeModelColumn<Glib::ustring> _attributeName;
+ Gtk::TreeModelColumn<Glib::ustring> _attributeValue;
+ };
+ AttrColumns _attrColumns;
+
+ // TreeView
+ Gtk::TreeView _treeView;
+ Glib::RefPtr<Gtk::ListStore> _store;
+ Gtk::CellRendererText *_nameRenderer;
+ Gtk::CellRendererText *_valueRenderer;
+ Gtk::TreeViewColumn *_nameCol;
+ Gtk::TreeViewColumn *_valueCol;
+
+ // Widgets
+ Gtk::VBox _mainBox;
+ Gtk::ScrolledWindow _scrolledWindow;
+ Gtk::HBox _buttonBox;
+ Gtk::Button _buttonAddAttribute;
+
+ // Variables - Inkscape
+ SPDesktop* _desktop;
+ Inkscape::XML::Node* _repr;
+
+ // Helper functions
+ void setDesktop(SPDesktop* desktop) override;
+ void setRepr(Inkscape::XML::Node * repr);
+
+ // Signal handlers
+ void onAttrChanged(Inkscape::XML::Node *repr, const gchar * name, const gchar * new_value);
+ bool onAttrCreate(GdkEventButton *event);
+ bool onAttrDelete(GdkEventButton *event);
+ void nameEdited(const Glib::ustring &path, const Glib::ustring &name);
+ void valueEdited(const Glib::ustring &path, const Glib::ustring &value);
+
+};
+
+
+} // namespace Dialog
+} // namespace UI
+} // namespace Inkscape
+
+#endif // ATTRDIALOG_H
diff --git a/src/ui/dialog/cssdialog.cpp b/src/ui/dialog/cssdialog.cpp
index 901bcf36c..47922fc64 100644
--- a/src/ui/dialog/cssdialog.cpp
+++ b/src/ui/dialog/cssdialog.cpp
@@ -80,7 +80,11 @@ CssDialog::CssDialog():
_attrCol->add_attribute(_attrRenderer->property_text(), _cssColumns._styleAttrVal);
}
- _styleButton(_buttonAddProperty, "list-add", "Add a new property");
+ GtkWidget *child = GTK_WIDGET(sp_get_icon_image("list-add", GTK_ICON_SIZE_SMALL_TOOLBAR)->gobj());
+ gtk_widget_show(child);
+ _buttonAddProperty.add(*manage(Glib::wrap(child)));
+ _buttonAddProperty.set_relief(Gtk::RELIEF_NONE);
+ _buttonAddProperty.set_tooltip_text("Add a new property");
_mainBox.pack_end(_buttonBox, Gtk::PACK_SHRINK);
_buttonBox.pack_start(_buttonAddProperty, Gtk::PACK_SHRINK);
@@ -113,25 +117,6 @@ void CssDialog::setDesktop(SPDesktop* desktop)
_desktop = desktop;
}
-
-/**
- * @brief CssDialog::_styleButton
- * @param btn
- * @param iconName
- * @param tooltip
- * This function sets the style of '+'button at the bottom of dialog.
- */
-void CssDialog::_styleButton(Gtk::Button& btn, char const* iconName,
- char const* tooltip)
-{
- GtkWidget *child = GTK_WIDGET(sp_get_icon_image(iconName, GTK_ICON_SIZE_SMALL_TOOLBAR)->gobj());
- gtk_widget_show(child);
- btn.add(*manage(Glib::wrap(child)));
- btn.set_relief(Gtk::RELIEF_NONE);
- btn.set_tooltip_text(tooltip);
-}
-
-
/**
* @brief CssDialog::_addProperty
* This function is a slot to signal_clicked for '+' button at the bottom of CSS
diff --git a/src/ui/dialog/cssdialog.h b/src/ui/dialog/cssdialog.h
index 76c98ee8d..6b9657599 100644
--- a/src/ui/dialog/cssdialog.h
+++ b/src/ui/dialog/cssdialog.h
@@ -79,7 +79,6 @@ public:
// Helper functions
void setDesktop(SPDesktop* desktop) override;
- void _styleButton(Gtk::Button& btn, char const* iconName, char const* tooltip);
// Signal handlers
void _addProperty();
diff --git a/src/ui/dialog/xml-tree.cpp b/src/ui/dialog/xml-tree.cpp
index e62f0232d..2e53ebf32 100644
--- a/src/ui/dialog/xml-tree.cpp
+++ b/src/ui/dialog/xml-tree.cpp
@@ -41,8 +41,8 @@
#include "ui/interface.h"
#include "ui/tools/tool-base.h"
-#include "widgets/sp-xmlview-attr-list.h"
#include "widgets/sp-xmlview-tree.h"
+#include "ui/dialog/attrdialog.h"
#include "ui/dialog/cssdialog.h"
namespace Inkscape {
@@ -59,7 +59,6 @@ XmlTree::XmlTree() :
selected_attr (0),
selected_repr (nullptr),
tree (nullptr),
- attributes (nullptr),
status (""),
tree_toolbar(),
xml_element_new_button ( _("New element node")),
@@ -181,28 +180,19 @@ XmlTree::XmlTree() :
node_box.pack_start(*tree_scroller);
- /* node view */
+ /* attributes */
+ attributes = new AttrDialog;
+ attr_box.pack_start(*attributes);
notebook_content->insert_page(attr_box, _("_Attributes"), NOTEBOOK_PAGE_ATTRS, true);
notebook_content->set_tab_detachable(attr_box, true);
- /* attributes */
- attributes = SP_XMLVIEW_ATTR_LIST(sp_xmlview_attr_list_new(nullptr));
-
- Gtk::ScrolledWindow *attr_scroller = new Gtk::ScrolledWindow();
- attr_scroller->set_policy( Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC );
- attr_scroller->set_shadow_type(Gtk::SHADOW_IN);
- attr_scroller->set_size_request(-1, 80);
-
- attr_box.pack_start( *attr_scroller );
- attr_scroller->add(*Gtk::manage(Glib::wrap(GTK_WIDGET(attributes))));
-
/* Signal handlers */
GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(tree));
g_signal_connect (G_OBJECT(selection), "changed", G_CALLBACK (on_tree_select_row), this);
g_signal_connect_after( G_OBJECT(tree), "tree_move", G_CALLBACK(after_tree_move), this);
- g_signal_connect( G_OBJECT(attributes), "row-value-changed", G_CALLBACK(on_attr_row_changed), this);
- g_signal_connect( G_OBJECT(attributes), "attr-value-edited", G_CALLBACK(on_attr_edited), this);
+ //g_signal_connect( G_OBJECT(attributes), "row-value-changed", G_CALLBACK(on_attr_row_changed), this);
+ //g_signal_connect( G_OBJECT(attributes), "attr-value-edited", G_CALLBACK(on_attr_edited), this);
xml_element_new_button.signal_clicked().connect(sigc::mem_fun(*this, &XmlTree::cmd_new_element_node));
xml_text_new_button.signal_clicked().connect(sigc::mem_fun(*this, &XmlTree::cmd_new_text_node));
@@ -388,9 +378,9 @@ void XmlTree::set_tree_select(Inkscape::XML::Node *repr)
void XmlTree::propagate_tree_select(Inkscape::XML::Node *repr)
{
if (repr && (repr->type() == Inkscape::XML::ELEMENT_NODE)) {
- sp_xmlview_attr_list_set_repr(attributes, repr);
+ attributes->setRepr(repr);
} else {
- sp_xmlview_attr_list_set_repr(attributes, nullptr);
+ attributes->setRepr(nullptr);
}
}
@@ -482,7 +472,7 @@ void XmlTree::on_tree_select_row(GtkTreeSelection *selection, gpointer data)
}
-void XmlTree::after_tree_move(SPXMLViewTree * /*attributes*/, gpointer value, gpointer data)
+void XmlTree::after_tree_move(SPXMLViewTree * /*tree*/, gpointer value, gpointer data)
{
XmlTree *self = static_cast<XmlTree *>(data);
guint val = GPOINTER_TO_UINT(value);
@@ -631,7 +621,7 @@ void XmlTree::on_tree_unselect_row_disable()
lower_node_button.set_sensitive(false);
}
-void XmlTree::on_attr_edited(SPXMLViewAttrList *attributes, const gchar * name, const gchar * value, gpointer data)
+/*void XmlTree::on_attr_edited(SPXMLViewAttrList *attributes, const gchar * name, const gchar * value, gpointer data)
{
XmlTree *self = static_cast<XmlTree *>(data);
g_assert(self->selected_repr != nullptr);
@@ -656,10 +646,10 @@ void XmlTree::on_attr_edited(SPXMLViewAttrList *attributes, const gchar * name,
} else {
DocumentUndo::done(self->current_document, SP_VERB_DIALOG_XML_EDITOR, _("Delete attribute"));
}
-}
+}*/
-void XmlTree::on_attr_row_changed(SPXMLViewAttrList *attributes, const gchar * name, gpointer /*data*/)
-{
+//void XmlTree::on_attr_row_changed(SPXMLViewAttrList *attributes, const gchar * name, gpointer /*data*/)
+/*{
// Reselect the selected row if the data changes to refresh the attribute and value edit boxes.
GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(attributes));
GtkTreeIter iter;
@@ -679,7 +669,7 @@ void XmlTree::on_attr_row_changed(SPXMLViewAttrList *attributes, const gchar * n
g_free(attr_name);
attr_name = nullptr;
}
-}
+}*/
void XmlTree::onCreateNameChanged()
{
diff --git a/src/ui/dialog/xml-tree.h b/src/ui/dialog/xml-tree.h
index 2eff808ef..d5049bb84 100644
--- a/src/ui/dialog/xml-tree.h
+++ b/src/ui/dialog/xml-tree.h
@@ -27,6 +27,7 @@
#include <gtkmm/paned.h>
#include <gtkmm/button.h>
+#include "ui/dialog/attrdialog.h"
#include "ui/dialog/cssdialog.h"
#include "ui/dialog/desktop-tracker.h"
#include "message.h"
@@ -125,17 +126,17 @@ private:
/**
* Callback when a node is moved in the tree
*/
- static void after_tree_move(SPXMLViewTree *attributes, gpointer value, gpointer data);
+ static void after_tree_move(SPXMLViewTree *tree, gpointer value, gpointer data);
/**
* Callback for when an attribute is edited.
*/
- static void on_attr_edited(SPXMLViewAttrList *attributes, const gchar * name, const gchar * value, gpointer /*data*/);
+ //static void on_attr_edited(SPXMLViewAttrList *attributes, const gchar * name, const gchar * value, gpointer /*data*/);
/**
* Callback for when attribute list values change
*/
- static void on_attr_row_changed(SPXMLViewAttrList *attributes, const gchar * name, gpointer data);
+ //static void on_attr_row_changed(SPXMLViewAttrList *attributes, const gchar * name, gpointer data);
/**
* Enable widgets based on current selections
@@ -216,7 +217,8 @@ private:
/* XmlTree Widgets */
SPXMLViewTree *tree;
- SPXMLViewAttrList *attributes;
+ //SPXMLViewAttrList *attributes;
+ AttrDialog *attributes;
CssDialog *styles;
/* XML Node Creation pop-up window */
diff --git a/src/widgets/CMakeLists.txt b/src/widgets/CMakeLists.txt
index 3853bb91a..f0beeed4a 100644
--- a/src/widgets/CMakeLists.txt
+++ b/src/widgets/CMakeLists.txt
@@ -21,7 +21,6 @@ set(widgets_SRC
sp-attribute-widget.cpp
sp-color-selector.cpp
sp-widget.cpp
- sp-xmlview-attr-list.cpp
sp-xmlview-tree.cpp
spinbutton-events.cpp
spw-utilities.cpp
@@ -53,7 +52,6 @@ set(widgets_SRC
sp-attribute-widget.h
sp-color-selector.h
sp-widget.h
- sp-xmlview-attr-list.h
sp-xmlview-tree.h
spinbutton-events.h
spw-utilities.h
diff --git a/src/widgets/sp-xmlview-attr-list.cpp b/src/widgets/sp-xmlview-attr-list.cpp
deleted file mode 100644
index 81bd58dbc..000000000
--- a/src/widgets/sp-xmlview-attr-list.cpp
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- * Specialization of GtkTreeView for the XML tree view
- *
- * Authors:
- * MenTaLguY <mental@rydia.net>
- *
- * Copyright (C) 2002 MenTaLguY
- *
- * Released under the GNU GPL; see COPYING for details
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <cstring>
-#include <glibmm/i18n.h>
-
-#include "helper/sp-marshal.h"
-#include "../xml/node-event-vector.h"
-#include "sp-xmlview-attr-list.h"
-
-static void sp_xmlview_attr_list_destroy(GtkWidget * object);
-
-static void event_attr_changed (Inkscape::XML::Node * repr, const gchar * name, const gchar * old_value, const gchar * new_value, bool is_interactive, gpointer data);
-
-static Inkscape::XML::NodeEventVector repr_events = {
- nullptr, /* child_added */
- nullptr, /* child_removed */
- event_attr_changed,
- nullptr, /* content_changed */
- nullptr /* order_changed */
-};
-
-GtkWidget *sp_xmlview_attr_list_new (Inkscape::XML::Node * repr)
-{
- SPXMLViewAttrList * attr_list = SP_XMLVIEW_ATTR_LIST(g_object_new(SP_TYPE_XMLVIEW_ATTR_LIST, nullptr));
-
- attr_list->store = gtk_list_store_new (ATTR_N_COLS, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_STRING);
- gtk_tree_view_set_model (GTK_TREE_VIEW(attr_list), GTK_TREE_MODEL(attr_list->store));
-
- // Attribute name column
- int colpos = 0;
- GtkCellRenderer *cell = gtk_cell_renderer_text_new ();
- gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(attr_list), colpos, _("Name"), cell, "text", ATTR_COL_NAME, NULL);
- GtkTreeViewColumn *column = gtk_tree_view_get_column (GTK_TREE_VIEW(attr_list), colpos);
- gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
-
- gtk_tree_sortable_set_sort_func( GTK_TREE_SORTABLE(attr_list->store), ATTR_COL_NAME, attr_sort_name_iter, GINT_TO_POINTER(ATTR_COL_NAME), NULL);
- gtk_tree_sortable_set_sort_column_id ( GTK_TREE_SORTABLE(attr_list->store), ATTR_COL_NAME, GTK_SORT_ASCENDING);
- gtk_cell_renderer_set_padding (cell, 2, 0);
- g_object_set(cell, "editable", TRUE, NULL);
- g_signal_connect(cell, "edited", (GCallback) attr_name_edited, attr_list);
-
- // Attribute value column
- colpos = 1;
- cell = gtk_cell_renderer_text_new ();
- gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(attr_list), colpos, _("Value"), cell, "text", ATTR_COL_VALUE, NULL);
- column = gtk_tree_view_get_column (GTK_TREE_VIEW(attr_list), colpos);
- gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
- gtk_cell_renderer_set_padding (cell, 2, 0);
- g_object_set(cell, "editable", TRUE, NULL);
- g_signal_connect(cell, "edited", (GCallback) attr_value_edited, attr_list);
-
- // Final listview settings
- g_signal_connect( G_OBJECT(attr_list), "key-press-event", G_CALLBACK(attr_key_pressed), NULL);
- gtk_widget_set_name(GTK_WIDGET(attr_list), "attrlist");
- sp_xmlview_attr_list_set_repr (attr_list, repr);
-
- return GTK_WIDGET(attr_list);
-}
-
-gint
-attr_sort_name_iter (GtkTreeModel *model, GtkTreeIter *iter_a, GtkTreeIter *iter_b, gpointer /*data*/)
-{
- gint ret;
- gchar *name1, *name2;
-
- gtk_tree_model_get(model, iter_a, ATTR_COL_NAME, &name1, -1);
- gtk_tree_model_get(model, iter_b, ATTR_COL_NAME, &name2, -1);
- if(name1[0] == 0) { return 1; }
- if(name2[0] == 0) { return -1; }
- ret = g_utf8_collate(name1, name2);
- g_free(name1);
- g_free(name2);
- return ret;
-}
-
-void
-sp_xmlview_attr_list_set_repr (SPXMLViewAttrList * list, Inkscape::XML::Node * repr)
-{
- if ( repr == list->repr ) return;
- if (list->repr) {
- gtk_list_store_clear(list->store);
- sp_repr_remove_listener_by_data (list->repr, list);
- Inkscape::GC::release(list->repr);
- }
- list->repr = repr;
- if (repr) {
- Inkscape::GC::anchor(repr);
- sp_repr_add_listener (repr, &repr_events, list);
- sp_repr_synthesize_events (repr, &repr_events, list);
-
- // Create an 'add-new' row to create new rows
- GtkTreeIter iter;
- gtk_list_store_append (list->store, &iter);
- gtk_list_store_set (list->store, &iter, ATTR_COL_NAME, "", ATTR_COL_VALUE, "", ATTR_COL_ATTR, NULL, -1);
- }
-}
-
-G_DEFINE_TYPE(SPXMLViewAttrList, sp_xmlview_attr_list, GTK_TYPE_TREE_VIEW);
-
-void sp_xmlview_attr_list_class_init (SPXMLViewAttrListClass * klass)
-{
- auto widget_class = GTK_WIDGET_CLASS(klass);
- widget_class->destroy = sp_xmlview_attr_list_destroy;
-
- g_signal_new("row-value-changed",
- G_TYPE_FROM_CLASS(klass),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (SPXMLViewAttrListClass, row_changed),
- nullptr, nullptr,
- g_cclosure_marshal_VOID__STRING,
- G_TYPE_NONE, 1, G_TYPE_STRING);
- g_signal_new("attr-value-edited",
- G_TYPE_FROM_CLASS(klass),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (SPXMLViewAttrListClass, row_changed),
- nullptr, nullptr,
- sp_marshal_VOID__STRING_STRING,
- G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRING);
-}
-
-void
-sp_xmlview_attr_list_init (SPXMLViewAttrList * list)
-{
- list->store = nullptr;
- list->repr = nullptr;
-}
-
-void sp_xmlview_attr_list_destroy(GtkWidget * object)
-{
- SPXMLViewAttrList * list;
-
- list = SP_XMLVIEW_ATTR_LIST (object);
-
- g_object_unref(list->store);
- sp_xmlview_attr_list_set_repr (list, nullptr);
-
- GTK_WIDGET_CLASS(sp_xmlview_attr_list_parent_class)->destroy (object);
-}
-
-void sp_xmlview_attr_list_select_row_by_key(SPXMLViewAttrList * list, const gchar *name)
-{
- GtkTreeIter iter;
- gboolean match = false;
- gboolean valid = gtk_tree_model_get_iter_first( GTK_TREE_MODEL(list->store), &iter );
- while ( valid ) {
- gchar *n = nullptr;
- gtk_tree_model_get (GTK_TREE_MODEL(list->store), &iter, ATTR_COL_NAME, &n, -1);
- if (!strcmp(n, name)) {
- match = true;
- break;
- }
- valid = gtk_tree_model_iter_next (GTK_TREE_MODEL(list->store), &iter);
- // cppcheck-suppress nullPointer // a string was copied in n by gtk_tree_model_get
- if (n) {
- g_free(n);
- }
- }
-
- if (match) {
- GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(list));
- gtk_tree_selection_select_iter(selection, &iter);
- }
-}
-
-void
-attr_name_edited (GtkCellRendererText *cell,
- gchar * path_string,
- gchar * new_name,
- gpointer data) {
-
- SPXMLViewAttrList * list = SP_XMLVIEW_ATTR_LIST (data);
- GtkTreeIter iter;
- gboolean valid = gtk_tree_model_get_iter_from_string( GTK_TREE_MODEL(list->store), &iter, path_string );
- if(valid) {
- gchar *old_name = nullptr;
- gchar *value = nullptr;
- gtk_tree_model_get (GTK_TREE_MODEL(list->store), &iter, ATTR_COL_NAME, &old_name, ATTR_COL_VALUE, &value, -1);
- if(old_name[0] != 0) {
- // Remove named value
- g_signal_emit_by_name(G_OBJECT (list), "attr-value-edited", old_name, nullptr );
- }
- g_signal_emit_by_name(G_OBJECT (list), "attr-value-edited", new_name, value );
- }
-}
-
-void
-attr_value_edited (GtkCellRendererText *cell,
- gchar * path_string,
- gchar * new_value,
- gpointer data) {
-
- SPXMLViewAttrList * list = SP_XMLVIEW_ATTR_LIST (data);
- GtkTreeIter iter;
- gboolean valid = gtk_tree_model_get_iter_from_string( GTK_TREE_MODEL(list->store), &iter, path_string );
- if(valid) {
- gchar *name = nullptr;
- gtk_tree_model_get (GTK_TREE_MODEL(list->store), &iter, ATTR_COL_NAME, &name, -1);
- if(name[0] == 0 or name[0] == '<') { return; }
- g_signal_emit_by_name(G_OBJECT (list), "attr-value-edited", name, new_value );
- }
-}
-
-gboolean
-attr_key_pressed(GtkWidget *attributes, GdkEventKey *event, gpointer /*data*/)
-{
- GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(attributes));
- GtkTreeIter iter;
- GtkTreeModel *model;
- if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
- switch (event->keyval)
- {
- case GDK_KEY_Delete:
- case GDK_KEY_KP_Delete:
- gchar *name = nullptr;
- gtk_tree_model_get (model, &iter, 0, &name, -1);
- g_signal_emit_by_name(G_OBJECT (attributes), "attr-value-edited", name, nullptr);
- if(name) g_free(name);
- return true;
- }
- }
- return false;
-}
-
-void
-event_attr_changed (Inkscape::XML::Node * /*repr*/,
- const gchar * name,
- const gchar * /*old_value*/,
- const gchar * new_value,
- bool /*is_interactive*/,
- gpointer data)
-{
- gint row = -1;
- SPXMLViewAttrList * list = SP_XMLVIEW_ATTR_LIST (data);
-
- GtkTreeIter iter;
- gboolean valid = gtk_tree_model_get_iter_first( GTK_TREE_MODEL(list->store), &iter );
- gboolean match = false;
- while ( valid ) {
- gchar *n = nullptr;
- gtk_tree_model_get (GTK_TREE_MODEL(list->store), &iter, ATTR_COL_NAME, &n, -1);
- if (!strcmp(n, name)) {
- match = true;
- break;
- }
- row++;
- valid = gtk_tree_model_iter_next (GTK_TREE_MODEL(list->store), &iter);
- // cppcheck-suppress nullPointer // a string was copied in n by gtk_tree_model_get
- if (n) {
- g_free(n);
- }
- }
-
- if (match) {
- if (new_value) {
- gtk_list_store_set (list->store, &iter, ATTR_COL_NAME, name, ATTR_COL_VALUE, new_value, ATTR_COL_ATTR, g_quark_from_string (name), -1);
- } else {
- gtk_list_store_remove (list->store, &iter);
- }
- } else if (new_value != nullptr) {
- gtk_list_store_append (list->store, &iter);
- gtk_list_store_set (list->store, &iter, ATTR_COL_NAME, name, ATTR_COL_VALUE, new_value, ATTR_COL_ATTR, g_quark_from_string (name), -1);
- }
-
- // send a "changed" signal so widget owners will know I've updated
- g_signal_emit_by_name(G_OBJECT (list), "row-value-changed", name );
-}
-
diff --git a/src/widgets/sp-xmlview-attr-list.h b/src/widgets/sp-xmlview-attr-list.h
deleted file mode 100644
index 2d6e84fe4..000000000
--- a/src/widgets/sp-xmlview-attr-list.h
+++ /dev/null
@@ -1,57 +0,0 @@
-#ifndef __SP_XMLVIEW_ATTR_LIST_H__
-#define __SP_XMLVIEW_ATTR_LIST_H__
-
-/*
- * Specialization of GtkTreeView for editing XML node attributes
- *
- * Authors:
- * MenTaLguY <mental@rydia.net>
- *
- * Copyright (C) 2002 MenTaLguY
- *
- * Released under the GNU GPL; see COPYING for details
- */
-
-#include <gtk/gtk.h>
-
-#define SP_TYPE_XMLVIEW_ATTR_LIST (sp_xmlview_attr_list_get_type ())
-#define SP_XMLVIEW_ATTR_LIST(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SP_TYPE_XMLVIEW_ATTR_LIST, SPXMLViewAttrList))
-#define SP_IS_XMLVIEW_ATTR_LIST(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), SP_TYPE_XMLVIEW_ATTR_LIST))
-#define SP_XMLVIEW_ATTR_LIST_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), SP_TYPE_XMLVIEW_ATTR_LIST))
-
-struct SPXMLViewAttrList
-{
- GtkTreeView list;
- GtkListStore *store;
-
- Inkscape::XML::Node * repr;
-};
-
-struct SPXMLViewAttrListClass
-{
- GtkTreeViewClass parent_class;
-
- void (* row_changed) (SPXMLViewAttrList *list, gint row);
-};
-
-GType sp_xmlview_attr_list_get_type ();
-GtkWidget * sp_xmlview_attr_list_new (Inkscape::XML::Node * repr);
-
-#define SP_XMLVIEW_ATTR_LIST_GET_REPR(list) (SP_XMLVIEW_ATTR_LIST (list)->repr)
-
-gint attr_sort_name_iter (GtkTreeModel *model, GtkTreeIter *iter_a, GtkTreeIter *iter_b, gpointer data);
-void sp_xmlview_attr_list_set_repr (SPXMLViewAttrList * list, Inkscape::XML::Node * repr);
-void sp_xmlview_attr_list_select_row_by_key(SPXMLViewAttrList * list, const gchar *name);
-void attr_name_edited (GtkCellRendererText *cell, gchar * path_string, gchar * new_value, gpointer data);
-void attr_value_edited (GtkCellRendererText *cell, gchar * path_string, gchar * new_value, gpointer data);
-gboolean attr_key_pressed(GtkWidget *attributes, GdkEventKey *event, gpointer data);
-
-/* Attribute list store columns */
-enum {
- ATTR_COL_NAME,
- ATTR_COL_ATTR,
- ATTR_COL_VALUE,
- ATTR_N_COLS,
-};
-
-#endif