1## Copyright (C) 2007, 2008, 2009 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 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>
65function 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]);