summaryrefslogtreecommitdiffstats
path: root/src/ui
diff options
context:
space:
mode:
authorJabier Arraiza <jabier.arraiza@marker.es>2017-06-24 17:50:36 +0000
committerJabier Arraiza <jabier.arraiza@marker.es>2017-06-24 17:50:36 +0000
commitd71265c629a103d8c821fe85ccf71bd9c93baf47 (patch)
treec01fe4543cd48f64a8ca4b60e01e1bb5040922d9 /src/ui
parentWorking with powerclip and powermask (diff)
parentMerge branch 'ui-files-for-ui-xml' (diff)
downloadinkscape-d71265c629a103d8c821fe85ccf71bd9c93baf47.tar.gz
inkscape-d71265c629a103d8c821fe85ccf71bd9c93baf47.zip
Updating to master
Diffstat (limited to 'src/ui')
-rw-r--r--src/ui/dialog/filedialogimpl-win32.cpp25
-rw-r--r--src/ui/dialog/styledialog.cpp138
-rw-r--r--src/ui/dialog/styledialog.h12
3 files changed, 165 insertions, 10 deletions
diff --git a/src/ui/dialog/filedialogimpl-win32.cpp b/src/ui/dialog/filedialogimpl-win32.cpp
index 1efec7d52..4fb8089ee 100644
--- a/src/ui/dialog/filedialogimpl-win32.cpp
+++ b/src/ui/dialog/filedialogimpl-win32.cpp
@@ -1586,10 +1586,15 @@ FileSaveDialogImplWin32::FileSaveDialogImplWin32(Gtk::Window &parent,
if (len != 0 && udir[len - 1] == '\\') udir.erase(len - 1);
// Remove the extension: remove everything past the last period found past the last slash
- size_t last_slash_index = udir.find_last_of( '\\' );
- size_t last_period_index = udir.find_last_of( '.' );
- if (last_period_index > last_slash_index) {
- myFilename = udir.substr(0, last_period_index );
+ // (not for CUSTOM_TYPE as we can not automatically add a file extension in that case yet)
+ if (dialogType == CUSTOM_TYPE) {
+ myFilename = udir;
+ } else {
+ size_t last_slash_index = udir.find_last_of( '\\' );
+ size_t last_period_index = udir.find_last_of( '.' );
+ if (last_period_index > last_slash_index) {
+ myFilename = udir.substr(0, last_period_index );
+ }
}
// remove one slash if double
@@ -1685,28 +1690,28 @@ void FileSaveDialogImplWin32::addFileType(Glib::ustring name, Glib::ustring patt
knownExtensions.clear();
- int extension_index = 0;
- int filter_length = 1;
-
- ustring all_exe_files_filter = pattern;
Filter all_exe_files;
const gchar *all_exe_files_filter_name = name.data();
+ const gchar *all_exe_files_filter = pattern.data();
// Calculate the amount of memory required
int filter_count = 1;
-
+ int filter_length = 1;
// Filter Executable Files
all_exe_files.name = g_utf8_to_utf16(all_exe_files_filter_name,
-1, NULL, &all_exe_files.name_length, NULL);
- all_exe_files.filter = g_utf8_to_utf16(all_exe_files_filter.data(),
+ all_exe_files.filter = g_utf8_to_utf16(all_exe_files_filter,
-1, NULL, &all_exe_files.filter_length, NULL);
all_exe_files.mod = NULL;
filter_list.push_front(all_exe_files);
+
+ filter_length = all_exe_files.name_length + all_exe_files.filter_length + 3; // Add 3 for two \0s and a *
knownExtensions.insert( Glib::ustring(all_exe_files_filter).casefold() );
+ int extension_index = 0;
_extension_map = new Inkscape::Extension::Extension*[filter_count];
_filter = new wchar_t[filter_length];
diff --git a/src/ui/dialog/styledialog.cpp b/src/ui/dialog/styledialog.cpp
index b1bcddd45..8679659ce 100644
--- a/src/ui/dialog/styledialog.cpp
+++ b/src/ui/dialog/styledialog.cpp
@@ -45,6 +45,7 @@ namespace Inkscape {
namespace UI {
namespace Dialog {
+// Keeps a watch on style element
class StyleDialog::NodeObserver : public Inkscape::XML::NodeObserver {
public:
NodeObserver(StyleDialog* styleDialog) :
@@ -78,6 +79,93 @@ StyleDialog::NodeObserver::notifyContentChanged(
}
+// Keeps a watch for new/removed/changed nodes
+// (Must update objects that selectors match.)
+class StyleDialog::NodeWatcher : public Inkscape::XML::NodeObserver {
+public:
+ NodeWatcher(StyleDialog* styleDialog, Inkscape::XML::Node *repr) :
+ _styleDialog(styleDialog),
+ _repr(repr)
+ {
+#ifdef DEBUG_STYLEDIALOG
+ std::cout << "StyleDialog::NodeWatcher: Constructor" << std::endl;
+#endif
+ };
+
+ virtual void notifyChildAdded( Inkscape::XML::Node &/*node*/,
+ Inkscape::XML::Node &child,
+ Inkscape::XML::Node */*prev*/ )
+ {
+ if ( _styleDialog && _repr ) {
+ _styleDialog->_nodeAdded( child );
+ }
+ }
+
+ virtual void notifyChildRemoved( Inkscape::XML::Node &/*node*/,
+ Inkscape::XML::Node &child,
+ Inkscape::XML::Node */*prev*/ )
+ {
+ if ( _styleDialog && _repr ) {
+ _styleDialog->_nodeRemoved( child );
+ }
+ }
+
+ virtual void notifyAttributeChanged( Inkscape::XML::Node &node,
+ GQuark qname,
+ Util::ptr_shared<char> /*old_value*/,
+ Util::ptr_shared<char> /*new_value*/ ) {
+ if ( _styleDialog && _repr ) {
+
+ // For the moment only care about attributes that are directly used in selectors.
+ const gchar * cname = g_quark_to_string (qname );
+ Glib::ustring name;
+ if (cname) {
+ name = cname;
+ }
+
+ if ( name == "id" || name == "class" ) {
+ _styleDialog->_nodeChanged( node );
+ }
+ }
+ }
+
+ StyleDialog * _styleDialog;
+ Inkscape::XML::Node * _repr; // Need to track if document changes.
+};
+
+void
+StyleDialog::_nodeAdded( Inkscape::XML::Node &node ) {
+
+ StyleDialog::NodeWatcher *w = new StyleDialog::NodeWatcher (this, &node);
+ node.addObserver (*w);
+ _nodeWatchers.push_back(w);
+
+ _readStyleElement();
+ _selectRow();
+}
+
+void
+StyleDialog::_nodeRemoved( Inkscape::XML::Node &repr ) {
+
+ for (auto it = _nodeWatchers.begin(); it != _nodeWatchers.end(); ++it) {
+ if ( (*it)->_repr == &repr ) {
+ (*it)->_repr->removeObserver (**it);
+ _nodeWatchers.erase( it );
+ break;
+ }
+ }
+
+ _readStyleElement();
+ _selectRow();
+}
+
+void
+StyleDialog::_nodeChanged( Inkscape::XML::Node &object ) {
+
+ _readStyleElement();
+ _selectRow();
+}
+
StyleDialog::TreeStore::TreeStore()
{
}
@@ -248,6 +336,9 @@ StyleDialog::StyleDialog() :
_selection_changed_connection = getDesktop()->getSelection()->connectChanged(
sigc::hide(sigc::mem_fun(this, &StyleDialog::_handleSelectionChanged)));
+ // Add watchers
+ _updateWatchers();
+
// Load tree
_readStyleElement();
_selectRow();
@@ -407,6 +498,7 @@ void StyleDialog::_readStyleElement()
// 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;
@@ -446,6 +538,49 @@ void StyleDialog::_writeStyleElement()
}
+void StyleDialog::_addWatcherRecursive(Inkscape::XML::Node *node) {
+
+#ifdef DEBUG_STYLEDIALOG
+ std::cout << "StyleDialog::_addWatcherRecursive()" << std::endl;
+#endif
+
+ StyleDialog::NodeWatcher *w = new StyleDialog::NodeWatcher(this, node);
+ node->addObserver(*w);
+ _nodeWatchers.push_back(w);
+
+ for (unsigned i = 0; i < node->childCount(); ++i) {
+ _addWatcherRecursive(node->nthChild(i));
+ }
+}
+
+/**
+ * @brief StyleDialog::_updateWatchers
+ * Update the watchers on objects.
+ */
+void StyleDialog::_updateWatchers()
+{
+ _updating = true;
+
+ // Remove old document watchers
+ while (!_nodeWatchers.empty()) {
+ StyleDialog::NodeWatcher *w = _nodeWatchers.back();
+ w->_repr->removeObserver(*w);
+ _nodeWatchers.pop_back();
+ delete w;
+ }
+
+ // Recursively add new watchers
+ Inkscape::XML::Node *root = SP_ACTIVE_DOCUMENT->getReprRoot();
+ _addWatcherRecursive(root);
+
+#ifdef DEBUG_STYLEDIALOG
+ std::cout << "StyleDialog::_updateWatchers(): " << _nodeWatchers.size() << std::endl;
+#endif
+
+ _updating = false;
+}
+
+
/**
* @brief StyleDialog::_addToSelector
* @param row
@@ -711,6 +846,7 @@ void StyleDialog::_selectObjects(int eventX, int eventY)
Gtk::TreeModel::Row row = *iter;
Gtk::TreeModel::Children children = row.children();
std::vector<SPObject *> objVec = row[_mColumns._colObj];
+
for (unsigned i = 0; i < objVec.size(); ++i) {
SPObject *obj = objVec[i];
getDesktop()->selection->add(obj);
@@ -1046,6 +1182,7 @@ StyleDialog::_handleDocumentReplaced(SPDesktop *desktop, SPDocument * /* documen
_selection_changed_connection = desktop->getSelection()->connectChanged(
sigc::hide(sigc::mem_fun(this, &StyleDialog::_handleSelectionChanged)));
+ _updateWatchers();
_readStyleElement();
_selectRow();
}
@@ -1076,6 +1213,7 @@ StyleDialog::_handleDesktopChanged(SPDesktop* desktop) {
_document_replaced_connection = desktop->connectDocumentReplaced(
sigc::mem_fun(this, &StyleDialog::_handleDocumentReplaced));
+ _updateWatchers();
_readStyleElement();
_selectRow();
}
diff --git a/src/ui/dialog/styledialog.h b/src/ui/dialog/styledialog.h
index e84489e66..dbbc1e480 100644
--- a/src/ui/dialog/styledialog.h
+++ b/src/ui/dialog/styledialog.h
@@ -58,6 +58,14 @@ private:
// Monitor <style> element for changes.
class NodeObserver;
+ // Monitor all objects for addition/removal/attribute change
+ class NodeWatcher;
+
+ std::vector<StyleDialog::NodeWatcher*> _nodeWatchers;
+ void _nodeAdded( Inkscape::XML::Node &repr );
+ void _nodeRemoved( Inkscape::XML::Node &repr );
+ void _nodeChanged( Inkscape::XML::Node &repr );
+
// Data structure
class ModelColumns : public Gtk::TreeModel::ColumnRecord {
public:
@@ -112,6 +120,10 @@ private:
Inkscape::XML::Node *_getStyleTextNode();
void _readStyleElement();
void _writeStyleElement();
+
+ // Update watchers
+ void _addWatcherRecursive(Inkscape::XML::Node *node);
+ void _updateWatchers();
// Manipulate Tree
void _addToSelector(Gtk::TreeModel::Row row);