changeset 20077:69f92e0affd2

Handle uicontextmenu deletion/reset (bug #44801) *graphics.in.h (base_graphics_opbject::properties): add updater for uicontextmenu property *graphics.in.h (uicontextmenu::properties::dependent_obj_list): new private attribute to store the list of objects that may depend on this uicontextmenu. *graphics.in.h (uicontextmenu::properties::get_dependent_obj_list (), uicontextmenu::properties::add_dependent_obj ()): new methods * graphics.cc (base_graphics_opbject::properties::update_uicontextmenu): new method to mark this graphics object as dependent on an uicontextmenu object. * graphics.cc (uicontextmenu::~uicontextmenu): reset the "uicontextmenu" property of objects that have this uicontextmenu as current. * graphics.cc (handle_property::do_set): let users reset a handle property using empty matrix. * graphics.cc: add BIST for bug #44801 * genpropdoc.m: document "uicontextmenu" property
author Pantxo Diribarne <pantxo.diribarne@gmail.com>
date Sat, 11 Apr 2015 17:25:35 +0200
parents a00d545c95df
children 2d638e67aeef
files doc/interpreter/genpropdoc.m libinterp/corefcn/graphics.cc libinterp/corefcn/graphics.in.h
diffstat 3 files changed, 93 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/doc/interpreter/genpropdoc.m	Tue Apr 14 14:27:22 2015 -0400
+++ b/doc/interpreter/genpropdoc.m	Sat Apr 11 17:25:35 2015 +0200
@@ -166,6 +166,10 @@
         s.printdefault = false;
 
       case "uicontextmenu"
+        s.doc = "Graphics handle of the uicontextmenu object that is \
+currently associated to this __objname__ object.";
+        s.valid = valid_handle;
+        
       case "userdata"
         s.doc = "User-defined data to associate with the graphics object.";
         s.valid = "Any Octave data";
--- a/libinterp/corefcn/graphics.cc	Tue Apr 14 14:27:22 2015 -0400
+++ b/libinterp/corefcn/graphics.cc	Sat Apr 11 17:25:35 2015 +0200
@@ -1473,6 +1473,18 @@
 bool
 handle_property::do_set (const octave_value& v)
 {
+  // Users may want to use empty matrix to reset a handle property
+  if (v.is_empty ())
+    {
+      if (! get ().is_empty ())
+        {
+          current_val = graphics_handle ();
+          return true;
+        }
+      else
+        return false;
+    }
+
   double dv = v.double_value ();
 
   if (! error_state)
@@ -3085,6 +3097,21 @@
     obj.update_axis_limits (axis_type, h);
 }
 
+void
+base_properties::update_uicontextmenu (void) const
+{
+  if (uicontextmenu.get ().is_empty ())
+    return;
+  
+  graphics_object obj = gh_manager::get_object (uicontextmenu.get ());
+  if (obj && obj.isa ("uicontextmenu"))
+    {
+      uicontextmenu::properties& props =
+        reinterpret_cast<uicontextmenu::properties&> (obj.get_properties ());
+      props.add_dependent_obj (__myhandle__);
+    }
+}
+
 bool
 base_properties::is_handle_visible (void) const
 {
@@ -8813,6 +8840,51 @@
 
 // ---------------------------------------------------------------------
 
+uicontextmenu::~uicontextmenu (void)
+{ 
+  std::list<graphics_handle> lst = xproperties.get_dependent_obj_list ();
+  std::list<graphics_handle>::const_iterator it;
+  
+  for (it = lst.begin (); it != lst.end (); it++)
+    {
+      graphics_object go = gh_manager::get_object (*it);
+      
+      if (go.valid_object () &&
+          go.get ("uicontextmenu") == xproperties.get___myhandle__ ())
+        go.set ("uicontextmenu", Matrix ());
+    }
+}
+
+
+/*
+## Test deletion/reset of uicontextmenu
+%!test
+%! hf = figure ("visible", "off");
+%! hax = axes ("parent", hf);
+%! unwind_protect
+%!   hctx1 = uicontextmenu ("parent", hf);
+%!   hctx2 = uicontextmenu ("parent", hf);
+%!   set (hf, "uicontextmenu", hctx2);
+%!   set (hax, "uicontextmenu", hctx2);
+%!   assert (get (hf, "uicontextmenu"), hctx2);
+%!   assert (get (hax, "uicontextmenu"), hctx2);
+%!   assert (get (hf, "children"), [hctx2; hctx1; hax]);
+%!   delete (hctx2);
+%!   assert (get (hf, "uicontextmenu"), []);
+%!   assert (get (hax, "uicontextmenu"), []);
+%!   assert (get (hf, "children"), [hctx1; hax]);
+%!   set (hf, "uicontextmenu", hctx1);
+%!   assert (get (hf, "uicontextmenu"), hctx1);
+%!   set (hf, "uicontextmenu", []);
+%!   assert (get (hf, "uicontextmenu"), []);
+%!   assert (get (hf, "children"), [hctx1; hax]);
+%! unwind_protect_cleanup
+%!   close (hf);
+%! end_unwind_protect;
+ */
+
+// ---------------------------------------------------------------------
+
 octave_value
 uicontrol::properties::get_extent (void) const
 {
--- a/libinterp/corefcn/graphics.in.h	Tue Apr 14 14:27:22 2015 -0400
+++ b/libinterp/corefcn/graphics.in.h	Sat Apr 11 17:25:35 2015 +0200
@@ -2595,6 +2595,8 @@
   virtual void update_axis_limits (const std::string& axis_type,
                                    const graphics_handle& h) const;
 
+  virtual void update_uicontextmenu (void) const;
+
   virtual void delete_children (bool clear = false)
   {
     children.delete_children (clear);
@@ -2663,7 +2665,7 @@
     bool_property selectionhighlight , "on"
     string_property tag s , ""
     string_property type frs , ty
-    handle_property uicontextmenu , graphics_handle ()
+    handle_property uicontextmenu u , graphics_handle ()
     any_property userdata , Matrix ()
     bool_property visible , "on"
     // additional (Octave-specific) properties
@@ -5355,6 +5357,15 @@
   class OCTINTERP_API properties : public base_properties
   {
   public:
+  
+    void add_dependent_obj (graphics_handle gh) 
+    { dependent_obj_list.push_back (gh); }
+
+    // FIXME: the list may contain duplicates. 
+    //        Should we return only unique elements? 
+    const std::list<graphics_handle> get_dependent_obj_list (void) 
+    { return dependent_obj_list; }
+
     // See the genprops.awk script for an explanation of the
     // properties declarations.
     // Programming note: Keep property list sorted if new ones are added.
@@ -5372,6 +5383,10 @@
       position.add_constraint (dim_vector (2, 1));
       visible.set (octave_value (true));
     }
+
+  private:
+    // List of objects that might depend on this uicontextmenu object
+    std::list<graphics_handle> dependent_obj_list;
   };
 
 private:
@@ -5382,7 +5397,7 @@
     : base_graphics_object (), xproperties (mh, p)
   { }
 
-  ~uicontextmenu (void) { }
+  ~uicontextmenu (void);
 
   base_properties& get_properties (void) { return xproperties; }