]> Creatis software - CreaPhase.git/blob - octave_packages/m/plot/findobj.m
update packages
[CreaPhase.git] / octave_packages / m / plot / findobj.m
1 ## Copyright (C) 2007-2012 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 graphics 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
65 function 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]);
244 endfunction
245
246
247 %!test
248 %! hf = figure ("visible", "off");
249 %! unwind_protect
250 %!   l = line;
251 %!   obj = findobj (hf, "type", "line");
252 %!   assert (l, obj);
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
257 %!   close (hf);
258 %! end_unwind_protect
259