changeset 16468:0f143f68078d

use signal/slot for updating workspace instead of using event listener * main-window.h, main-window.cc: Clean up list of include files. (main_window::prepare_to_exit): Rename from prepare_to_quit. Change all uses. (main_window::update_workspace): Delete. (main_window::construct): Don't connect _octave_qt_event_listener:update_workspace_signal to main_window::update_workspace. (main_window::construct_octave_qt_link): Connect _octave_qt_link::set_workspace_signal to _workspace_model::set_workspace. Connect _octave_qt_link::clear_workspace_signal to _workspace_model::clear_workspace. * symbol-information.h, symbol-information.cc: Delete * libgui/src/module.mk (noinst_HEADERS, src_libgui_src_la_SOURCES): Remove them from the lists. * octave-qt-link.h, octave-qt-link.cc: Don't use symbol_information to store workspace info. (octave_qt_link::do_update_workspace): Delete. (octave_qt_link::do_set_workspace, octave_qt_link::do_clear_workspace): New functions. (octave_qt_link::do_pre_input_event): Don't call do_update_workspace. (octave_qt_link::set_workspace_signal, octave_qt_link::clear_workspace_signal): New signals. * workspace-model.h, workspace-model.cc: Don't use symbol_information to store workspace info. Accept workspace info through a signal/slot combination, not by asking the symbol table. (workspace_model::request_update_workspace, (workspace_model::update_workspace_callback): Delete. (workspace_model::set_workspace, workspace_model::clear_workspace, workspace_model::clear_data, workspace_model::clear_tree, workspace_model::update_tree, workspace_model::append_tree): New functions. * workspace-view.h, workspace-view.cc (workspace_view::model_changed): Don't call update_workspace_callback. The model now signals the view when it has changed. * input.cc (octave_base_reader::octave_gets, get_debug_input): Call octave_link::set_workspace just prior to prompting for input. * workspace-element.h: New file. * libinterp/interpfcn/module.mk (INTERPFCN_INC): Include it in the list. * octave-link.cc: Don't include symtab.h. * octave-link.h (octave_link::update_workspace): Delete. (octave_link::set_workspace, octave_link::do_set_workspace, * octave_link::clear_workspace, octave_link::do_clear_workspace): New functions. * symtab.h, symtab.cc (symbol_table::workspace_info, symbol_table::do_workspace_info): New functions. * ov.h (octave_value::short_disp): New function. * ov-base.h, ov-base.cc (octave_base_value::short_disp): New function. * ov-base-scalar.h, ov-base-scalar.cc (octave_base_scalar<ST>::short_disp): New function. * ov-range.h, ov-range.cc (octave_range::short_disp): New function.
author John W. Eaton <jwe@octave.org>
date Mon, 08 Apr 2013 12:01:24 -0400
parents cc9e2751e073
children c89699ca005a
files libgui/src/main-window.cc libgui/src/main-window.h libgui/src/module.mk libgui/src/octave-qt-link.cc libgui/src/octave-qt-link.h libgui/src/symbol-information.cc libgui/src/symbol-information.h libgui/src/workspace-model.cc libgui/src/workspace-model.h libgui/src/workspace-view.cc libinterp/interpfcn/input.cc libinterp/interpfcn/module.mk libinterp/interpfcn/octave-link.cc libinterp/interpfcn/octave-link.h libinterp/interpfcn/symtab.cc libinterp/interpfcn/symtab.h libinterp/octave-value/ov-base-scalar.cc libinterp/octave-value/ov-base-scalar.h libinterp/octave-value/ov-base.h libinterp/octave-value/ov-range.cc libinterp/octave-value/ov-range.h libinterp/octave-value/ov.h
diffstat 22 files changed, 280 insertions(+), 323 deletions(-) [+]
line wrap: on
line diff
--- a/libgui/src/main-window.cc	Sat Apr 06 18:08:08 2013 +0100
+++ b/libgui/src/main-window.cc	Mon Apr 08 12:01:24 2013 -0400
@@ -45,16 +45,12 @@
 #include "main-window.h"
 #include "settings-dialog.h"
 
-#include "builtins.h"
+#include "cmd-edit.h"
+
+#include "builtin-defun-decls.h"
 #include "defaults.h"
-#include "load-save.h"
-#include "toplev.h"
 #include "version.h"
 
-#include "cmd-edit.h"
-#include "cmd-hist.h"
-#include "oct-env.h"
-
 static file_editor_interface *
 create_default_editor (QWidget *p)
 {
@@ -264,7 +260,7 @@
 
 
 void
-main_window::prepare_for_quit (void)
+main_window::prepare_to_exit (void)
 {
   write_settings ();
 }
@@ -276,12 +272,6 @@
 }
 
 void
-main_window::update_workspace (void)
-{
-  workspace_window->model_changed ();
-}
-
-void
 main_window::change_directory (const QString& dir)
 {
   // Remove existing entry, if any, then add new directory at top and
@@ -553,7 +543,7 @@
   construct_tool_bar ();
 
   connect (qApp, SIGNAL (aboutToQuit ()),
-           this, SLOT (prepare_for_quit ()));
+           this, SLOT (prepare_to_exit ()));
 
   connect (this, SIGNAL (settings_changed (const QSettings *)),
            this, SLOT (notice_settings (const QSettings *)));
@@ -592,9 +582,6 @@
 
   _octave_qt_event_listener = new octave_qt_event_listener ();
 
-  connect (_octave_qt_event_listener, SIGNAL (update_workspace_signal ()),
-           this, SLOT (update_workspace ()));
-
   // FIXME -- is it possible to eliminate the event_listenter?
 
   construct_octave_qt_link ();
@@ -608,6 +595,18 @@
 {
   _octave_qt_link = new octave_qt_link ();
 
+  connect (_octave_qt_link,
+           SIGNAL (set_workspace_signal
+                   (const QString&, const QStringList&, const QStringList&,
+                    const QStringList&, const QStringList&)),
+           _workspace_model,
+           SLOT (set_workspace
+                 (const QString&, const QStringList&,const QStringList&,
+                  const QStringList&, const QStringList&)));
+
+  connect (_octave_qt_link, SIGNAL (clear_workspace_signal ()),
+           _workspace_model, SLOT (clear_workspace ()));
+
   connect (_octave_qt_link, SIGNAL (change_directory_signal (QString)),
            this, SLOT (change_directory (QString)));
 
--- a/libgui/src/main-window.h	Sat Apr 06 18:08:08 2013 +0100
+++ b/libgui/src/main-window.h	Mon Apr 08 12:01:24 2013 -0400
@@ -92,9 +92,8 @@
   void process_settings_dialog_request (void);
   void show_about_octave (void);
   void notice_settings (const QSettings *settings);
-  void prepare_for_quit (void);
+  void prepare_to_exit (void);
   void reset_windows (void);
-  void update_workspace (void);
 
   void change_directory (const QString& dir);
   void browse_for_directory (void);
--- a/libgui/src/module.mk	Sat Apr 06 18:08:08 2013 +0100
+++ b/libgui/src/module.mk	Mon Apr 08 12:01:24 2013 -0400
@@ -113,7 +113,6 @@
   src/qtinfo/webinfo.h \
   src/resource-manager.h \
   src/settings-dialog.h \
-  src/symbol-information.h \
   src/terminal-dock-widget.h \
   src/color-picker.h \
   src/welcome-wizard.h \
@@ -137,7 +136,6 @@
   src/qtinfo/webinfo.cc \
   src/resource-manager.cc \
   src/settings-dialog.cc \
-  src/symbol-information.cc \
   src/terminal-dock-widget.cc \
   src/color-picker.cc \
   src/welcome-wizard.cc \
--- a/libgui/src/octave-qt-link.cc	Sat Apr 06 18:08:08 2013 +0100
+++ b/libgui/src/octave-qt-link.cc	Mon Apr 08 12:01:24 2013 -0400
@@ -30,6 +30,8 @@
 
 #include "str-vec.h"
 
+#include "workspace-element.h"
+
 #include "octave-qt-link.h"
 
 octave_qt_link::octave_qt_link (void)
@@ -58,14 +60,31 @@
 }
 
 void
-octave_qt_link::do_update_workspace (void)
+octave_qt_link::do_set_workspace (const std::list<workspace_element>& ws)
 {
-  if (event_listener)
+  QString scopes;
+  QStringList symbols;
+  QStringList class_names;
+  QStringList dimensions;
+  QStringList values;
+
+  for (std::list<workspace_element>::const_iterator it = ws.begin ();
+       it != ws.end (); it++)
     {
-      event_listener->update_workspace ();
+      scopes.append (it->scope ());
+      symbols.append (QString::fromStdString (it->symbol ()));
+      class_names.append (QString::fromStdString (it->class_name ()));
+      dimensions.append (QString::fromStdString (it->dimension ()));
+      values.append (QString::fromStdString (it->value ()));
+    }
 
-      do_process_events ();
-    }
+  emit set_workspace_signal (scopes, symbols, class_names, dimensions, values);
+}
+
+void
+octave_qt_link::do_clear_workspace (void)
+{
+  emit clear_workspace_signal ();
 }
 
 void
@@ -94,7 +113,6 @@
 void
 octave_qt_link::do_pre_input_event (void)
 {
-  do_update_workspace ();
 }
 
 void
--- a/libgui/src/octave-qt-link.h	Sat Apr 06 18:08:08 2013 +0100
+++ b/libgui/src/octave-qt-link.h	Mon Apr 08 12:01:24 2013 -0400
@@ -25,8 +25,10 @@
 #ifndef OCTAVE_QT_LINK_H
 #define OCTAVE_QT_LINK_H
 
+#include <list>
 #include <string>
 
+#include <QList>
 #include <QObject>
 #include <QString>
 
@@ -57,7 +59,8 @@
 
   void do_change_directory (const std::string& dir);
 
-  void do_update_workspace (void);
+  void do_set_workspace (const std::list<workspace_element>& ws);
+  void do_clear_workspace (void);
 
   void do_set_history (const string_vector& hist);
   void do_append_history (const std::string& hist_entry);
@@ -92,6 +95,14 @@
 
   void change_directory_signal (const QString& dir);
 
+  void set_workspace_signal (const QString& scopes,
+                             const QStringList& symbols,
+                             const QStringList& class_names,
+                             const QStringList& dimensions,
+                             const QStringList& values);
+
+  void clear_workspace_signal (void);
+
   void set_history_signal (const QStringList& hist);
   void append_history_signal (const QString& hist_entry);
   void clear_history_signal (void);
--- a/libgui/src/symbol-information.cc	Sat Apr 06 18:08:08 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,113 +0,0 @@
-/*
-
-Copyright (C) 2011-2012 Jacob Dawid
-
-This file is part of Octave.
-
-Octave is free software; you can redistribute it and/or modify it
-under the terms of the GNU General Public License as published by the
-Free Software Foundation; either version 3 of the License, or (at your
-option) any later version.
-
-Octave is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-for more details.
-
-You should have received a copy of the GNU General Public License
-along with Octave; see the file COPYING.  If not, see
-<http://www.gnu.org/licenses/>.
-
-*/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <QString>
-
-#include "ov.h"
-#include "symtab.h"
-
-#include "symbol-information.h"
-
-symbol_information::symbol_information (const symbol_table::symbol_record& sr)
-{
-  if (sr.is_local () && !sr.is_global () && !sr.is_hidden ())
-    _scope = local;
-  else if (sr.is_global ())
-    _scope = global;
-  else if (sr.is_persistent ())
-    _scope = persistent;
-  else
-    _scope = unknown;
-
-  _symbol = QString (sr.name ().c_str ());
-  _class_name = QString (sr.varval ().class_name ().c_str ());
-  octave_value ov = sr.varval ();
-  dim_vector dv = ov.dims ();
-
-  // In case we have really large matrices or strings, cut them down
-  // for performance reasons.
-  QString short_value_string;
-  bool use_short_value_string = false;
-
-  if (ov.is_range ())
-    {
-      use_short_value_string = true;
-
-      Range r = ov.range_value ();
-
-      double base = r.base ();
-      double increment = r.inc ();
-      double limit = r.limit ();
-
-      std::stringstream buffer;
-
-      buffer << base << ":";
-      if (increment != 1 )
-        buffer << increment << ":";
-      buffer << limit;
-
-      short_value_string = QString::fromStdString (buffer.str ());
-    }
-  else if (ov.is_matrix_type () || ov.is_cell ())
-    {
-      if (ov.is_string ())  // a string?
-        {
-          if (ov.string_value ().length () > 30)
-            {
-              use_short_value_string = true;
-              short_value_string = QString ("\"")
-                  + QString::fromStdString (ov.string_value ().substr (0, 30))
-                  + QString (" ... \"");
-            }
-        }
-      else  // arrays and cell arrays
-        {
-          if (ov.numel () > 10)
-            {
-              use_short_value_string = true;
-              short_value_string = QString("...");
-              // TODO: what kind of short version can be printed for arrays?
-            }
-        }
-    }
-
-  if (use_short_value_string)
-    {
-      _value = short_value_string;
-    }
-  else
-    {
-      std::stringstream buffer;
-      ov.print (buffer, true);
-      _value  = QString::fromStdString (buffer.str ());
-    }
-  _value.replace("\n", " ");
-
-  _dimension = QString::fromStdString (dv.str ());
-
-  _hash = _scope + qHash (_symbol) + qHash (_class_name) + qHash (_value)
-    + qHash (_dimension);
-}
--- a/libgui/src/symbol-information.h	Sat Apr 06 18:08:08 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,118 +0,0 @@
-/*
-
-Copyright (C) 2011-2012 Jacob Dawid
-
-This file is part of Octave.
-
-Octave is free software; you can redistribute it and/or modify it
-under the terms of the GNU General Public License as published by the
-Free Software Foundation; either version 3 of the License, or (at your
-option) any later version.
-
-Octave is distributed in the hope that it will be useful, but WITHOUT
-ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-for more details.
-
-You should have received a copy of the GNU General Public License
-along with Octave; see the file COPYING.  If not, see
-<http://www.gnu.org/licenses/>.
-
-*/
-
-#ifndef SYMBOLINFORMATION_H
-#define SYMBOLINFORMATION_H
-
-// FIXME -- we should not be including config.h in header files.
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <QString>
-#include <QHash>
-
-#include "symtab.h"
-
-/**
- * \struct symbol_information
- * \brief Meta-information over a symbol-table entry.
- * \author Jacob Dawid
- * This struct is used to store meta information over a symbol entry.
- * It reduces memory consumption, since it only stores relevant data
- * about a symbol-table entry that will be used in the model for the
- * graphical user interface.
- */
-class symbol_information
-{
-public:
-
-  enum Scope
-    {
-      unknown     = 0,
-      local       = 1,
-      global      = 2,
-      persistent  = 3
-    };
-
-  symbol_information (const symbol_table::symbol_record& symbol_record);
-
-  symbol_information (const symbol_information& x)
-    : _scope (x._scope), _symbol (x._symbol), _class_name (x._class_name),
-      _value (x._value), _dimension (x._dimension), _hash (x._hash)
-  { }
-
-  symbol_information operator = (const symbol_information& x)
-  {
-    if (this != &x)
-      {
-        _scope = x._scope;
-        _symbol = x._symbol;
-        _class_name = x._class_name;
-        _value = x._value;
-        _dimension = x._dimension;
-        _hash = x._hash;
-      }
-
-    return *this;
-  }
-
-  ~symbol_information (void) { }
-
-  QString symbol (void) const { return _symbol; }
-  QString class_name (void) const { return _class_name; }
-  QString value (void) const
-    {
-      return QString::fromUtf8 (_value.toStdString ().data (),
-                                _value.toStdString ().size ());
-    }
-  QString dimension (void) const { return _dimension; }
-  Scope scope (void) const { return _scope; }
-
-  friend bool
-  operator == (const symbol_information& a, const symbol_information& b)
-  {
-    return (a.hash () == b.hash ()
-            && a.scope () == b.scope ()
-            && a.symbol () == b.symbol ()
-            && a.class_name () == b.class_name ()
-            && a.value () == b.value ()
-            && a.dimension () == b.dimension ());
-  }
-
-private:
-
-  // FIXME -- this is not really the scope of the symbol.
-  Scope _scope;
-
-  QString _symbol;
-  QString _class_name;
-  QString _value;
-  QString _dimension;
-
-  int _hash;
-
-  int hash (void) const { return _hash; }
-};
-
-#endif // SYMBOLINFORMATION_H
--- a/libgui/src/workspace-model.cc	Sat Apr 06 18:08:08 2013 +0100
+++ b/libgui/src/workspace-model.cc	Mon Apr 08 12:01:24 2013 -0400
@@ -1,6 +1,7 @@
 
 /*
 
+Copyright (C) 2013 John W. Eaton
 Copyright (C) 2011-2012 Jacob Dawid
 
 This file is part of Octave.
@@ -28,8 +29,6 @@
 #include <QTreeWidget>
 #include <QTime>
 
-#include <list>
-
 #include "symtab.h"
 #include "variables.h"
 
@@ -53,12 +52,6 @@
   delete _rootItem;
 }
 
-void
-workspace_model::request_update_workspace ()
-{
-  octave_link::post_event (this, &workspace_model::update_workspace_callback);
-}
-
 QModelIndex
 workspace_model::index(int row, int column, const QModelIndex &p) const
 {
@@ -169,47 +162,84 @@
 }
 
 void
-workspace_model::update_workspace_callback (void)
+workspace_model::set_workspace (const QString& scopes,
+                                const QStringList& symbols,
+                                const QStringList& class_names,
+                                const QStringList& dimensions,
+                                const QStringList& values)
 {
-  std::list < symbol_table::symbol_record > symbolTable = symbol_table::all_variables ();
+  _scopes = scopes;
+  _symbols = symbols;
+  _class_names = class_names;
+  _dimensions = dimensions;
+  _values = values;
 
-  _symbol_information.clear ();
-  for (std::list < symbol_table::symbol_record > ::iterator iterator = symbolTable.begin ();
-       iterator != symbolTable.end (); iterator++)
-    _symbol_information.push_back (symbol_information (*iterator));
+  update_tree ();
+
+  emit model_changed ();
+}
 
-  beginResetModel();
-  top_level_item (0)->delete_child_items ();
-  top_level_item (1)->delete_child_items ();
-  top_level_item (2)->delete_child_items ();
+void
+workspace_model::clear_workspace (void)
+{
+  clear_data ();
+
+  update_tree ();
+
+  emit model_changed ();
+}
 
-  foreach (const symbol_information& s, _symbol_information)
-    {
-      tree_item *child = new tree_item ();
+void
+workspace_model::clear_data (void)
+{
+  _scopes = QString ();
+  _symbols = QStringList ();
+  _class_names = QStringList ();
+  _dimensions = QStringList ();
+  _values = QStringList ();
+}
 
-      child->set_data (0, s.symbol ());
-      child->set_data (1, s.class_name ());
-      child->set_data (2, s.dimension ());
-      child->set_data (3, s.value ());
+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 ();
+}
 
-      switch (s.scope ())
-        {
-        case symbol_information::local:
-          top_level_item (0)->add_child (child);
-          break;
+void
+workspace_model::update_tree (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]);
+
+  endResetModel ();
 
-        case symbol_information::global:
-          top_level_item (1)->add_child (child);
-          break;
+  emit model_changed ();
+}
 
-        case symbol_information::persistent:
-          top_level_item (2)->add_child (child);
-          break;
+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 ();
 
-        default:
-          break;
-        }
-    }
+  child->set_data (0, symbol);
+  child->set_data (1, class_name);
+  child->set_data (2, dimension);
+  child->set_data (3, value);
 
-  endResetModel();
+  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	Sat Apr 06 18:08:08 2013 +0100
+++ b/libgui/src/workspace-model.h	Mon Apr 08 12:01:24 2013 -0400
@@ -1,5 +1,6 @@
 /*
 
+Copyright (C) 2013 John W. Eaton
 Copyright (C) 2011-2012 Jacob Dawid
 
 This file is part of Octave.
@@ -20,15 +21,13 @@
 
 */
 
-#ifndef WORKSPACEMODEL_H
-#define WORKSPACEMODEL_H
+#if !defined (workspace_model_h)
+#define workspace_model_h 1
 
-// Qt includes
 #include <QAbstractItemModel>
 #include <QVector>
 #include <QSemaphore>
-
-#include "symbol-information.h"
+#include <QStringList>
 
 class tree_item
 {
@@ -114,35 +113,64 @@
 {
   Q_OBJECT
 
-  public:
+public:
+
   workspace_model (QObject *parent = 0);
-  ~workspace_model ();
+
+  ~workspace_model (void);
 
   QVariant data (const QModelIndex &index, int role) const;
+
   Qt::ItemFlags flags (const QModelIndex &index) const;
+
   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);
 
-  void update_workspace_callback (void);
-
 public slots:
-  void request_update_workspace ();
+
+  void set_workspace (const QString& scopes,
+                      const QStringList& symbols,
+                      const QStringList& class_names,
+                      const QStringList& dimensions,
+                      const QStringList& values);
+
+  void clear_workspace (void);
 
 signals:
-  void model_changed ();
+
+  void model_changed (void);
 
 private:
 
-  /** Stores the current symbol information. */
-  QList <symbol_information> _symbol_information;
+  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);
+
+  QString _scopes;
+  QStringList _symbols;
+  QStringList _class_names;
+  QStringList _dimensions;
+  QStringList _values;
+
   tree_item *_rootItem;
 };
 
--- a/libgui/src/workspace-view.cc	Sat Apr 06 18:08:08 2013 +0100
+++ b/libgui/src/workspace-view.cc	Mon Apr 08 12:01:24 2013 -0400
@@ -121,8 +121,6 @@
 {
   QAbstractItemModel *m = view->model ();
 
-  dynamic_cast<workspace_model *> (m)->update_workspace_callback ();
-
   // 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
--- a/libinterp/interpfcn/input.cc	Sat Apr 06 18:08:08 2013 +0100
+++ b/libinterp/interpfcn/input.cc	Mon Apr 08 12:01:24 2013 -0400
@@ -67,6 +67,7 @@
 #include "pt-eval.h"
 #include "pt-stmt.h"
 #include "sighandlers.h"
+#include "symtab.h"
 #include "sysdep.h"
 #include "toplev.h"
 #include "unwind-prot.h"
@@ -217,6 +218,8 @@
         octave_link::exit_debugger_event ();
 
       octave_link::pre_input_event ();
+
+      octave_link::set_workspace (symbol_table::workspace_info ());
     }
 
   bool history_skip_auto_repeated_debugging_command = false;
@@ -519,6 +522,8 @@
             {
               octave_link::enter_debugger_event (nm, curr_debug_line);
 
+              octave_link::set_workspace (symbol_table::workspace_info ());
+
               frame.add_fcn (execute_in_debugger_handler,
                              std::pair<std::string, int> (nm, curr_debug_line));
 
--- a/libinterp/interpfcn/module.mk	Sat Apr 06 18:08:08 2013 +0100
+++ b/libinterp/interpfcn/module.mk	Mon Apr 08 12:01:24 2013 -0400
@@ -26,7 +26,8 @@
   interpfcn/sysdep.h \
   interpfcn/toplev.h \
   interpfcn/utils.h \
-  interpfcn/variables.h
+  interpfcn/variables.h \
+  interpfcn/workspace-element.h
 
 INTERPFCN_SRC = \
   interpfcn/data.cc \
--- a/libinterp/interpfcn/octave-link.cc	Sat Apr 06 18:08:08 2013 +0100
+++ b/libinterp/interpfcn/octave-link.cc	Mon Apr 08 12:01:24 2013 -0400
@@ -31,7 +31,6 @@
 #include "oct-env.h"
 #include "oct-mutex.h"
 #include "singleton-cleanup.h"
-#include "symtab.h"
 #include "toplev.h"
 
 #include "octave-link.h"
--- a/libinterp/interpfcn/octave-link.h	Sat Apr 06 18:08:08 2013 +0100
+++ b/libinterp/interpfcn/octave-link.h	Mon Apr 08 12:01:24 2013 -0400
@@ -32,6 +32,7 @@
 
 class octave_mutex;
 class string_vector;
+class workspace_element;
 
 // \class OctaveLink
 // \brief Provides threadsafe access to octave.
@@ -120,10 +121,16 @@
       instance->do_change_directory (dir);
   }
 
-  static void update_workspace (void)
+  static void set_workspace (const std::list<workspace_element>& ws)
   {
     if (instance_ok ())
-      instance->do_update_workspace ();
+      instance->do_set_workspace (ws);
+  }
+
+  static void clear_workspace (void)
+  {
+    if (instance_ok ())
+      instance->do_clear_workspace ();
   }
 
   static void set_history (const string_vector& hist)
@@ -249,7 +256,10 @@
 
   virtual void do_change_directory (const std::string& dir) = 0;
 
-  virtual void do_update_workspace (void) = 0;
+  virtual void
+  do_set_workspace (const std::list<workspace_element>& ws) = 0;
+
+  virtual void do_clear_workspace (void) = 0;
 
   virtual void do_set_history (const string_vector& hist) = 0;
   virtual void do_append_history (const std::string& hist_entry) = 0;
@@ -258,8 +268,12 @@
   virtual void do_pre_input_event (void) = 0;
   virtual void do_post_input_event (void) = 0;
 
-  virtual void do_enter_debugger_event (const std::string& file, int line) = 0;
-  virtual void do_execute_in_debugger_event (const std::string& file, int line) = 0;
+  virtual void
+  do_enter_debugger_event (const std::string& file, int line) = 0;
+
+  virtual void
+  do_execute_in_debugger_event (const std::string& file, int line) = 0;
+
   virtual void do_exit_debugger_event (void) = 0;
 
   virtual void do_update_breakpoint (bool insert,
--- a/libinterp/interpfcn/symtab.cc	Sat Apr 06 18:08:08 2013 +0100
+++ b/libinterp/interpfcn/symtab.cc	Mon Apr 08 12:01:24 2013 -0400
@@ -1380,6 +1380,41 @@
   return retval;
 }
 
+std::list<workspace_element>
+symbol_table::do_workspace_info (void) const
+{
+  std::list<workspace_element> retval;
+
+  for (table_const_iterator p = table.begin (); p != table.end (); p++)
+    {
+      std::string nm = p->first;
+      symbol_record sr = p->second;
+
+      if (! sr.is_hidden ())
+        {
+          octave_value val = sr.varval ();
+
+          if (val.is_defined ())
+            {
+              dim_vector dv = val.dims ();
+
+              char storage = ' ';
+              if (sr.is_global ())
+                storage = 'g';
+              else if (sr.is_persistent ())
+                storage = 'p';
+
+              workspace_element elt (storage, nm, val.class_name (),
+                                     val.short_disp (), dv.str ());
+
+              retval.push_back (elt);
+            }
+        }
+    }
+
+  return retval;
+}
+
 void
 symbol_table::do_dump (std::ostream& os)
 {
--- a/libinterp/interpfcn/symtab.h	Sat Apr 06 18:08:08 2013 +0100
+++ b/libinterp/interpfcn/symtab.h	Mon Apr 08 12:01:24 2013 -0400
@@ -37,6 +37,7 @@
 class octave_user_function;
 
 #include "oct-obj.h"
+#include "workspace-element.h"
 #include "oct-refcount.h"
 #include "ov.h"
 
@@ -2126,6 +2127,14 @@
       }
   }
 
+  static std::list<workspace_element> workspace_info (void)
+  {
+    symbol_table *inst = get_instance (xcurrent_scope);
+
+    return inst
+      ? inst->do_workspace_info () : std::list<workspace_element> ();
+  }
+
   static void dump (std::ostream& os, scope_id scope = xcurrent_scope);
 
   static void dump_global (std::ostream& os);
@@ -2795,6 +2804,8 @@
     return p != table.end () && p->second.is_global ();
   }
 
+  std::list<workspace_element> do_workspace_info (void) const;
+
   void do_dump (std::ostream& os);
 
   void do_cache_name (const std::string& name) { table_name = name; }
--- a/libinterp/octave-value/ov-base-scalar.cc	Sat Apr 06 18:08:08 2013 +0100
+++ b/libinterp/octave-value/ov-base-scalar.cc	Mon Apr 08 12:01:24 2013 -0400
@@ -169,6 +169,15 @@
 }
 
 template <class ST>
+std::string
+octave_base_scalar<ST>::short_disp (void) const
+{
+  std::ostringstream buf;
+  octave_print_internal (buf, scalar);
+  return buf.str ();
+}
+
+template <class ST>
 bool
 octave_base_scalar<ST>::fast_elem_insert_self (void *where, builtin_type_t btyp) const
 {
--- a/libinterp/octave-value/ov-base-scalar.h	Sat Apr 06 18:08:08 2013 +0100
+++ b/libinterp/octave-value/ov-base-scalar.h	Mon Apr 08 12:01:24 2013 -0400
@@ -138,6 +138,8 @@
 
   bool print_name_tag (std::ostream& os, const std::string& name) const;
 
+  std::string short_disp (void) const;
+
   // Unsafe.  This function exists to support the MEX interface.
   // You should not use it anywhere else.
   void *mex_get_data (void) const { return const_cast<ST *> (&scalar); }
--- a/libinterp/octave-value/ov-base.h	Sat Apr 06 18:08:08 2013 +0100
+++ b/libinterp/octave-value/ov-base.h	Mon Apr 08 12:01:24 2013 -0400
@@ -616,6 +616,8 @@
   print_with_name (std::ostream& output_buf, const std::string& name,
                    bool print_padding = true);
 
+  virtual std::string short_disp (void) const { return "..."; }
+
   virtual void print_info (std::ostream& os, const std::string& prefix) const;
 
   virtual bool save_ascii (std::ostream& os);
--- a/libinterp/octave-value/ov-range.cc	Sat Apr 06 18:08:08 2013 +0100
+++ b/libinterp/octave-value/ov-range.cc	Mon Apr 08 12:01:24 2013 -0400
@@ -387,6 +387,31 @@
   return retval;
 }
 
+std::string
+octave_range::short_disp (void) const
+{
+  std::ostringstream buf;
+  
+  octave_idx_type len = range.nelem ();
+
+  if (len == 0)
+    buf << "[]";
+  else
+    {
+      buf << range.base () << ":";
+
+      if (len > 1)
+        {
+          if (range.inc () != 1)
+            buf << range.inc () << ":";
+
+          buf << range.limit ();
+        }
+    }
+
+  return buf.str ();
+}
+
 // Skip white space and comments on stream IS.
 
 static void
--- a/libinterp/octave-value/ov-range.h	Sat Apr 06 18:08:08 2013 +0100
+++ b/libinterp/octave-value/ov-range.h	Mon Apr 08 12:01:24 2013 -0400
@@ -255,6 +255,8 @@
 
   bool print_name_tag (std::ostream& os, const std::string& name) const;
 
+  std::string short_disp (void) const;
+
   bool save_ascii (std::ostream& os);
 
   bool load_ascii (std::istream& is);
--- a/libinterp/octave-value/ov.h	Sat Apr 06 18:08:08 2013 +0100
+++ b/libinterp/octave-value/ov.h	Mon Apr 08 12:01:24 2013 -0400
@@ -1022,6 +1022,8 @@
   void print_with_name (std::ostream& os, const std::string& name) const
   { rep->print_with_name (os, name, true); }
 
+  std::string short_disp (void) const { return rep->short_disp (); }
+
   int type_id (void) const { return rep->type_id (); }
 
   std::string type_name (void) const { return rep->type_name (); }