# HG changeset patch
# User pantxo <pantxo.diribarne@gmail.com>
# Date 1395396328 -3600
# Node ID d2c0a74168bafb92c47977a4c6f36184845af3e7
# Parent  5556ddfb841b4138e9ec03694263aee955b86321
Freset: properly reset graphics objects (bug #35511)

* graphics.in.h (base_graphics_object, graphics_object, root): add new method "get_factory_defaults_list" to retrieve factory defaults as property_list
* graphics.in.h (base_graphics_object::reset_default_properties (void)): move definition to graphics.cc

* graphics.cc (xreset_default_properties): new function to set a list of prop/val
* graphics.cc (base_graphics_object::reset_default_properties): use xreset_default_properties, override with parents' defaults
* graphics.cc (root_figure::reset_default_properties, figure::reset_default_properties,  uitoolbar::reset_default_properties): same as above but first empty local defaults and finally restore undmofified properties if necessary
* graphics.cc (axes_figure::reset_default_properties): same as above but use "propeties.set_defaults" to reset properties to their factory value.
* graphics.cc (axes_figure::properties::set_defaults): new "reset" mode (does the same as replace). The method now resets text children x/y/zlabels and title instead of deleting/recreating them.

diff -r 5556ddfb841b -r d2c0a74168ba libinterp/corefcn/graphics.cc
--- a/libinterp/corefcn/graphics.cc	Sun May 25 13:13:17 2014 -0700
+++ b/libinterp/corefcn/graphics.cc	Fri Mar 21 11:05:28 2014 +0100
@@ -2739,6 +2739,38 @@
   finalize (go);
 }
 
+static void
+xreset_default_properties (graphics_handle gh,
+                           property_list::pval_map_type factory_pval)
+{
+  graphics_object obj = gh_manager::get_object (gh);
+
+  property_list::pval_map_type pval;
+
+  for (property_list::pval_map_const_iterator it = factory_pval.begin ();
+     it != factory_pval.end (); it++)
+    {
+      std::string pname = it->first;
+
+      if (! obj.has_readonly_property (pname) &&
+          pname.find ("ui") != 0 &&
+          pname.find ("__") != 0)
+        {
+          // Store *mode prop/val in order to set theim last 
+          if (pname.find ("mode") == (pname.length () - 4))
+            pval.insert (std::pair<std::string, octave_value>
+                         (pname, it->second));
+          else
+            obj.set (it->first, it->second);
+        }
+    }
+
+  // set *mode properties
+  for (property_list::pval_map_const_iterator it = pval.begin ();
+       it != pval.end (); it++)
+    obj.set (it->first, it->second);
+}
+
 // ---------------------------------------------------------------------
 
 void
@@ -2758,7 +2790,7 @@
            q++)
         {
           std::string pname = q->first;
-
+          
           obj.set (pname, q->second);
 
           if (error_state)
@@ -3070,6 +3102,21 @@
     }
 }
 
+void 
+base_graphics_object::reset_default_properties (void)
+  {
+    if (valid_object ())
+      {
+        property_list::pval_map_type factory_pval = 
+          gh_manager::get_object (0).get_factory_defaults_list ()
+          .find (type ())->second;
+        
+        xreset_default_properties (get_handle (), factory_pval);
+
+        override_defaults (*this);
+      }
+  }
+
 std::string
 base_graphics_object::values_as_string (void)
 {
@@ -3554,39 +3601,14 @@
 property_list
 root_figure::factory_properties = root_figure::init_factory_properties ();
 
-static void
-reset_default_properties (property_list& default_properties)
-{
-  property_list new_defaults;
-
-  for (property_list::plist_map_const_iterator p = default_properties.begin ();
-       p != default_properties.end (); p++)
-    {
-      const property_list::pval_map_type pval_map = p->second;
-      std::string prefix = p->first;
-
-      for (property_list::pval_map_const_iterator q = pval_map.begin ();
-           q != pval_map.end ();
-           q++)
-        {
-          std::string s = q->first;
-
-          if (prefix == "axes" && (s == "position" || s == "units"))
-            new_defaults.set (prefix + s, q->second);
-          else if (prefix == "figure" && (s == "position" || s == "units"
-                                          || s == "windowstyle"
-                                          || s == "paperunits"))
-            new_defaults.set (prefix + s, q->second);
-        }
-    }
-
-  default_properties = new_defaults;
-}
-
 void
 root_figure::reset_default_properties (void)
 {
-  ::reset_default_properties (default_properties);
+  // empty list of local defaults
+  default_properties = property_list ();
+
+  xreset_default_properties (get_handle (), 
+                             xproperties.factory_defaults ());
 }
 
 // ---------------------------------------------------------------------
@@ -4407,7 +4429,25 @@
 void
 figure::reset_default_properties (void)
 {
-  ::reset_default_properties (default_properties);
+  octave_value position = xproperties.get_position ();
+  octave_value units = xproperties.get_units ();
+  octave_value windowstyle = xproperties.get_windowstyle ();
+  octave_value paperunits = xproperties.get_paperunits ();
+
+  // empty list of local defaults
+  default_properties = property_list ();
+
+  xreset_default_properties (get_handle (), 
+                             xproperties.factory_defaults ());
+
+  // override with parents' defaults
+  override_defaults (*this);
+
+  // restore unmodified properties
+  xproperties.set_position (position);
+  xproperties.set_units (units);
+  xproperties.set_windowstyle (windowstyle);
+  xproperties.set_paperunits (paperunits);
 }
 
 // ---------------------------------------------------------------------
@@ -4828,27 +4868,24 @@
 
   visible = "on";
 
-  // Replace preserves Position and Units properties
-  if (mode != "replace")
+  // Replace/Reset preserves Position and Units properties
+  if (mode != "replace" && mode != "reset")
     {
       outerposition = default_axes_outerposition ();
       position = default_axes_position ();
       activepositionproperty = "outerposition";
     }
 
-  delete_children (true);
-
-  xlabel = gh_manager::make_graphics_handle ("text", __myhandle__,
-                                             false, false);
-
-  ylabel = gh_manager::make_graphics_handle ("text", __myhandle__,
-                                             false, false);
-
-  zlabel = gh_manager::make_graphics_handle ("text", __myhandle__,
-                                             false, false);
-
-  title = gh_manager::make_graphics_handle ("text", __myhandle__,
-                                            false, false);
+  // Reset text child properties
+  graphics_object xl = gh_manager::get_object (xlabel.handle_value ());
+  xl.reset_default_properties ();
+  graphics_object yl = gh_manager::get_object (ylabel.handle_value ());
+  yl.reset_default_properties ();
+  graphics_object zl = gh_manager::get_object (zlabel.handle_value ());
+  zl.reset_default_properties ();
+  graphics_object tit = gh_manager::get_object (title.handle_value ());
+  tit.reset_default_properties ();
+
 
   xset (xlabel.handle_value (), "handlevisibility", "off");
   xset (ylabel.handle_value (), "handlevisibility", "off");
@@ -4886,11 +4923,6 @@
   xset (zlabel.handle_value (), "autopos_tag", "zlabel");
   xset (title.handle_value (), "autopos_tag", "title");
 
-  adopt (xlabel.handle_value ());
-  adopt (ylabel.handle_value ());
-  adopt (zlabel.handle_value ());
-  adopt (title.handle_value ());
-
   update_transform ();
   sync_positions ();
   override_defaults (obj);
@@ -7562,7 +7594,18 @@
 void
 axes::reset_default_properties (void)
 {
-  ::reset_default_properties (default_properties);
+  octave_value position = xproperties.get_position ();
+  octave_value units = xproperties.get_units ();
+
+  // empty list of local defaults
+  default_properties = property_list ();
+
+  // reset factory defaults
+  set_defaults ("reset");
+
+  // restore unmodified properties
+  xproperties.set_position (position);
+  xproperties.set_units (units);
 }
 
 void
@@ -8407,7 +8450,14 @@
 void
 uitoolbar::reset_default_properties (void)
 {
-  ::reset_default_properties (default_properties);
+  // empty list of local defaults
+  default_properties = property_list ();
+
+  xreset_default_properties (get_handle (), 
+                             xproperties.factory_defaults ());
+
+  // override with parents' defaults
+  override_defaults (*this);
 }
 
 // ---------------------------------------------------------------------
@@ -9055,6 +9105,9 @@
           // loop over graphics objects
           for (octave_idx_type n = 0; n < hcv.length (); n++)
             gh_manager::get_object (hcv(n)).reset_default_properties ();
+
+          if (! error_state)
+            Fdrawnow ();
         }
     }
 
diff -r 5556ddfb841b -r d2c0a74168ba libinterp/corefcn/graphics.in.h
--- a/libinterp/corefcn/graphics.in.h	Sun May 25 13:13:17 2014 -0700
+++ b/libinterp/corefcn/graphics.in.h	Fri Mar 21 11:05:28 2014 +0100
@@ -2698,6 +2698,12 @@
     return octave_value ();
   }
 
+  virtual property_list get_factory_defaults_list (void) const
+  {
+    error ("base_graphics_object::get_factory_defaults_list: invalid graphics object");
+    return property_list ();
+  }
+
   virtual bool has_readonly_property (const caseless_str& pname) const
   {
     return base_properties::has_readonly_property (pname);
@@ -2829,16 +2835,7 @@
 
   virtual void remove_all_listeners (void);
 
-  virtual void reset_default_properties (void)
-  {
-    if (valid_object ())
-      {
-        std::string msg = (type () + "::reset_default_properties");
-        gripe_not_implemented (msg.c_str ());
-      }
-    else
-      error ("base_graphics_object::default: invalid graphics object");
-  }
+  virtual void reset_default_properties (void);
 
 protected:
   virtual void initialize (const graphics_object& go)
@@ -2976,6 +2973,11 @@
     return rep->get_factory_defaults ();
   }
 
+  property_list get_factory_defaults_list (void) const
+  {
+    return rep->get_factory_defaults_list ();
+  }
+
   bool has_readonly_property (const caseless_str& pname) const
   {
     return rep->has_readonly_property (pname);
@@ -3225,6 +3227,11 @@
     return factory_properties.as_struct ("factory");
   }
 
+  property_list get_factory_defaults_list (void) const
+  {
+    return factory_properties;
+  }
+
   base_properties& get_properties (void) { return xproperties; }
 
   const base_properties& get_properties (void) const { return xproperties; }
