Mercurial > octave
changeset 24660:a4ea36915e38
handle structure arrays in the variable editor
* ov-struct.h, ov-struct.cc (octave_struct::edit_display,
octave_scalar_struct::edit_display): New functions.
* variable-editor-model.h, variable-editor-model.cc
(variable_editor_model::impl::cell::init_data_and_sub_editor):
New function.
(get_rows_and_columns, variable_editor_model::impl,
variable_editor_model::impl::quote_char,
variable_editor_model::value_at,
variable_editor_model::type_is_editable,
variable_editor_model::subscript_expression): Handle structs.
(variable_editor_model::impl::header_data,
variable_editor_model::headerData): New functions.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Wed, 31 Jan 2018 16:18:24 -0500 |
parents | 13d7fdaad391 |
children | 02989d7d68dc |
files | libgui/src/variable-editor-model.cc libgui/src/variable-editor-model.h libinterp/octave-value/ov-struct.cc libinterp/octave-value/ov-struct.h |
diffstat | 4 files changed, 265 insertions(+), 17 deletions(-) [+] |
line wrap: on
line diff
--- a/libgui/src/variable-editor-model.cc Wed Jan 31 12:41:36 2018 -0800 +++ b/libgui/src/variable-editor-model.cc Wed Jan 31 16:18:24 2018 -0500 @@ -91,6 +91,32 @@ rows = 1; cols = 1; } + else if (val.isstruct ()) + { + if (val.numel () == 1) + { + // Scalar struct. Rows are fields, single column for + // values. + + rows = val.nfields (); + cols = 1; + } + else if (val.rows () == 1 || val.columns () == 1) + { + // Vector struct. Columns are fields, rows are values. + + rows = val.numel (); + cols = val.nfields (); + } + else + { + // 2-d struct array. Rows and columns index individual + // scalar structs. + + rows = val.rows (); + cols = val.columns (); + } + } else { rows = val.rows (); @@ -115,18 +141,41 @@ octave_value ov = cval(r,c); - if ((ov.numel () == 1 && (ov.isnumeric () || ov.islogical ())) - || (ov.is_string () && (ov.rows () == 1 || ov.isempty ()))) + init_data_and_sub_editor (val, cval(r,c), r, c); + } + else if (val.isstruct ()) + { + if (val.numel () == 1) { - m_data = QString::fromStdString (ov.edit_display (r, c)); + // Scalar struct. Rows are fields, single column for + // values. + + octave_scalar_map m = val.scalar_map_value (); - return; + init_data_and_sub_editor (val, m.contents (r), r, c); + } + else if (val.rows () == 1 || val.columns () == 1) + { + // Vector struct. Columns are fields, rows are values. + + octave_map m = val.map_value (); + + Cell cval = m.contents (c); + + init_data_and_sub_editor (val, cval(r), r, c); } else - m_requires_sub_editor = true; + { + // 2-d struct array. Rows and columns index individual + // scalar structs. + + octave_map m = val.map_value (); + + init_data_and_sub_editor (val, m(r,c), r, c); + } } - - m_data = QString::fromStdString (val.edit_display (r, c)); + else + m_data = QString::fromStdString (val.edit_display (r, c)); } cell (const QString& d, const QString& s, const QString& t, @@ -135,6 +184,23 @@ m_requires_sub_editor (rse), m_editor_type (edtype) { } + void init_data_and_sub_editor (const octave_value& val, + const octave_value& elt, + int r, int c) + { + if ((elt.numel () == 1 && (elt.isnumeric () || elt.islogical ())) + || (elt.is_string () && (elt.rows () == 1 || elt.isempty ()))) + { + m_requires_sub_editor = false; + m_data = QString::fromStdString (elt.edit_display (0, 0)); + } + else + { + m_requires_sub_editor = true; + m_data = QString::fromStdString (val.edit_display (r, c)); + } + } + bool m_defined; QVariant m_data; @@ -190,17 +256,73 @@ return get_quote_char (m_value); else if (m_value.iscell ()) { - Cell cval = m_value.cell_value (); + octave_value ov = value_at (r, c); - octave_value ov = cval(r,c); + if (ov.is_string ()) + return get_quote_char (ov); + } + else if (m_value.isstruct ()) + { + octave_value ov = value_at (r, c); - if (ov.rows () == 1 || ov.is_zero_by_zero ()) + if (ov.is_string ()) return get_quote_char (ov); } return 0; } + QVariant header_data (int section, Qt::Orientation orientation, + int role) const + { + if (role != Qt::DisplayRole) + return QVariant (); + + if (m_value.isstruct ()) + { + if (m_value.numel () == 1) + { + // Scalar struct. Rows are fields, single column for + // values. + + if (orientation == Qt::Horizontal) + return QString ("Values"); + else + { + octave_scalar_map m = m_value.scalar_map_value (); + + string_vector fields = m.fieldnames (); + + return QString::fromStdString (fields(section)); + } + } + else if (m_value.rows () == 1 || m_value.columns () == 1) + { + // Vector struct. Columns are fields, rows are values. + + if (orientation == Qt::Horizontal) + { + octave_map m = m_value.map_value (); + + string_vector fields = m.fieldnames (); + + return QString::fromStdString (fields(section)); + } + else + return QString::number (section+1); + } + else + { + // 2-d struct array. Rows and columns index individual + // scalar structs. + + return QString::number (section+1); + } + } + + return QString::number (section+1); + } + QString subscript_expression (int r, int c) const { if (m_value.is_string ()) @@ -209,6 +331,43 @@ return (QString ("{%1, %2}") .arg (r + 1) .arg (c + 1)); + else if (m_value.isstruct ()) + { + if (m_value.numel () == 1) + { + // Scalar struct. Rows are fields, single column for + // values. + + octave_scalar_map m = m_value.scalar_map_value (); + + string_vector fields = m.fieldnames (); + + return QString (".%1").arg (QString::fromStdString (fields(r))); + } + else if (m_value.rows () == 1 || m_value.columns () == 1) + { + // Vector struct. Columns are fields, rows are values. + + octave_map m = m_value.map_value (); + + string_vector fields = m.fieldnames (); + + return (QString ("(%1).%2") + .arg (r + 1) + .arg (QString::fromStdString (fields(c)))); + } + else + { + // 2-d struct array. Rows and columns index individual + // scalar structs. + + octave_map m = m_value.map_value (); + + return (QString ("(%1,%2)") + .arg (r + 1) + .arg (c + 1)); + } + } else return (QString ("(%1, %2)") .arg (r + 1) @@ -233,12 +392,45 @@ octave_value value_at (int r, int c) const { - if (! m_value.iscell ()) - return octave_value (); + if (m_value.iscell ()) + { + Cell cval = m_value.cell_value (); + + return cval(r,c); + } + else if (m_value.isstruct ()) + { + if (m_value.numel () == 1) + { + // Scalar struct. Rows are fields, single column for + // values. + + octave_scalar_map m = m_value.scalar_map_value (); - Cell cval = m_value.cell_value (); + return m.contents (r); + } + else if (m_value.rows () == 1 || m_value.columns () == 1) + { + // Vector struct. Columns are fields, rows are values. + + octave_map m = m_value.map_value (); + + Cell cval = m.contents (c); - return cval.elem (r, c); + return cval(r); + } + else + { + // 2-d struct array. Rows and columns index individual + // scalar structs. + + octave_map m = m_value.map_value (); + + return m(r,c); + } + } + else + return octave_value (); } octave_value value_at (const QModelIndex& idx) const @@ -593,6 +785,13 @@ return m_d->quote_char (r, c); } +QVariant +variable_editor_model::headerData (int section, Qt::Orientation orientation, + int role) const +{ + return m_d->header_data (section, orientation, role); +} + QString variable_editor_model::subscript_expression (int r, int c) const { @@ -841,9 +1040,11 @@ variable_editor_model::type_is_editable (const octave_value& val, bool display_error) const { - if (((val.isnumeric () || val.islogical () || val.iscell ()) - && val.ndims () == 2) - || (val.is_string () && (val.rows () == 1 || val.is_zero_by_zero ()))) + if ((val.isnumeric () || val.islogical () || val.iscell () + || val.isstruct ()) && val.ndims () == 2) + return true; + + if (val.is_string () && (val.rows () == 1 || val.is_zero_by_zero ())) return true; if (display_error)
--- a/libgui/src/variable-editor-model.h Wed Jan 31 12:41:36 2018 -0800 +++ b/libgui/src/variable-editor-model.h Wed Jan 31 16:18:24 2018 -0500 @@ -94,6 +94,9 @@ char quote_char (int r, int c) const; + QVariant + headerData (int section, Qt::Orientation orientation, int role) 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).
--- a/libinterp/octave-value/ov-struct.cc Wed Jan 31 12:41:36 2018 -0800 +++ b/libinterp/octave-value/ov-struct.cc Wed Jan 31 16:18:24 2018 -0500 @@ -656,6 +656,33 @@ return dims.ndims () == 2 && dims(0) == 1 && dims(1) == 1; } +std::string +octave_struct::edit_display (octave_idx_type r, octave_idx_type c) const +{ + octave_value val; + if (map.rows () == 1 || map.columns () == 1) + { + // Vector struct. Columns are fields, rows are values. + + Cell cval = map.contents (c); + + val = cval(r); + } + else + { + // 2-d struct array. Rows and columns index individual + // scalar structs. + + val = map(r,c); + } + + std::string tname = val.type_name (); + dim_vector dv = val.dims (); + std::string dimstr = dv.str (); + return "[" + dimstr + " " + tname + "]"; +} + + bool octave_struct::save_ascii (std::ostream& os) { @@ -1331,6 +1358,19 @@ return retval; } +std::string +octave_scalar_struct::edit_display (octave_idx_type r, octave_idx_type) const +{ + // Scalar struct. Rows are fields, single column for values. + + octave_value val = map.contents (r); + + std::string tname = val.type_name (); + dim_vector dv = val.dims (); + std::string dimstr = dv.str (); + return "[" + dimstr + " " + tname + "]"; +} + bool octave_scalar_struct::save_ascii (std::ostream& os) {
--- a/libinterp/octave-value/ov-struct.h Wed Jan 31 12:41:36 2018 -0800 +++ b/libinterp/octave-value/ov-struct.h Wed Jan 31 16:18:24 2018 -0500 @@ -131,6 +131,8 @@ bool print_name_tag (std::ostream& os, const std::string& name) 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); @@ -252,6 +254,8 @@ bool print_name_tag (std::ostream& os, const std::string& name) 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);