# HG changeset patch
# User Stefan Miereis <stefan.miereis@gmx.de>
# Date 1447353191 -3600
#      Thu Nov 12 19:33:11 2015 +0100
# Node ID 1f94d4eb08477b25fe840cf4447e4979150f3094
# Parent  6faaab833605973694a8ce545df8e84544a11456
Add more columns to the workspace table (Bug #46236)

* main-window.cc (construct_octave_qt_link): Add parameters for the additional columns, remove Attribute field

* octave-qt-link.cc (do_set_workspace): Add columns to workspace_element

* octave-qt-link.h (set_workspace_signal): Add parameters to signal

* settings-dialog.cc (settings_dialog): Initialize the dialog with the maximum array size for which we want to calculate statistics
* settings-dialog.cc (write_changed_settings): save the user-defined limit for the array size

* settings-dialog.ui: Add dialog option to change the maximum array size for which we compute statistics

* workspace-model.cc (workspace_model): Add column headings, remove heading "Attribute"
* workspace-model.cc (data): Fill the columns with values, move "Attribute" into "Class" field
* workspace-model.cc (set_workspace) Add columns to slot and initialize
* workspace-model.cc (clear_data) clear the added columns

* workspace-model.h (set_workspace) Add columns to slot
* workspace-model.h Add variables to store the added column values

* workspace-view.cc (notice_settings): Read max array size from settings, add column headers, remove Attribute column

* symtab.cc: include builtin-defun.decls.h to access functions mean, median, mode, var, std
* symtab.cc: Define variable "max_numel_for_statistics". It stores the maximum array size for which we calculate statistics
* symtab.cc (do_workspace_info): Calculate statistics for the new columns

* symtab.h: Declare variable "max_numel_for_statistics"
* symtab.h (set_max_numel_for_statistics): New function

* workspace-element.h: Add variables, remove Attribute parameter. Add functions to access the new variables

diff -r 6faaab833605 -r 1f94d4eb0847 libgui/src/main-window.cc
--- a/libgui/src/main-window.cc	Wed Nov 11 16:58:18 2015 -0800
+++ b/libgui/src/main-window.cc	Thu Nov 12 19:33:11 2015 +0100
@@ -1512,12 +1512,22 @@
                SIGNAL (set_workspace_signal
                        (bool, bool, const QString&, const QStringList&,
                         const QStringList&, const QStringList&,
-                        const QStringList&, const QIntList&)),
+                        const QStringList&, const QStringList&,
+                        const QStringList&, const QStringList&,
+                        const QStringList&, const QStringList&,
+                        const QStringList&, const QStringList&,
+                        const QStringList&, const QStringList&,
+                        const QIntList&)),
                _workspace_model,
                SLOT (set_workspace
                      (bool, bool, const QString&, const QStringList&,
                       const QStringList&, const QStringList&,
-                      const QStringList&, const QIntList&)));
+                      const QStringList&, const QStringList&,
+                      const QStringList&, const QStringList&,
+                      const QStringList&, const QStringList&,
+                      const QStringList&, const QStringList&,
+                      const QStringList&, const QStringList&,
+                      const QIntList&)));
 
       connect (_octave_qt_link, SIGNAL (clear_workspace_signal ()),
                _workspace_model, SLOT (clear_workspace ()));
diff -r 6faaab833605 -r 1f94d4eb0847 libgui/src/octave-qt-link.cc
--- a/libgui/src/octave-qt-link.cc	Wed Nov 11 16:58:18 2015 -0800
+++ b/libgui/src/octave-qt-link.cc	Thu Nov 12 19:33:11 2015 +0100
@@ -462,6 +462,15 @@
   QStringList class_names;
   QStringList dimensions;
   QStringList values;
+  QStringList bytes;
+  QStringList minvals;
+  QStringList maxvals;
+  QStringList ranges;
+  QStringList means;
+  QStringList medians;
+  QStringList modes;
+  QStringList variances;
+  QStringList stddeviations;
   QIntList complex_flags;
 
   for (std::list<workspace_element>::const_iterator it = ws.begin ();
@@ -472,11 +481,23 @@
       class_names.append (QString::fromStdString (it->class_name ()));
       dimensions.append (QString::fromStdString (it->dimension ()));
       values.append (QString::fromStdString (it->value ()));
+      bytes.append (QString::fromStdString (it->bytes ()));
+      minvals.append (QString::fromStdString (it->min ()));
+      maxvals.append (QString::fromStdString (it->max ()));
+      ranges.append (QString::fromStdString (it->range ()));
+      means.append (QString::fromStdString (it->mean ()));
+      medians.append (QString::fromStdString (it->median ()));
+      modes.append (QString::fromStdString (it->mode ()));
+      variances.append (QString::fromStdString (it->var ()));
+      stddeviations.append (QString::fromStdString (it->std ()));
       complex_flags.append (it->complex_flag ());
     }
 
   emit set_workspace_signal (top_level, debug, scopes, symbols, class_names,
-                             dimensions, values, complex_flags);
+                             dimensions, values, bytes, minvals, maxvals,
+                             ranges, means, medians, modes, variances,
+                             stddeviations, complex_flags);
+
 }
 
 void
diff -r 6faaab833605 -r 1f94d4eb0847 libgui/src/octave-qt-link.h
--- a/libgui/src/octave-qt-link.h	Wed Nov 11 16:58:18 2015 -0800
+++ b/libgui/src/octave-qt-link.h	Thu Nov 12 19:33:11 2015 +0100
@@ -179,6 +179,15 @@
                              const QStringList& class_names,
                              const QStringList& dimensions,
                              const QStringList& values,
+			     const QStringList& bytes,
+			     const QStringList& minvals,
+			     const QStringList& maxvals,
+			     const QStringList& ranges,
+			     const QStringList& means,
+			     const QStringList& medians,
+			     const QStringList& modes,
+			     const QStringList& variances,
+			     const QStringList& stddeviations,
                              const QIntList& complex_flags);
 
   void clear_workspace_signal (void);
diff -r 6faaab833605 -r 1f94d4eb0847 libgui/src/settings-dialog.cc
--- a/libgui/src/settings-dialog.cc	Wed Nov 11 16:58:18 2015 -0800
+++ b/libgui/src/settings-dialog.cc	Thu Nov 12 19:33:11 2015 +0100
@@ -532,6 +532,10 @@
   // hide tool tips
   ui->cb_hide_tool_tips->setChecked (
     settings->value ("workspaceview/hide_tool_tips",false).toBool ());
+  // set max array size to calculate statistics for
+  ui->sb_max_array_size_for_workspace_stats->setValue (
+    settings->value ("workspaceview/set_max_array_size_for_workspace_stats",
+                     1000000).toInt ());
 
   // terminal colors
   read_terminal_colors (settings);
@@ -898,6 +902,9 @@
   // hide tool tips
   settings->setValue ("workspaceview/hide_tool_tips",
                       ui->cb_hide_tool_tips->isChecked ());
+  // Set the maximum array size for which we compute statistics in the Workspace
+  settings->setValue ("workspaceview/set_max_array_size_for_workspace_stats",
+                      ui->sb_max_array_size_for_workspace_stats->value ());
 
   // Terminal
   write_terminal_colors (settings);
diff -r 6faaab833605 -r 1f94d4eb0847 libgui/src/settings-dialog.ui
--- a/libgui/src/settings-dialog.ui	Wed Nov 11 16:58:18 2015 -0800
+++ b/libgui/src/settings-dialog.ui	Thu Nov 12 19:33:11 2015 +0100
@@ -1908,6 +1908,40 @@
                </property>
               </widget>
              </item>
+             <item row="2" column="0">
+               <widget class="Line" name="line_10">
+                 <property name="orientation">
+                   <enum>Qt::Horizontal</enum>
+                 </property>
+               </widget>
+             </item>
+             <item row="3" column="0">
+               <layout class="QHBoxLayout">
+                 <item row="3" column="0">
+                   <widget class="QLabel" name="cb_max_array_label">
+                     <property name="text">
+                       <string>Change the maximum array size for which statistics are computed: </string>
+                     </property>
+                   </widget>
+                 </item>
+                 <item row="3" column="1">
+                   <widget class="QSpinBox" name="sb_max_array_size_for_workspace_stats">
+                     <property name="enabled">
+                       <bool>true</bool>
+                     </property>
+                     <property name="minimum">
+                       <number>1</number>
+                     </property>
+                     <property name="maximum">
+                       <number>1000000000</number>
+                     </property>
+                     <property name="value">
+                       <number>1000000</number>
+                     </property>
+                   </widget>
+                 </item>
+               </layout>
+             </item>
             </layout>
            </item>
            <item>
diff -r 6faaab833605 -r 1f94d4eb0847 libgui/src/workspace-model.cc
--- a/libgui/src/workspace-model.cc	Wed Nov 11 16:58:18 2015 -0800
+++ b/libgui/src/workspace-model.cc	Thu Nov 12 19:33:11 2015 +0100
@@ -39,7 +39,16 @@
   _columnNames.append (tr ("Class"));
   _columnNames.append (tr ("Dimension"));
   _columnNames.append (tr ("Value"));
-  _columnNames.append (tr ("Attribute"));
+  _columnNames.append (tr ("Bytes"));
+  _columnNames.append (tr ("Min"));
+  _columnNames.append (tr ("Max"));
+  _columnNames.append (tr ("Range"));
+  _columnNames.append (tr ("Mean"));
+  _columnNames.append (tr ("Median"));
+  _columnNames.append (tr ("Mode"));
+  _columnNames.append (tr ("Var"));
+  _columnNames.append (tr ("Std"));
+
 
   for (int i = 0; i < resource_manager::storage_class_chars ().length (); i++)
     _storage_class_colors.append (QColor (Qt::white));
@@ -154,18 +163,6 @@
               break;
 
             case 1:
-              retval = QVariant (_class_names[idx.row ()]);
-              break;
-
-            case 2:
-              retval = QVariant (_dimensions[idx.row ()]);
-              break;
-
-            case 3:
-              retval = QVariant (_values[idx.row ()]);
-              break;
-
-            case 4:
               {
                 QString sclass;
 
@@ -189,10 +186,58 @@
                     else
                       sclass += ", " + tr ("complex");
                   }
+                if (!sclass.isEmpty ())
+                  retval = QVariant (QString (_class_names[idx.row ()])
+                                     + " (" + sclass  + ") ");
+                else
+                  retval = QVariant (_class_names[idx.row ()]);
 
-                retval = QVariant (sclass);
               }
               break;
+
+            case 2:
+              retval = QVariant (_dimensions[idx.row ()]);
+              break;
+
+            case 3:
+              retval = QVariant (_values[idx.row ()]);
+              break;
+
+            case 4:
+              retval = QVariant (_bytes[idx.row ()]);
+              break;
+
+            case 5:
+              retval = QVariant (_minvals[idx.row ()]);
+              break;
+
+            case 6:
+              retval = QVariant (_maxvals[idx.row ()]);
+              break;
+
+            case 7:
+              retval = QVariant (_ranges[idx.row ()]);
+              break;
+
+            case 8:
+              retval = QVariant (_means[idx.row ()]);
+              break;
+
+            case 9:
+              retval = QVariant (_medians[idx.row ()]);
+              break;
+
+            case 10:
+              retval = QVariant (_modes[idx.row ()]);
+              break;
+
+            case 11:
+              retval = QVariant (_variances[idx.row ()]);
+              break;
+
+            case 12:
+              retval = QVariant (_stddeviations[idx.row ()]);
+               break;
             }
         }
     }
@@ -234,6 +279,15 @@
                                 const QStringList& class_names,
                                 const QStringList& dimensions,
                                 const QStringList& values,
+                                const QStringList& bytes,
+                                const QStringList& minvals,
+                                const QStringList& maxvals,
+                                const QStringList& ranges,
+                                const QStringList& means,
+                                const QStringList& medians,
+                                const QStringList& modes,
+                                const QStringList& variances,
+                                const QStringList& stddeviations,
                                 const QIntList& complex_flags)
 {
   _top_level = top_level;
@@ -242,6 +296,15 @@
   _class_names = class_names;
   _dimensions = dimensions;
   _values = values;
+  _bytes = bytes;
+  _minvals = minvals;
+  _maxvals = maxvals;
+  _ranges = ranges;
+  _means = means;
+  _medians = medians;
+  _modes = modes;
+  _variances = variances;
+  _stddeviations = stddeviations;
   _complex_flags = complex_flags;
 
   update_table ();
@@ -263,6 +326,15 @@
   _class_names = QStringList ();
   _dimensions = QStringList ();
   _values = QStringList ();
+  _bytes =  QStringList ();
+  _minvals = QStringList ();
+  _maxvals = QStringList ();
+  _ranges = QStringList ();
+  _means = QStringList ();
+  _medians = QStringList ();
+  _modes = QStringList ();
+  _variances = QStringList ();
+  _stddeviations = QStringList ();
   _complex_flags = QIntList ();
 }
 
diff -r 6faaab833605 -r 1f94d4eb0847 libgui/src/workspace-model.h
--- a/libgui/src/workspace-model.h	Wed Nov 11 16:58:18 2015 -0800
+++ b/libgui/src/workspace-model.h	Thu Nov 12 19:33:11 2015 +0100
@@ -79,6 +79,15 @@
                       const QStringList& class_names,
                       const QStringList& dimensions,
                       const QStringList& values,
+		      const QStringList& bytes,
+		      const QStringList& minvals,
+		      const QStringList& maxvals,
+		      const QStringList& ranges,
+		      const QStringList& means,
+		      const QStringList& medians,
+		      const QStringList& modes,
+		      const QStringList& variances,
+		      const QStringList& stddeviations,
                       const QIntList& complex_flags);
 
   void clear_workspace (void);
@@ -102,6 +111,15 @@
   QStringList _class_names;
   QStringList _dimensions;
   QStringList _values;
+  QStringList _bytes;
+  QStringList _minvals;
+  QStringList _maxvals;
+  QStringList _ranges;
+  QStringList _means;
+  QStringList _medians;
+  QStringList _modes;
+  QStringList _variances;
+  QStringList _stddeviations;
   QIntList _complex_flags;
 
   QStringList _columnNames;
diff -r 6faaab833605 -r 1f94d4eb0847 libgui/src/workspace-view.cc
--- a/libgui/src/workspace-view.cc	Wed Nov 11 16:58:18 2015 -0800
+++ b/libgui/src/workspace-view.cc	Thu Nov 12 19:33:11 2015 +0100
@@ -477,17 +477,35 @@
 
   setToolTip (tool_tip);
 
+  symbol_table::set_max_numel_for_statistics (settings->value ("workspaceview/set_max_array_size_for_workspace_stats", 1000000).toInt ());
+
   _columns_shown = QStringList ();
   _columns_shown.append (tr ("Class"));
   _columns_shown.append (tr ("Dimension"));
   _columns_shown.append (tr ("Value"));
-  _columns_shown.append (tr ("Attribute"));
+  _columns_shown.append (tr ("Bytes"));
+  _columns_shown.append (tr ("Min"));
+  _columns_shown.append (tr ("Max"));
+  _columns_shown.append (tr ("Range"));
+  _columns_shown.append (tr ("Mean"));
+  _columns_shown.append (tr ("Median"));
+  _columns_shown.append (tr ("Mode"));
+  _columns_shown.append (tr ("Var"));
+  _columns_shown.append (tr ("Std"));
 
   _columns_shown_keys = QStringList ();
   _columns_shown_keys.append ("workspaceview/show_class");
   _columns_shown_keys.append ("workspaceview/show_dimension");
   _columns_shown_keys.append ("workspaceview/show_value");
-  _columns_shown_keys.append ("workspaceview/show_attribute");
+  _columns_shown_keys.append ("workspaceview/show_bytes");
+  _columns_shown_keys.append ("workspaceview/show_min");
+  _columns_shown_keys.append ("workspaceview/show_max");
+  _columns_shown_keys.append ("workspaceview/show_range");
+  _columns_shown_keys.append ("workspaceview/show_mean");
+  _columns_shown_keys.append ("workspaceview/show_median");
+  _columns_shown_keys.append ("workspaceview/show_mode");
+  _columns_shown_keys.append ("workspaceview/show_var");
+  _columns_shown_keys.append ("workspaceview/show_std");
 
   _sig_mapper = 0;
 }
diff -r 6faaab833605 -r 1f94d4eb0847 libinterp/corefcn/symtab.cc
--- a/libinterp/corefcn/symtab.cc	Wed Nov 11 16:58:18 2015 -0800
+++ b/libinterp/corefcn/symtab.cc	Thu Nov 12 19:33:11 2015 +0100
@@ -48,6 +48,7 @@
 #include "symtab.h"
 #include "unwind-prot.h"
 #include "utils.h"
+#include "builtin-defun-decls.h"
 
 symbol_table *symbol_table::instance = 0;
 
@@ -71,6 +72,8 @@
 
 symbol_table::context_id symbol_table::xcurrent_context = 0;
 
+int symbol_table::max_numel_for_statistics=1000000;
+
 // Should Octave always check to see if function files have changed
 // since they were last compiled?
 static int Vignore_function_time_stamp = 1;
@@ -1535,8 +1538,83 @@
               val.short_disp (buf);
               std::string short_disp_str = buf.str ();
 
+              buf.str (std::string () );
+              buf.clear ();
+              buf << val.byte_size ();
+              std::string disp_bytes = buf.str ();
+
+              std::string minval = std::string ("...");
+              std::string maxval = std::string ("...");
+              std::string range = std::string ("...");
+              std::string mean = std::string ("...");
+              std::string median = std::string ("...");
+              std::string mode = std::string ("...");
+              std::string variance = std::string ("...");
+              std::string stddeviation = std::string ("...");
+
+              if ( val.is_numeric_type () )
+                {
+                  if (val.numel () > max_numel_for_statistics)
+                    {
+                      minval = std::string ("<too many elements>");
+                      maxval = std::string ("<too many elements>");
+                      range = std::string ("<too many elements>");
+                      mean = std::string ("<too many elements>");
+                      median = std::string ("<too many elements>");
+                      mode = std::string ("<too many elements>");
+                      variance = std::string ("<too many elements>");
+                      stddeviation = std::string ("<too many elements>");
+                    } else
+                    {
+                      buf.str ( std::string () );
+                      buf.clear ();
+                      Fmin (val) (0).short_disp (buf);
+                      minval = buf.str ();
+
+                      buf.str (std::string ());
+                      buf.clear ();
+                      Fmax (val) (0).short_disp (buf);
+                      maxval = buf.str ();
+
+                      buf.str ( std::string () );
+                      buf.clear ();
+                      feval ("range", val) (0).short_disp (buf);
+                      range = buf.str ();
+
+                      buf.str ( std::string () );
+                      buf.clear ();
+                      feval ("mean", val) (0).short_disp (buf);
+                      mean = buf.str ();
+
+                      buf.str ( std::string () );
+                      buf.clear ();
+                      feval ("median", val) (0).short_disp (buf);
+                      median = buf.str ();
+
+                      buf.str ( std::string () );
+                      buf.clear ();
+                      feval ("mode", val) (0).short_disp (buf);
+                      mode = buf.str ();
+
+                      buf.str ( std::string () );
+                      buf.clear ();
+                      feval ("var", val) (0).short_disp (buf);
+                      variance = buf.str ();
+
+                      buf.str ( std::string () );
+                      buf.clear ();
+                      feval ("std", val) (0).short_disp (buf);
+                      stddeviation = buf.str ();
+                      buf.str ( std::string () );
+                      buf.clear ();
+                    }
+                }
+
               workspace_element elt (storage, nm, val.class_name (),
                                      short_disp_str, dv.str (),
+                                     disp_bytes, minval, maxval,
+                                     range, mean, median, mode,
+                                     variance, stddeviation,
                                      val.is_complex_type ());
 
               retval.push_back (elt);
diff -r 6faaab833605 -r 1f94d4eb0847 libinterp/corefcn/symtab.h
--- a/libinterp/corefcn/symtab.h	Wed Nov 11 16:58:18 2015 -0800
+++ b/libinterp/corefcn/symtab.h	Thu Nov 12 19:33:11 2015 +0100
@@ -2309,8 +2309,20 @@
 
   static void cleanup (void);
 
+  // Set the maximum number of elements in an array for which
+  // we calculate the statistics for the workspace window
+  static void
+  set_max_numel_for_statistics (int _max_numel)
+  {
+    symbol_table::max_numel_for_statistics = _max_numel;
+  }
+
 private:
 
+  // the biggest array size for which we compute statistics for the
+  // workspace view
+  static int max_numel_for_statistics;
+
   // No copying!
 
   symbol_table (const symbol_table&);
diff -r 6faaab833605 -r 1f94d4eb0847 libinterp/corefcn/workspace-element.h
--- a/libinterp/corefcn/workspace-element.h	Wed Nov 11 16:58:18 2015 -0800
+++ b/libinterp/corefcn/workspace-element.h	Thu Nov 12 19:33:11 2015 +0100
@@ -34,16 +34,32 @@
                      const std::string& class_name_arg = "<class>",
                      const std::string& value_arg = "<value>",
                      const std::string& dimension_arg = "<dimension>",
+		     const std::string& bytes_arg = "<bytes>",
+		     const std::string& min_arg = "<min>",
+		     const std::string& max_arg = "<max>",
+		     const std::string& range_arg = "<range>",
+		     const std::string& mean_arg = "<mean>",
+		     const std::string& median_arg = "<median>",
+		     const std::string& mode_arg = "<mode>",
+		     const std::string& var_arg = "<var>",
+		     const std::string& std_arg = "<std>",
                      bool complex_flag_arg = false)
     : xscope (scope_arg), xsymbol (symbol_arg),
       xclass_name (class_name_arg), xvalue (value_arg),
-      xdimension (dimension_arg), xcomplex_flag (complex_flag_arg)
+      xdimension (dimension_arg), xbytes (bytes_arg), xmin(min_arg),
+      xmax(max_arg), xrange(range_arg), xmean(mean_arg), xmedian(median_arg),
+      xmode(mode_arg), xvar(var_arg), xstd(std_arg),
+      xcomplex_flag (complex_flag_arg)
   { }
 
   workspace_element (const workspace_element& ws_elt)
     : xscope (ws_elt.xscope), xsymbol (ws_elt.xsymbol),
       xclass_name (ws_elt.xclass_name), xvalue (ws_elt.xvalue),
-      xdimension (ws_elt.xdimension), xcomplex_flag (ws_elt.xcomplex_flag)
+      xdimension (ws_elt.xdimension), xbytes(ws_elt.xbytes),
+      xmin(ws_elt.xmin), xmax(ws_elt.xmax), xrange(ws_elt.xrange),
+      xmean(ws_elt.xmean), xmedian(ws_elt.xmedian), xmode(ws_elt.xmode),
+      xvar(ws_elt.xvar), xstd(ws_elt.xstd),
+      xcomplex_flag (ws_elt.xcomplex_flag)
   { }
 
   workspace_element operator = (const workspace_element& ws_elt)
@@ -55,6 +71,15 @@
         xclass_name = ws_elt.xclass_name;
         xvalue = ws_elt.xvalue;
         xdimension = ws_elt.xdimension;
+	xbytes = ws_elt.xbytes;
+	xmin = ws_elt.xmin;
+	xmax = ws_elt.xmax;
+	xrange = ws_elt.xrange;
+	xmean = ws_elt.xmean;
+	xmedian = ws_elt.xmedian;
+	xmode = ws_elt.xmode;
+	xvar = ws_elt.xvar;
+	xstd = ws_elt.xstd;
         xcomplex_flag = ws_elt.xcomplex_flag;
       }
 
@@ -73,6 +98,24 @@
 
   std::string dimension (void) const { return xdimension; }
 
+  std::string bytes (void) const { return xbytes; }
+
+  std::string min (void) const { return xmin; }
+
+  std::string max (void) const { return xmax; }
+
+  std::string range (void) const { return xrange; }
+
+  std::string mean (void) const { return xmean; }
+
+  std::string median (void) const { return xmedian; }
+
+  std::string mode (void) const { return xmode; }
+
+  std::string var (void) const { return xvar; }
+
+  std::string std (void) const { return xstd; }
+
   bool complex_flag (void) const { return xcomplex_flag; }
 
 private:
@@ -83,6 +126,15 @@
   std::string xclass_name;
   std::string xvalue;
   std::string xdimension;
+  std::string xbytes;
+  std::string xmin;
+  std::string xmax;
+  std::string xrange;
+  std::string xmean;
+  std::string xmedian;
+  std::string xmode;
+  std::string xvar;
+  std::string xstd;
   bool xcomplex_flag;
 };
 
