# HG changeset patch
# User Pantxo Diribarne <pantxo.diribarne@gmail.com>
# Date 1398093435 -7200
# Node ID 25c62e62f10904bb1cd51864322d2d6d9a41de3d
# Parent  65f19ac3cd1bace5fd80a27d0e0489391e7feb01
Add callbacks for root properties format and formatspacing (bug #42135)

* graphics.in.h (root format and formatspacing properties) define custom get and set methods
* graphics.in.h (root format property) replace allowed value "rationale" (not supported by Fformat) by "rat" 
* pr-output.cc: new static variable format_string
* pr-output.cc (set_format_style): store the actual current format in format_string
* pr-output.cc (F__compactformat__): new defun to set/get the current Vcompactformat state
* pr-output.cc (F__formatstring__): new defun to set/get the current format string

diff -r 65f19ac3cd1b -r 25c62e62f109 libinterp/corefcn/graphics.in.h
--- a/libinterp/corefcn/graphics.in.h	Mon May 05 13:14:17 2014 -0700
+++ b/libinterp/corefcn/graphics.in.h	Mon Apr 21 17:17:15 2014 +0200
@@ -45,6 +45,7 @@
 #include "oct-refcount.h"
 #include "ov.h"
 #include "txt-eng-ft.h"
+#include "builtin-defun-decls.h"
 
 // FIXME: maybe this should be a configure option?
 // Matlab defaults to "Helvetica", but that causes problems for many
@@ -3107,20 +3108,16 @@
     // See the genprops.awk script for an explanation of the
     // properties declarations.
 
-    // FIXME: it seems strange to me that the diary, diaryfile,
-    // echo, errormessage, format, formatspacing, language, and
-    // recursionlimit properties are here.
-    // WTF do they have to do with graphics?
-    // Also note that these properties (and the monitorpositions,
+    // FIXME: Matlab defines some root properties and uses them in
+    // the same way that Octave uses an internal static variable to
+    // keep track of state.  set (0, "echo", "on") is equivalent
+    // to Octave's echo ("on"). Properties that still dont have callbacks
+    // are : diary, diaryfileecho, errormessage, language, and recursionlimit.
+    // Note that these properties (and the monitorpositions,
     // pointerlocation, and pointerwindow properties) are not yet used
     // by Octave, so setting them will have no effect, and changes
     // made elswhere (say, the diary or format functions) will not
     // cause these properties to be updated.
-    // ANSWER: Matlab defines these properties and uses them in
-    // the same way that Octave uses an internal static variable to
-    // keep track of state.  set (0, "echo", "on") is equivalent
-    // to Octave's echo ("on").  Maybe someday we can connect callbacks
-    // that actually call Octave's own functions for this.
 
     // Programming note: Keep property list sorted if new ones are added.
 
@@ -3133,8 +3130,8 @@
       bool_property echo , "off"
       string_property errormessage , ""
       string_property fixedwidthfontname , "Courier"
-      radio_property format , "+|bank|bit|hex|long|longe|longeng|longg|native-bit|native-hex|none|rational|{short}|shorte|shorteng|shortg"
-      radio_property formatspacing , "compact|{loose}"
+      radio_property format gs , "+|bank|bit|hex|long|longe|longeng|longg|native-bit|native-hex|none|rat|{short}|shorte|shorteng|shortg"
+      radio_property formatspacing gs , "compact|{loose}"
       string_property language , "ascii"
       array_property monitorpositions , Matrix (1, 4, 0)
       array_property pointerlocation , Matrix (1, 2, 0)
@@ -3149,6 +3146,58 @@
 
   private:
     std::list<graphics_handle> cbo_stack;
+  
+    std::string get_formatspacing (void) const
+    {
+      bool iscompact = F__compactformat__ ()(0).bool_value ();
+      if (iscompact)
+        return std::string ("compact");
+      else
+        return std::string ("loose");
+    }
+
+    void set_formatspacing (const octave_value& val)
+    {
+      if (! error_state)
+        {
+          // Input checking and abrev. matching
+          formatspacing.set (val, false);
+          
+          if (! error_state)
+            {
+              std::string strval = formatspacing.current_value ();
+
+              if (strval == "compact")
+                F__compactformat__ (ovl (true));
+              else
+                F__compactformat__ (ovl (false));
+
+              formatspacing.run_listeners ();
+            }
+        }
+    }
+
+    std::string get_format (void) const
+    {
+      return F__formatstring__ ()(0).string_value ();
+    }
+
+    void set_format (const octave_value& val)
+    {
+      if (! error_state)
+        {
+          // Input checking and abrev. matching
+          format.set (val, false);
+          
+          if (! error_state)
+            {
+              Fformat (ovl (format.current_value ()));     
+
+              format.run_listeners ();
+            }
+        }
+    }
+
   };
 
 private:
diff -r 65f19ac3cd1b -r 25c62e62f109 libinterp/corefcn/pr-output.cc
--- a/libinterp/corefcn/pr-output.cc	Mon May 05 13:14:17 2014 -0700
+++ b/libinterp/corefcn/pr-output.cc	Mon Apr 21 17:17:15 2014 +0200
@@ -3612,20 +3612,25 @@
   Voutput_max_field_width = fw;
 }
 
+static std::string format_string ("short");
+
 static void
 set_format_style (int argc, const string_vector& argv)
 {
   int idx = 1;
+  std::string format;
 
   if (--argc > 0)
     {
       std::string arg = argv[idx++];
+      format = arg;
 
       if (arg == "short")
         {
           if (--argc > 0)
             {
               arg = argv[idx++];
+              format.append (arg);
 
               if (arg == "e")
                 {
@@ -3703,6 +3708,7 @@
           if (--argc > 0)
             {
               arg = argv[idx++];
+              format.append (arg);
 
               if (arg == "e")
                 {
@@ -3800,6 +3806,7 @@
           if (--argc > 0)
             {
               arg = argv[idx++];
+              format.append (arg);
 
               if (arg.length () == 3)
                 plus_format_chars = arg;
@@ -3838,21 +3845,30 @@
       else if (arg == "compact")
         {
           Vcompact_format = true;
+          return;
         }
       else if (arg == "loose")
         {
           Vcompact_format = false;
+          return;
         }
       else
-        error ("format: unrecognized format state '%s'", arg.c_str ());
+        {
+          error ("format: unrecognized format state '%s'", arg.c_str ());
+          return;
+        }  
     }
   else
     {
       init_format_state ();
       set_output_prec_and_fw (5, 10);
+      format = std::string ("short");
     }
+
+  format_string = format;
 }
 
+
 DEFUN (format, args, ,
        "-*- texinfo -*-\n\
 @deftypefn  {Command} {} format\n\
@@ -4037,6 +4053,25 @@
   return retval;
 }
 
+DEFUN (__compactformat__, args, nargout,
+       "-*- texinfo -*-\n\
+@deftypefn  {Built-in Function} {@var{val} =} __compactformat__ ()\n\
+@deftypefnx {Built-in Function} {} __compactformat__ (@var{TRUE|FALSE})\n\
+Undocumented internal function\n\
+@end deftypefn")
+{
+  return SET_INTERNAL_VARIABLE (compact_format);
+}
+
+DEFUN (__formatstring__, args, nargout,
+       "-*- texinfo -*-\n\
+@deftypefn  {Built-in Function} {@var{val} =} __formatstring__ ()\n\
+Undocumented internal function\n\
+@end deftypefn")
+{
+  return ovl (format_string);
+}
+
 DEFUN (fixed_point_format, args, nargout,
        "-*- texinfo -*-\n\
 @deftypefn  {Built-in Function} {@var{val} =} fixed_point_format ()\n\
