changelog shortlog tags changeset files revisions annotate raw

scripts/plot/findobj.m

changeset 10289: 4b124317dc38
parent:eb63fbe60fab
author: John W. Eaton <jwe@octave.org>
date: Tue Feb 09 20:58:55 2010 -0500 (61 minutes ago)
permissions: -rw-r--r--
description: base_properties::set_children: account for hidden children
1## Copyright (C) 2007, 2008, 2009 Ben Abbott
2##
3## This file is part of Octave.
4##
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.
9##
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.
14##
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/>.
18
19## -*- texinfo -*-
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
28##
29## @example
30## findobj (@var{prop_name}, @var{prop_Value})
31## @end example
32##
33## @noindent
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
38## @code{findobj}.
39##
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
43##
44## @example
45## findobj (@var{h}, '-depth', @var{d}, @var{prop_Name}, @var{prop_Value})
46## @end example
47##
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'
50## argument.
51##
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',
54## '-xor', '-not'.
55##
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.
60## @seealso{get, set}
61## @end deftypefn
62
63## Author: Ben Abbott <bpabbott@mac.com>
64
65function h = findobj (varargin)
66
67 depth = NaN;
68 if (nargin == 0)
69 handles = 0;
70 n1 = 0;
71 else
72 if (! isempty (varargin{1}))
73 if (ishandle (varargin{1}(1)))
74 handles = varargin{1};
75 n1 = 2;
76 else
77 handles = 0;
78 n1 = 1;
79 endif
80 else
81 ## Return [](0x1) for compatibility.
82 h = zeros (0, 1);
83 return;
84 endif
85 if (n1 <= nargin)
86 if (ischar (varargin{n1}))
87 if (strcmpi (varargin{n1}, "flat"))
88 depth = 0;
89 n1 = n1 + 1;
90 elseif (strcmpi (varargin{n1}, "-depth"))
91 depth = varargin{n1+1};
92 n1 = n1 + 2;
93 endif
94 else
95 error ("findobj: properties and options must be strings");
96 endif
97 endif
98 endif
99
100 if (n1 <= nargin && nargin > 0)
101 args = varargin(n1 : nargin);
102 else
103 args = {};
104 endif
105
106 regularexpression = [];
107 property = [];
108 logicaloperator = {};
109 pname = {};
110 pvalue = {};
111 np = 1;
112 na = 1;
113
114 while (na <= numel (args))
115 regularexpression(np) = 0;
116 property(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;
122 na = na + 1;
123 pname{np} = args{na};
124 na = na + 1;
125 pvalue{np} = args{na};
126 na = na + 1;
127 np = np + 1;
128 else
129 error ("findobj: inconsistent number of arguments");
130 endif
131 elseif (strcmpi (args{na}, "-property"))
132 if (na + 1 <= numel (args))
133 na = na + 1;
134 property(np) = 1;
135 pname{np} = args{na};
136 na = na + 1;
137 pvalue{np} = [];
138 np = np + 1;
139 else
140 error ("findobj: inconsistent number of arguments");
141 endif
142 elseif (! strcmp (args{na}(1), "-"))
143 ## Parameter/value pairs.
144 if (na + 1 <= numel (args))
145 pname{np} = args{na};
146 na = na + 1;
147 pvalue{np} = args{na};
148 na = na + 1;
149 if (na <= numel(args))
150 if (ischar (args{na}))
151 if strcmpi(args{na}, "-and")
152 logicaloperator{np} = "and";
153 na = na+1;
154 elseif strcmpi(args{na}, "-or")
155 logicaloperator{np} = "or";
156 na = na+1;
157 elseif strcmpi(args{na}, "-xor")
158 logicaloperator{np} = "xor";
159 na = na+1;
160 elseif strcmpi(args{na}, "-not")
161 logicaloperator{np} = "not";
162 na = na+1;
163 endif
164 else
165 error ("findobj: properties and options must be strings");
166 endif
167 else
168 logicaloperator{np} = "and";
169 endif
170 np = np + 1;
171 else
172 error ("findobj: inconsistent number of arguments");
173 endif
174 else
175 ## This is sloppy ... but works like Matlab.
176 if strcmpi(args{na}, "-not")
177 h = [];
178 return
179 endif
180 na = na + 1;
181 endif
182 else
183 error ("findobj: properties and options must be strings");
184 endif
185 endwhile
186
187 numpairs = np - 1;
188
189 ## Load all objects which qualify for being searched.
190 idepth = 0;
191 h = handles;
192 while (numel (handles) && ! (idepth >= depth))
193 children = [];
194 for n = 1 : numel (handles)
195 children = union (children, get(handles(n), "children"));
196 endfor
197 handles = children;
198 h = union (h, children);
199 idepth = idepth + 1;
200 endwhile
201
202 keepers = ones (size (h));
203 if (numpairs > 0)
204 for nh = 1 : numel(h)
205 p = get (h (nh));
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};
211 if (property(np))
212 match = 1;
213 else
214 if (regularexpression(np))
215 match = regexp (p.(pname{np}), pvalue{np});
216 if isempty (match)
217 match = 0;
218 endif
219 elseif (numel (p.(pname{np})) == numel (pvalue{np}))
220 if (ischar (pvalue{np}))
221 match = strcmpi (pvalue{np}, p.(pname{np}));
222 else
223 match = (pvalue{np} == p.(pname{np}));
224 endif
225 else
226 match = 0;
227 endif
228 match = all (match);
229 endif
230 if (strcmpi (logicaloperator{np}, "not"))
231 keepers(nh) = ! keepers(nh) & ! match;
232 else
233 keepers(nh) = feval (logicaloperator{np}, keepers(nh), match);
234 endif
235 else
236 keepers(nh) = 0;
237 endif
238 endfor
239 endfor
240 endif
241
242 h = h (keepers != 0);
243 h = reshape (h, [numel(h), 1]);
244endfunction