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

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