summaryrefslogtreecommitdiffstats
path: root/src/ui/dialog/attrdialog.cpp
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/dialog/attrdialog.cpp
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/dialog/attrdialog.cpp')
-rw-r--r--src/ui/dialog/attrdialog.cpp207
1 files changed, 183 insertions, 24 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"));
}
}