6935
|
1 ## Copyright (C) 2007 Ben Abbott <bpabbott@mac.com> |
|
2 ## |
|
3 ## This program is free software; you can redistribute it and/or modify |
|
4 ## it under the terms of the GNU General Public License as published by |
|
5 ## the Free Software Foundation; either version 2 of the License, or |
|
6 ## (at your option) any later version. |
|
7 ## |
|
8 ## This program is distributed in the hope that it will be useful, |
|
9 ## but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
10 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
11 ## GNU General Public License for more details. |
|
12 ## |
|
13 ## You should have received a copy of the GNU General Public License |
|
14 ## along with this program; if not, write to the Free Software |
|
15 ## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
|
16 ## 02110-1301 USA |
|
17 |
|
18 ## -*- texinfo -*- |
|
19 ## @deftypefn {Function File} {@var{h} =} findobj () |
|
20 ## @deftypefnx {Function File} {@var{h} =} findobj (@var{propName}, @var{propValue}) |
|
21 ## @deftypefnx {Function File} {@var{h} =} findobj ('-property', @var{propName}) |
|
22 ## @deftypefnx {Function File} {@var{h} =} findobj ('-regexp', @var{propName},, @var{pattern}) |
|
23 ## @deftypefnx {Function File} {@var{h} =} findobj ('flat', @dots{}) |
|
24 ## @deftypefnx {Function File} {@var{h} =} findobj (@var{h}, @dots{}) |
|
25 ## @deftypefnx {Function File} {@var{h} =} findobj (@var{h}, '-depth', @var{d}, @dots{}) |
7001
|
26 ## Find object with specified property values. The simplest form is |
6935
|
27 ## |
|
28 ## @example |
|
29 ## findobj (@var{propName}, @var{propValue}) |
|
30 ## @end example |
|
31 ## |
|
32 ## @noindent |
|
33 ## which returns all of the handles to the objects with the name |
|
34 ## @var{propName} and the name @var{propValue}. The search can be limited |
|
35 ## to a particular object or set of objects and their descendants by |
|
36 ## passing a handle or set of handles @var{h} as the first argument to |
|
37 ## @code{findobj}. |
|
38 ## |
|
39 ## The depth of hierarchy of objects to which to search to can be limited |
|
40 ## with the '-depth' argument. To limit the number depth of the hierarchy |
|
41 ## to search to @var{d} generations of children, and example is |
|
42 ## |
|
43 ## @example |
|
44 ## findobj (@var{h}, '-depth', @var{d}, @var{propName}, @var{propValue}) |
|
45 ## @end example |
|
46 ## |
|
47 ## Specifying a depth @var{d} of 0, limits the search to the set of object |
|
48 ## passed in @var{h}. A depth @var{d} of 0 is equivalent to the '-flat' |
|
49 ## argument. |
|
50 ## |
|
51 ## A specified logical operator may be applied to the pairs of @var{propName} |
|
52 ## and @var{propValue}. The supported logical operators are '-and', '-or', |
|
53 ## '-xor', '-not'. |
|
54 ## |
|
55 ## The objects may also be matched by comparing a regular expression to the |
|
56 ## property values, where property values that match @code{regexp |
|
57 ## (@var{propValue}, @var{pattern})} are returned. Finally, objects may be |
|
58 ## matched by property name only, using the '-property' option. |
|
59 ## @seealso{get, set} |
|
60 ## @end deftypefn |
|
61 |
|
62 function h = findobj (varargin) |
|
63 |
|
64 depth = NaN; |
|
65 if (nargin == 0) |
|
66 handles = 0; |
|
67 n1 = 0; |
|
68 else |
|
69 if (ishandle (varargin{1}(1))) |
|
70 handles = varargin{1}; |
|
71 n1 = 2; |
|
72 else |
|
73 handles = 0; |
|
74 n1 = 1; |
|
75 end |
|
76 if (n1 <= nargin) |
|
77 if (ischar (varargin{n1})) |
|
78 if (strcmpi (varargin{n1}, 'flat')) |
|
79 depth = 0; |
|
80 n1 = n1 + 1; |
|
81 elseif (strcmpi(varargin{n1}, '-depth')) |
|
82 depth = varargin{n1+1}; |
|
83 n1 = n1 + 2; |
|
84 endif |
|
85 else |
|
86 error ("findobj: properties and options must be strings"); |
|
87 endif |
|
88 endif |
|
89 endif |
|
90 |
|
91 if (n1 <= nargin && nargin > 0) |
|
92 args = varargin(n1 : nargin); |
|
93 else |
|
94 args = {}; |
|
95 endif |
|
96 |
|
97 regularexpression = []; |
|
98 property = []; |
|
99 logicaloperator = {}; |
|
100 pname = {}; |
|
101 pvalue = {}; |
|
102 np = 1; |
|
103 na = 1; |
|
104 |
|
105 while (na <= numel (args)) |
|
106 regularexpression(np) = 0; |
|
107 property(np) = 0; |
|
108 logicaloperator{np} = 'and'; |
|
109 if (ischar (args {na})) |
|
110 if (strcmpi(args{na}, '-regexp')) |
|
111 if (na + 2 <= numel (args)) |
|
112 regularexpression(np) = 1; |
|
113 na = na + 1; |
|
114 pname{np} = args{na}; |
|
115 na = na + 1; |
|
116 pvalue{np} = args{na}; |
|
117 na = na + 1; |
|
118 np = np + 1; |
|
119 else |
|
120 error ("findobj: inconsistent number of arguments"); |
|
121 endif |
|
122 elseif (strcmpi(args{na}, '-property')) |
|
123 if (na + 1 <= numel (args)) |
|
124 na = na + 1; |
|
125 property(np) = 1; |
|
126 pname{np} = args{na}; |
|
127 na = na + 1; |
|
128 pvalue{np} = []; |
|
129 np = np + 1; |
|
130 else |
|
131 error ("findobj: inconsistent number of arguments"); |
|
132 endif |
|
133 elseif (! strcmp (args{na}(1), '-')) # parameter/value pairs |
|
134 if (na + 1 <= numel (args)) |
|
135 pname{np} = args{na}; |
|
136 na = na + 1; |
|
137 pvalue{np} = args{na}; |
|
138 na = na + 1; |
|
139 if (na <= numel(args)) |
|
140 if (ischar (args{na})) |
|
141 if strcmpi(args{na}, '-and') |
|
142 logicaloperator{np} = 'and'; |
|
143 na = na+1; |
|
144 elseif strcmpi(args{na}, '-or') |
|
145 logicaloperator{np} = 'or'; |
|
146 na = na+1; |
|
147 elseif strcmpi(args{na}, '-xor') |
|
148 logicaloperator{np} = 'xor'; |
|
149 na = na+1; |
|
150 elseif strcmpi(args{na}, '-not') |
|
151 logicaloperator{np} = 'not'; |
|
152 na = na+1; |
|
153 endif |
|
154 else |
|
155 error ("findobj: properties and options must be strings"); |
|
156 endif |
|
157 else |
|
158 logicaloperator{np} = 'and'; |
|
159 endif |
|
160 np = np + 1; |
|
161 else |
|
162 error ("findobj: inconsistent number of arguments"); |
|
163 endif |
|
164 else |
|
165 ## this is sloppy ... but works like matlab |
|
166 if strcmpi(args{na}, '-not') |
|
167 h = []; |
|
168 return |
|
169 endif |
|
170 na = na + 1; |
|
171 endif |
|
172 else |
|
173 error ("findobj: properties and options must be strings"); |
|
174 endif |
|
175 endwhile |
|
176 |
|
177 numpairs = np - 1; |
|
178 |
|
179 ## load all objects which qualify for being searched |
|
180 idepth = 0; |
|
181 h = handles; |
|
182 while (numel (handles) && ! (idepth >= depth)) |
|
183 children = []; |
|
184 for n = 1 : numel (handles) |
|
185 children = union (children, get(handles(n), 'children')); |
|
186 endfor |
|
187 handles = children; |
|
188 h = union (h, children); |
|
189 idepth = idepth + 1; |
|
190 endwhile |
|
191 |
|
192 keepers = ones (size (h)); |
|
193 if (numpairs > 0) |
|
194 for nh = 1 : numel(h) |
|
195 p = get (h (nh)); |
|
196 for np = 1 : numpairs |
|
197 fields = fieldnames (p); |
|
198 fieldindex = find (strcmpi (fields, pname{np}), 1); |
|
199 if (numel (fieldindex)) |
|
200 pname{np} = fields{fieldindex}; |
|
201 if (property(np)) |
|
202 match = 1; |
|
203 else |
|
204 if (regularexpression(np)) |
|
205 match = regexp (p.(pname{np}), pvalue{np}); |
|
206 if isempty (match) |
|
207 match = 0; |
|
208 end |
|
209 elseif (numel (p.(pname{np})) == numel (pvalue{np})) |
|
210 if (ischar (pvalue{np})) |
|
211 match = strcmpi (pvalue{np}, p.(pname{np})); |
|
212 else |
|
213 match = (pvalue{np} == p.(pname{np})); |
|
214 endif |
|
215 else |
|
216 match = 0; |
|
217 endif |
|
218 match = all (match); |
|
219 endif |
|
220 if (strcmpi (logicaloperator{np}, 'not')) |
|
221 keepers(nh) = ! keepers(nh) & ! match; |
|
222 else |
|
223 keepers(nh) = feval (logicaloperator{np}, keepers(nh), match); |
|
224 endif |
|
225 else |
|
226 keepers(nh) = 0; |
|
227 endif |
|
228 endfor |
|
229 endfor |
|
230 endif |
|
231 |
|
232 h = h (keepers != 0); |
|
233 h = reshape (h, [numel(h), 1]); |
|
234 endfunction |