changeset 24643:78aff6f14227

more variable editor improvements; allow more variable types to be edited * ov.h (octave_value::edit_display): New function. * ov-base.h (octave_base_value::edit_display): New virtual function. * ov-base-mat.h, ov-base-mat.cc, ov-base-scalar.h, ov-base-scalar.cc, ov-cell.h, ov-cell.cc: Overload edit_display function. * variable-editor.cc (variable_editor::variable_editor): Increase default width to 30. * variable-editor-model.h, variable-editor-model.cc (make_label): Now file-scope static function instead of member function. (get_rows_and_columns): New file-scope static function. Use to eliminate duplicated code. (impl::cell::cell (const octave_value&, int, int)): New ctor. (variable_editor_model::resize_columns_signal): New signal. (variable_editor_model::update_data): Emit resize_columns_signal when done. (variable_editor_model::variable_editor_model): Connect resize_columns_signal. Don't nest calls to insertRows and insertColumns. (variable_editor_model::type_is_editable) Allow all numeric types, logical arrays, and cells to be edited. Include dimensions in error message.
author John W. Eaton <jwe@octave.org>
date Fri, 26 Jan 2018 19:39:46 -0500
parents d58543eb53e9
children e04a56630c8a
files libgui/src/variable-editor-model.cc libgui/src/variable-editor-model.h libgui/src/variable-editor.cc libinterp/octave-value/ov-base-mat.cc libinterp/octave-value/ov-base-mat.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-cell.cc libinterp/octave-value/ov.h
diffstat 10 files changed, 131 insertions(+), 63 deletions(-) [+]
line wrap: on
line diff
--- a/libgui/src/variable-editor-model.cc	Fri Jan 26 00:11:11 2018 -0500
+++ b/libgui/src/variable-editor-model.cc	Fri Jan 26 19:39:46 2018 -0500
@@ -44,12 +44,65 @@
 
 // Pimpl/Dpointer for variable_editor_model.
 
+static QString
+make_label (const std::string& name, const octave_value& val)
+{
+  QString lbl_txt = QString::fromStdString (name);
+
+  if (val.is_defined ())
+    {
+      if (! lbl_txt.isEmpty ())
+        lbl_txt += " ";
+
+      dim_vector dv = val.dims ();
+
+      lbl_txt += ("["
+                  + QString::fromStdString (dv.str ())
+                  + " "
+                  + QString::fromStdString (val.class_name ())
+                  + "]");
+    }
+  else
+    lbl_txt += " [undefined]";
+
+  return lbl_txt;
+}
+
+static void
+get_rows_and_columns (const octave_value& val, int& rows, int& cols)
+{
+  rows = val.rows ();
+  cols = val.columns ();
+}
+
 struct variable_editor_model::impl
 {
   struct cell
   {
     cell (void) : m_defined (false) { }
 
+    cell (const octave_value& val, int r, int c)
+      : m_defined (true), m_data ("no display"), m_status_tip ("status"),
+        m_tool_tip ("tip"), m_requires_sub_editor (false),
+        m_editor_type (sub_none)
+    {
+      if (val.iscell ())
+        {
+          Cell cval = val.cell_value ();
+
+          octave_value ov = cval(r,c);
+          dim_vector dv = ov.dims ();
+
+          m_requires_sub_editor = true;
+
+          m_data = make_label ("", ov);
+        }
+      else
+        {
+          m_data = QString::fromStdString (val.edit_display (r, c));
+        }
+    }
+
     cell (const QString& d, const QString& s, const QString& t,
           bool rse, sub_editor_types edtype)
       : m_defined (true), m_data (d), m_status_tip (s), m_tool_tip (t),
@@ -111,35 +164,12 @@
 
     if (idx.isValid ())
       {
-        QString dat;
-        bool requires_sub_editor = false;
-
         int r = idx.row ();
         int c = idx.column ();
 
-        if (m_value.iscell ())
-          {
-            requires_sub_editor = true;
-
-            Cell cval = m_value.cell_value ();
-
-            octave_value ov = cval(r,c);
-            dim_vector dv = ov.dims ();
+        cell edit_cell (m_value, r, c);
 
-            dat = make_label ("", ov);
-          }
-        else
-          {
-            // XXX
-            Matrix mval = m_value.matrix_value ();
-
-            double dval = mval(r,c);
-
-            dat.setNum (dval);
-          }
-
-        set (r, c, cell (dat, "status", "tip", requires_sub_editor,
-                         sub_matrix));
+        set (r, c, edit_cell);
       }
   }
 
@@ -207,8 +237,7 @@
       {
         m_validity = true;
 
-        r = m_value.rows ();
-        c = m_value.columns ();
+        get_rows_and_columns (m_value, r, c);
       }
 
     m_rows = r;
@@ -221,31 +250,6 @@
     m_validtext = make_label (m_name, m_value);
   }
 
-  QString make_label (const std::string& name, const octave_value& val)
-  {
-    QString lbl_txt = QString::fromStdString (name);
-
-    if (val.is_defined ())
-      {
-        if (! lbl_txt.isEmpty ())
-          lbl_txt += " ";
-
-        lbl_txt += "[";
-
-        if (! val.is_scalar_type ())
-          {
-            dim_vector dv = val.dims ();
-            lbl_txt += QString::fromStdString (dv.str ());
-          }
-
-        lbl_txt += " " + QString::fromStdString (val.class_name ()) + "]";
-      }
-    else
-      lbl_txt += " [undefined]";
-
-    return lbl_txt;
-  }
-
   void invalidate (void)
   {
     reset (octave_value ());
@@ -313,21 +317,26 @@
   connect (this, SIGNAL (clear_data_cell_signal (int, int)),
            this, SLOT (clear_data_cell (int, int)));
 
+  connect (this, SIGNAL (resize_columns_signal (void)),
+           parent, SLOT (resizeColumnsToContents (void)));
+
   if (! type_is_editable (val))
     return;
 
   // Initializes everything.
 
-  int rows = val.rows ();
-  int cols = val.columns ();
+  int rows = 0;
+  int cols = 0;
 
-  beginInsertRows (QModelIndex (), 0, rows-1);
-  beginInsertColumns (QModelIndex (), 0, cols-1);
+  get_rows_and_columns (val, rows, cols);
 
   m_d->reset (val);
 
+  beginInsertRows (QModelIndex (), 0, rows-1);
+  endInsertRows ();
+
+  beginInsertColumns (QModelIndex (), 0, cols-1);
   endInsertColumns ();
-  endInsertRows ();
 }
 
 variable_editor_model::~variable_editor_model (void)
@@ -556,8 +565,10 @@
   int old_rows = m_d->rows ();
   int old_cols = m_d->columns ();
 
-  int new_rows = val.rows ();
-  int new_cols = val.columns ();
+  int new_rows = 0;
+  int new_cols = 0;
+
+  get_rows_and_columns (val, new_rows, new_cols);
 
   m_d->reset (val);
 
@@ -587,6 +598,8 @@
 
   emit dataChanged (QAbstractTableModel::index (0, 0),
                     QAbstractTableModel::index (new_rows-1, new_cols-1));
+
+  emit resize_columns_signal ();
 }
 
 // Private.
@@ -744,12 +757,21 @@
 variable_editor_model::type_is_editable (const octave_value& val,
                                          bool display_error) const
 {
-  if (val.is_matrix_type () || val.iscell ())
+  if ((val.isnumeric () || val.islogical () || val.iscell ()
+      && val.ndims () == 2)
     return true;
 
   if (display_error)
-    emit data_error_signal (QString ("unable to edit '%1' objects")
-                            .arg (QString::fromStdString (val.type_name ())));
+    {
+      QString tname = QString::fromStdString (val.type_name ());
+
+      dim_vector dv = val.dims ();
+      QString dimstr = QString::fromStdString (dv.str ());
+
+      emit data_error_signal (QString ("unable to edit [%1] '%2' objects")
+                              .arg (dimstr)
+                              .arg (tname));
+    }
 
   return false;
 }
--- a/libgui/src/variable-editor-model.h	Fri Jan 26 00:11:11 2018 -0500
+++ b/libgui/src/variable-editor-model.h	Fri Jan 26 19:39:46 2018 -0500
@@ -107,6 +107,8 @@
 
   void user_error_signal (const QString& title, const QString& msg) const;
 
+  void resize_columns_signal (void);
+
 private slots:
 
   void update_data (const octave_value& val);
--- a/libgui/src/variable-editor.cc	Fri Jan 26 00:11:11 2018 -0500
+++ b/libgui/src/variable-editor.cc	Fri Jan 26 19:39:46 2018 -0500
@@ -85,7 +85,7 @@
   : octave_dock_widget (p), m_main (new QMainWindow ()),
     m_tool_bar (new QToolBar (m_main)),
     m_tab_widget (new QTabWidget (m_main)),
-    m_default_width (20), m_default_height (100), m_add_font_height (0),
+    m_default_width (30), m_default_height (100), m_add_font_height (0),
     m_autofit (false), m_autofit_max (false), m_use_terminal_font (true),
     m_alternate_rows (true), m_stylesheet (""), m_font (), m_sel_font (),
     m_table_colors ()
--- a/libinterp/octave-value/ov-base-mat.cc	Fri Jan 26 00:11:11 2018 -0500
+++ b/libinterp/octave-value/ov-base-mat.cc	Fri Jan 26 19:39:46 2018 -0500
@@ -507,6 +507,16 @@
 }
 
 template <typename MT>
+std::string
+octave_base_matrix<MT>::edit_display (octave_idx_type i,
+                                      octave_idx_type j) const
+{
+  std::ostringstream buf;
+  octave_print_internal (buf, matrix(i,j));
+  return buf.str ();
+}
+
+template <typename MT>
 octave_value
 octave_base_matrix<MT>::fast_elem_extract (octave_idx_type n) const
 {
--- a/libinterp/octave-value/ov-base-mat.h	Fri Jan 26 00:11:11 2018 -0500
+++ b/libinterp/octave-value/ov-base-mat.h	Fri Jan 26 19:39:46 2018 -0500
@@ -163,6 +163,8 @@
 
   void short_disp (std::ostream& os) const;
 
+  std::string edit_display (octave_idx_type i, octave_idx_type j) const;
+
   MT& matrix_ref (void)
   {
     clear_cached_info ();
--- a/libinterp/octave-value/ov-base-scalar.cc	Fri Jan 26 00:11:11 2018 -0500
+++ b/libinterp/octave-value/ov-base-scalar.cc	Fri Jan 26 19:39:46 2018 -0500
@@ -189,6 +189,15 @@
 }
 
 template <typename ST>
+std::string
+octave_base_scalar<ST>::edit_display (octave_idx_type, octave_idx_type) const
+{
+  std::ostringstream buf;
+  octave_print_internal (buf, scalar);
+  return buf.str ();
+}
+
+template <typename ST>
 octave_value
 octave_base_scalar<ST>::fast_elem_extract (octave_idx_type n) const
 {
--- a/libinterp/octave-value/ov-base-scalar.h	Fri Jan 26 00:11:11 2018 -0500
+++ b/libinterp/octave-value/ov-base-scalar.h	Fri Jan 26 19:39:46 2018 -0500
@@ -138,6 +138,8 @@
 
   void short_disp (std::ostream& os) const;
 
+  std::string edit_display (octave_idx_type i, octave_idx_type j) 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	Fri Jan 26 00:11:11 2018 -0500
+++ b/libinterp/octave-value/ov-base.h	Fri Jan 26 19:39:46 2018 -0500
@@ -661,6 +661,9 @@
 
   virtual void short_disp (std::ostream& os) const { os << "..."; }
 
+  virtual std::string edit_display (octave_idx_type, octave_idx_type) const
+  { return "#VAL"; }
+
   virtual void print_info (std::ostream& os, const std::string& prefix) const;
 
   virtual bool save_ascii (std::ostream& os);
--- a/libinterp/octave-value/ov-cell.cc	Fri Jan 26 00:11:11 2018 -0500
+++ b/libinterp/octave-value/ov-cell.cc	Fri Jan 26 19:39:46 2018 -0500
@@ -100,6 +100,19 @@
 // really ask whether octave_cell should inherit from octave_base_matrix at all.
 
 template <>
+std::string
+octave_base_matrix<Cell>::edit_display (octave_idx_type i,
+                                        octave_idx_type j) const
+{
+  octave_value val = matrix(i,j);
+
+  if (val.numel () == 1)
+    return edit_display(0,0);
+  else
+    return "type + dims";
+}
+
+template <>
 octave_value
 octave_base_matrix<Cell>::fast_elem_extract (octave_idx_type n) const
 {
--- a/libinterp/octave-value/ov.h	Fri Jan 26 00:11:11 2018 -0500
+++ b/libinterp/octave-value/ov.h	Fri Jan 26 19:39:46 2018 -0500
@@ -1275,6 +1275,11 @@
 
   void short_disp (std::ostream& os) const { rep->short_disp (os); }
 
+  std::string edit_display (octave_idx_type i, octave_idx_type j) const
+  {
+    return rep->edit_display (i, j);
+  }
+
   int type_id (void) const { return rep->type_id (); }
 
   std::string type_name (void) const { return rep->type_name (); }