summaryrefslogtreecommitdiffstats
path: root/src/ui
diff options
context:
space:
mode:
authorJabier Arraiza <jabier.arraiza@marker.es>2019-08-22 01:39:49 +0000
committerJabier Arraiza <jabier.arraiza@marker.es>2019-08-22 01:39:49 +0000
commitd1a647def410422f10d4386529efbcbf14532ce4 (patch)
tree19e7e1b57cd5c8e048b434a44122577cda134729 /src/ui
parentUpdate it.po (diff)
downloadinkscape-d1a647def410422f10d4386529efbcbf14532ce4.tar.gz
inkscape-d1a647def410422f10d4386529efbcbf14532ce4.zip
Merge XML and CSS widgets improvements from https://gitlab.com/inkscape/inkscape/merge_requests/801
Diffstat (limited to 'src/ui')
-rw-r--r--src/ui/dialog/attrdialog.cpp207
-rw-r--r--src/ui/dialog/attrdialog.h17
-rw-r--r--src/ui/dialog/desktop-tracker.h2
-rw-r--r--src/ui/dialog/selectorsdialog.cpp156
-rw-r--r--src/ui/dialog/selectorsdialog.h12
-rw-r--r--src/ui/dialog/styledialog.cpp258
-rw-r--r--src/ui/dialog/styledialog.h19
-rw-r--r--src/ui/dialog/symbols.cpp2
-rw-r--r--src/ui/dialog/xml-tree.cpp128
-rw-r--r--src/ui/dialog/xml-tree.h10
10 files changed, 572 insertions, 239 deletions
diff --git a/src/ui/dialog/attrdialog.cpp b/src/ui/dialog/attrdialog.cpp
index 3db739059..a499602ce 100644
--- a/src/ui/dialog/attrdialog.cpp
+++ b/src/ui/dialog/attrdialog.cpp
@@ -58,7 +58,6 @@ namespace Inkscape {
namespace UI {
namespace Dialog {
-
/**
* Constructor
* A treeview whose each row corresponds to an XML attribute of a selected node
@@ -72,6 +71,9 @@ AttrDialog::AttrDialog()
set_size_request(20, 15);
_mainBox.pack_start(_scrolledWindow, Gtk::PACK_EXPAND_WIDGET);
_treeView.set_headers_visible(true);
+ _treeView.set_hover_selection(true);
+ _treeView.set_activate_on_single_click(true);
+ _treeView.set_can_focus(false);
_scrolledWindow.add(_treeView);
_scrolledWindow.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
@@ -103,16 +105,19 @@ AttrDialog::AttrDialog()
_nameRenderer->property_editable() = true;
_nameRenderer->property_placeholder_text().set_value(_("Attribute Name"));
_nameRenderer->signal_edited().connect(sigc::mem_fun(*this, &AttrDialog::nameEdited));
+ _nameRenderer->signal_editing_started().connect(sigc::mem_fun(*this, &AttrDialog::startNameEdit));
_treeView.append_column(_("Name"), *_nameRenderer);
_nameCol = _treeView.get_column(1);
if (_nameCol) {
- _nameCol->add_attribute(_nameRenderer->property_text(), _attrColumns._attributeName);
+ _nameCol->set_resizable(true);
+ _nameCol->add_attribute(_nameRenderer->property_text(), _attrColumns._attributeName);
}
status.set_halign(Gtk::ALIGN_START);
status.set_valign(Gtk::ALIGN_CENTER);
status.set_size_request(1, -1);
status.set_markup("");
status.set_line_wrap(true);
+ status.get_style_context()->add_class("inksmall");
status_box.pack_start(status, TRUE, TRUE, 0);
_getContents()->pack_end(status_box, false, false, 2);
@@ -126,19 +131,44 @@ AttrDialog::AttrDialog()
_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));
+ _valueRenderer->signal_editing_started().connect(sigc::mem_fun(*this, &AttrDialog::startValueEdit));
_treeView.append_column(_("Value"), *_valueRenderer);
_valueCol = _treeView.get_column(2);
if (_valueCol) {
_valueCol->add_attribute(_valueRenderer->property_text(), _attrColumns._attributeValue);
}
+ _popover = Gtk::manage(new Gtk::Popover());
+ Gtk::Box *vbox = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_VERTICAL));
+ Gtk::Box *hbox = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_HORIZONTAL));
+ _textview = Gtk::manage(new Gtk::TextView());
+ _textview->set_wrap_mode(Gtk::WrapMode::WRAP_CHAR);
+ _textview->set_editable(true);
+ _textview->set_monospace(true);
+ _textview->set_border_width(6);
+ Glib::RefPtr<Gtk::TextBuffer> textbuffer = Gtk::TextBuffer::create();
+ textbuffer->set_text("");
+ _textview->set_buffer(textbuffer);
+ _scrolled_text_view.add(*_textview);
+ _scrolled_text_view.set_max_content_height(450);
+ _scrolled_text_view.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
+ _scrolled_text_view.set_propagate_natural_width(true);
+ _update = Gtk::manage(new Gtk::Button(_("Update")));
+ _update->signal_clicked().connect(sigc::mem_fun(*this, &AttrDialog::valueEditedPop));
+ hbox->pack_end(*_update, Gtk::PACK_EXPAND_WIDGET, 3);
+ vbox->pack_start(_scrolled_text_view, Gtk::PACK_EXPAND_WIDGET, 3);
+ vbox->pack_start(*hbox, Gtk::PACK_EXPAND_WIDGET, 3);
+ _popover->add(*vbox);
+ _popover->hide();
+ _popover->set_relative_to(_treeView);
+ _popover->set_position(Gtk::PositionType::POS_BOTTOM);
+ _popover->signal_closed().connect(sigc::mem_fun(*this, &AttrDialog::popClosed));
+ _popover->get_style_context()->add_class("inverted");
attr_reset_context(0);
_getContents()->pack_start(_mainBox, Gtk::PACK_EXPAND_WIDGET);
-
setDesktop(getDesktop());
+ _updating = false;
}
-
-
/**
* @brief AttrDialog::~AttrDialog
* Class destructor
@@ -152,6 +182,71 @@ AttrDialog::~AttrDialog()
_message_changed_connection.~connection();
}
+void AttrDialog::startNameEdit(Gtk::CellEditable *cell, const Glib::ustring &path)
+{
+ Gtk::Entry *entry = dynamic_cast<Gtk::Entry *>(cell);
+ entry->signal_key_press_event().connect(sigc::bind(sigc::mem_fun(*this, &AttrDialog::onNameKeyPressed), entry));
+}
+
+gboolean sp_show_attr_pop(gpointer data)
+{
+ AttrDialog *attrdialog = reinterpret_cast<AttrDialog *>(data);
+ auto vscroll = attrdialog->_scrolled_text_view.get_vadjustment();
+ int height = vscroll->get_upper() + 12; // padding 6+6
+ if (height < 450) {
+ attrdialog->_scrolled_text_view.set_min_content_height(height);
+ } else {
+ attrdialog->_scrolled_text_view.set_min_content_height(450);
+ }
+ return FALSE;
+}
+
+void AttrDialog::startValueEdit(Gtk::CellEditable *cell, const Glib::ustring &path)
+{
+ Gtk::Entry *entry = dynamic_cast<Gtk::Entry *>(cell);
+ entry->signal_key_press_event().connect(sigc::bind(sigc::mem_fun(*this, &AttrDialog::onValueKeyPressed), entry));
+ int width = 0;
+ int height = 0;
+ int colwidth = _valueCol->get_width();
+ _textview->set_size_request(colwidth - 6, -1);
+ _popover->set_size_request(colwidth, -1);
+ valuepath = path;
+ entry->get_layout()->get_pixel_size(width, height);
+ Gtk::TreeIter iter = *_store->get_iter(path);
+ Gtk::TreeModel::Row row = *iter;
+ if (row && this->_repr) {
+ Glib::ustring name = row[_attrColumns._attributeName];
+ if (colwidth < width || name == "content") {
+ Gtk::TreeIter iter = *_store->get_iter(path);
+ Gdk::Rectangle rect;
+ _treeView.get_cell_area((Gtk::TreeModel::Path)iter, *_valueCol, rect);
+ if (_popover->get_position() == Gtk::PositionType::POS_BOTTOM) {
+ rect.set_y(rect.get_y() + 20);
+ }
+ _popover->set_pointing_to(rect);
+ Glib::RefPtr<Gtk::TextBuffer> textbuffer = Gtk::TextBuffer::create();
+ textbuffer->set_text(entry->get_text());
+ _textview->set_buffer(textbuffer);
+ cell->editing_done();
+ cell->remove_widget();
+ int scrolledcontentheight = 20;
+ if (name == "content") {
+ scrolledcontentheight = 450;
+ }
+ _scrolled_text_view.set_min_content_height(scrolledcontentheight);
+ _popover->show_all();
+ _popover->check_resize();
+ g_timeout_add(50, &sp_show_attr_pop, this);
+ }
+ }
+}
+
+void AttrDialog::popClosed()
+{
+ Glib::RefPtr<Gtk::TextBuffer> textbuffer = Gtk::TextBuffer::create();
+ textbuffer->set_text("");
+ _textview->set_buffer(textbuffer);
+}
/**
* @brief AttrDialog::setDesktop
@@ -224,6 +319,9 @@ void AttrDialog::attr_reset_context(gint attr)
*/
void AttrDialog::onAttrChanged(Inkscape::XML::Node *repr, const gchar * name, const gchar * new_value)
{
+ if (_updating) {
+ return;
+ }
for(auto iter: this->_store->children())
{
Gtk::TreeModel::Row row = *iter;
@@ -235,6 +333,7 @@ void AttrDialog::onAttrChanged(Inkscape::XML::Node *repr, const gchar * name, co
} else {
_store->erase(iter);
}
+ break;
}
}
if (new_value && strcmp(new_value, "") != 0) {
@@ -243,7 +342,7 @@ void AttrDialog::onAttrChanged(Inkscape::XML::Node *repr, const gchar * name, co
{
return;
} else {
- Gtk::TreeModel::Row row = *(_store->append());
+ Gtk::TreeModel::Row row = *(_store->prepend());
row[_attrColumns._attributeName] = name;
row[_attrColumns._attributeValue] = new_value;
}
@@ -257,7 +356,7 @@ void AttrDialog::onAttrChanged(Inkscape::XML::Node *repr, const gchar * name, co
bool AttrDialog::onAttrCreate(GdkEventButton *event)
{
if(event->type == GDK_BUTTON_RELEASE && event->button == 1 && this->_repr) {
- Gtk::TreeIter iter = _store->append();
+ Gtk::TreeIter iter = _store->prepend();
Gtk::TreeModel::Path path = (Gtk::TreeModel::Path)iter;
_treeView.set_cursor(path, *_nameCol, true);
grab_focus();
@@ -298,39 +397,80 @@ bool AttrDialog::onKeyPressed(GdkEventKey *event)
if(this->_repr) {
auto selection = this->_treeView.get_selection();
Gtk::TreeModel::Row row = *(selection->get_selected());
+ Gtk::TreeIter iter = *(selection->get_selected());
+ bool ret = false;
switch (event->keyval)
{
case GDK_KEY_Delete:
- case GDK_KEY_KP_Delete:
- {
+ case GDK_KEY_KP_Delete: {
// Create new attribute (repeat code, fold into above event!)
Glib::ustring name = row[_attrColumns._attributeName];
- if(name == "content") {
- return true;
- } else {
+ if (name != "content") {
this->_store->erase(row);
this->_repr->setAttribute(name.c_str(), nullptr, false);
this->setUndo(_("Delete attribute"));
}
- return true;
- }
+ ret = true;
+ } break;
case GDK_KEY_plus:
case GDK_KEY_Insert:
{
// Create new attribute (repeat code, fold into above event!)
- Gtk::TreeIter iter = this->_store->append();
+ Gtk::TreeIter iter = this->_store->prepend();
Gtk::TreeModel::Path path = (Gtk::TreeModel::Path)iter;
this->_treeView.set_cursor(path, *this->_nameCol, true);
grab_focus();
- return true;
- }
+ ret = true;
+ } break;
}
}
return false;
}
+bool AttrDialog::onNameKeyPressed(GdkEventKey *event, Gtk::Entry *entry)
+{
+ g_debug("StyleDialog::_onNameKeyPressed");
+ bool ret = false;
+ switch (event->keyval) {
+ case GDK_KEY_Tab:
+ case GDK_KEY_KP_Tab:
+ entry->editing_done();
+ ret = true;
+ break;
+ }
+ return ret;
+}
+
+
+bool AttrDialog::onValueKeyPressed(GdkEventKey *event, Gtk::Entry *entry)
+{
+ g_debug("StyleDialog::_onValueKeyPressed");
+ bool ret = false;
+ switch (event->keyval) {
+ case GDK_KEY_Tab:
+ case GDK_KEY_KP_Tab:
+ entry->editing_done();
+ ret = true;
+ break;
+ }
+ return ret;
+}
+
+gboolean sp_attrdialog_store_move_to_next(gpointer data)
+{
+ AttrDialog *attrdialog = reinterpret_cast<AttrDialog *>(data);
+ auto selection = attrdialog->_treeView.get_selection();
+ Gtk::TreeIter iter = *(selection->get_selected());
+ Gtk::TreeModel::Path model = (Gtk::TreeModel::Path)iter;
+ if (model == attrdialog->_modelpath) {
+ attrdialog->_treeView.set_cursor(attrdialog->_modelpath, *attrdialog->_valueCol, true);
+ }
+ return FALSE;
+}
/**
+ *
+ *
* @brief AttrDialog::nameEdited
* @param event
* @return
@@ -339,36 +479,44 @@ bool AttrDialog::onKeyPressed(GdkEventKey *event)
void AttrDialog::nameEdited (const Glib::ustring& path, const Glib::ustring& name)
{
Gtk::TreeIter iter = *_store->get_iter(path);
- Gtk::TreeModel::Path modelpath = (Gtk::TreeModel::Path)iter;
+ _modelpath = (Gtk::TreeModel::Path)iter;
Gtk::TreeModel::Row row = *iter;
if(row && this->_repr) {
Glib::ustring old_name = row[_attrColumns._attributeName];
if (old_name == name) {
- _treeView.set_cursor(modelpath, *_valueCol, true);
+ g_timeout_add(50, &sp_attrdialog_store_move_to_next, this);
grab_focus();
return;
}
- if (old_name == "content" ||
- old_name == name)
- {
+ if (old_name == "content") {
return;
}
Glib::ustring value = row[_attrColumns._attributeValue];
// Move to editing value, we set the name as a temporary store value
if (!old_name.empty()) {
// Remove old named value
+ _updating = true;
_repr->setAttribute(old_name.c_str(), nullptr, false);
+ _updating = false;
}
if (!name.empty()) {
row[_attrColumns._attributeName] = name;
- _repr->setAttribute(name.c_str(), value, false);
- _treeView.set_cursor(modelpath, *_valueCol, true);
grab_focus();
+ _updating = true;
+ _repr->setAttribute(name.c_str(), value, false);
+ _updating = false;
+ g_timeout_add(50, &sp_attrdialog_store_move_to_next, this);
}
this->setUndo(_("Rename attribute"));
}
}
+void AttrDialog::valueEditedPop()
+{
+ Glib::ustring value = _textview->get_buffer()->get_text();
+ valueEdited(valuepath, value);
+}
+
/**
* @brief AttrDialog::valueEdited
* @param event
@@ -380,6 +528,10 @@ void AttrDialog::valueEdited (const Glib::ustring& path, const Glib::ustring& va
Gtk::TreeModel::Row row = *_store->get_iter(path);
if(row && this->_repr) {
Glib::ustring name = row[_attrColumns._attributeName];
+ Glib::ustring old_value = row[_attrColumns._attributeValue];
+ if (old_value == value) {
+ return;
+ }
if(name.empty()) return;
if (name == "content") {
_repr->setContent(value.c_str());
@@ -389,7 +541,14 @@ void AttrDialog::valueEdited (const Glib::ustring& path, const Glib::ustring& va
if(!value.empty()) {
row[_attrColumns._attributeValue] = value;
}
+ Inkscape::Selection *selection = _desktop->getSelection();
+ SPObject *obj = nullptr;
+ if (selection->objects().size() == 1) {
+ obj = selection->objects().back();
+ obj->style->readFromObject(obj);
+ obj->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG);
+ }
this->setUndo(_("Change attribute value"));
}
}
diff --git a/src/ui/dialog/attrdialog.h b/src/ui/dialog/attrdialog.h
index 68ea14cc9..2c57447c4 100644
--- a/src/ui/dialog/attrdialog.h
+++ b/src/ui/dialog/attrdialog.h
@@ -17,7 +17,9 @@
#include "message.h"
#include <gtkmm/dialog.h>
#include <gtkmm/liststore.h>
+#include <gtkmm/popover.h>
#include <gtkmm/scrolledwindow.h>
+#include <gtkmm/textview.h>
#include <gtkmm/treeview.h>
#include <ui/widget/panel.h>
@@ -61,6 +63,11 @@ public:
Gtk::CellRendererText *_valueRenderer;
Gtk::TreeViewColumn *_nameCol;
Gtk::TreeViewColumn *_valueCol;
+ Gtk::TreeModel::Path _modelpath;
+ Gtk::Popover *_popover;
+ Gtk::TextView *_textview;
+ Gtk::Button *_update;
+ Glib::ustring valuepath;
/**
* Status bar
@@ -71,14 +78,15 @@ public:
// Widgets
Gtk::VBox _mainBox;
Gtk::ScrolledWindow _scrolledWindow;
+ Gtk::ScrolledWindow _scrolled_text_view;
Gtk::HBox _buttonBox;
Gtk::Button _buttonAddAttribute;
-
// Variables - Inkscape
SPDesktop* _desktop;
Inkscape::XML::Node* _repr;
Gtk::HBox status_box;
Gtk::Label status;
+ bool _updating;
// Helper functions
void setDesktop(SPDesktop* desktop) override;
@@ -95,12 +103,17 @@ public:
*/
sigc::connection _message_changed_connection;
void onAttrChanged(Inkscape::XML::Node *repr, const gchar * name, const gchar * new_value);
+ bool onNameKeyPressed(GdkEventKey *event, Gtk::Entry *entry);
+ bool onValueKeyPressed(GdkEventKey *event, Gtk::Entry *entry);
void onAttrDelete(Glib::ustring path);
bool onAttrCreate(GdkEventButton *event);
bool onKeyPressed(GdkEventKey *event);
+ void popClosed();
+ void startNameEdit(Gtk::CellEditable *cell, const Glib::ustring &path);
+ void startValueEdit(Gtk::CellEditable *cell, const Glib::ustring &path);
void nameEdited(const Glib::ustring &path, const Glib::ustring &name);
void valueEdited(const Glib::ustring &path, const Glib::ustring &value);
-
+ void valueEditedPop();
};
diff --git a/src/ui/dialog/desktop-tracker.h b/src/ui/dialog/desktop-tracker.h
index b681c9ca1..7b9439006 100644
--- a/src/ui/dialog/desktop-tracker.h
+++ b/src/ui/dialog/desktop-tracker.h
@@ -46,7 +46,7 @@ private:
SPDesktop *base;
SPDesktop *desktop;
GtkWidget *widget;
- gulong hierID;
+ unsigned long hierID;
sigc::connection inkID;
bool trackActive;
sigc::signal<void, SPDesktop*> desktopChangedSig;
diff --git a/src/ui/dialog/selectorsdialog.cpp b/src/ui/dialog/selectorsdialog.cpp
index eda036c58..89d109ae9 100644
--- a/src/ui/dialog/selectorsdialog.cpp
+++ b/src/ui/dialog/selectorsdialog.cpp
@@ -19,9 +19,10 @@
#include "inkscape.h"
#include "selection.h"
#include "style.h"
-#include "verbs.h"
#include "ui/icon-loader.h"
+#include "ui/icon-names.h"
#include "ui/widget/iconrenderer.h"
+#include "verbs.h"
#include "xml/attribute-record.h"
#include "xml/node-observer.h"
@@ -200,69 +201,6 @@ bool SelectorsDialog::TreeStore::row_draggable_vfunc(const Gtk::TreeModel::Path
return Gtk::TreeStore::row_draggable_vfunc(path);
}
-void SelectorsDialog::fixCSSSelectors(Glib::ustring &selector)
-{
- g_debug("SelectorsDialog::fixCSSSelectors");
- REMOVE_SPACES(selector);
- Glib::ustring my_selector = selector + " {"; // Parsing fails sometimes without '{'. Fix me
- CRSelector *cr_selector = cr_selector_parse_from_buf((guchar *)my_selector.c_str(), CR_UTF_8);
- selector = Glib::ustring("");
- CRSelector const *cur = nullptr;
- for (cur = cr_selector; cur; cur = cur->next) {
- if (cur->simple_sel) {
- gchar *selectorchar = reinterpret_cast<gchar *>(cr_simple_sel_to_string(cur->simple_sel));
- if (selectorchar) {
- Glib::ustring toadd = Glib::ustring(selectorchar);
- selector = selector.empty() ? toadd : selector + "," + toadd;
- g_free(selectorchar);
- }
- }
- }
- std::vector<Glib::ustring> tokens = Glib::Regex::split_simple("[,]+", selector);
- std::vector<Glib::ustring> selectorresult;
- selector = Glib::ustring("");
- for (auto token : tokens) {
- REMOVE_SPACES(token);
- std::vector<Glib::ustring> tokensplus = Glib::Regex::split_simple("[ ]+", token);
- Glib::ustring selectorpart = Glib::ustring("");
- for (auto tokenplus : tokensplus) {
- REMOVE_SPACES(tokenplus);
- Glib::ustring toparse = Glib::ustring(tokenplus);
- Glib::ustring tag = Glib::ustring("");
- if (toparse[0] != '.' && toparse[0] != '#') {
- auto i = std::min(toparse.find("#"), toparse.find("."));
- tag = toparse.substr(0, i);
- if (!SPAttributeRelSVG::isSVGElement(tag)) {
- continue;
- }
- if (i != std::string::npos) {
- toparse.erase(0, i);
- } else {
- toparse = tag;
- selectorpart = selectorpart == Glib::ustring("") ? toparse : selectorpart + " " + toparse;
- continue;
- }
- }
- auto i = toparse.find("#");
- if (i != std::string::npos) {
- toparse.erase(i, 1);
- }
- auto j = toparse.find("#");
- if (i != std::string::npos && j != std::string::npos) {
- continue;
- } else if (i != std::string::npos) {
- toparse.insert(i, "#");
- }
- toparse = tag + toparse;
- selectorpart = selectorpart == Glib::ustring("") ? toparse : selectorpart + " " + toparse;
- }
- selectorresult.push_back(selectorpart);
- }
- for (auto selectorpart : selectorresult) {
- selector = selector == Glib::ustring("") ? selectorpart : selector + "," + selectorpart;
- }
-}
-
/**
* Allow dropping only in between other selectors.
*/
@@ -404,19 +342,30 @@ void SelectorsDialog::_showWidgets()
_vadj = _scrolled_window_selectors.get_vadjustment();
_vadj->signal_value_changed().connect(sigc::mem_fun(*this, &SelectorsDialog::_vscrool));
_selectors_box.pack_start(_scrolled_window_selectors, Gtk::PACK_EXPAND_WIDGET);
- Gtk::Label *dirtogglerlabel = Gtk::manage(new Gtk::Label(_("Paned vertical")));
+ /* Gtk::Label *dirtogglerlabel = Gtk::manage(new Gtk::Label(_("Paned vertical")));
dirtogglerlabel->get_style_context()->add_class("inksmall");
_direction.property_active() = dir;
_direction.property_active().signal_changed().connect(sigc::mem_fun(*this, &SelectorsDialog::_toggleDirection));
- _direction.get_style_context()->add_class("inkswitch");
+ _direction.get_style_context()->add_class("inkswitch"); */
_styleButton(_create, "list-add", "Add a new CSS Selector");
_create.signal_clicked().connect(sigc::mem_fun(*this, &SelectorsDialog::_addSelector));
_styleButton(_del, "list-remove", "Remove a CSS Selector");
_button_box.pack_start(_create, Gtk::PACK_SHRINK);
_button_box.pack_start(_del, Gtk::PACK_SHRINK);
- _button_box.pack_start(_direction, false, false, 0);
- _button_box.pack_start(*dirtogglerlabel, false, false, 0);
- _selectors_box.pack_end(_button_box, false, false, 0);
+ Gtk::RadioButton::Group group;
+ Gtk::RadioButton *_horizontal = Gtk::manage(new Gtk::RadioButton());
+ Gtk::RadioButton *_vertical = Gtk::manage(new Gtk::RadioButton());
+ _horizontal->set_image_from_icon_name(INKSCAPE_ICON("horizontal"));
+ _vertical->set_image_from_icon_name(INKSCAPE_ICON("vertical"));
+ _horizontal->set_group(group);
+ _vertical->set_group(group);
+ _vertical->set_active(dir);
+ _vertical->signal_toggled().connect(
+ sigc::bind(sigc::mem_fun(*this, &SelectorsDialog::_toggleDirection), _vertical));
+ _horizontal->property_draw_indicator() = false;
+ _vertical->property_draw_indicator() = false;
+ _button_box.pack_end(*_horizontal, false, false, 0);
+ _button_box.pack_end(*_vertical, false, false, 0);
_del.signal_clicked().connect(sigc::mem_fun(*this, &SelectorsDialog::_delSelector));
_del.hide();
_style_dialog = new StyleDialog;
@@ -424,36 +373,62 @@ void SelectorsDialog::_showWidgets()
_paned.pack1(*_style_dialog, Gtk::SHRINK);
_paned.pack2(_selectors_box, true, true);
_getContents()->pack_start(_paned, Gtk::PACK_EXPAND_WIDGET);
+ _getContents()->pack_start(_button_box, false, false, 0);
show_all();
int widthpos = _paned.property_max_position();
int panedpos = prefs->getInt("/dialogs/selectors/panedpos", 130);
_paned.set_position(panedpos);
_paned.property_wide_handle() = true;
- _paned.signal_button_release_event().connect(sigc::mem_fun(*this, &SelectorsDialog::_resized), false);
+ _paned.property_position().signal_changed().connect(sigc::mem_fun(*this, &SelectorsDialog::_childresized));
+ _paned.signal_size_allocate().connect(sigc::mem_fun(*this, &SelectorsDialog::_panedresized));
set_size_request(320, 260);
set_name("SelectorsAndStyleDialog");
}
-bool SelectorsDialog::_resized(GdkEventButton *event)
+void SelectorsDialog::_panedresized(Gtk::Allocation allocation)
+{
+ g_debug("SelectorsDialog::_panedresized");
+ _resized();
+}
+
+void SelectorsDialog::_childresized()
+{
+ g_debug("SelectorsDialog::_childresized");
+ _resized();
+}
+
+void SelectorsDialog::_resized()
{
g_debug("SelectorsDialog::_resized");
_scroollock = true;
+ if (_updating) {
+ return;
+ }
+ _updating = true;
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ bool dir = !prefs->getBool("/dialogs/selectors/vertical", true);
+ int max = int(_paned.property_max_position() * 0.95);
+ int min = int(_paned.property_max_position() * 0.05);
+ if (_paned.get_position() > max) {
+ _paned.property_position() = max;
+ }
+ if (_paned.get_position() < min) {
+ _paned.property_position() = min;
+ }
prefs->setInt("/dialogs/selectors/panedpos", _paned.get_position());
- return false;
+ _updating = false;
}
-
-void SelectorsDialog::_toggleDirection()
+void SelectorsDialog::_toggleDirection(Gtk::RadioButton *vertical)
{
g_debug("SelectorsDialog::_toggleDirection");
-
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
- bool dir = !prefs->getBool("/dialogs/selectors/vertical", true);
+ bool dir = vertical->get_active();
prefs->setBool("/dialogs/selectors/vertical", dir);
_paned.set_orientation(dir ? Gtk::ORIENTATION_VERTICAL : Gtk::ORIENTATION_HORIZONTAL);
- int widthpos = _paned.property_max_position();
+ _paned.check_resize();
+ int widthpos = _paned.property_max_position() - _paned.property_min_position();
prefs->setInt("/dialogs/selectors/panedpos", widthpos / 2);
_paned.set_position(widthpos / 2);
}
@@ -573,7 +548,7 @@ void SelectorsDialog::_readStyleElement()
for (unsigned i = 0; i < tokens.size() - 1; i += 2) {
Glib::ustring selector = tokens[i];
REMOVE_SPACES(selector); // Remove leading/trailing spaces
- fixCSSSelectors(selector);
+ selector = _style_dialog->fixCSSSelectors(selector);
for (auto &row : _store->children()) {
Glib::ustring selectorold = row[_mColumns._colSelector];
if (selectorold == selector) {
@@ -588,7 +563,7 @@ void SelectorsDialog::_readStyleElement()
Glib::ustring selector = tokens[i];
REMOVE_SPACES(selector); // Remove leading/trailing spaces
Glib::ustring selector_old = selector;
- fixCSSSelectors(selector);
+ selector = _style_dialog->fixCSSSelectors(selector);
if (selector_old != selector) {
rewrite = true;
}
@@ -778,8 +753,12 @@ Glib::ustring sp_get_selector_classes(Glib::ustring selector) //, SelectorType s
REMOVE_SPACES(selector);
Glib::ustring toparse = Glib::ustring(selector);
selector = Glib::ustring("");
+ auto i = toparse.find(".");
+ if (i == std::string::npos) {
+ return "";
+ }
if (toparse[0] != '.' && toparse[0] != '#') {
- auto i = std::min(toparse.find("#"), toparse.find("."));
+ i = std::min(toparse.find("#"), toparse.find("."));
Glib::ustring tag = toparse.substr(0, i);
if (!SPAttributeRelSVG::isSVGElement(tag)) {
return selector;
@@ -788,7 +767,7 @@ Glib::ustring sp_get_selector_classes(Glib::ustring selector) //, SelectorType s
toparse.erase(0, i);
}
}
- auto i = toparse.find("#");
+ i = toparse.find("#");
if (i != std::string::npos) {
toparse.erase(i, 1);
}
@@ -856,7 +835,7 @@ void SelectorsDialog::_addToSelector(Gtk::TreeModel::Row row)
if (insertid) {
multiselector = multiselector + ",#" + id;
}
- Gtk::TreeModel::Row childrow = *(_store->append(row->children()));
+ Gtk::TreeModel::Row childrow = *(_store->prepend(row->children()));
childrow[_mColumns._colSelector] = "#" + Glib::ustring(id);
childrow[_mColumns._colExpand] = false;
childrow[_mColumns._colType] = OBJECT;
@@ -1093,6 +1072,9 @@ void SelectorsDialog::_selectObjects(int eventX, int eventY)
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 (_lastpath.size() && _lastpath == path) {
+ return;
+ }
if (col == _treeView.get_column(1) && x2 > 25) {
getDesktop()->selection->clear();
Gtk::TreeModel::iterator iter = _store->get_iter(path);
@@ -1108,6 +1090,7 @@ void SelectorsDialog::_selectObjects(int eventX, int eventY)
getDesktop()->selection->add(obj);
}
}
+ _lastpath = path;
}
}
}
@@ -1179,9 +1162,8 @@ void SelectorsDialog::_addSelector()
* for selector. If the entrybox is empty, the text (thus selectorName) is
* set to ".Class1"
*/
- selectorValue = textEditPtr->get_text();
+ selectorValue = _style_dialog->fixCSSSelectors(Glib::ustring(textEditPtr->get_text()));
_del.show();
- fixCSSSelectors(selectorValue);
if (selectorValue.empty()) {
textLabelPtr->show();
} else {
@@ -1190,7 +1172,6 @@ void SelectorsDialog::_addSelector()
}
delete textDialogPtr;
// ==== Handle response ====
-
// If class selector, add selector name to class attribute for each object
REMOVE_SPACES(selectorValue);
std::vector<Glib::ustring> tokens = Glib::Regex::split_simple("[,]+", selectorValue);
@@ -1214,7 +1195,7 @@ void SelectorsDialog::_addSelector()
}
}
objVec = _getObjVec(selectorValue);
- Gtk::TreeModel::Row row = *(_store->append());
+ Gtk::TreeModel::Row row = *(_store->prepend());
row[_mColumns._colExpand] = true;
row[_mColumns._colType] = SELECTOR;
row[_mColumns._colSelector] = selectorValue;
@@ -1223,7 +1204,7 @@ void SelectorsDialog::_addSelector()
row[_mColumns._colVisible] = true;
row[_mColumns._colSelected] = 400;
for (auto &obj : objVec) {
- Gtk::TreeModel::Row childrow = *(_store->append(row->children()));
+ Gtk::TreeModel::Row childrow = *(_store->prepend(row->children()));
childrow[_mColumns._colSelector] = "#" + Glib::ustring(obj->getId());
childrow[_mColumns._colExpand] = false;
childrow[_mColumns._colType] = OBJECT;
@@ -1382,6 +1363,7 @@ void SelectorsDialog::_handleDesktopChanged(SPDesktop *desktop)
void SelectorsDialog::_handleSelectionChanged()
{
g_debug("SelectorsDialog::_handleSelectionChanged()");
+ _lastpath.clear();
_treeView.get_selection()->set_mode(Gtk::SELECTION_MULTIPLE);
_selectRow();
}
diff --git a/src/ui/dialog/selectorsdialog.h b/src/ui/dialog/selectorsdialog.h
index 6830a0124..66d9bb859 100644
--- a/src/ui/dialog/selectorsdialog.h
+++ b/src/ui/dialog/selectorsdialog.h
@@ -15,12 +15,13 @@
#ifndef SELECTORSDIALOG_H
#define SELECTORSDIALOG_H
-#include "ui/dialog/styledialog.h"
#include "ui/dialog/desktop-tracker.h"
#include "ui/dialog/dialog-manager.h"
+#include "ui/dialog/styledialog.h"
#include "ui/widget/panel.h"
#include <gtkmm/dialog.h>
#include <gtkmm/paned.h>
+#include <gtkmm/radiobutton.h>
#include <gtkmm/scrolledwindow.h>
#include <gtkmm/switch.h>
#include <gtkmm/treemodelfilter.h>
@@ -64,7 +65,6 @@ class SelectorsDialog : public Widget::Panel {
// Monitor all objects for addition/removal/attribute change
class NodeWatcher;
enum SelectorType { CLASS, ID, TAG };
- void fixCSSSelectors(Glib::ustring &selector);
std::vector<SelectorsDialog::NodeWatcher *> _nodeWatchers;
void _nodeAdded( Inkscape::XML::Node &repr );
void _nodeRemoved( Inkscape::XML::Node &repr );
@@ -117,10 +117,10 @@ class SelectorsDialog : public Widget::Panel {
Glib::RefPtr<Gtk::TreeModelFilter> _modelfilter;
Glib::RefPtr<TreeStore> _store;
Gtk::TreeView _treeView;
+ Gtk::TreeModel::Path _lastpath;
// Widgets
Gtk::Paned _paned;
Glib::RefPtr<Gtk::Adjustment> _vadj;
- Gtk::Switch _direction;
Gtk::Box _button_box;
Gtk::Box _selectors_box;
Gtk::ScrolledWindow _scrolled_window_selectors;
@@ -146,9 +146,11 @@ class SelectorsDialog : public Widget::Panel {
void _insertClass(SPObject *obj, const Glib::ustring &className);
void _removeClass(const std::vector<SPObject *> &objVec, const Glib::ustring &className, bool all = false);
void _removeClass(SPObject *obj, const Glib::ustring &className, bool all = false);
- void _toggleDirection();
+ void _toggleDirection(Gtk::RadioButton *vertical);
void _showWidgets();
- bool _resized(GdkEventButton *event);
+ void _resized();
+ void _childresized();
+ void _panedresized(Gtk::Allocation allocation);
void _selectObjects(int, int);
// Variables
diff --git a/src/ui/dialog/styledialog.cpp b/src/ui/dialog/styledialog.cpp
index 75b44f831..884da2df2 100644
--- a/src/ui/dialog/styledialog.cpp
+++ b/src/ui/dialog/styledialog.cpp
@@ -201,18 +201,11 @@ StyleDialog::StyleDialog()
Gtk::Box *alltoggler = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_HORIZONTAL));
Gtk::Label *infotoggler = Gtk::manage(new Gtk::Label(_("Edit Full Stylesheet")));
infotoggler->get_style_context()->add_class("inksmall");
- _all_css = Gtk::manage(new Gtk::Switch());
_vadj = _scrolledWindow.get_vadjustment();
_vadj->signal_value_changed().connect(sigc::mem_fun(*this, &StyleDialog::_vscrool));
- //_all_css->property_active().signal_changed().connect(sigc::mem_fun(*this, &StyleDialog::_reload));
- // alltoggler->pack_start(*_all_css, false, false, 0);
- // alltoggler->pack_start(*infotoggler, false, false, 0);
- //_all_css->set_active(false);
- //_mainBox.pack_start(*alltoggler, false, false, 0);
_mainBox.set_orientation(Gtk::ORIENTATION_VERTICAL);
_getContents()->pack_start(_mainBox, Gtk::PACK_EXPAND_WIDGET);
- //_all_css->get_style_context()->add_class("inkswitch");
// Document & Desktop
_desktop_changed_connection =
_desktopTracker.connectDesktopChanged(sigc::mem_fun(*this, &StyleDialog::_handleDesktopChanged));
@@ -223,6 +216,7 @@ StyleDialog::StyleDialog()
_selection_changed_connection = getDesktop()->getSelection()->connectChanged(
sigc::hide(sigc::mem_fun(this, &StyleDialog::_handleSelectionChanged)));
+
// Add watchers
_updateWatchers();
@@ -240,6 +234,43 @@ void StyleDialog::_vscrool()
}
}
+Glib::ustring StyleDialog::fixCSSSelectors(Glib::ustring selector)
+{
+ g_debug("SelectorsDialog::fixCSSSelectors");
+ REMOVE_SPACES(selector);
+ Glib::ustring selector_out = "";
+ std::vector<Glib::ustring> tokens = Glib::Regex::split_simple("[,]+", selector);
+ for (auto token : tokens) {
+ if (!selector_out.empty()) {
+ selector_out += ",";
+ }
+ REMOVE_SPACES(token);
+ std::vector<Glib::ustring> subtokens = Glib::Regex::split_simple("[ ]+", token);
+ for (auto subtoken : subtokens) {
+ REMOVE_SPACES(subtoken);
+ Glib::ustring my_selector = subtoken + " {"; // Parsing fails sometimes without '{'. Fix me
+ CRSelector *cr_selector = cr_selector_parse_from_buf((guchar *)my_selector.c_str(), CR_UTF_8);
+ gchar *selectorchar = reinterpret_cast<gchar *>(cr_selector_to_string(cr_selector));
+ if (selectorchar) {
+ Glib::ustring toadd = Glib::ustring(selectorchar);
+ g_free(selectorchar);
+ if (toadd[0] != '.' && toadd[0] != '#' && toadd.size() > 1) {
+ auto i = std::min(toadd.find("#"), toadd.find("."));
+ Glib::ustring tag = toadd;
+ if (i != std::string::npos) {
+ tag = tag.substr(0, i);
+ }
+ if (!SPAttributeRelSVG::isSVGElement(tag)) {
+ return "";
+ }
+ }
+ selector_out = selector_out.empty() ? toadd : selector_out + " " + toadd;
+ }
+ }
+ }
+ return selector_out;
+}
+
/**
* Class destructor
*/
@@ -466,6 +497,7 @@ void StyleDialog::_readStyleElement()
css_selector->set_text("element");
Gtk::TreeView *css_tree;
_builder->get_widget("CSSTree", css_tree);
+ css_tree->get_style_context()->add_class("style_element");
Glib::RefPtr<Gtk::TreeStore> store = Gtk::TreeStore::create(_mColumns);
css_tree->set_model(store);
css_selector_event_add->signal_button_release_event().connect(
@@ -473,7 +505,7 @@ void StyleDialog::_readStyleElement()
sigc::mem_fun(*this, &StyleDialog::_addRow), store, css_tree, "style_properties", selectorpos));
Inkscape::UI::Widget::IconRenderer *addRenderer = manage(new Inkscape::UI::Widget::IconRenderer());
addRenderer->add_icon("edit-delete");
- int addCol = css_tree->append_column("Delete row", *addRenderer) - 1;
+ int addCol = css_tree->append_column("", *addRenderer) - 1;
Gtk::TreeViewColumn *col = css_tree->get_column(addCol);
if (col) {
addRenderer->signal_activated().connect(
@@ -485,9 +517,10 @@ void StyleDialog::_readStyleElement()
label->signal_edited().connect(sigc::bind<Glib::RefPtr<Gtk::TreeStore>, Gtk::TreeView *>(
sigc::mem_fun(*this, &StyleDialog::_nameEdited), store, css_tree));
label->signal_editing_started().connect(sigc::mem_fun(*this, &StyleDialog::_startNameEdit));
- addCol = css_tree->append_column("CSS Property", *label) - 1;
+ addCol = css_tree->append_column("", *label) - 1;
col = css_tree->get_column(addCol);
if (col) {
+ col->set_resizable(true);
col->add_attribute(label->property_text(), _mColumns._colName);
}
Gtk::CellRendererText *value = Gtk::manage(new Gtk::CellRendererText());
@@ -497,7 +530,7 @@ void StyleDialog::_readStyleElement()
sigc::bind<Glib::RefPtr<Gtk::TreeStore>>(sigc::mem_fun(*this, &StyleDialog::_valueEdited), store));
value->signal_editing_started().connect(
sigc::bind<Glib::RefPtr<Gtk::TreeStore>>(sigc::mem_fun(*this, &StyleDialog::_startValueEdit), store));
- addCol = css_tree->append_column("CSS Value", *value) - 1;
+ addCol = css_tree->append_column("", *value) - 1;
col = css_tree->get_column(addCol);
if (col) {
col->add_attribute(value->property_text(), _mColumns._colValue);
@@ -506,7 +539,7 @@ void StyleDialog::_readStyleElement()
Inkscape::UI::Widget::IconRenderer *urlRenderer = manage(new Inkscape::UI::Widget::IconRenderer());
urlRenderer->add_icon("empty");
urlRenderer->add_icon("edit-redo");
- int urlCol = css_tree->append_column("Go to", *urlRenderer) - 1;
+ int urlCol = css_tree->append_column("", *urlRenderer) - 1;
Gtk::TreeViewColumn *urlcol = css_tree->get_column(urlCol);
if (urlcol) {
urlRenderer->signal_activated().connect(
@@ -515,19 +548,19 @@ void StyleDialog::_readStyleElement()
}
std::map<Glib::ustring, Glib::ustring> attr_prop;
Gtk::TreeModel::Path path;
- if (!_all_css->get_active() && obj && obj->getRepr()->attribute("style")) {
+ if (obj && obj->getRepr()->attribute("style")) {
Glib::ustring style = obj->getRepr()->attribute("style");
attr_prop = parseStyle(style);
for (auto iter : obj->style->properties()) {
if (attr_prop.count(iter->name)) {
- Gtk::TreeModel::Row row = *(store->append());
+ Gtk::TreeModel::Row row = *(store->prepend());
row[_mColumns._colSelector] = "style_properties";
row[_mColumns._colSelectorPos] = 0;
row[_mColumns._colActive] = true;
row[_mColumns._colName] = iter->name;
row[_mColumns._colValue] = iter->get_value();
row[_mColumns._colStrike] = false;
- row[_mColumns._colOwner] = Glib::ustring("Value active");
+ row[_mColumns._colOwner] = Glib::ustring("Current value");
row[_mColumns._colHref] = nullptr;
row[_mColumns._colLinked] = false;
if (is_url(iter->get_value().c_str())) {
@@ -554,7 +587,7 @@ void StyleDialog::_readStyleElement()
REMOVE_SPACES(selector); // Remove leading/trailing spaces
// Get list of objects selector matches
std::vector<SPObject *> objVec = _getObjVec(selector);
- if (obj && !_all_css->get_active()) {
+ if (obj) {
bool stop = true;
for (auto objel : objVec) {
if (objel->getId() == obj->getId()) {
@@ -592,14 +625,25 @@ void StyleDialog::_readStyleElement()
_builder->get_widget("CSSSelectorContainer", css_selector_container);
Gtk::Label *css_selector;
_builder->get_widget("CSSSelector", css_selector);
+ Gtk::EventBox *css_selector_event_box;
+ _builder->get_widget("CSSSelectorEventBox", css_selector_event_box);
+ Gtk::Entry *css_edit_selector;
+ _builder->get_widget("CSSEditSelector", css_edit_selector);
Gtk::EventBox *css_selector_event_add;
_builder->get_widget("CSSSelectorEventAdd", css_selector_event_add);
css_selector_event_add->add_events(Gdk::BUTTON_RELEASE_MASK);
css_selector->set_text(selector);
Gtk::TreeView *css_tree;
_builder->get_widget("CSSTree", css_tree);
+ css_tree->get_style_context()->add_class("style_sheet");
Glib::RefPtr<Gtk::TreeStore> store = Gtk::TreeStore::create(_mColumns);
css_tree->set_model(store);
+ css_selector_event_box->signal_button_release_event().connect(
+ sigc::bind(sigc::mem_fun(*this, &StyleDialog::_selectorStartEdit), css_selector, css_edit_selector));
+ css_edit_selector->signal_key_press_event().connect(sigc::bind(
+ sigc::mem_fun(*this, &StyleDialog::_selectorEditKeyPress), store, css_selector, css_edit_selector));
+ css_edit_selector->signal_activate().connect(
+ sigc::bind(sigc::mem_fun(*this, &StyleDialog::_selectorActivate), store, css_selector, css_edit_selector));
Inkscape::UI::Widget::IconRenderer *addRenderer = manage(new Inkscape::UI::Widget::IconRenderer());
addRenderer->add_icon("edit-delete");
int addCol = css_tree->append_column("Delete row", *addRenderer) - 1;
@@ -625,6 +669,7 @@ void StyleDialog::_readStyleElement()
addCol = css_tree->append_column("CSS Selector", *label) - 1;
col = css_tree->get_column(addCol);
if (col) {
+ col->set_resizable(true);
col->add_attribute(label->property_text(), _mColumns._colName);
}
Gtk::CellRendererText *value = Gtk::manage(new Gtk::CellRendererText());
@@ -662,7 +707,7 @@ void StyleDialog::_readStyleElement()
css_selector_event_add->signal_button_release_event().connect(
sigc::bind<Glib::RefPtr<Gtk::TreeStore>, Gtk::TreeView *, Glib::ustring, gint>(
sigc::mem_fun(*this, &StyleDialog::_addRow), store, css_tree, selector, selectorpos));
- if (obj && !_all_css->get_active()) {
+ if (obj) {
for (auto iter : result_props) {
Gtk::TreeIter iterstore = store->append();
Gtk::TreeModel::Path path = (Gtk::TreeModel::Path)iterstore;
@@ -690,7 +735,7 @@ void StyleDialog::_readStyleElement()
row[_mColumns._colOwner] = Glib::ustring("");
} else {
row[_mColumns._colStrike] = false;
- row[_mColumns._colOwner] = Glib::ustring("Value active");
+ row[_mColumns._colOwner] = Glib::ustring("Current value");
_addOwnerStyle(iter.first, selector);
}
} else {
@@ -701,7 +746,7 @@ void StyleDialog::_readStyleElement()
}
} else {
for (auto iter : result_props) {
- Gtk::TreeModel::Row row = *(store->append());
+ Gtk::TreeModel::Row row = *(store->prepend());
row[_mColumns._colSelector] = selector;
row[_mColumns._colSelectorPos] = selectorpos;
row[_mColumns._colActive] = iter.second.second;
@@ -727,12 +772,13 @@ void StyleDialog::_readStyleElement()
css_selector_event_add->add_events(Gdk::BUTTON_RELEASE_MASK);
store = Gtk::TreeStore::create(_mColumns);
_builder->get_widget("CSSTree", css_tree);
+ css_tree->get_style_context()->add_class("style_attribute");
css_tree->set_model(store);
css_selector_event_add->signal_button_release_event().connect(
sigc::bind<Glib::RefPtr<Gtk::TreeStore>, Gtk::TreeView *, Glib::ustring, gint>(
sigc::mem_fun(*this, &StyleDialog::_addRow), store, css_tree, "attributes", selectorpos));
bool hasattributes = false;
- if (obj && !_all_css->get_active()) {
+ if (obj) {
for (auto iter : obj->style->properties()) {
if (iter->style_src != SP_STYLE_SRC_UNSET) {
if (iter->name != "font" && iter->name != "d" && iter->name != "marker") {
@@ -757,6 +803,7 @@ void StyleDialog::_readStyleElement()
addCol = css_tree->append_column("CSS Property", *label) - 1;
col = css_tree->get_column(addCol);
if (col) {
+ col->set_resizable(true);
col->add_attribute(label->property_text(), _mColumns._colName);
}
Gtk::CellRendererText *value = Gtk::manage(new Gtk::CellRendererText());
@@ -774,7 +821,7 @@ void StyleDialog::_readStyleElement()
col->add_attribute(value->property_strikethrough(), _mColumns._colStrike);
}
}
- Gtk::TreeIter iterstore = store->append();
+ Gtk::TreeIter iterstore = store->prepend();
Gtk::TreeModel::Path path = (Gtk::TreeModel::Path)iterstore;
Gtk::TreeModel::Row row = *(iterstore);
row[_mColumns._colSelector] = "attributes";
@@ -788,7 +835,7 @@ void StyleDialog::_readStyleElement()
row[_mColumns._colOwner] = tooltiptext;
} else {
row[_mColumns._colStrike] = false;
- row[_mColumns._colOwner] = Glib::ustring("Value active");
+ row[_mColumns._colOwner] = Glib::ustring("Current value");
_addOwnerStyle(iter->name, "inline attributes");
}
hasattributes = true;
@@ -826,6 +873,43 @@ void StyleDialog::_readStyleElement()
_updating = false;
}
+bool StyleDialog::_selectorStartEdit(GdkEventButton *event, Gtk::Label *selector, Gtk::Entry *selector_edit)
+{
+ g_debug("StyleDialog::_selectorStartEdit");
+ if (event->type == GDK_BUTTON_RELEASE && event->button == 1) {
+ selector->hide();
+ selector_edit->set_text(selector->get_text());
+ selector_edit->show();
+ }
+ return false;
+}
+
+void StyleDialog::_selectorActivate(Glib::RefPtr<Gtk::TreeStore> store, Gtk::Label *selector, Gtk::Entry *selector_edit)
+{
+ g_debug("StyleDialog::_selectorEditKeyPress");
+ bool ret = false;
+ Glib::ustring newselector = fixCSSSelectors(selector_edit->get_text());
+ if (newselector.empty()) {
+ selector_edit->get_style_context()->add_class("system_error_color");
+ return;
+ }
+ _writeStyleElement(store, selector->get_text(), selector_edit->get_text());
+}
+
+bool StyleDialog::_selectorEditKeyPress(GdkEventKey *event, Glib::RefPtr<Gtk::TreeStore> store, Gtk::Label *selector,
+ Gtk::Entry *selector_edit)
+{
+ g_debug("StyleDialog::_selectorEditKeyPress");
+ switch (event->keyval) {
+ case GDK_KEY_Escape:
+ selector->show();
+ selector_edit->hide();
+ selector_edit->get_style_context()->remove_class("system_error_color");
+ break;
+ }
+ return false;
+}
+
bool StyleDialog::_on_foreach_iter(const Gtk::TreeModel::iterator &iter)
{
g_debug("StyleDialog::_on_foreach_iter");
@@ -921,7 +1005,8 @@ std::map<Glib::ustring, Glib::ustring> StyleDialog::parseStyle(Glib::ustring sty
/**
* Update the content of the style element as selectors (or objects) are added/removed.
*/
-void StyleDialog::_writeStyleElement(Glib::RefPtr<Gtk::TreeStore> store, Glib::ustring selector)
+void StyleDialog::_writeStyleElement(Glib::RefPtr<Gtk::TreeStore> store, Glib::ustring selector,
+ Glib::ustring new_selector)
{
g_debug("StyleDialog::_writeStyleElemen");
if (_updating) {
@@ -936,7 +1021,7 @@ void StyleDialog::_writeStyleElement(Glib::RefPtr<Gtk::TreeStore> store, Glib::u
if (!obj) {
obj = getDesktop()->getDocument()->getXMLDialogSelectedObject();
}
- if (selection->objects().size() < 2 && !obj && !_all_css->get_active()) {
+ if (selection->objects().size() < 2 && !obj) {
_readStyleElement();
return;
}
@@ -944,6 +1029,9 @@ void StyleDialog::_writeStyleElement(Glib::RefPtr<Gtk::TreeStore> store, Glib::u
gint selectorpos = 0;
std::string styleContent = "";
if (selector != "style_properties" && selector != "attributes") {
+ if (!new_selector.empty()) {
+ selector = new_selector;
+ }
styleContent = "\n" + selector + " { \n";
}
for (auto &row : store->children()) {
@@ -965,13 +1053,17 @@ void StyleDialog::_writeStyleElement(Glib::RefPtr<Gtk::TreeStore> store, Glib::u
styleContent = styleContent + "}";
}
if (selector == "style_properties") {
+ _updating = true;
obj->getRepr()->setAttribute("style", styleContent, false);
+ _updating = false;
} else if (selector == "attributes") {
for (auto iter : obj->style->properties()) {
if (iter->name != "font" && iter->name != "d" && iter->name != "marker") {
const gchar *attr = obj->getRepr()->attribute(iter->name.c_str());
if (attr) {
+ _updating = true;
obj->getRepr()->setAttribute(iter->name.c_str(), nullptr);
+ _updating = false;
}
}
}
@@ -979,13 +1071,15 @@ void StyleDialog::_writeStyleElement(Glib::RefPtr<Gtk::TreeStore> store, Glib::u
Glib::ustring name = row[_mColumns._colName];
Glib::ustring value = row[_mColumns._colValue];
if (!(name.empty() && value.empty())) {
+ _updating = true;
obj->getRepr()->setAttribute(name.c_str(), value, false);
+ _updating = false;
}
}
} else if (!selector.empty()) { // styleshet
// We could test if styleContent is empty and then delete the style node here but there is no
// harm in keeping it around ...
- SPDocument *document = SP_ACTIVE_DOCUMENT;
+
std::string pos = std::to_string(selectorpos);
std::string selectormatch = "(";
for (selectorpos; selectorpos > 1; selectorpos--) {
@@ -998,14 +1092,16 @@ void StyleDialog::_writeStyleElement(Glib::RefPtr<Gtk::TreeStore> store, Glib::u
std::string result;
std::regex_replace(std::back_inserter(result), content.begin(), content.end(), e, "$1" + styleContent + "$3");
textNode->setContent(result.c_str());
- INKSCAPE.readStyleSheets();
- for (auto iter : document->getObjectsBySelector(selector)) {
- iter->style->readFromObject(iter);
- iter->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG);
- }
+ INKSCAPE.readStyleSheets(true);
}
_updating = false;
_readStyleElement();
+ /* SPDocument *document = SP_ACTIVE_DOCUMENT;
+ for (auto iter : document->getObjectsBySelector(selector)) {
+ std::cout << std::endl;
+ iter->style->readFromObject(iter);
+ iter->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG);
+ } */
DocumentUndo::done(SP_ACTIVE_DOCUMENT, SP_VERB_DIALOG_STYLE, _("Edited style element."));
g_debug("StyleDialog::_writeStyleElement(): | %s |", styleContent.c_str());
@@ -1017,7 +1113,7 @@ bool StyleDialog::_addRow(GdkEventButton *evt, Glib::RefPtr<Gtk::TreeStore> stor
g_debug("StyleDialog::_addRow");
if (evt->type == GDK_BUTTON_RELEASE && evt->button == 1) {
- Gtk::TreeIter iter = store->append();
+ Gtk::TreeIter iter = store->prepend();
Gtk::TreeModel::Path path = (Gtk::TreeModel::Path)iter;
Gtk::TreeModel::Row row = *(iter);
row[_mColumns._colSelector] = selector;
@@ -1050,7 +1146,7 @@ void StyleDialog::_setAutocompletion(Gtk::Entry *entry, SPStyleEnum const cssenu
gint counter = 0;
const char * key = cssenum[counter].key;
while (key) {
- Gtk::TreeModel::Row row = *(completionModel->append());
+ Gtk::TreeModel::Row row = *(completionModel->prepend());
row[_mCSSData._colCSSData] = Glib::ustring(key);
counter++;
key = cssenum[counter].key;
@@ -1144,7 +1240,9 @@ StyleDialog::_startValueEdit(Gtk::CellEditable* cell, const Glib::ustring& path,
_setAutocompletion(entry, enum_color_interpolation);
}
entry->signal_key_release_event().connect(
- sigc::bind(sigc::mem_fun(*this, &StyleDialog::_onValueKeyReleased), cell));
+ sigc::bind(sigc::mem_fun(*this, &StyleDialog::_onValueKeyReleased), entry));
+ entry->signal_key_press_event().connect(
+ sigc::bind(sigc::mem_fun(*this, &StyleDialog::_onValueKeyPressed), entry));
}
}
@@ -1165,7 +1263,22 @@ void StyleDialog::_startNameEdit(Gtk::CellEditable *cell, const Glib::ustring &p
}
Gtk::Entry *entry = dynamic_cast<Gtk::Entry *>(cell);
entry->set_completion(entry_completion);
- entry->signal_key_release_event().connect(sigc::bind(sigc::mem_fun(*this, &StyleDialog::_onNameKeyReleased), cell));
+ entry->signal_key_release_event().connect(
+ sigc::bind(sigc::mem_fun(*this, &StyleDialog::_onNameKeyReleased), entry));
+ entry->signal_key_press_event().connect(sigc::bind(sigc::mem_fun(*this, &StyleDialog::_onNameKeyPressed), entry));
+}
+
+
+gboolean sp_styledialog_store_move_to_next(gpointer data)
+{
+ StyleDialog *styledialog = reinterpret_cast<StyleDialog *>(data);
+ auto selection = styledialog->_current_css_tree->get_selection();
+ Gtk::TreeIter iter = *(selection->get_selected());
+ Gtk::TreeModel::Path model = (Gtk::TreeModel::Path)iter;
+ if (model == styledialog->_current_path) {
+ styledialog->_current_css_tree->set_cursor(styledialog->_current_path, *styledialog->_current_value_col, true);
+ }
+ return FALSE;
}
/**
@@ -1181,9 +1294,10 @@ void StyleDialog::_nameEdited(const Glib::ustring &path, const Glib::ustring &na
_scroollock = true;
Gtk::TreeModel::Row row = *store->get_iter(path);
- Gtk::TreeModel::Path pathel = (Gtk::TreeModel::Path)*store->get_iter(path);
+ _current_path = (Gtk::TreeModel::Path)*store->get_iter(path);
if (row) {
+ _current_css_tree = css_tree;
Glib::ustring finalname = name;
auto i = std::min(finalname.find(";"), finalname.find(":"));
if (i != std::string::npos) {
@@ -1197,7 +1311,7 @@ void StyleDialog::_nameEdited(const Glib::ustring &path, const Glib::ustring &na
Glib::ustring selector = row[_mColumns._colSelector];
Glib::ustring value = row[_mColumns._colValue];
bool is_attr = selector == "attributes";
-
+ Glib::ustring old_name = row[_mColumns._colName];
row[_mColumns._colName] = finalname;
if (finalname.empty() && value.empty()) {
store->erase(row);
@@ -1206,10 +1320,11 @@ void StyleDialog::_nameEdited(const Glib::ustring &path, const Glib::ustring &na
if (pos < 1 || is_attr) {
col = 2;
}
- if (write) {
+ _current_value_col = css_tree->get_column(col);
+ if (write && old_name != name) {
_writeStyleElement(store, selector);
} else {
- css_tree->set_cursor(pathel, *(css_tree->get_column(col)), true);
+ g_timeout_add(50, &sp_styledialog_store_move_to_next, this);
grab_focus();
}
}
@@ -1235,6 +1350,10 @@ void StyleDialog::_valueEdited(const Glib::ustring &path, const Glib::ustring &v
if (i != std::string::npos) {
finalvalue.erase(i, finalvalue.size() - i);
}
+ Glib::ustring old_value = row[_mColumns._colValue];
+ if (old_value == finalvalue) {
+ return;
+ }
row[_mColumns._colValue] = finalvalue;
Glib::ustring selector = row[_mColumns._colSelector];
Glib::ustring name = row[_mColumns._colName];
@@ -1258,56 +1377,81 @@ void StyleDialog::_activeToggled(const Glib::ustring &path, Glib::RefPtr<Gtk::Tr
}
}
-bool StyleDialog::_onNameKeyReleased(GdkEventKey *event, Gtk::CellEditable *cell)
+bool StyleDialog::_onNameKeyPressed(GdkEventKey *event, Gtk::Entry *entry)
{
g_debug("StyleDialog::_onNameKeyReleased");
-
+ bool ret = false;
switch (event->keyval) {
case GDK_KEY_Tab:
case GDK_KEY_KP_Tab:
- case GDK_KEY_colon: {
- cell->editing_done();
- return true;
- }
+ entry->editing_done();
+ ret = true;
+ break;
+ }
+ return ret;
+}
+
+bool StyleDialog::_onNameKeyReleased(GdkEventKey *event, Gtk::Entry *entry)
+{
+ g_debug("StyleDialog::_onNameKeyReleased");
+ bool ret = false;
+ switch (event->keyval) {
+ case GDK_KEY_equal:
+ case GDK_KEY_colon:
+ entry->editing_done();
+ ret = true;
+ break;
case GDK_KEY_Shift_L:
case GDK_KEY_Shift_R:
case GDK_KEY_semicolon: {
- Gtk::Entry *entry = dynamic_cast<Gtk::Entry *>(cell);
Glib::ustring text = entry->get_text();
auto i = std::min(text.find(";"), text.find(":"));
if (i != std::string::npos) {
- cell->editing_done();
- return true;
+ entry->editing_done();
+ ret = true;
}
+ break;
}
}
- return false;
+ return ret;
}
-bool StyleDialog::_onValueKeyReleased(GdkEventKey *event, Gtk::CellEditable *cell)
+bool StyleDialog::_onValueKeyPressed(GdkEventKey *event, Gtk::Entry *entry)
{
g_debug("StyleDialog::_onValueKeyReleased");
-
+ bool ret = false;
switch (event->keyval) {
case GDK_KEY_Tab:
case GDK_KEY_KP_Tab:
- case GDK_KEY_semicolon: {
- cell->editing_done();
- return true;
- }
+ entry->editing_done();
+ ret = true;
+ break;
+ }
+ return ret;
+}
+
+bool StyleDialog::_onValueKeyReleased(GdkEventKey *event, Gtk::Entry *entry)
+{
+ g_debug("StyleDialog::_onValueKeyReleased");
+ bool ret = false;
+ switch (event->keyval) {
+ case GDK_KEY_semicolon:
+ entry->editing_done();
+ ret = true;
+ break;
case GDK_KEY_Shift_L:
case GDK_KEY_Shift_R:
case GDK_KEY_colon: {
- Gtk::Entry *entry = dynamic_cast<Gtk::Entry *>(cell);
Glib::ustring text = entry->get_text();
auto i = std::min(text.find(";"), text.find(":"));
if (i != std::string::npos) {
- cell->editing_done();
- return true;
+ entry->editing_done();
+ ret = true;
}
+ break;
}
}
- return false;
+ return ret;
}
void StyleDialog::_addWatcherRecursive(Inkscape::XML::Node *node)
diff --git a/src/ui/dialog/styledialog.h b/src/ui/dialog/styledialog.h
index 90b9d298f..b7ccf6619 100644
--- a/src/ui/dialog/styledialog.h
+++ b/src/ui/dialog/styledialog.h
@@ -67,6 +67,10 @@ class StyleDialog : public Widget::Panel {
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;
+ Glib::ustring fixCSSSelectors(Glib::ustring selector);
private:
// Monitor <style> element for changes.
@@ -119,21 +123,26 @@ class StyleDialog : public Widget::Panel {
Glib::RefPtr<Gtk::Adjustment> _vadj;
Gtk::Box _mainBox;
Gtk::Box _styleBox;
- Gtk::Switch *_all_css;
-
// Reading and writing the style element.
Inkscape::XML::Node *_getStyleTextNode();
void _readStyleElement();
Glib::RefPtr<Gtk::TreeModel> _selectTree(Glib::ustring selector);
- void _writeStyleElement(Glib::RefPtr<Gtk::TreeStore> store, 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::CellEditable *cell);
- bool _onValueKeyReleased(GdkEventKey *event, Gtk::CellEditable *cell);
+ 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);
diff --git a/src/ui/dialog/symbols.cpp b/src/ui/dialog/symbols.cpp
index de5184058..2ecf612d2 100644
--- a/src/ui/dialog/symbols.cpp
+++ b/src/ui/dialog/symbols.cpp
@@ -207,7 +207,7 @@ SymbolsDialog::SymbolsDialog( gchar const* prefsPath ) :
overlay_opacity = new Gtk::Image();
overlay_opacity->set_halign(Gtk::ALIGN_START);
overlay_opacity->set_valign(Gtk::ALIGN_START);
- overlay_opacity->get_style_context()->add_class("rawimage");
+ overlay_opacity->get_style_context()->add_class("rawstyle");
// No results
overlay_icon = sp_get_icon_image("searching", Gtk::ICON_SIZE_DIALOG);
diff --git a/src/ui/dialog/xml-tree.cpp b/src/ui/dialog/xml-tree.cpp
index 91c24bd4c..ef0131168 100644
--- a/src/ui/dialog/xml-tree.cpp
+++ b/src/ui/dialog/xml-tree.cpp
@@ -46,27 +46,28 @@ namespace Inkscape {
namespace UI {
namespace Dialog {
-XmlTree::XmlTree() :
- UI::Widget::Panel("/dialogs/xml/", SP_VERB_DIALOG_XML_EDITOR),
- blocked (0),
- _message_stack (nullptr),
- _message_context (nullptr),
- current_desktop (nullptr),
- current_document (nullptr),
- selected_attr (0),
- selected_repr (nullptr),
- tree (nullptr),
- status (""),
- tree_toolbar(),
- xml_element_new_button ( _("New element node")),
- xml_text_new_button ( _("New text node")),
- xml_node_delete_button ( Q_("nodeAsInXMLdialogTooltip|Delete node")),
- xml_node_duplicate_button ( _("Duplicate node")),
- unindent_node_button(),
- indent_node_button(),
- raise_node_button(),
- lower_node_button(),
- new_window(nullptr)
+XmlTree::XmlTree()
+ : UI::Widget::Panel("/dialogs/xml/", SP_VERB_DIALOG_XML_EDITOR)
+ , blocked(0)
+ , _message_stack(nullptr)
+ , _message_context(nullptr)
+ , current_desktop(nullptr)
+ , current_document(nullptr)
+ , selected_attr(0)
+ , selected_repr(nullptr)
+ , tree(nullptr)
+ , status("")
+ , tree_toolbar()
+ , xml_element_new_button(_("New element node"))
+ , xml_text_new_button(_("New text node"))
+ , xml_node_delete_button(Q_("nodeAsInXMLdialogTooltip|Delete node"))
+ , xml_node_duplicate_button(_("Duplicate node"))
+ , unindent_node_button()
+ , indent_node_button()
+ , raise_node_button()
+ , lower_node_button()
+ , new_window(nullptr)
+ , _updating(false)
{
SPDesktop *desktop = SP_ACTIVE_DESKTOP;
@@ -79,6 +80,7 @@ XmlTree::XmlTree() :
status.set_size_request(1, -1);
status.set_markup("");
status.set_line_wrap(true);
+ status.get_style_context()->add_class("inksmall");
status_box.pack_start( status, TRUE, TRUE, 0);
contents->pack_start(_paned, true, true, 0);
contents->set_valign(Gtk::ALIGN_FILL);
@@ -172,28 +174,35 @@ XmlTree::XmlTree() :
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
bool attrtoggler = prefs->getBool("/dialogs/xml/attrtoggler", true);
bool dir = prefs->getBool("/dialogs/xml/vertical", true);
- attributes = new AttrDialog;
+ attributes = new AttrDialog();
_paned.set_orientation(dir ? Gtk::ORIENTATION_VERTICAL : Gtk::ORIENTATION_HORIZONTAL);
+ _paned.check_resize();
_paned.pack1(node_box, Gtk::SHRINK);
/* attributes */
Gtk::Box *actionsbox = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_HORIZONTAL));
actionsbox->set_valign(Gtk::ALIGN_START);
Gtk::Label *attrtogglerlabel = Gtk::manage(new Gtk::Label(_("Show attributes")));
attrtogglerlabel->set_margin_right(5);
- _attrswitch.property_active() = attrtoggler;
_attrswitch.get_style_context()->add_class("inkswitch");
+ _attrswitch.get_style_context()->add_class("rawstyle");
+ _attrswitch.property_active() = attrtoggler;
_attrswitch.property_active().signal_changed().connect(sigc::mem_fun(*this, &XmlTree::_attrtoggler));
attrtogglerlabel->get_style_context()->add_class("inksmall");
- _dirtogglerlabel = Gtk::manage(new Gtk::Label(_("Paned vertical")));
- _direction.property_active() = dir;
- _direction.property_active().signal_changed().connect(sigc::mem_fun(*this, &XmlTree::_toggleDirection));
- _direction.get_style_context()->add_class("inkswitch");
- _dirtogglerlabel->get_style_context()->add_class("inksmall");
- actionsbox->pack_start(_attrswitch, Gtk::PACK_SHRINK);
actionsbox->pack_start(*attrtogglerlabel, Gtk::PACK_SHRINK);
- actionsbox->pack_start(_direction, Gtk::PACK_SHRINK);
- actionsbox->pack_start(*_dirtogglerlabel, Gtk::PACK_SHRINK);
-
+ actionsbox->pack_start(_attrswitch, Gtk::PACK_SHRINK);
+ Gtk::RadioButton::Group group;
+ Gtk::RadioButton *_horizontal = Gtk::manage(new Gtk::RadioButton());
+ Gtk::RadioButton *_vertical = Gtk::manage(new Gtk::RadioButton());
+ _horizontal->set_image_from_icon_name(INKSCAPE_ICON("horizontal"));
+ _vertical->set_image_from_icon_name(INKSCAPE_ICON("vertical"));
+ _horizontal->set_group(group);
+ _vertical->set_group(group);
+ _vertical->set_active(dir);
+ _vertical->signal_toggled().connect(sigc::bind(sigc::mem_fun(*this, &XmlTree::_toggleDirection), _vertical));
+ _horizontal->property_draw_indicator() = false;
+ _vertical->property_draw_indicator() = false;
+ actionsbox->pack_end(*_horizontal, false, false, 0);
+ actionsbox->pack_end(*_vertical, false, false, 0);
_paned.pack2(*attributes, true, true);
contents->pack_start(*actionsbox, false, false, 0);
/* Signal handlers */
@@ -213,22 +222,16 @@ XmlTree::XmlTree() :
desktopChangeConn = deskTrack.connectDesktopChanged( sigc::mem_fun(*this, &XmlTree::set_tree_desktop) );
deskTrack.connect(GTK_WIDGET(gobj()));
int widthpos = _paned.property_max_position();
- int panedpos = prefs->getInt("/dialogs/xml/panedpos", 130);
-
- _paned.set_position(panedpos);
- _paned.signal_button_release_event().connect(sigc::mem_fun(*this, &XmlTree::_resized),
- false); /* initial show/hide */
+ _paned.property_position().signal_changed().connect(sigc::mem_fun(*this, &XmlTree::_childresized));
+ _paned.signal_size_allocate().connect(sigc::mem_fun(*this, &XmlTree::_panedresized));
set_name("XMLAndAttributesDialog");
set_spacing(0);
set_size_request(320, 260);
show_all();
_paned.property_wide_handle() = true;
- if (!attrtoggler) {
- attributes->hide();
- _dirtogglerlabel->hide();
- _direction.hide();
- _paned.set_position(widthpos);
- }
+ int panedpos = prefs->getInt("/dialogs/xml/panedpos", 130);
+ _paned.set_position(panedpos);
+ _resized();
tree_reset_context();
g_assert(desktop != nullptr);
@@ -236,20 +239,43 @@ XmlTree::XmlTree() :
}
-bool XmlTree::_resized(GdkEventButton *event)
+void XmlTree::_panedresized(Gtk::Allocation allocation) { _resized(); }
+
+void XmlTree::_childresized() { _resized(); }
+
+void XmlTree::_resized()
{
+ if (_updating) {
+ return;
+ }
+ _updating = true;
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ bool dir = !prefs->getBool("/dialogs/xml/vertical", true);
+ int max = int(_paned.property_max_position() * 0.95);
+ int min = int(_paned.property_max_position() * 0.05);
+ bool attrtoggler = prefs->getBool("/dialogs/xml/attrtoggler", true);
+ if (attrtoggler && _paned.get_position() > max) {
+ _paned.property_position() = max;
+ }
+ if (attrtoggler && _paned.get_position() < min) {
+ _paned.property_position() = min;
+ }
+ if (!attrtoggler) {
+ attributes->hide();
+ _paned.property_position() = _paned.property_max_position();
+ }
prefs->setInt("/dialogs/xml/panedpos", _paned.get_position());
- return true;
+ _updating = false;
}
-void XmlTree::_toggleDirection()
+void XmlTree::_toggleDirection(Gtk::RadioButton *vertical)
{
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
- bool dir = !prefs->getBool("/dialogs/xml/vertical", true);
+ bool dir = vertical->get_active();
prefs->setBool("/dialogs/xml/vertical", dir);
_paned.set_orientation(dir ? Gtk::ORIENTATION_VERTICAL : Gtk::ORIENTATION_HORIZONTAL);
- int widthpos = _paned.property_max_position();
+ _paned.check_resize();
+ int widthpos = _paned.property_max_position() - _paned.property_min_position();
prefs->setInt("/dialogs/xml/panedpos", widthpos / 2);
_paned.set_position(widthpos / 2);
}
@@ -261,15 +287,11 @@ void XmlTree::_attrtoggler()
prefs->setBool("/dialogs/xml/attrtoggler", attrtoggler);
if (attrtoggler) {
attributes->show();
- _dirtogglerlabel->show();
- _direction.show();
- int widthpos = _paned.property_max_position();
+ int widthpos = _paned.property_max_position() - _paned.property_min_position();
prefs->setInt("/dialogs/xml/panedpos", widthpos / 2);
_paned.set_position(widthpos / 2);
} else {
attributes->hide();
- _dirtogglerlabel->hide();
- _direction.hide();
int widthpos = _paned.property_max_position();
_paned.set_position(widthpos);
}
diff --git a/src/ui/dialog/xml-tree.h b/src/ui/dialog/xml-tree.h
index f9c3c1c02..ea24ac52b 100644
--- a/src/ui/dialog/xml-tree.h
+++ b/src/ui/dialog/xml-tree.h
@@ -19,6 +19,7 @@
#include <gtkmm/button.h>
#include <gtkmm/entry.h>
#include <gtkmm/paned.h>
+#include <gtkmm/radiobutton.h>
#include <gtkmm/scrolledwindow.h>
#include <gtkmm/separatortoolitem.h>
#include <gtkmm/switch.h>
@@ -166,8 +167,10 @@ private:
void present() override;
void _attrtoggler();
- void _toggleDirection();
- bool _resized(GdkEventButton *event);
+ void _toggleDirection(Gtk::RadioButton *vertical);
+ void _resized();
+ void _childresized();
+ void _panedresized(Gtk::Allocation allocation);
bool in_dt_coordsys(SPObject const &item);
/**
@@ -180,6 +183,7 @@ private:
*/
gint blocked;
+ bool _updating;
/**
* Status bar
*/
@@ -217,8 +221,6 @@ private:
Gtk::VBox node_box;
Gtk::HBox status_box;
Gtk::Switch _attrswitch;
- Gtk::Switch _direction;
- Gtk::Label *_dirtogglerlabel;
Gtk::Label status;
Gtk::Toolbar tree_toolbar;
Gtk::ToolButton xml_element_new_button;