help-octave
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: findobj.m


From: David Bateman
Subject: Re: findobj.m
Date: Sun, 30 Sep 2007 17:47:40 +0200
User-agent: Thunderbird 1.5.0.7 (X11/20060921)

Ben Abbott wrote:
> David, I corrected an embarrassing oversight/error in the script that impacts 
> the "-regexp" functionality.  It appears to be working now, can you, or 
> anyone for that matter, verify? 
> 
> 
> On Thursday, September 27, 2007, at 08:37AM, "David Bateman" <address@hidden> 
> wrote:
>> I believe the attached version addresses the issues I mentioned with the
>> previous version of findobj.m. John do you want it?
>>
>> D.
>>
>> ------------------------------------------------------------------------
>>
>> _______________________________________________
>> Help-octave mailing list
>> address@hidden
>> https://www.cae.wisc.edu/mailman/listinfo/help-octave

Ok, I see the following

octave:1> plot(1:10)
octave:2> findobj('-regexp','type')
error: invalid vector index = 3
error: evaluating assignment expression near line 115, column 14
error: evaluating if command near line 110, column 7
error: evaluating if command near line 109, column 5
error: evaluating while command near line 105, column 3
error: called from `findobj' in file `/home/adb014/findobj.m'

Where I would expect a more informative error message. I fixed this in
the attached version. I then tried

octave:1> plot (1:10)
octave:2> findobj('-regexp','type','figure')
ans =

   0
   1

Which is the "root figure" and the "figure" itself, so it appears to
work. In any case I attach here the code as a patch against the CVS with
a changelog entry. John do you want this?

D.
*** ./scripts/plot/findobj.m.orig13     2007-09-30 17:43:53.033188449 +0200
--- ./scripts/plot/findobj.m    2007-09-30 17:39:14.594443325 +0200
***************
*** 0 ****
--- 1,234 ----
+ ## Copyright (C) 2007   Ben Abbott  <address@hidden>
+ ##
+ ## This program 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 2 of the License, or
+ ## (at your option) any later version.
+ ##
+ ## This program 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 this program; if not, write to the Free Software
+ ## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  
+ ## 02110-1301  USA
+ 
+ ## -*- texinfo -*-
+ ## @deftypefn {Function File} address@hidden =} findobj ()
+ ## @deftypefnx {Function File} address@hidden =} findobj (@var{propName}, 
@var{propValue})
+ ## @deftypefnx {Function File} address@hidden =} findobj ('-property', 
@var{propName})
+ ## @deftypefnx {Function File} address@hidden =} findobj ('-regexp', 
@var{propName},, @var{pattern})
+ ## @deftypefnx {Function File} address@hidden =} findobj ('flat', @dots{})
+ ## @deftypefnx {Function File} address@hidden =} findobj (@var{h}, @dots{})
+ ## @deftypefnx {Function File} address@hidden =} findobj (@var{h}, '-depth', 
@var{d}, @dots{})
+ ## Find object with specified property values. The simpliest form is
+ ##
+ ## @example
+ ## findobj (@var{propName}, @var{propValue})
+ ## @end example
+ ##
+ ## @noindent
+ ## which returns all of the handles to the objects with the name 
+ ## @var{propName} and the name @var{propValue}. The search can be limited
+ ## to a particular object or set of objects and their descendants by 
+ ## passing a handle or set of handles @var{h} as the first argument to 
+ ## @code{findobj}.
+ ##
+ ## The depth of hierarchy of objects to which to search to can be limited
+ ## with the '-depth' argument. To limit the number depth of the hierarchy
+ ## to search to @var{d} generations of children, and example is
+ ##
+ ## @example
+ ## findobj (@var{h}, '-depth', @var{d}, @var{propName}, @var{propValue})
+ ## @end example
+ ##
+ ## Specifying a depth @var{d} of 0, limits the search to the set of object
+ ## passed in @var{h}. A depth @var{d} of 0 is equivalent to the '-flat'
+ ## argument. 
+ ##
+ ## A specified logical operator may be applied to the pairs of @var{propName}
+ ## and @var{propValue}. The supported logical operators are '-and', '-or', 
+ ## '-xor', '-not'.
+ ##
+ ## The objects may also be matched by comparing a regular expression to the 
+ ## property values, where property values that match @code{regexp 
+ ## (@var{propValue}, @var{pattern})} are returned.  Finally, objects may be 
+ ## matched by property name only, using the '-property' option.
+ ## @seealso{get, set}
+ ## @end deftypefn
+ 
+ function h = findobj (varargin)
+ 
+   depth = NaN;
+   if (nargin == 0)
+     handles = 0;
+     n1 = 0;
+   else
+     if (ishandle (varargin{1}(1)))
+       handles = varargin{1};
+       n1 = 2;
+     else
+       handles = 0;
+       n1 = 1;
+     end
+     if (n1 <= nargin)
+       if (ischar (varargin{n1}))
+       if (strcmpi (varargin{n1}, 'flat'))
+         depth = 0;
+         n1 = n1 + 1;
+       elseif (strcmpi(varargin{n1}, '-depth'))
+         depth = varargin{n1+1};
+         n1 = n1 + 2;
+       endif
+       else
+       error ("findobj: properties and options must be strings");
+       endif
+     endif
+   endif
+ 
+   if (n1 <= nargin && nargin > 0)
+     args = varargin(n1 : nargin);
+   else
+     args = {};
+   endif
+ 
+   regularexpression = [];
+   property          = [];
+   logicaloperator   = {};
+   pname             = {};
+   pvalue            = {};
+   np = 1;
+   na = 1;
+ 
+   while (na <= numel (args))
+     regularexpression(np) = 0;
+     property(np) = 0;
+     logicaloperator{np} = 'and';
+     if (ischar (args {na}))
+       if (strcmpi(args{na}, '-regexp'))
+       if (na + 2 <= numel (args))
+         regularexpression(np) = 1;
+         na = na + 1;
+         pname{np} = args{na};
+         na = na + 1;
+         pvalue{np} = args{na};
+         na = na + 1;
+         np = np + 1;
+       else
+         error ("findobj: inconsistent number of arguments");
+       endif
+       elseif (strcmpi(args{na}, '-property'))
+       if (na + 1 <= numel (args))
+         na = na + 1;
+         property(np) = 1;
+         pname{np} = args{na};
+         na = na + 1;
+         pvalue{np} = [];
+         np = np + 1;
+       else
+         error ("findobj: inconsistent number of arguments");
+       endif
+       elseif (! strcmp (args{na}(1), '-')) # parameter/value pairs
+       if (na + 1 <= numel (args))
+         pname{np} = args{na};
+         na = na + 1;
+         pvalue{np} = args{na};
+         na = na + 1;
+         if (na <= numel(args))
+           if (ischar (args{na}))
+             if strcmpi(args{na}, '-and')
+               logicaloperator{np} = 'and';
+               na = na+1;
+             elseif strcmpi(args{na}, '-or')
+               logicaloperator{np} = 'or';
+               na = na+1;
+             elseif strcmpi(args{na}, '-xor')
+               logicaloperator{np} = 'xor';
+               na = na+1;
+             elseif strcmpi(args{na}, '-not')
+               logicaloperator{np} = 'not';
+               na = na+1;
+             endif
+           else
+             error ("findobj: properties and options must be strings");
+           endif
+         else
+           logicaloperator{np} = 'and';
+         endif
+         np = np + 1;
+       else
+         error ("findobj: inconsistent number of arguments");
+       endif
+       else
+       ## this is sloppy ... but works like matlab
+       if strcmpi(args{na}, '-not')
+         h = [];
+         return
+       endif
+       na = na + 1;
+       endif
+     else
+       error ("findobj: properties and options must be strings");
+     endif
+   endwhile
+ 
+   numpairs = np - 1;
+   
+   ## load all objects which qualify for being searched
+   idepth = 0;
+   h = handles;
+   while (numel (handles) && ! (idepth >= depth))
+     children = [];
+     for n = 1 : numel (handles)
+       children = union (children, get(handles(n), 'children'));
+     endfor 
+     handles = children;
+     h = union (h, children);
+     idepth = idepth + 1;
+   endwhile
+ 
+   keepers = ones (size (h));
+   if (numpairs > 0)
+     for nh = 1 : numel(h)
+       p = get (h (nh));
+       for np = 1 : numpairs
+       fields = fieldnames (p);
+       fieldindex = find (strcmpi (fields, pname{np}), 1);
+       if (numel (fieldindex))
+           pname{np} = fields{fieldindex};
+           if (property(np))
+             match = 1;
+           else
+             if (regularexpression(np))
+             match = regexp (p.(pname{np}), pvalue{np});
+               if isempty (match)
+                 match = 0;
+               end
+             elseif (numel (p.(pname{np})) == numel (pvalue{np}))
+             if (ischar (pvalue{np}))
+               match = strcmpi (pvalue{np}, p.(pname{np}));
+             else
+               match = (pvalue{np} == p.(pname{np}));
+             endif
+             else
+             match = 0;
+             endif
+             match = all (match);
+           endif
+           if (strcmpi (logicaloperator{np}, 'not'))
+             keepers(nh) = ! keepers(nh) & ! match;
+           else
+             keepers(nh) = feval (logicaloperator{np}, keepers(nh), match);
+           endif
+       else
+         keepers(nh) = 0;
+       endif
+       endfor
+     endfor
+   endif
+ 
+   h = h (keepers != 0);
+   h = reshape (h, [numel(h), 1]);
+ endfunction
*** ./scripts/plot/Makefile.in.orig13   2007-09-30 17:44:38.913839555 +0200
--- ./scripts/plot/Makefile.in  2007-09-30 17:44:14.880069981 +0200
***************
*** 60,65 ****
--- 60,66 ----
    drawnow.m \
    errorbar.m \
    figure.m \
+   findobj.m \
    fplot.m \
    gca.m \
    gcf.m \
2007-09-30  Ben Abbott  <address@hidden>

        * plot/findobj.m: New function.
        * plot/Makefile.m (SOURCES): Add it to SOURCES.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]