source: trunk/autoquest-plugin-mfc/src/main/java/de/ugoe/cs/autoquest/plugin/mfc/guimodel/MFCWindowTree.java @ 1008

Last change on this file since 1008 was 1008, checked in by fglaser, 12 years ago
  • autoquest-plugin-mfc subproject refactored to use GUI element naming convention were appropriate
  • MFCWindowTree marked as deprecated (one should use generalized GUIElementTree instead)
File size: 9.8 KB
Line 
1//   Copyright 2012 Georg-August-Universität Göttingen, Germany
2//
3//   Licensed under the Apache License, Version 2.0 (the "License");
4//   you may not use this file except in compliance with the License.
5//   You may obtain a copy of the License at
6//
7//       http://www.apache.org/licenses/LICENSE-2.0
8//
9//   Unless required by applicable law or agreed to in writing, software
10//   distributed under the License is distributed on an "AS IS" BASIS,
11//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12//   See the License for the specific language governing permissions and
13//   limitations under the License.
14
15package de.ugoe.cs.autoquest.plugin.mfc.guimodel;
16
17import java.util.ArrayList;
18import java.util.HashMap;
19import java.util.HashSet;
20import java.util.List;
21import java.util.Map;
22import java.util.Set;
23
24import de.ugoe.cs.autoquest.eventcore.guimodel.GUIElementFactory;
25import de.ugoe.cs.autoquest.eventcore.guimodel.GUIElementTree;
26import de.ugoe.cs.autoquest.eventcore.guimodel.GUIModel;
27import de.ugoe.cs.autoquest.eventcore.guimodel.GUIModelException;
28import de.ugoe.cs.autoquest.eventcore.guimodel.IGUIElementFactory;
29
30/**
31 * <p>
32 * This class provides an the interfaces for window trees.
33 * </p>
34 * <p>
35 * The window tree represents the hierarchical structure of the windows "as it is" currently during
36 * a session. It may change during the session due to creation and destruction of windows.
37 * </p>
38 *
39 * @author Steffen Herbold
40 * @version 1.0
41 * @deprecated This class is replaced by a generalized version. Use {@link #GUIElementTree} instead.
42 * @see #GUIElementTree
43 */
44public class MFCWindowTree {
45
46    /**
47     * <p>
48     * Maintains a set of all the targets of all widgets that were at some point part of the window
49     * tree.
50     * </p>
51     */
52    private Set<MFCGUIElementSpec> targets;
53
54    /**
55     * <p>
56     * Map of all GUI element specifications that are part of the tree for efficient searching. The
57     * keys of the map are the hwnd's of the GUI elements.
58     * </p>
59     */
60    private Map<Long, MFCGUIElementSpec> guiElementSpecs;
61
62    /**
63     * <p>
64     * Map of all children of GUI elements that are part of the tree. The keys of the map are the
65     * hwnd's of the parent GUI elements.
66     * </p>
67     */
68    private Map<Long, List<MFCGUIElementSpec>> childRelations;
69
70    /**
71     * <p>
72     * Map of all parents of GUI elements that are part of the tree. The keys of the map are the
73     * hwnd's of the child GUI elements.
74     * </p>
75     */
76    private Map<Long, MFCGUIElementSpec> parentRelations;
77
78    /**
79     * <p>
80     * the internally created GUI model
81     * </p>
82     */
83    private GUIModel guiModel = new GUIModel();
84
85    /**
86     * <p>
87     * the GUI element factory used in the model
88     * </p>
89     */
90    private IGUIElementFactory guiElementFactory = GUIElementFactory.getInstance();
91
92    /**
93     * <p>
94     * Map of all GUI elements that are part of the tree for efficient searching. The keys of the
95     * map are the hwnd's of the GUI elements.
96     * </p>
97     */
98    private Map<Long, MFCGUIElement> guiElements;
99
100    /**
101     * <p>
102     * Creates a new MFCWindowTree.
103     * </p>
104     * <p>
105     * Private, as the class is a singleton.
106     * </p>
107     */
108    public MFCWindowTree() {
109        guiElementSpecs = new HashMap<Long, MFCGUIElementSpec>();
110        targets = new HashSet<MFCGUIElementSpec>();
111        childRelations = new HashMap<Long, List<MFCGUIElementSpec>>();
112        parentRelations = new HashMap<Long, MFCGUIElementSpec>();
113        guiElements = new HashMap<Long, MFCGUIElement>();
114    }
115
116    /**
117     * <p>
118     * Adds a new window to the tree.
119     * </p>
120     *
121     * @param parentHwnd
122     *            hwnd of the parent window
123     * @param childHwnd
124     *            hwnd of the window to be created
125     * @param childWindowName
126     *            resource id of the window to be created
127     * @param resourceId
128     *            resource id of the window to be created
129     * @param className
130     *            class name of the window to be created
131     */
132    public void add(long parentHwnd,
133                    long childHwnd,
134                    String childWindowName,
135                    int resourceId,
136                    String className,
137                    boolean isModal)
138    {
139        MFCGUIElementSpec parent = guiElementSpecs.get(parentHwnd);
140        MFCGUIElementSpec child = guiElementSpecs.get(childHwnd);
141        if (child == null) {
142            child =
143                new MFCGUIElementSpec(childHwnd, childWindowName, resourceId, className, isModal);
144            if (parent != null) {
145                List<MFCGUIElementSpec> otherChildren = childRelations.get(parentHwnd);
146
147                if (otherChildren == null) {
148                    otherChildren = new ArrayList<MFCGUIElementSpec>();
149                    childRelations.put(parentHwnd, otherChildren);
150                }
151
152                otherChildren.add(child);
153
154                parentRelations.put(childHwnd, parent);
155            }
156            guiElementSpecs.put(childHwnd, child);
157            targets.add(child);
158        }
159    }
160
161    /**
162     * <p>
163     * Searches the tree for a window with the specified hwnd and returns its
164     * {@link MFCGUIElementSpec} .
165     * </p>
166     *
167     * @param hwnd
168     *            hwnd that is looked for
169     * @return {@link MFCGUIElementSpec} of the window with the given hwnd if found, null otherwise
170     */
171    public MFCGUIElement find(long hwnd) {
172        MFCGUIElement guiElement = guiElements.get(hwnd);
173        if (guiElement == null) {
174            List<MFCGUIElementSpec> guiElementPath = new ArrayList<MFCGUIElementSpec>();
175
176            MFCGUIElementSpec child = guiElementSpecs.get(hwnd);
177
178            if (child == null) {
179                throw new RuntimeException("no GUI element found with id " + hwnd);
180            }
181
182            while (child != null) {
183                guiElementPath.add(0, child);
184                child = parentRelations.get(child.getHwnd());
185            }
186
187            try {
188                guiElement =
189                    (MFCGUIElement) guiModel.integratePath(guiElementPath, guiElementFactory);
190            }
191            catch (GUIModelException e) {
192                throw new RuntimeException("could not instantiate GUI element with id " + hwnd, e);
193            }
194            guiElements.put(hwnd, guiElement);
195        }
196        return guiElement;
197    }
198
199    /**
200     * <p>
201     * Sets the name of a GUI element given its HWND.
202     * </p>
203     *
204     * @param hwnd
205     *            HWND of the GUI element
206     * @param windowName
207     *            new name of the GUI element
208     */
209    public void setName(long hwnd, String windowName) {
210        MFCGUIElementSpec child = guiElementSpecs.get(hwnd);
211        if (child != null) {
212            child.setName(windowName);
213
214            MFCGUIElement guiElement = guiElements.remove(hwnd);
215            if (guiElement == null) {
216                // we need to update the GUI model as well
217                find(hwnd);
218            }
219        }
220    }
221
222    /**
223     * <p>
224     * Removes a window (defined by its hwnd) from the tree. All children of the window will be
225     * removed recursively.
226     * </p>
227     *
228     * @param hwnd
229     *            hwnd of the window to be removed
230     * @return number of windows that were removed
231     */
232    public int remove(long hwnd) {
233        MFCGUIElementSpec node = guiElementSpecs.remove(hwnd);
234        int removedCounter = 1;
235
236        if (node != null) {
237            List<MFCGUIElementSpec> nodesToBeRemoved = childRelations.remove(hwnd);
238
239            // remove all children and sub-children, if any
240            if (nodesToBeRemoved != null) {
241                for (int i = 0; i < nodesToBeRemoved.size(); i++) {
242                    MFCGUIElementSpec nodeToBeRemoved = nodesToBeRemoved.get(i);
243                    List<MFCGUIElementSpec> children =
244                        childRelations.remove(nodeToBeRemoved.getHwnd());
245
246                    if (children != null) {
247                        nodesToBeRemoved.addAll(children);
248                    }
249
250                    guiElementSpecs.remove(nodeToBeRemoved.getHwnd());
251                    parentRelations.remove(nodeToBeRemoved.getHwnd());
252                    removedCounter++;
253                }
254            }
255
256            // the node may be a child node of a parent. So search for it and remove it
257            MFCGUIElementSpec parent = parentRelations.remove(hwnd);
258            if (parent != null) {
259                List<MFCGUIElementSpec> children = childRelations.get(parent.getHwnd());
260
261                if (children != null) {
262                    for (int i = 0; i < children.size(); i++) {
263                        if (children.get(i).getHwnd() == hwnd) {
264                            children.remove(i);
265                            break;
266                        }
267                    }
268
269                    if (children.size() <= 0) {
270                        childRelations.remove(parent.getHwnd());
271                    }
272                }
273            }
274        }
275        return removedCounter;
276    }
277
278    /**
279     * @return the guiModel
280     */
281    public GUIModel getGUIModel() {
282        return guiModel;
283    }
284
285    /**
286     * <p>
287     * Returns the number of nodes contained in the MFCWindowTree.
288     * </p>
289     *
290     * @return number of nodes
291     */
292    public int size() {
293        return guiElementSpecs.size();
294    }
295
296    /**
297     * <p>
298     * Returns a sorted set of all targets that existed any time in the window tree.
299     * </p>
300     *
301     * @return set of targets
302     */
303    public Set<MFCGUIElementSpec> getTargets() {
304        return targets;
305    }
306
307}
Note: See TracBrowser for help on using the repository browser.