1 ## Copyright (C) 2007-2012 Ben Abbott
3 ## This file is part of Octave.
5 ## Octave is free software; you can redistribute it and/or modify it
6 ## under the terms of the GNU General Public License as published by
7 ## the Free Software Foundation; either version 3 of the License, or (at
8 ## your option) any later version.
10 ## Octave is distributed in the hope that it will be useful, but
11 ## WITHOUT ANY WARRANTY; without even the implied warranty of
12 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 ## General Public License for more details.
15 ## You should have received a copy of the GNU General Public License
16 ## along with Octave; see the file COPYING. If not, see
17 ## <http://www.gnu.org/licenses/>.
20 ## @deftypefn {Function File} {@var{h} =} findobj ()
21 ## @deftypefnx {Function File} {@var{h} =} findobj (@var{prop_name}, @var{prop_value})
22 ## @deftypefnx {Function File} {@var{h} =} findobj ("-property", @var{prop_name})
23 ## @deftypefnx {Function File} {@var{h} =} findobj ("-regexp", @var{prop_name}, @var{pattern})
24 ## @deftypefnx {Function File} {@var{h} =} findobj ("flat", @dots{})
25 ## @deftypefnx {Function File} {@var{h} =} findobj (@var{h}, @dots{})
26 ## @deftypefnx {Function File} {@var{h} =} findobj (@var{h}, "-depth", @var{d}, @dots{})
27 ## Find graphics object with specified property values. The simplest form is
30 ## findobj (@var{prop_name}, @var{prop_value})
34 ## which returns all of the handles to the objects with the name
35 ## @var{prop_name} and the name @var{prop_value}. The search can be limited
36 ## to a particular object or set of objects and their descendants by
37 ## passing a handle or set of handles @var{h} as the first argument to
40 ## The depth of hierarchy of objects to which to search to can be limited
41 ## with the "-depth" argument. To limit the number depth of the hierarchy
42 ## to search to @var{d} generations of children, and example is
45 ## findobj (@var{h}, "-depth", @var{d}, @var{prop_name}, @var{prop_value})
48 ## Specifying a depth @var{d} of 0, limits the search to the set of object
49 ## passed in @var{h}. A depth @var{d} of 0 is equivalent to the "-flat"
52 ## A specified logical operator may be applied to the pairs of @var{prop_name}
53 ## and @var{prop_value}. The supported logical operators are "-and", "-or",
56 ## The objects may also be matched by comparing a regular expression to the
57 ## property values, where property values that match @code{regexp
58 ## (@var{prop_value}, @var{pattern})} are returned. Finally, objects may be
59 ## matched by property name only, using the "-property" option.
63 ## Author: Ben Abbott <bpabbott@mac.com>
65 function h = findobj (varargin)
72 if (! isempty (varargin{1}))
73 if (ishandle (varargin{1}(1)))
74 handles = varargin{1};
81 ## Return [](0x1) for compatibility.
86 if (ischar (varargin{n1}))
87 if (strcmpi (varargin{n1}, "flat"))
90 elseif (strcmpi (varargin{n1}, "-depth"))
91 depth = varargin{n1+1};
95 error ("findobj: properties and options must be strings");
100 if (n1 <= nargin && nargin > 0)
101 args = varargin(n1 : nargin);
106 regularexpression = [];
108 logicaloperator = {};
114 while (na <= numel (args))
115 regularexpression(np) = 0;
117 logicaloperator{np} = "and";
118 if (ischar (args{na}))
119 if (strcmpi (args{na}, "-regexp"))
120 if (na + 2 <= numel (args))
121 regularexpression(np) = 1;
123 pname{np} = args{na};
125 pvalue{np} = args{na};
129 error ("findobj: inconsistent number of arguments");
131 elseif (strcmpi (args{na}, "-property"))
132 if (na + 1 <= numel (args))
135 pname{np} = args{na};
140 error ("findobj: inconsistent number of arguments");
142 elseif (! strcmp (args{na}(1), "-"))
143 ## Parameter/value pairs.
144 if (na + 1 <= numel (args))
145 pname{np} = args{na};
147 pvalue{np} = args{na};
149 if (na <= numel(args))
150 if (ischar (args{na}))
151 if strcmpi(args{na}, "-and")
152 logicaloperator{np} = "and";
154 elseif strcmpi(args{na}, "-or")
155 logicaloperator{np} = "or";
157 elseif strcmpi(args{na}, "-xor")
158 logicaloperator{np} = "xor";
160 elseif strcmpi(args{na}, "-not")
161 logicaloperator{np} = "not";
165 error ("findobj: properties and options must be strings");
168 logicaloperator{np} = "and";
172 error ("findobj: inconsistent number of arguments");
175 ## This is sloppy ... but works like Matlab.
176 if strcmpi(args{na}, "-not")
183 error ("findobj: properties and options must be strings");
189 ## Load all objects which qualify for being searched.
192 while (numel (handles) && ! (idepth >= depth))
194 for n = 1 : numel (handles)
195 children = union (children, get(handles(n), "children"));
198 h = union (h, children);
202 keepers = ones (size (h));
204 for nh = 1 : numel(h)
206 for np = 1 : numpairs
207 fields = fieldnames (p);
208 fieldindex = find (strcmpi (fields, pname{np}), 1);
209 if (numel (fieldindex))
210 pname{np} = fields{fieldindex};
214 if (regularexpression(np))
215 match = regexp (p.(pname{np}), pvalue{np});
219 elseif (numel (p.(pname{np})) == numel (pvalue{np}))
220 if (ischar (pvalue{np}))
221 match = strcmpi (pvalue{np}, p.(pname{np}));
223 match = (pvalue{np} == p.(pname{np}));
230 if (strcmpi (logicaloperator{np}, "not"))
231 keepers(nh) = ! keepers(nh) & ! match;
233 keepers(nh) = feval (logicaloperator{np}, keepers(nh), match);
242 h = h (keepers != 0);
243 h = reshape (h, [numel(h), 1]);
248 %! hf = figure ("visible", "off");
251 %! obj = findobj (hf, "type", "line");
253 %! assert (gca, findobj (hf, "type", "axes"));
254 %! assert (hf, findobj (hf, "type", "figure"));
255 %! assert (isempty (findobj (hf, "type", "xyzxyz")));
256 %! unwind_protect_cleanup
258 %! end_unwind_protect