changeset 12339:eda5eabd5d0b

Fix for inline legends (#32022, #32343)
author David Bateman <dbateman@free.fr>
date Sat, 05 Feb 2011 10:19:13 -0500
parents 591f75ffa968
children d63007ac067a
files scripts/ChangeLog scripts/plot/legend.m scripts/plot/module.mk scripts/plot/private/__getlegenddata__.m scripts/plot/private/__plt__.m
diffstat 5 files changed, 113 insertions(+), 54 deletions(-) [+]
line wrap: on
line diff
--- a/scripts/ChangeLog
+++ b/scripts/ChangeLog
@@ -1,3 +1,17 @@
+2011-02-05  David Bateman  <dbateman@free.fr>
+
+	Bug #32022 and #32343.
+
+	* plot/legend.m (updatelegend): Don't flip plots when resetting the
+	legend. Use unwind_protect to ensure that the resursive flag is reset
+	in case of an error.
+	(getlegenddata): Remove this function and replace its use with the
+	function __getlegenddata__.
+	* plot/privata/__getlegenddata__.m: New function
+	* plot/module.mk (plot_PRIVATE_FCN_FILES): Add it here.
+	* plot/private/__plt__.m: Set initial values of hlgnd and tlgnd
+	if a legend exists already.
+
 2010-02-02  Rik  <octave@nomad.inbox5.com>
 
 	* sparse/svds.m: Use testif to only run some sparse tests when
--- a/scripts/plot/legend.m
+++ b/scripts/plot/legend.m
@@ -775,10 +775,13 @@
   persistent recursive = false;
   if (! recursive)
     recursive = true;
-    hax = getfield (get (h, "userdata"), "handle");
-    [hplots, text_strings] = getlegenddata (h);
-    h = legend (hax, flipud (hplots), get (h, "string"));
-    recursive = false;
+    unwind_protect
+      hax = getfield (get (h, "userdata"), "handle");
+      [hplots, text_strings] = __getlegenddata__ (h);
+      h = legend (hax, hplots, get (h, "string"));
+    unwind_protect_cleanup
+      recursive = false;
+    end_unwind_protect
   endif
 endfunction
 
@@ -895,7 +898,7 @@
        && (! isempty (lm) || isempty (ll)))
     ## An element was removed from the legend. Need to recall the
     ## legend function to recreate a new legend
-    [hplots, text_strings] = getlegenddata (hlegend);
+    [hplots, text_strings] = __getlegenddata__ (hlegend);
     for i = 1 : numel (hplots)
       if (hplots (i) == h)
         hplots(i) = [];
@@ -909,7 +912,7 @@
           && isempty (lm) && isempty (ll))
     ## An element was added to the legend. Need to recall the
     ## legend function to recreate a new legend
-    [hplots, text_strings] = getlegenddata (hlegend);
+    [hplots, text_strings] = __getlegenddata__ (hlegend);
     hplots = [hplots, h];
     text_strings = {text_strings{:}, displayname};
     legend (hplots, text_strings);
@@ -945,47 +948,6 @@
   endif
 endfunction
 
-function [hplots, text_strings] = getlegenddata (hlegend)
-  hplots = [];
-  text_strings = {};
-  ca = getfield (get (hlegend, "userdata"), "handle");
-  kids = [];
-  for i = 1  : numel (ca)
-    kids = [kids; get(ca (i), "children")];
-  endfor
-  k = numel (kids);
-  while (k > 0)
-    typ = get (kids(k), "type");
-    while (k > 0
-           && ! (strcmp (typ, "line") || strcmp (typ, "surface")
-                 || strcmp (typ, "patch") || strcmp (typ, "hggroup")))
-      typ = get (kids(--k), "type");
-    endwhile
-    if (k > 0)
-      if (strcmp (get (kids(k), "type"), "hggroup"))
-        hgkids = get (kids(k), "children");
-        for j = 1 : length (hgkids)
-          hgobj = get (hgkids (j));
-          if (isfield (hgobj, "displayname")
-              && ! isempty (hgobj.displayname))
-            hplots = [hplots, hgkids(j)];
-            text_strings = {text_strings{:}, hbobj.displayname};
-            break;
-          endif
-        endfor
-      else
-        if (! isempty (get (kids (k), "displayname")))
-          hplots = [hplots, kids(k)];
-          text_strings = {text_strings{:}, get(kids (k), "displayname")};
-        endif
-      endif
-      if (--k == 0)
-        break;
-      endif
-    endif
-  endwhile
-endfunction
-
 %!demo
 %! clf
 %! x = 0:1;
--- a/scripts/plot/module.mk
+++ b/scripts/plot/module.mk
@@ -21,6 +21,7 @@
   plot/private/__ezplot__.m \
   plot/private/__fltk_file_filter__.m \
   plot/private/__ghostscript__.m \
+  plot/private/__getlegenddata__.m \
   plot/private/__gnuplot_has_terminal__.m\
   plot/private/__interp_cube__.m \
   plot/private/__line__.m \
new file mode 100644
--- /dev/null
+++ b/scripts/plot/private/__getlegenddata__.m
@@ -0,0 +1,63 @@
+## Copyright (C) 2010-2011 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{hplots}, @var{strings}]} = __getlegenddata__ (@var{h})
+## Undocumented internal function.
+## @end deftypefn
+
+function [hplots, text_strings] = __getlegenddata__ (hlegend)
+  hplots = [];
+  text_strings = {};
+  ca = getfield (get (hlegend, "userdata"), "handle");
+  kids = [];
+  for i = 1  : numel (ca)
+    kids = [kids; get(ca (i), "children")];
+  endfor
+  k = numel (kids);
+  while (k > 0)
+    typ = get (kids(k), "type");
+    while (k > 0
+           && ! (strcmp (typ, "line") || strcmp (typ, "surface")
+                 || strcmp (typ, "patch") || strcmp (typ, "hggroup")))
+      typ = get (kids(--k), "type");
+    endwhile
+    if (k > 0)
+      if (strcmp (get (kids(k), "type"), "hggroup"))
+        hgkids = get (kids(k), "children");
+        for j = 1 : length (hgkids)
+          hgobj = get (hgkids (j));
+          if (isfield (hgobj, "displayname")
+              && ! isempty (hgobj.displayname))
+            hplots = [hplots, hgkids(j)];
+            text_strings = {text_strings{:}, hbobj.displayname};
+            break;
+          endif
+        endfor
+      else
+        if (! isempty (get (kids (k), "displayname")))
+          hplots = [hplots, kids(k)];
+          text_strings = {text_strings{:}, get(kids (k), "displayname")};
+        endif
+      endif
+      if (--k == 0)
+        break;
+      endif
+    endif
+  endwhile
+endfunction
--- a/scripts/plot/private/__plt__.m
+++ b/scripts/plot/private/__plt__.m
@@ -36,8 +36,26 @@
     property_set = false;
     properties = {};
 
-    hlgnd = [];
-    tlgnd = {};
+    hlegend = [];
+    fkids = get (gcf(), "children");
+    for i = 1 : numel(fkids)
+      if (ishandle (fkids (i)) && strcmp (get (fkids (i), "type"), "axes")
+          && (strcmp (get (fkids (i), "tag"), "legend")))
+        udata = get (fkids (i), "userdata");
+        if (! isempty (intersect (udata.handle, gca ())))
+          hlegend = fkids (i);
+          break;
+        endif
+      endif
+    endfor
+
+    setlgnd = false;
+    if (isempty (hlegend))
+      hlgnd = [];
+      tlgnd = {};
+    else
+      [hlgnd, tlgnd] = __getlegenddata__ (hlegend);
+    endif
 
     ## Gather arguments, decode format, gather plot strings, and plot lines.
 
@@ -79,12 +97,12 @@
           endif
           if (y_set)
             tmp = __plt2__ (h, x, y, options, properties);
-            [hlgnd, tlgnd] = __plt_key__ (tmp, options, hlgnd, tlgnd);
+            [hlgnd, tlgnd, setlgnd] = __plt_key__ (tmp, options, hlgnd, tlgnd, setlgnd);
             properties = {};
             retval = [retval; tmp];
           else
             tmp = __plt1__ (h, x, options, properties);
-            [hlgnd, tlgnd] = __plt_key__ (tmp, options, hlgnd, tlgnd);
+            [hlgnd, tlgnd, setlgnd] = __plt_key__ (tmp, options, hlgnd, tlgnd, setlgnd);
             properties = {};
             retval = [retval; tmp];
           endif
@@ -97,7 +115,7 @@
         if (y_set)
           options = __pltopt__ (caller, {""});
           tmp = __plt2__ (h, x, y, options, properties);
-          [hlgnd, tlgnd] = __plt_key__ (tmp, options, hlgnd, tlgnd);
+          [hlgnd, tlgnd, setlgnd] = __plt_key__ (tmp, options, hlgnd, tlgnd, setlgnd);
           retval = [retval; tmp];
           x = next_arg;
           y_set = false;
@@ -113,7 +131,7 @@
 
     endwhile
 
-    if (!isempty (hlgnd))
+    if (setlgnd)
       legend (gca(), hlgnd, tlgnd);
     endif
   else
@@ -122,7 +140,7 @@
 
 endfunction
 
-function [hlgnd, tlgnd] = __plt_key__ (h, options, hlgnd, tlgnd)
+function [hlgnd, tlgnd, setlgnd] = __plt_key__ (h, options, hlgnd, tlgnd, setlgnd)
   n = numel (h);
   if (numel (options) == 1)
     options = repmat (options(:), n, 1);
@@ -133,6 +151,7 @@
     if (! isempty (key))
       hlgnd = [hlgnd(:); h(i)];
       tlgnd = {tlgnd{:}, key};
+      setlgnd = true;
     endif
   endfor
 endfunction