changeset 24655:3ceee1910e1a

allow single character strings to be edited (bug #51848) * variable-editor-model.h, variable-editor-model.cc (get_quote_char): New function. (variable_editor_model::quote_char, variable_editor_model::impl::quote_char): New functions. (variable_editor_model::subscript_expression): New overload. Handle cells and strings. (variable_editor_model::set_data_oct): Don't pass name as argument. Change all uses. Handle character strings. (get_rows_and_columns): Special case for strings. (variable_editor_model::impl): Special case for strings. (variable_editor_model::impl::value_at): New overload. (variable_editor_model::type_is_editable): Handle strings. * ov-str-mat.h, ov-str-mat.cc (octave_char_matrix_str::edit_display): New function. * ov-cell.cc (octave_base_matrix<Cell>::edit_display): Don't handle special cases here.
author John W. Eaton <jwe@octave.org>
date Tue, 30 Jan 2018 17:18:01 -0500
parents 6daa29105d21
children cd79f32fba85
files libgui/src/variable-editor-model.cc libgui/src/variable-editor-model.h libinterp/octave-value/ov-cell.cc libinterp/octave-value/ov-str-mat.cc libinterp/octave-value/ov-str-mat.h
diffstat 5 files changed, 127 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/libgui/src/variable-editor-model.cc	Tue Jan 30 13:23:07 2018 -0500
+++ b/libgui/src/variable-editor-model.cc	Tue Jan 30 17:18:01 2018 -0500
@@ -68,11 +68,23 @@
   return lbl_txt;
 }
 
+static char
+get_quote_char (const octave_value& val)
+{
+  if (val.is_sq_string ())
+    return '\'';
+
+  if (val.is_dq_string ())
+    return '"';
+
+  return 0;
+}
+
 static void
 get_rows_and_columns (const octave_value& val, int& rows, int& cols)
 {
   rows = val.rows ();
-  cols = val.columns ();
+  cols = (val.is_string () ? 1 : val.columns ());
 }
 
 struct variable_editor_model::impl
@@ -92,7 +104,14 @@
 
           octave_value ov = cval(r,c);
 
-          if (! (ov.numel () == 1 && (ov.isnumeric () || ov.islogical ())))
+          if ((ov.numel () == 1 && (ov.isnumeric () || ov.islogical ()))
+              || (ov.rows () == 1 && ov.is_string ()))
+            {
+              m_data = QString::fromStdString (ov.edit_display (r, c));
+
+              return;
+            }
+          else
             m_requires_sub_editor = true;
         }
 
@@ -154,6 +173,37 @@
   const cell& elem (int r, int c) const { return elem (index (r, c)); }
   const cell& elem (const QModelIndex& idx) const { return elem (index (idx)); }
 
+  char quote_char (int r, int c) const
+  {
+    if (m_value.is_string ())
+      return get_quote_char (m_value);
+    else if (m_value.iscell ())
+      {
+        Cell cval = m_value.cell_value ();
+
+        octave_value ov = cval(r,c);
+
+        if (ov.rows () == 1)
+          return get_quote_char (ov);
+      }
+
+    return 0;
+  }
+
+  QString subscript_expression (int r, int c) const
+  {
+    if (m_value.is_string ())
+      return "";
+    else if (m_value.iscell ())
+      return (QString ("{%1, %2}")
+              .arg (r + 1)
+              .arg (c + 1));
+    else
+      return (QString ("(%1, %2)")
+              .arg (r + 1)
+              .arg (c + 1));
+  }
+
   void update (const QModelIndex& idx)
   {
     if (is_defined (idx))
@@ -170,14 +220,19 @@
       }
   }
 
-  octave_value value_at (const QModelIndex& idx) const
+  octave_value value_at (int r, int c) const
   {
     if (! m_value.iscell ())
       return octave_value ();
 
     Cell cval = m_value.cell_value ();
 
-    return cval.elem (idx.row (), idx.column ());
+    return cval.elem (r, c);
+  }
+
+  octave_value value_at (const QModelIndex& idx) const
+  {
+    return value_at (idx.row (), idx.column ());
   }
 
   void set (const QModelIndex& idx, const cell& dat)
@@ -240,7 +295,7 @@
     m_rows = r;
     m_cols = c;
 
-    m_table.resize (r * c);
+    m_table.resize (m_rows * m_cols);
 
     m_label->setTextFormat (Qt::PlainText);
 
@@ -401,10 +456,8 @@
   // Evaluate the string that the user entered.  If that fails, we
   // will restore previous value.
 
-  octave_link::post_event<variable_editor_model,
-                          std::string, int, int, std::string>
-    (this, &variable_editor_model::set_data_oct,
-     m_d->m_name, r, c, vstr.toStdString ());
+  octave_link::post_event<variable_editor_model, int, int, std::string>
+    (this, &variable_editor_model::set_data_oct, r, c, vstr.toStdString ());
 
   // This is success so far...
 
@@ -523,12 +576,22 @@
   return m_d->sub_editor_type (idx) == sub_string;
 }
 
+char
+variable_editor_model::quote_char (int r, int c) const
+{
+  return m_d->quote_char (r, c);
+}
+
+QString
+variable_editor_model::subscript_expression (int r, int c) const
+{
+  return m_d->subscript_expression (r, c);
+}
+
 QString
 variable_editor_model::subscript_expression (const QModelIndex& idx) const
 {
-  return (QString (m_d->m_value.iscell () ? "{%1, %2}" : "(%1, %2)")
-          .arg (idx.row () + 1)
-          .arg (idx.column () + 1));
+  return subscript_expression (idx.row (), idx.column ());
 }
 
 // Private slots.
@@ -604,8 +667,7 @@
 // val has to be copied!
 
 void
-variable_editor_model::set_data_oct (const std::string& name,
-                                     const int& row, const int& col,
+variable_editor_model::set_data_oct (const int& row, const int& col,
                                      const std::string& rhs)
 {
   // INTERPRETER THREAD
@@ -617,7 +679,21 @@
       int parse_status = 0;
 
       std::ostringstream os;
-      os << name << "(" << row+1 << "," << col+1 << ") = " << rhs;
+
+      std::string name = m_d->m_name;
+      os << name;
+
+      QString tmp = subscript_expression (row, col);
+      os << tmp.toStdString () << " = ";
+
+      char qc = quote_char (row, col);
+      if (qc)
+        os << qc;
+
+      os << rhs;
+
+      if (qc)
+        os << qc;
 
       expr = os.str ();
 
@@ -754,8 +830,9 @@
 variable_editor_model::type_is_editable (const octave_value& val,
                                          bool display_error) const
 {
-  if ((val.isnumeric () || val.islogical () || val.iscell ())
-      && val.ndims () == 2)
+  if (((val.isnumeric () || val.islogical () || val.iscell ())
+       && val.ndims () == 2)
+      || (val.is_string () && val.rows () == 1))
     return true;
 
   if (display_error)
--- a/libgui/src/variable-editor-model.h	Tue Jan 30 13:23:07 2018 -0500
+++ b/libgui/src/variable-editor-model.h	Tue Jan 30 17:18:01 2018 -0500
@@ -92,9 +92,14 @@
 
   bool editor_type_string (const QModelIndex& idx) const;
 
+  char quote_char (int r, int c) const;
+
   // Return a subscript expression as a string that can be used to
   // access a sub-element of a data structure.  For example "{1,3}"
   // for cell array element {1,3} or "(2,4)" for array element (2,4).
+
+  QString subscript_expression (int r, int c) const;
+
   QString subscript_expression (const QModelIndex& idx) const;
 
 signals: // private
@@ -122,8 +127,7 @@
 
 private:
 
-  void set_data_oct (const std::string& v, const int& row, const int& col,
-                     const std::string& val);
+  void set_data_oct (const int& row, const int& col, const std::string& val);
 
   void init_from_oct (const std::string& x);
 
--- a/libinterp/octave-value/ov-cell.cc	Tue Jan 30 13:23:07 2018 -0500
+++ b/libinterp/octave-value/ov-cell.cc	Tue Jan 30 17:18:01 2018 -0500
@@ -106,15 +106,10 @@
 {
   octave_value val = matrix(i,j);
 
-  if (val.numel () == 1 && (val.isnumeric () || val.islogical ()))
-    return val.edit_display (0, 0);
-  else
-    {
-      std::string tname = val.type_name ();
-      dim_vector dv = val.dims ();
-      std::string dimstr = dv.str ();
-      return "[" + dimstr + " " + tname + "]";
-    }
+  std::string tname = val.type_name ();
+  dim_vector dv = val.dims ();
+  std::string dimstr = dv.str ();
+  return "[" + dimstr + " " + tname + "]";
 }
 
 template <>
--- a/libinterp/octave-value/ov-str-mat.cc	Tue Jan 30 13:23:07 2018 -0500
+++ b/libinterp/octave-value/ov-str-mat.cc	Tue Jan 30 17:18:01 2018 -0500
@@ -277,6 +277,27 @@
     }
 }
 
+std::string
+octave_char_matrix_str::edit_display (octave_idx_type i, octave_idx_type) const
+{
+  if (matrix.rows () == 1 && i == 0)
+    {
+      std::string retval = string_value ();
+
+      if (! is_sq_string ())
+        retval = undo_string_escapes (retval);
+
+      return retval;
+    }
+  else
+    {
+      std::string tname = type_name ();
+      dim_vector dv = matrix.dims ();
+      std::string dimstr = dv.str ();
+      return "[" + dimstr + " " + tname + "]";
+    }
+}
+
 bool
 octave_char_matrix_str::save_ascii (std::ostream& os)
 {
--- a/libinterp/octave-value/ov-str-mat.h	Tue Jan 30 13:23:07 2018 -0500
+++ b/libinterp/octave-value/ov-str-mat.h	Tue Jan 30 17:18:01 2018 -0500
@@ -146,6 +146,8 @@
 
   void short_disp (std::ostream& os) const;
 
+  std::string edit_display (octave_idx_type i, octave_idx_type j) const;
+
   bool save_ascii (std::ostream& os);
 
   bool load_ascii (std::istream& is);