changeset 16477:64727ed135cb

use QTableView instead of QTreeView to display workspace * libgui/src/workspace-model.cc, libgui/src/workspace-model.h (workspace_model::workspace_model): Change to subclass QTreeView, using _columnNames for columns. (workspace_model::~workspace_model): Don't delete rootItem. (workspace_model::index): Delete. (workspace_model::parent): Delete. (workspace_model::rowCount): Return _symbols.size (workspace_model::columnCount): Return _columnNames.size. (workspace_model::insert_top_level_item): Delete. (workspace_model::top_level_item): Delete. (workspace_model::headerData): Return _columnNames. (workspace_model::data): Return data from string lists values. (workspace_model::set_workspace): Call update_table. (workspace_model::clear_workspace): Call update_table. (workspace_model::update_table): Rename from workspace_model::update_tree. (workspace_model::append_tree): Delete. * libgui/src/workspace-model.h (tree_item): Delete class decl. * libgui/src/workspace-view.h, libgui/src/workspace-view.cc (workspace_view::workspace_view): Use QTableView instead of QTreeView. (workspace_view::_explicit_collapse): Delete. (workspace_view::~workspace_view): Don't save _explicit_collapse settings. (workspace_view::model_changed): Delete. (workspace_view::collapse_requested): Delete. (workspace_view::expand_requested): Delete. (workspace_view::relay_contextmenu_command): Get cell 0 of the row. (workspace_view::contextmenu_requested): Get cell 0 of the row.
author John Donoghue <john.donoghue@ieee.org>
date Tue, 09 Apr 2013 03:26:11 -0400
parents 98155e2b6d42
children 079ec7ce60e0
files libgui/src/workspace-model.cc libgui/src/workspace-model.h libgui/src/workspace-view.cc libgui/src/workspace-view.h
diffstat 4 files changed, 42 insertions(+), 362 deletions(-) [+]
line wrap: on
line diff
--- a/libgui/src/workspace-model.cc	Tue Apr 09 03:17:48 2013 -0400
+++ b/libgui/src/workspace-model.cc	Tue Apr 09 03:26:11 2013 -0400
@@ -36,97 +36,28 @@
 #include "octave-link.h"
 
 workspace_model::workspace_model(QObject *p)
-  : QAbstractItemModel (p)
+  : QAbstractTableModel (p)
 {
-  QList<QVariant> rootData;
-  rootData << tr ("Name") << tr ("Class") << tr("Dimension") << tr ("Value");
-  _rootItem = new tree_item(rootData);
-
-  insert_top_level_item(0, new tree_item ("Local"));
-  insert_top_level_item(1, new tree_item ("Global"));
-  insert_top_level_item(2, new tree_item ("Persistent"));
+  _columnNames.append(tr("Name"));
+  _columnNames.append(tr("Class"));
+  _columnNames.append(tr("Dimension"));
+  _columnNames.append(tr("Value"));
 }
 
 workspace_model::~workspace_model()
 {
-  delete _rootItem;
-}
-
-QModelIndex
-workspace_model::index(int row, int column, const QModelIndex &p) const
-{
-  if (!hasIndex(row, column, p))
-    return QModelIndex();
-
-  tree_item *parentItem;
-
-  if (!p.isValid())
-    parentItem = _rootItem;
-  else
-    parentItem = static_cast<tree_item*>(p.internalPointer());
-
-  tree_item *childItem = parentItem->child(row);
-  if (childItem)
-    return createIndex(row, column, childItem);
-  else
-    return QModelIndex();
-}
-
-QModelIndex
-workspace_model::parent(const QModelIndex &idx) const
-{
-  if (!idx.isValid())
-    return QModelIndex();
-
-  tree_item *childItem = static_cast<tree_item*>(idx.internalPointer());
-
-  if (childItem)
-    {
-      tree_item *parentItem = childItem->parent();
-
-      if (! parentItem || parentItem == _rootItem)
-        return QModelIndex();
-
-      return createIndex(parentItem->row(), 0, parentItem);
-    }
-  else
-    return QModelIndex ();
 }
 
 int
 workspace_model::rowCount(const QModelIndex &p) const
 {
-  tree_item *parentItem;
-  if (p.column() > 0)
-    return 0;
-
-  if (!p.isValid())
-    parentItem = _rootItem;
-  else
-    parentItem = static_cast<tree_item*>(p.internalPointer());
-
-  return parentItem->child_count();
+  return _symbols.size();
 }
 
 int
 workspace_model::columnCount(const QModelIndex &p) const
 {
-  if (p.isValid())
-    return static_cast<tree_item*>(p.internalPointer())->column_count();
-  else
-    return _rootItem->column_count();
-}
-
-void
-workspace_model::insert_top_level_item(int at, tree_item *treeItem)
-{
-  _rootItem->insert_child_item(at, treeItem);
-}
-
-tree_item *
-workspace_model::top_level_item (int at)
-{
-  return _rootItem->child(at);
+  return _columnNames.size();
 }
 
 Qt::ItemFlags
@@ -142,7 +73,9 @@
 workspace_model::headerData(int section, Qt::Orientation orientation, int role) const
 {
   if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
-    return _rootItem->data(section);
+  {
+     return _columnNames[section];
+  }
 
   return QVariant();
 }
@@ -152,13 +85,21 @@
 {
   if (!idx.isValid())
     return QVariant();
-
   if (role != Qt::DisplayRole)
     return QVariant();
 
-  tree_item *item = static_cast<tree_item*>(idx.internalPointer());
-
-  return item->data(idx.column());
+  switch(idx.column())
+  {
+  case 0:
+    return QVariant(_symbols[idx.row()]);
+  case 1:
+    return QVariant(_class_names[idx.row()]);
+  case 2:
+    return QVariant(_dimensions[idx.row()]);
+  case 3:
+    return QVariant(_values[idx.row()]);
+  }
+  return QVariant();
 }
 
 void
@@ -168,13 +109,14 @@
                                 const QStringList& dimensions,
                                 const QStringList& values)
 {
+
   _scopes = scopes;
   _symbols = symbols;
   _class_names = class_names;
   _dimensions = dimensions;
   _values = values;
 
-  update_tree ();
+  update_table ();
 
   emit model_changed ();
 }
@@ -183,8 +125,7 @@
 workspace_model::clear_workspace (void)
 {
   clear_data ();
-
-  update_tree ();
+  update_table ();
 
   emit model_changed ();
 }
@@ -200,46 +141,14 @@
 }
 
 void
-workspace_model::clear_tree (void)
-{
-  top_level_item(0)->delete_child_items ();
-  top_level_item(1)->delete_child_items ();
-  top_level_item(2)->delete_child_items ();
-}
-
-void
-workspace_model::update_tree (void)
+workspace_model::update_table (void)
 {
   beginResetModel();
 
-  clear_tree ();
-
-  for (int i = 0; i < _symbols.size (); i++)
-    append_tree (_scopes[i], _symbols[i], _class_names[i], _dimensions[i],
-                 _values[i]);
+  // nothing to do except tell the world to recalc
 
   endResetModel ();
 
   emit model_changed ();
 }
 
-void
-workspace_model::append_tree (QChar scope, const QString& symbol,
-                              const QString& class_name,
-                              const QString& dimension,
-                              const QString& value)
-{
-  tree_item *child = new tree_item ();
-
-  child->set_data (0, symbol);
-  child->set_data (1, class_name);
-  child->set_data (2, dimension);
-  child->set_data (3, value);
-
-  if (scope == 'p')
-    top_level_item(2)->add_child (child);
-  else if (scope == 'g')
-    top_level_item(1)->add_child (child);
-  else
-    top_level_item(0)->add_child (child);
-}
--- a/libgui/src/workspace-model.h	Tue Apr 09 03:17:48 2013 -0400
+++ b/libgui/src/workspace-model.h	Tue Apr 09 03:26:11 2013 -0400
@@ -24,92 +24,13 @@
 #if !defined (workspace_model_h)
 #define workspace_model_h 1
 
-#include <QAbstractItemModel>
+#include <QAbstractTableModel>
 #include <QVector>
 #include <QSemaphore>
 #include <QStringList>
 
-class tree_item
-{
-public:
-  tree_item (const QList<QVariant> &d, tree_item *p = 0) {
-    _parent_item = p;
-    _item_data = d;
-  }
-
-  tree_item (QVariant d = QVariant(), tree_item *p = 0) {
-    QList<QVariant> variantList;
-    variantList << d << QVariant () << QVariant () << QVariant ();
-    _parent_item = p;
-    _item_data = variantList;
-  }
-
-  ~tree_item () {
-    qDeleteAll (_child_items);
-  }
-
-  void insert_child_item (int at, tree_item *item) {
-    item->_parent_item = this;
-    _child_items.insert (at, item);
-  }
-
-  void add_child (tree_item *item) {
-    item->_parent_item = this;
-    _child_items.append (item);
-  }
-
-  void delete_child_items () {
-    qDeleteAll (_child_items);
-    _child_items.clear ();
-  }
-
-  void remove_child (tree_item *item) {
-    _child_items.removeAll (item);
-  }
-
-  QVariant data (int column) const
-  {
-    return _item_data[column];
-  }
-
-  void set_data (int column, QVariant d)
-  {
-    _item_data[column] = d;
-  }
-
-  tree_item *child (int r) {
-    return _child_items[r];
-  }
-
-  int child_count () const {
-    return _child_items.count();
-  }
-
-  int column_count () const
-  {
-    return _item_data.count();
-  }
-
-  int row () const {
-    if (_parent_item)
-      return _parent_item->_child_items.indexOf (const_cast<tree_item*>(this));
-
-    return 0;
-  }
-
-  tree_item *parent ()
-  {
-    return _parent_item;
-  }
-
-private:
-  QList<tree_item*> _child_items;
-  QList<QVariant> _item_data;
-  tree_item *_parent_item;
-};
-
 class workspace_model
-  : public QAbstractItemModel
+  : public QAbstractTableModel
 {
   Q_OBJECT
 
@@ -126,19 +47,10 @@
   QVariant headerData (int section, Qt::Orientation orientation,
                        int role = Qt::DisplayRole) const;
 
-  QModelIndex index (int row, int column,
-                     const QModelIndex &parent = QModelIndex ()) const;
-
-  QModelIndex parent (const QModelIndex &index) const;
-
   int rowCount (const QModelIndex &parent = QModelIndex ()) const;
 
   int columnCount (const QModelIndex &parent = QModelIndex ()) const;
 
-  void insert_top_level_item (int at, tree_item *treeItem);
-
-  tree_item *top_level_item (int at);
-
 public slots:
 
   void set_workspace (const QString& scopes,
@@ -156,14 +68,7 @@
 private:
 
   void clear_data (void);
-
-  void clear_tree (void);
-
-  void update_tree (void);
-
-  void append_tree (QChar scope, const QString& symbol,
-                    const QString& class_name, const QString& dimension,
-                    const QString& value);
+  void update_table (void);
 
   QString _scopes;
   QStringList _symbols;
@@ -171,7 +76,7 @@
   QStringList _dimensions;
   QStringList _values;
 
-  tree_item *_rootItem;
+  QStringList _columnNames;
 };
 
 #endif // WORKSPACEMODEL_H
--- a/libgui/src/workspace-view.cc	Tue Apr 09 03:17:48 2013 -0400
+++ b/libgui/src/workspace-view.cc	Tue Apr 09 03:26:11 2013 -0400
@@ -41,12 +41,8 @@
   setWindowTitle (tr ("Workspace"));
   setStatusTip (tr ("View the variables in the active workspace."));
 
-  view = new QTreeView (this);
+  view = new QTableView (this);
 
-  view->setHeaderHidden (false);
-  view->setAlternatingRowColors (true);
-  view->setAnimated (false);
-  view->setTextElideMode (Qt::ElideRight);
   view->setWordWrap (false);
   view->setContextMenuPolicy (Qt::CustomContextMenu);
 
@@ -67,25 +63,11 @@
 
   // FIXME -- what should happen if settings is 0?
 
-  _explicit_collapse.local
-    = settings->value ("workspaceview/local_collapsed", false).toBool ();
-
-  _explicit_collapse.global
-    = settings->value ("workspaceview/global_collapsed", false).toBool ();
-
-  _explicit_collapse.persistent
-    = settings->value ("workspaceview/persistent_collapsed", false).toBool ();
-
   // Initialize column order and width of the workspace
   
-  view->header ()->restoreState (settings->value ("workspaceview/column_state").toByteArray ());
+  view->horizontalHeader ()->restoreState (settings->value ("workspaceview/column_state").toByteArray ());
 
   // Connect signals and slots.
-  connect (view, SIGNAL (collapsed (QModelIndex)),
-           this, SLOT (collapse_requested (QModelIndex)));
-
-  connect (view, SIGNAL (expanded (QModelIndex)),
-           this, SLOT (expand_requested (QModelIndex)));
 
   connect (view, SIGNAL (doubleClicked (QModelIndex)),
            this, SLOT (item_double_clicked (QModelIndex)));
@@ -101,121 +83,13 @@
 {
   QSettings *settings = resource_manager::get_settings ();
 
-  settings->setValue ("workspaceview/local_collapsed",
-                      _explicit_collapse.local);
-
-  settings->setValue ("workspaceview/global_collapsed",
-                      _explicit_collapse.global);
-
-  settings->setValue ("workspaceview/persistent_collapsed",
-                      _explicit_collapse.persistent);
-
   settings->setValue("workspaceview/column_state",
-                     view->header ()->saveState ());
+                     view->horizontalHeader ()->saveState ());
 
   settings->sync ();
 }
 
 void
-workspace_view::model_changed ()
-{
-  QAbstractItemModel *m = view->model ();
-
-  // 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 = m->index (0, 0);
-  QModelIndex global_model_index = m->index (1, 0);
-  QModelIndex persistent_model_index = m->index (2, 0);
-
-  if (_explicit_collapse.local)
-    view->collapse (local_model_index);
-  else
-    view->expand (local_model_index);
-
-  if (_explicit_collapse.global)
-    view->collapse (global_model_index);
-  else
-    view->expand (global_model_index);
-
-  if (_explicit_collapse.persistent)
-    view->collapse (persistent_model_index);
-  else
-    view->expand (persistent_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.
-  QAbstractItemModel *m = view->model ();
-
-  QMap<int, QVariant> item_data = m->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;
-}
-
-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.
-  QAbstractItemModel *m = view->model ();
-
-  QMap<int, QVariant> item_data = m->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;
-}
-
-void
 workspace_view::item_double_clicked (QModelIndex)
 {
   // TODO: Implement opening a dialog that allows the user to change a
@@ -238,8 +112,10 @@
   QAbstractItemModel *m = view->model ();
 
   // if it isnt Local, Glocal etc, allow the ctx menu
-  if (index.parent() != QModelIndex())
+  if (index.isValid())
     {
+      index = index.sibling(index.row(), 0);
+
       QMap<int, QVariant> item_data = m->itemData (index);
   
       QString var_name = item_data[0].toString ();
@@ -280,8 +156,10 @@
 {
   QModelIndex index = view->currentIndex ();
 
-  if (index.parent () != QModelIndex ())
+  if (index.isValid ())
     {
+      index = index.sibling(index.row(), 0);
+
       QAbstractItemModel *m = view->model ();
 
       QMap<int, QVariant> item_data = m->itemData (index);
--- a/libgui/src/workspace-view.h	Tue Apr 09 03:17:48 2013 -0400
+++ b/libgui/src/workspace-view.h	Tue Apr 09 03:26:11 2013 -0400
@@ -24,7 +24,7 @@
 #if !defined (workspace_view_h)
 #define workspace_view_h 1
 
-#include <QTreeView>
+#include <QTableView>
 #include <QSemaphore>
 
 #include "octave-dock-widget.h"
@@ -44,9 +44,6 @@
 
   void setModel (workspace_model *model) { view->setModel (model); }
 
-public slots:
-
-  void model_changed (void);
 
 signals:
 
@@ -59,8 +56,6 @@
 
 protected slots:
 
-  void collapse_requested (QModelIndex index);
-  void expand_requested (QModelIndex index);
   void item_double_clicked (QModelIndex index);
   void contextmenu_requested (const QPoint& pos);
 
@@ -73,14 +68,7 @@
 
   void relay_contextmenu_command (const QString& cmdname);
 
-  QTreeView *view;
-
-  struct
-  {
-    bool local;
-    bool global;
-    bool persistent;
-  } _explicit_collapse;
+  QTableView * view;
 };
 
 #endif