changeset 14818:8c4d5029d933 gui

Collapsing/Expanding items now works with a workaround. * workspace-model.cc: Calling beginResetModel and endResetModel instead of reset. * workspace-model.h: Changed signal name to model_changed (). * workspace-view.cc: Added logic to preserve data about collapsed/expanded tree items. * workspace-view.h: Added new slots and status flag struct.
author Jacob Dawid <jacob.dawid@googlemail.com>
date Wed, 13 Jun 2012 13:34:38 +0200
parents ace446cda345
children dc2a8d66e40b
files gui/src/workspace-model.cc gui/src/workspace-model.h gui/src/workspace-view.cc gui/src/workspace-view.h
diffstat 4 files changed, 136 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/gui/src/workspace-model.cc
+++ b/gui/src/workspace-model.cc
@@ -70,6 +70,7 @@
         _symbol_information.push_back (symbolInformation);
       }
 
+      beginResetModel();
       top_level_item (0)->delete_child_items ();
       top_level_item (1)->delete_child_items ();
       top_level_item (2)->delete_child_items ();
@@ -92,8 +93,8 @@
             }
         }
 
-      reset();
-      emit expand_request();
+      endResetModel();
+      emit model_changed();
     }
 
   // Post a new event in a given time.
--- a/gui/src/workspace-model.h
+++ b/gui/src/workspace-model.h
@@ -135,7 +135,7 @@
   void request_update_workspace ();
 
 signals:
-  void expand_request();
+  void model_changed();
 
 private:
   /** Timer for periodically updating the workspace model from the current
--- a/gui/src/workspace-view.cc
+++ b/gui/src/workspace-view.cc
@@ -31,7 +31,7 @@
   _workspace_tree_view = new QTreeView (this);
   _workspace_tree_view->setHeaderHidden (false);
   _workspace_tree_view->setAlternatingRowColors (true);
-  _workspace_tree_view->setAnimated (true);
+  //_workspace_tree_view->setAnimated (true);
   _workspace_tree_view->setModel (_workspace_model);
 
   setWidget (new QWidget (this));
@@ -43,15 +43,130 @@
   connect (this, SIGNAL (visibilityChanged (bool)),
            this, SLOT(handle_visibility_changed (bool)));
 
-  connect (_workspace_model, SIGNAL(expand_request()),
-           _workspace_tree_view, SLOT(expandAll()));
+  connect (_workspace_model, SIGNAL (model_changed ()),
+           this, SLOT (model_changed ()));
+
+  connect (_workspace_tree_view, SIGNAL (collapsed (QModelIndex)),
+           this, SLOT (collapse_requested (QModelIndex)));
+  connect (_workspace_tree_view, SIGNAL (expanded (QModelIndex)),
+           this, SLOT (expand_requested (QModelIndex)));
+
+  _explicit_collapse.local = false;
+  _explicit_collapse.global = false;
+  _explicit_collapse.persistent = false;
+  _explicit_collapse.hidden = false;
 }
 
 void
 workspace_view::handle_visibility_changed (bool visible)
 {
   if (visible)
-  emit active_changed (true);
+    emit active_changed (true);
+}
+
+void
+workspace_view::model_changed ()
+{
+  // This code is very quirky and requires some explanation.
+  // Usually, we should not deal with collapsing or expanding ourselves,
+  // because the view itself determines (based on the model) whether it
+  // is appropriate to collapse or expand items.
+  //
+  // Now, the logic requires that we update our model item by item, which
+  // would make it work correctly, but this is extremely slow and scales
+  // very bad (O(n^2)). That's why we throw away our model and rebuild it
+  // completely from scratch (O(n)), which is why the view renders all
+  // displayed data as invalid.
+  //
+  // In order to make collapsing/expanding work again, we need to set
+  // flags ourselves here.
+
+  QModelIndex local_model_index = _workspace_model->index (0, 0);
+  QModelIndex global_model_index = _workspace_model->index (1, 0);
+  QModelIndex persistent_model_index = _workspace_model->index (2, 0);
+  QModelIndex hidden_model_index = _workspace_model->index (3, 0);
+
+  if (_explicit_collapse.local) {
+    _workspace_tree_view->collapse (local_model_index);
+  } else {
+    _workspace_tree_view->expand (local_model_index);
+  }
+
+  if (_explicit_collapse.global) {
+    _workspace_tree_view->collapse (global_model_index);
+  } else {
+    _workspace_tree_view->expand (global_model_index);
+  }
+
+  if (_explicit_collapse.persistent) {
+    _workspace_tree_view->collapse (persistent_model_index);
+  } else {
+    _workspace_tree_view->expand (persistent_model_index);
+  }
+
+  if (_explicit_collapse.hidden) {
+    _workspace_tree_view->collapse (hidden_model_index);
+  } else {
+    _workspace_tree_view->expand (hidden_model_index);
+  }
+}
+
+void
+workspace_view::collapse_requested (QModelIndex index)
+{
+  // This code is very quirky and requires some explanation.
+  // Usually, we should not deal with collapsing or expanding ourselves,
+  // because the view itself determines (based on the model) whether it
+  // is appropriate to collapse or expand items.
+  //
+  // Now, the logic requires that we update our model item by item, which
+  // would make it work correctly, but this is extremely slow and scales
+  // very bad (O(n^2)). That's why we throw away our model and rebuild it
+  // completely from scratch (O(n)), which is why the view renders all
+  // displayed data as invalid.
+  //
+  // In order to make collapsing/expanding work again, we need to set
+  // flags ourselves here.
+  QMap<int, QVariant> item_data
+      = _workspace_model->itemData (index);
+
+  if (item_data[0] == "Local")
+    _explicit_collapse.local = true;
+  if (item_data[0] == "Global")
+    _explicit_collapse.global = true;
+  if (item_data[0] == "Persistent")
+    _explicit_collapse.persistent = true;
+  if (item_data[0] == "Hidden")
+    _explicit_collapse.hidden = true;
+}
+
+void
+workspace_view::expand_requested (QModelIndex index)
+{
+  // This code is very quirky and requires some explanation.
+  // Usually, we should not deal with collapsing or expanding ourselves,
+  // because the view itself determines (based on the model) whether it
+  // is appropriate to collapse or expand items.
+  //
+  // Now, the logic requires that we update our model item by item, which
+  // would make it work correctly, but this is extremely slow and scales
+  // very bad (O(n^2)). That's why we throw away our model and rebuild it
+  // completely from scratch (O(n)), which is why the view renders all
+  // displayed data as invalid.
+  //
+  // In order to make collapsing/expanding work again, we need to do set
+  // flags ourselves here.
+  QMap<int, QVariant> item_data
+      = _workspace_model->itemData (index);
+
+  if (item_data[0] == "Local")
+    _explicit_collapse.local = false;
+  if (item_data[0] == "Global")
+    _explicit_collapse.global = false;
+  if (item_data[0] == "Persistent")
+    _explicit_collapse.persistent = false;
+  if (item_data[0] == "Hidden")
+    _explicit_collapse.hidden = false;
 }
 
 void
--- a/gui/src/workspace-view.h
+++ b/gui/src/workspace-view.h
@@ -32,6 +32,7 @@
 
 public slots:
   void handle_visibility_changed (bool visible);
+  void model_changed ();
 
 signals:
   /** Custom signal that tells if a user has clicke away that dock widget. */
@@ -40,11 +41,23 @@
 protected:
   void closeEvent (QCloseEvent *event);
 
+protected slots:
+  void collapse_requested (QModelIndex index);
+  void expand_requested (QModelIndex index);
+
 private:
   QTreeView *_workspace_tree_view;
 
   /** Stores the current workspace model. */
   workspace_model *_workspace_model;
+
+  struct
+  {
+    bool local;
+    bool global;
+    bool persistent;
+    bool hidden;
+  } _explicit_collapse;
 };
 
 #endif // WORKSPACEVIEW_H