# HG changeset patch # User Colin Macdonald # Date 1430405226 -3600 # Thu Apr 30 15:47:06 2015 +0100 # Node ID a29374f709a5f334d39c57fc3d4fe8585b45b3d5 # Parent 522bfe4f2d2773442ef79875836416e3b69a3324 Attempt to improve cell array printing with user classes Instead of calling "display", call "disp", return string and then line-by-line indent that string. This removes a lot of freedom from how a class displays itself so we only do this when printing cell-arrays (rather than on general display). We introduce a new "print_with_name_force_indent" which in most cases just calls the original "print_with_name". But for user classes it implements the above. classdef will need to implement "print_with_name_force_indent" too, not done so here. diff -r 522bfe4f2d27 -r a29374f709a5 libinterp/octave-value/ov-base.cc --- a/libinterp/octave-value/ov-base.cc Thu Apr 30 15:35:12 2015 +0100 +++ b/libinterp/octave-value/ov-base.cc Thu Apr 30 15:47:06 2015 +0100 @@ -446,6 +446,14 @@ } void +octave_base_value::print_with_name_force_indent (std::ostream& output_buf, + const std::string& name, + bool print_padding) +{ + print_with_name (output_buf, name, print_padding); +} + +void octave_base_value::print_info (std::ostream& os, const std::string& /* prefix */) const { diff -r 522bfe4f2d27 -r a29374f709a5 libinterp/octave-value/ov-base.h --- a/libinterp/octave-value/ov-base.h Thu Apr 30 15:35:12 2015 +0100 +++ b/libinterp/octave-value/ov-base.h Thu Apr 30 15:47:06 2015 +0100 @@ -623,6 +623,10 @@ print_with_name (std::ostream& output_buf, const std::string& name, bool print_padding = true); + virtual void + print_with_name_force_indent (std::ostream& output_buf, + const std::string& name, bool print_padding); + virtual void short_disp (std::ostream& os) const { os << "..."; } virtual void print_info (std::ostream& os, const std::string& prefix) const; diff -r 522bfe4f2d27 -r a29374f709a5 libinterp/octave-value/ov-cell.cc --- a/libinterp/octave-value/ov-cell.cc Thu Apr 30 15:35:12 2015 +0100 +++ b/libinterp/octave-value/ov-cell.cc Thu Apr 30 15:47:06 2015 +0100 @@ -722,7 +722,15 @@ octave_value val = matrix(i,j); - val.print_with_name (os, buf.str ()); + // TODO: Dev note: remove before committing + // I didn't see a way to find a regular nonclassdef + // class and besides this is not very OO: + //if (val.is_classdef_object()) + // do something special + //else + // val.print_with_name (os, buf.str ()); + + val.print_with_name_force_indent (os, buf.str ()); } } diff -r 522bfe4f2d27 -r a29374f709a5 libinterp/octave-value/ov-class.cc --- a/libinterp/octave-value/ov-class.cc Thu Apr 30 15:35:12 2015 +0100 +++ b/libinterp/octave-value/ov-class.cc Thu Apr 30 15:47:06 2015 +0100 @@ -1132,6 +1132,71 @@ } } +void +octave_class::print_with_name_force_indent (std::ostream& os, + const std::string& name, + bool) +{ + octave_value fcn = symbol_table::find_method ("disp", class_name ()); + + if (fcn.is_defined ()) + { + octave_value_list args, retvals; + std::string mystr; + + count++; + args(0) = octave_value (this); + + string_vector arg_names (1); + + arg_names[0] = name; + + args.stash_name_tags (arg_names); + + retvals = feval (fcn.function_value (), args, 1); + + if (!error_state && retvals.length () == 1 && retvals(0).is_string ()) + { + std::string line; + mystr = retvals(0).string_value (); + int linecount = 0; + std::stringstream ss(mystr); + while (std::getline (ss, line)) + linecount++; + + if (linecount <= 1) + { + indent (os); + os << name << " = " << mystr; + newline (os); + } + else + { + indent (os); + os << name << " = "; + newline (os); + std::stringstream ss(mystr); + while (std::getline (ss, line)) + { + indent(os); + os << line; + newline(os); + } + } + } + else + { + error ("'disp' method did not return a string?"); + } + } + else + { + indent (os); + os << name << " = "; + newline (os); + } +} + // Loading a class properly requires an exemplar map entry for success. // If we don't have one, we attempt to create one by calling the constructor // with no arguments. diff -r 522bfe4f2d27 -r a29374f709a5 libinterp/octave-value/ov-class.h --- a/libinterp/octave-value/ov-class.h Thu Apr 30 15:35:12 2015 +0100 +++ b/libinterp/octave-value/ov-class.h Thu Apr 30 15:47:06 2015 +0100 @@ -179,6 +179,9 @@ void print_with_name (std::ostream& os, const std::string& name, bool print_padding = true); + void print_with_name_force_indent (std::ostream& os, const std::string& name, + bool print_padding = true); + bool reconstruct_exemplar (void); static void clear_exemplar_map (void); diff -r 522bfe4f2d27 -r a29374f709a5 libinterp/octave-value/ov.h --- a/libinterp/octave-value/ov.h Thu Apr 30 15:35:12 2015 +0100 +++ b/libinterp/octave-value/ov.h Thu Apr 30 15:47:06 2015 +0100 @@ -1040,6 +1040,9 @@ void print_with_name (std::ostream& os, const std::string& name) const { rep->print_with_name (os, name, true); } + void print_with_name_force_indent (std::ostream& os, const std::string& name) const + { rep->print_with_name_force_indent (os, name, true); } + void short_disp (std::ostream& os) const { rep->short_disp (os); } int type_id (void) const { return rep->type_id (); }