# HG changeset patch
# User Pantxo Diribarne <pantxo.diribarne@gmail.com>
# Date 1392811657 -3600
# Node ID 2e3e74028a05c9daf21ee01fefab435083372768
# Parent  079d196e5d61adb211b18c344a78829a6161389f
set: check if property is read-only

* graphics.cc: Add static "is_readonly" function
* graphics.cc (base_graphics_object::values_as_struct, 
  values_as_string, value_as_string): call is_readonly to avoid
  returning read-only properties
* Fset: make set (h, "prop") report if "prop" is read-only

diff -r 079d196e5d61 -r 2e3e74028a05 libinterp/corefcn/graphics.cc
--- a/libinterp/corefcn/graphics.cc	Tue Feb 18 16:55:08 2014 +0100
+++ b/libinterp/corefcn/graphics.cc	Wed Feb 19 13:07:37 2014 +0100
@@ -2976,10 +2976,40 @@
     }
 }
 
+
+static bool
+is_readonly (const graphics_object obj, 
+             const std::string& pname)
+{
+  bool retval = false;
+
+  if (obj.isa ("root_figure"))
+      retval = root_figure::properties::has_readonly_property (pname);
+  else if (obj.isa ("figure"))
+      retval = figure::properties::has_readonly_property (pname);
+  else if (obj.isa ("axes"))
+      retval = axes::properties::has_readonly_property (pname);
+  else if (obj.isa ("hggroup"))
+      retval = hggroup::properties::has_readonly_property (pname);
+  else if (obj.isa ("line"))
+      retval = line::properties::has_readonly_property (pname);
+  else if (obj.isa ("image"))
+      retval = image::properties::has_readonly_property (pname);
+  else if (obj.isa ("surface"))
+      retval = surface::properties::has_readonly_property (pname);
+  else if (obj.isa ("patch"))
+      retval = patch::properties::has_readonly_property (pname);
+  else if (obj.isa ("text"))
+      retval = text::properties::has_readonly_property (pname);
+  
+  return retval;
+}
+
 std::string
 base_graphics_object::values_as_string (void)
 {
   std::string retval;
+  graphics_object obj = gh_manager::get_object (get_handle ());
 
   if (valid_object ())
     {
@@ -2987,7 +3017,7 @@
 
       for (octave_map::const_iterator pa = m.begin (); pa != m.end (); pa++)
         {
-          if (pa->first != "children")
+          if (pa->first != "children"&& ! is_readonly (obj, pa->first))
             {
               property p = get_properties ().get_property (pa->first);
 
@@ -3013,8 +3043,9 @@
 base_graphics_object::value_as_string (const std::string& prop)
 {
   std::string retval;
-
-  if (valid_object ())
+  graphics_object obj = gh_manager::get_object (get_handle ());
+
+  if (valid_object () && ! is_readonly (obj, prop))
     {
       if (prop != "children")
         {
@@ -3040,6 +3071,7 @@
 base_graphics_object::values_as_struct (void)
 {
   octave_scalar_map retval;
+  graphics_object obj = gh_manager::get_object (get_handle ());
 
   if (valid_object ())
     {
@@ -3048,10 +3080,11 @@
       for (octave_scalar_map::const_iterator pa = m.begin ();
            pa != m.end (); pa++)
         {
-          if (pa->first != "children")
+          if (pa->first != "children" &&
+              ! is_readonly (obj, pa->first))
             {
               property p = get_properties ().get_property (pa->first);
-
+              
               if (p.ok () && ! p.is_hidden ())
                 {
                   if (p.is_radio ())
@@ -8776,22 +8809,32 @@
                     {
                       std::string property = args(1).string_value ();
                       
-                      octave_map pmap = obj.values_as_struct ();
-
-                      if (pmap.isfield (property))
+                      if (! is_readonly (obj, property))
                         {
-                          if (nargout != 0)
-                            retval = pmap.getfield (property)(0);
+                          octave_map pmap = obj.values_as_struct ();
+
+                          if (pmap.isfield (property))
+                            {
+                              if (nargout != 0)
+                                retval = pmap.getfield (property)(0);
+                              else
+                                {
+                                  std::string 
+                                    s = obj.value_as_string (property);
+                                  if (! error_state)
+                                    octave_stdout << s;
+                                }
+                            }
                           else
                             {
-                              std::string s = obj.value_as_string (property);
-                              if (! error_state)
-                                octave_stdout << s;
+                              error ("set: unknown property");
+                              break;
                             }
                         }
                       else
                         {
-                          error ("set: unknown property");
+                          error ("set: \"%s\" is read-only", 
+                                 property.c_str ());
                           break;
                         }
                     }
