summaryrefslogtreecommitdiffstats
path: root/src/ui
diff options
context:
space:
mode:
authorJabier Arraiza <jabier.arraiza@marker.es>2019-02-27 00:36:21 +0000
committerJabier Arraiza <jabier.arraiza@marker.es>2019-03-24 12:45:11 +0000
commit7dc58c52c128f933ca8b4b8cf95c1eb0f7903cdc (patch)
treec377ea5d34cc1f005959dd152b3dabb39788b604 /src/ui
parentAlso deploy the dependencies of .so files coming with Python (diff)
downloadinkscape-7dc58c52c128f933ca8b4b8cf95c1eb0f7903cdc.tar.gz
inkscape-7dc58c52c128f933ca8b4b8cf95c1eb0f7903cdc.zip
Add base of working
Diffstat (limited to 'src/ui')
-rw-r--r--src/ui/dialog/cssdialog.cpp1
-rw-r--r--src/ui/dialog/styledialog.cpp217
-rw-r--r--src/ui/dialog/styledialog.h7
3 files changed, 135 insertions, 90 deletions
diff --git a/src/ui/dialog/cssdialog.cpp b/src/ui/dialog/cssdialog.cpp
index 90488e203..06dfc9348 100644
--- a/src/ui/dialog/cssdialog.cpp
+++ b/src/ui/dialog/cssdialog.cpp
@@ -98,6 +98,7 @@ CssDialog::CssDialog()
}
Gtk::CellRendererText *renderer = Gtk::manage(new Gtk::CellRendererText());
+ _treeView.set_reorderable(false);
renderer->property_editable() = true;
int nameColNum = _treeView.append_column("Property", *renderer) - 1;
_propCol = _treeView.get_column(nameColNum);
diff --git a/src/ui/dialog/styledialog.cpp b/src/ui/dialog/styledialog.cpp
index 5cf0f5cb1..55d28eede 100644
--- a/src/ui/dialog/styledialog.cpp
+++ b/src/ui/dialog/styledialog.cpp
@@ -32,6 +32,7 @@
#include <utility>
//#define DEBUG_STYLEDIALOG
+#define G_LOG_DOMAIN "STYLEDIALOG"
using Inkscape::DocumentUndo;
using Inkscape::Util::List;
@@ -72,7 +73,6 @@ StyleDialog::NodeObserver::notifyContentChanged(
Inkscape::Util::ptr_shared /*new_content*/ ) {
g_debug("StyleDialog::NodeObserver::notifyContentChanged");
-
_styleDialog->_readStyleElement();
_styleDialog->_selectRow();
}
@@ -179,7 +179,8 @@ StyleDialog::TreeStore::row_draggable_vfunc(const Gtk::TreeModel::Path& path) co
const_iterator iter = unconstThis->get_iter(path);
if (iter) {
Gtk::TreeModel::Row row = *iter;
- bool is_draggable = row[_styledialog->_mColumns._colIsSelector];
+ bool is_draggable = row[_styledialog->_mColumns._colType] == SELECTOR ||
+ row[_styledialog->_mColumns._colType] == UNHANDLED;
return is_draggable;
}
return Gtk::TreeStore::row_draggable_vfunc(path);
@@ -205,9 +206,9 @@ StyleDialog::TreeStore::row_drop_possible_vfunc(const Gtk::TreeModel::Path& dest
void
StyleDialog::TreeStore::on_row_deleted(const TreeModel::Path& path)
{
- g_debug("on_row_deleted");
+ if (_styledialog->_updating || _styledialog->_block_drag) return; // Don't write if we deleted row (other than from DND)
- if (_styledialog->_updating) return; // Don't write if we deleted row (other than from DND)
+ g_debug("on_row_deleted");
_styledialog->_writeStyleElement();
}
@@ -231,7 +232,8 @@ StyleDialog::StyleDialog() :
UI::Widget::Panel("/dialogs/style", SP_VERB_DIALOG_STYLE),
_updating(false),
_textNode(nullptr),
- _desktopTracker()
+ _desktopTracker(),
+ _block_drag(false)
{
g_debug("StyleDialog::StyleDialog");
@@ -240,17 +242,17 @@ StyleDialog::StyleDialog() :
new Inkscape::UI::Widget::IconRenderer() );
addRenderer->add_icon("edit-delete");
addRenderer->add_icon("list-add");
+ addRenderer->add_icon("object-locked");
_store = TreeStore::create(this);
_treeView.set_model(_store);
_treeView.set_headers_visible(true);
_treeView.enable_model_drag_source();
_treeView.enable_model_drag_dest( Gdk::ACTION_MOVE );
-
int addCol = _treeView.append_column("", *addRenderer) - 1;
Gtk::TreeViewColumn *col = _treeView.get_column(addCol);
if ( col ) {
- col->add_attribute( addRenderer->property_icon(), _mColumns._colIsSelector );
+ col->add_attribute( addRenderer->property_icon(), _mColumns._colType );
}
_treeView.append_column("CSS Selector", _mColumns._colSelector);
_treeView.set_expander_column(*(_treeView.get_column(1)));
@@ -436,7 +438,14 @@ void StyleDialog::_readStyleElement()
Glib::ustring selector = tokens[i];
REMOVE_SPACES(selector); // Remove leading/trailing spaces
-
+ std::vector<Glib::ustring> tokensplus = Glib::Regex::split_simple("[,]+", selector);
+ coltype colType = SELECTOR;
+ for (auto tok : tokensplus){
+ REMOVE_SPACES(tok);
+ if (tok.find(" ") != -1){
+ colType = UNHANDLED;
+ }
+ }
// Get list of objects selector matches
std::vector<SPObject *> objVec = _getObjVec( selector );
@@ -452,18 +461,18 @@ void StyleDialog::_readStyleElement()
Gtk::TreeModel::Row row = *(_store->append());
row[_mColumns._colSelector] = selector;
- row[_mColumns._colIsSelector] = true;
+ row[_mColumns._colType] = colType;
row[_mColumns._colObj] = objVec;
row[_mColumns._colProperties] = properties;
-
- // Add as children, objects that match selector.
- for (auto& obj: objVec) {
- if (obj->cloned) continue; // Skip cloned objects (they also don't have 'id').
- Gtk::TreeModel::Row childrow = *(_store->append(row->children()));
- childrow[_mColumns._colSelector] = "#" + Glib::ustring(obj->getId());
- childrow[_mColumns._colIsSelector] = false;
- childrow[_mColumns._colObj] = std::vector<SPObject *>(1, obj);
- childrow[_mColumns._colProperties] = ""; // Unused
+ if (colType == SELECTOR) {
+ // Add as children, objects that match selector.
+ for (auto& obj: objVec) {
+ Gtk::TreeModel::Row childrow = *(_store->append(row->children()));
+ childrow[_mColumns._colSelector] = "#" + Glib::ustring(obj->getId());
+ childrow[_mColumns._colType] = OBJECT;
+ childrow[_mColumns._colObj] = std::vector<SPObject *>(1, obj);
+ childrow[_mColumns._colProperties] = ""; // Unused
+ }
}
}
_updating = false;
@@ -476,11 +485,22 @@ void StyleDialog::_readStyleElement()
*/
void StyleDialog::_writeStyleElement()
{
+ if (_updating) {
+ return;
+ }
_updating = true;
Glib::ustring styleContent;
for (auto& row: _store->children()) {
- styleContent = styleContent + row[_mColumns._colSelector] +
+ Glib::ustring selector = row[_mColumns._colSelector];
+/*
+ REMOVE_SPACES(selector);
+/* size_t len = selector.size();
+ if(selector[len-1] == ','){
+ selector.erase(len-1);
+ }
+ row[_mColumns._colSelector] = selector; */
+ styleContent = styleContent + selector +
" { " + row[_mColumns._colProperties] + " }\n";
}
// We could test if styleContent is empty and then delete the style node here but there is no
@@ -568,11 +588,10 @@ void StyleDialog::_addToSelector(Gtk::TreeModel::Row row)
objVec.push_back(obj); // Adding to copy so need to update tree
row[_mColumns._colObj] = objVec;
row[_mColumns._colSelector] = _getIdList( objVec );
-
// Add child row
Gtk::TreeModel::Row childrow = *(_store->append(row->children()));
childrow[_mColumns._colSelector] = "#" + Glib::ustring(obj->getId());
- childrow[_mColumns._colIsSelector] = false;
+ childrow[_mColumns._colType] = OBJECT;
childrow[_mColumns._colObj] = std::vector<SPObject *>(1, obj);
childrow[_mColumns._colProperties] = ""; // Unused
}
@@ -584,25 +603,28 @@ void StyleDialog::_addToSelector(Gtk::TreeModel::Row row)
// Get first class (split on white space or comma)
std::vector<Glib::ustring> tokens = Glib::Regex::split_simple("[,\\s]+", selector);
- Glib::ustring className = tokens[0];
- className.erase(0,1);
-
- // Get list of objects to modify
- Inkscape::Selection* selection = getDesktop()->getSelection();
- std::vector<SPObject *> objVec( selection->objects().begin(),
- selection->objects().end() );
+ Glib::ustring originClassName = tokens[0];
+ originClassName.erase(0,1);
+ std::vector<Glib::ustring> classes = Glib::Regex::split_simple("[\\.]+", originClassName);
+ for (auto className : classes) {
- _insertClass( objVec, className );
+ // Get list of objects to modify
+ Inkscape::Selection* selection = getDesktop()->getSelection();
+ std::vector<SPObject *> objVec( selection->objects().begin(),
+ selection->objects().end() );
- row[_mColumns._colObj] = _getObjVec( selector );
+ _insertClass( objVec, className );
- for (auto& obj: objVec) {
- // Add child row
- Gtk::TreeModel::Row childrow = *(_store->append(row->children()));
- childrow[_mColumns._colSelector] = "#" + Glib::ustring(obj->getId());
- childrow[_mColumns._colIsSelector] = false;
- childrow[_mColumns._colObj] = std::vector<SPObject *>(1, obj);
- childrow[_mColumns._colProperties] = ""; // Unused
+ row[_mColumns._colObj] = _getObjVec( selector );
+
+ for (auto& obj: objVec) {
+ // Add child row
+ Gtk::TreeModel::Row childrow = *(_store->append(row->children()));
+ childrow[_mColumns._colSelector] = "#" + Glib::ustring(obj->getId());
+ childrow[_mColumns._colType] = OBJECT;
+ childrow[_mColumns._colObj] = std::vector<SPObject *>(1, obj);
+ childrow[_mColumns._colProperties] = ""; // Unused
+ }
}
}
@@ -611,8 +633,13 @@ void StyleDialog::_addToSelector(Gtk::TreeModel::Row row)
// std::cout << " Element selector... doing nothing!" << std::endl;
}
}
-
_writeStyleElement();
+ if (*row) {
+ _updating = true;
+ _treeView.get_selection()->select(row);
+ _treeView.expand_to_path (Gtk::TreePath(row));
+ _updating = false;
+ }
}
@@ -631,7 +658,7 @@ void StyleDialog::_removeFromSelector(Gtk::TreeModel::Row row)
if (iter) {
Gtk::TreeModel::Row parent = *iter;
Glib::ustring selector = parent[_mColumns._colSelector];
-
+ REMOVE_SPACES(selector);
if (selector[0] == '#') {
// 'id' selector... remove selected object's id's to list.
@@ -641,12 +668,17 @@ void StyleDialog::_removeFromSelector(Gtk::TreeModel::Row row)
selector.erase(i, objectLabel.length());
}
// Erase any comma/space
+ REMOVE_SPACES(selector);
if (i != Glib::ustring::npos && selector[i] == ',') {
selector.erase(i, 1);
}
if (i != Glib::ustring::npos && selector[i] == ' ') {
selector.erase(i, 1);
}
+ REMOVE_SPACES(selector);
+ if (selector[selector.size()-1] == ',') {
+ selector.erase(selector.size()-1, 1);
+ }
// Update store
if (selector.empty()) {
@@ -655,6 +687,10 @@ void StyleDialog::_removeFromSelector(Gtk::TreeModel::Row row)
// Save new selector and update object vector.
parent[_mColumns._colSelector] = selector;
parent[_mColumns._colObj] = _getObjVec( selector );
+ _updating = true;
+ _treeView.get_selection()->select(parent);
+ _treeView.expand_to_path (Gtk::TreePath (parent));
+ _updating = false;
_store->erase(row);
}
}
@@ -663,36 +699,37 @@ void StyleDialog::_removeFromSelector(Gtk::TreeModel::Row row)
// 'class' selector... remove value to class attribute of selected objects.
std::vector<SPObject *> objVec = row[_mColumns._colObj]; // Just one
-
// Get first class (split on white space or comma)
std::vector<Glib::ustring> tokens = Glib::Regex::split_simple("[,\\s]+", selector);
- Glib::ustring className = tokens[0];
- className.erase(0,1); // Erase '.'
-
- // Erase class name from 'class' attribute.
- Glib::ustring classAttr = objVec[0]->getRepr()->attribute("class");
- auto i = classAttr.find( className );
- if (i != Glib::ustring::npos) {
- classAttr.erase(i, className.length());
- }
- if (i != Glib::ustring::npos && classAttr[i] == ' ') {
- classAttr.erase(i, 1);
- }
- objVec[0]->getRepr()->setAttribute("class", classAttr);
-
- parent[_mColumns._colObj] = _getObjVec( selector );
- _store->erase(row);
- }
+ Glib::ustring originClassName = tokens[0];
+ originClassName.erase(0,1);
+ std::vector<Glib::ustring> classes = Glib::Regex::split_simple("[\\.]+", originClassName);
+ for (auto className : classes) {
+ // Erase class name from 'class' attribute.
+ Glib::ustring classAttr = objVec[0]->getRepr()->attribute("class");
+ auto i = classAttr.find( className );
+ if (i != Glib::ustring::npos) {
+ classAttr.erase(i, className.length());
+ }
+ if (i != Glib::ustring::npos && classAttr[i] == ' ') {
+ classAttr.erase(i, 1);
+ }
+ objVec[0]->getRepr()->setAttribute("class", classAttr);
- else {
+ parent[_mColumns._colObj] = _getObjVec( selector);
+ _updating = true;
+ _treeView.get_selection()->select(parent);
+ _treeView.expand_to_path(Gtk::TreePath (parent));
+ _updating = false;
+ _store->erase(row);
+ }
+ } else {
// Do nothing for element selectors.
// std::cout << " Element selector... doing nothing!" << std::endl;
}
}
}
-
_writeStyleElement();
-
}
@@ -858,7 +895,7 @@ void StyleDialog::_addSelector()
int result = -1;
bool invalid = true;
Glib::ustring selectorValue;
-
+ bool handled = true;
while (invalid) {
result = textDialogPtr->run();
if (result != Gtk::RESPONSE_OK) { // Cancel, close dialog, etc.
@@ -874,24 +911,25 @@ void StyleDialog::_addSelector()
*/
selectorValue = textEditPtr->get_text();
Glib::ustring firstWord = selectorValue.substr(0, selectorValue.find_first_of(" >+~"));
-
+ if (firstWord != selectorValue ) {
+ handled = false;
+ }
del->set_sensitive(true);
if (selectorValue[0] == '.' ||
selectorValue[0] == '#' ||
selectorValue[0] == '*' ||
- SPAttributeRelSVG::isSVGElement( firstWord ) ) {
+ SPAttributeRelSVG::isSVGElement( selectorValue ) ) {
invalid = false;
} else {
textLabelPtr->show();
}
}
delete textDialogPtr;
-
// ==== Handle response ====
// If class selector, add selector name to class attribute for each object
- if (selectorValue[0] == '.') {
+ if (selectorValue[0] == '.' && handled) {
Glib::ustring className = selectorValue;
className.erase(0,1);
@@ -904,16 +942,18 @@ void StyleDialog::_addSelector()
// Add entry to GUI tree
Gtk::TreeModel::Row row = *(_store->append());
- row[_mColumns._colSelector] = selectorValue;
- row[_mColumns._colIsSelector] = true;
- row[_mColumns._colObj] = objVec;
+ row[_mColumns._colSelector] = selectorValue;
+ row[_mColumns._colType] = handled?SELECTOR: UNHANDLED;
+ row[_mColumns._colObj] = objVec;
// Add as children objects that match selector.
- for (auto& obj: objVec) {
- Gtk::TreeModel::Row childrow = *(_store->append(row->children()));
- childrow[_mColumns._colSelector] = "#" + Glib::ustring(obj->getId());
- childrow[_mColumns._colIsSelector] = false;
- childrow[_mColumns._colObj] = std::vector<SPObject *>(1, obj);
+ if (handled) {
+ for (auto& obj: objVec) {
+ Gtk::TreeModel::Row childrow = *(_store->append(row->children()));
+ childrow[_mColumns._colSelector] = "#" + Glib::ustring(obj->getId());
+ childrow[_mColumns._colType] = OBJECT;
+ childrow[_mColumns._colObj] = std::vector<SPObject *>(1, obj);
+ }
}
// Add entry to style element
@@ -933,6 +973,9 @@ void StyleDialog::_delSelector()
Gtk::TreeModel::iterator iter = refTreeSelection->get_selected();
if (iter) {
Gtk::TreeModel::Row row = *iter;
+ if(!row.children().empty()) {
+ return;
+ }
_updating = true;
_store->erase(iter);
_updating = false;
@@ -952,7 +995,7 @@ void StyleDialog::_delSelector()
bool StyleDialog::_handleButtonEvent(GdkEventButton *event)
{
g_debug("StyleDialog::_handleButtonEvent: Entrance");
-
+ _block_drag = true;
if (event->type == GDK_BUTTON_RELEASE && event->button == 1) {
Gtk::TreeViewColumn *col = nullptr;
Gtk::TreeModel::Path path;
@@ -960,22 +1003,27 @@ bool StyleDialog::_handleButtonEvent(GdkEventButton *event)
int y = static_cast<int>(event->y);
int x2 = 0;
int y2 = 0;
+
if (_treeView.get_path_at_pos(x, y, path, col, x2, y2)) {
if (col == _treeView.get_column(0)) {
+ bool remove_parent = false;
Gtk::TreeModel::iterator iter = _store->get_iter(path);
Gtk::TreeModel::Row row = *iter;
-
+ Glib::RefPtr<Gtk::TreeSelection> sel = _treeView.get_selection();
+ sel->select(row);
// Add or remove objects from a
+ Gtk::TreeModel::Row row_to_sel;
if (!row.parent()) {
- // Add selected objects to selector.
+ row_to_sel = row;
_addToSelector(row);
} else {
- // Remove object from selector
+ row_to_sel = *row.parent();
_removeFromSelector(row);
}
}
}
}
+ _block_drag = false;
return false;
}
@@ -1057,6 +1105,7 @@ StyleDialog::_handleDesktopChanged(SPDesktop* desktop) {
void
StyleDialog::_handleSelectionChanged() {
g_debug("StyleDialog::_handleSelectionChanged()");
+ _treeView.get_selection()->set_mode(Gtk::SELECTION_MULTIPLE);
_selectRow();
}
@@ -1071,15 +1120,16 @@ StyleDialog::_handleSelectionChanged() {
void StyleDialog::_buttonEventsSelectObjs(GdkEventButton* event )
{
g_debug("StyleDialog::_buttonEventsSelectObjs");
-
+ _treeView.get_selection()->set_mode(Gtk::SELECTION_SINGLE);
_updating = true;
-
+ del->set_sensitive(true);
if (event->type == GDK_BUTTON_RELEASE && event->button == 1) {
int x = static_cast<int>(event->x);
int y = static_cast<int>(event->y);
_selectObjects(x, y);
}
_updating = false;
+
}
@@ -1093,31 +1143,24 @@ void StyleDialog::_selectRow()
g_debug("StyleDialog::_selectRow: updating: %s", (_updating ? "true" : "false"));
if (_updating || !getDesktop()) return; // Avoid updating if we have set row via dialog.
-
if (SP_ACTIVE_DESKTOP != getDesktop()) {
std::cerr << "StyleDialog::_selectRow: SP_ACTIVE_DESKTOP != getDesktop()" << std::endl;
return;
}
-
+ _treeView.get_selection()->unselect_all();
Inkscape::Selection* selection = getDesktop()->getSelection();
if (!selection->isEmpty()) {
SPObject *obj = selection->objects().back();
-
Gtk::TreeModel::Children children = _store->children();
for(auto row : children) {
-
std::vector<SPObject *> objVec = row[_mColumns._colObj];
for (auto & i : objVec) {
if (obj->getId() == i->getId()) {
_treeView.get_selection()->select(row);
- return;
}
}
}
}
-
- // Selection empty or no row matches.
- _treeView.get_selection()->unselect_all();
}
diff --git a/src/ui/dialog/styledialog.h b/src/ui/dialog/styledialog.h
index f0fb6eddb..937c6d1eb 100644
--- a/src/ui/dialog/styledialog.h
+++ b/src/ui/dialog/styledialog.h
@@ -64,18 +64,18 @@ public:
void _nodeAdded( Inkscape::XML::Node &repr );
void _nodeRemoved( Inkscape::XML::Node &repr );
void _nodeChanged( Inkscape::XML::Node &repr );
-
// Data structure
+ enum coltype {OBJECT,SELECTOR,UNHANDLED};
class ModelColumns : public Gtk::TreeModel::ColumnRecord {
public:
ModelColumns() {
add(_colSelector);
- add(_colIsSelector);
+ add(_colType);
add(_colObj);
add(_colProperties);
}
Gtk::TreeModelColumn<Glib::ustring> _colSelector; // Selector or matching object id.
- Gtk::TreeModelColumn<bool> _colIsSelector; // Selector row or child object row.
+ Gtk::TreeModelColumn<gint> _colType; // Selector row or child object row.
Gtk::TreeModelColumn<std::vector<SPObject *> > _colObj; // List of matching objects.
Gtk::TreeModelColumn<Glib::ustring> _colProperties; // List of properties.
};
@@ -133,6 +133,7 @@ public:
// Variables
bool _updating; // Prevent cyclic actions: read <-> write, select via dialog <-> via desktop
+ bool _block_drag;
Inkscape::XML::Node *_textNode; // Track so we know when to add a NodeObserver.
// Signals and handlers - External