1
2
3
4
5
6
7
8
9
10
11
12 package sk.uniba.euromath.editor.xmlEditor.tools;
13
14 import java.util.ArrayList;
15 import java.util.List;
16
17 import org.eclipse.gef.EditPartViewer;
18 import org.eclipse.gef.GraphicalEditPart;
19 import org.eclipse.gef.tools.SelectionTool;
20 import org.eclipse.swt.SWT;
21 import org.eclipse.swt.events.KeyEvent;
22 import org.eclipse.swt.widgets.Event;
23 import org.w3c.dom.Node;
24
25 import sk.baka.ikslibs.interval.DOMInterval;
26 import sk.baka.ikslibs.interval.DOMIntervalSet;
27 import sk.baka.ikslibs.ptr.DomPointer;
28 import sk.baka.ikslibs.ptr.DomPointerFactory;
29 import sk.uniba.euromath.document.XMLAccess;
30 import sk.uniba.euromath.editor.xmlEditor.XMLEditDomain;
31 import sk.uniba.euromath.editor.xmlEditor.editParts.XMLEditPart;
32 import sk.uniba.euromath.editor.xmlEditor.viewers.IXMLGraphicalViewer;
33
34 /***
35 * <b>XMLStructureTool</b> - tool to make whole nodes selection<br>
36 * Structure is defined by tree of nodes, so this tool can select nodes of xml
37 * document.
38 * <ol>
39 * <li> Supports structure selection - selection is composed of nodes.</li>
40 * <li> Selections are performed by mouse and keyboard.</li>
41 * <li> Editing is performed through menu and keyboard.</li>
42 * <li> Suports clipboard, undo, redo</li>
43 * </ol>
44 * Key and mouse functionality control:
45 * <ul>
46 * <li><i>up, down arrow</i> - selects brother of selected node; if more nodes
47 * are selected, deselects all</li>
48 * <li><i>CTRL + wheel</i> - selects parent/child of selected node; if more
49 * nodes are selected, deselects all</li>
50 * <li><b><i>click in special place - square, triangel</i> selects element
51 * assigned to that place. So elements are bounded by visible border with square
52 * at corner.</b></li>
53 * <li><i>some mechanism</i> - selects elements only of selected type</li>
54 * </ul>
55 *
56 * @author Martin Kollar Created on 6.6.2005
57 */
58
59 public class XMLStructureTool extends SelectionTool {
60
61 public static final int PREV_SIBLING = 1;
62
63 public static final int NEXT_SIBLING = 2;
64
65 /***
66 * Stores KeyCodes of keys that are pressed down.
67 */
68 private List<Integer> keysDown = new ArrayList<Integer>();
69
70 /***
71 * Constructor.
72 */
73 public XMLStructureTool() {
74 super();
75 }
76
77 /***
78 * @return the EditPart that has focus
79 */
80 protected GraphicalEditPart getFocusEditPart() {
81 if (getCurrentViewer() == null)
82 return null;
83 return (GraphicalEditPart) getCurrentViewer().getFocusEditPart();
84 }
85
86 @Override
87 protected boolean handleKeyDown(KeyEvent event) {
88 addKey(event.keyCode);
89
90 switch (event.keyCode) {
91 case SWT.ARROW_LEFT:
92 return true;
93 case SWT.ARROW_RIGHT:
94 return true;
95 case SWT.ARROW_UP:
96 selectSiblingNode(XMLStructureTool.PREV_SIBLING);
97 return true;
98 case SWT.ARROW_DOWN:
99 selectSiblingNode(XMLStructureTool.NEXT_SIBLING);
100 return true;
101 default:
102 return false;
103 }
104 }
105
106 /***
107 * Selects previous or next sibling of selected node(if not exists such
108 * sibling, does nothing). If more nodes are selected, selects nothing.
109 */
110 protected void selectSiblingNode(int direction) {
111 DOMIntervalSet selection = null;
112
113 if (selection.getContentIds(getXMLAcces().getIdManager()).size() != 1) {
114 selection.clear();
115 this.getXMLGraphicalViewer().setSelection(selection);
116 }
117
118 Node node = selection.getIntervals().get(0).getContents().get(0);
119 Node nodeToSelect = null;
120 switch (direction) {
121 case XMLStructureTool.PREV_SIBLING: {
122 nodeToSelect = node.getPreviousSibling();
123 }
124 case XMLStructureTool.NEXT_SIBLING:
125 nodeToSelect = node.getNextSibling();
126 }
127 if (nodeToSelect == null)
128 return;
129 selection.clear();
130 DomPointer pointer = DomPointerFactory.create(nodeToSelect);
131 selection.union(new DOMInterval(pointer, pointer.getNextSibling()));
132
133 this.getXMLGraphicalViewer().setSelection(selection);
134 }
135
136 @Override
137 protected boolean handleKeyUp(KeyEvent e) {
138 removeKey(e.keyCode);
139 return super.handleKeyUp(e);
140 }
141
142 /***
143 * Selects parent of selected node. If more nodes are selected, selects
144 * nothing.
145 */
146 protected void ScrollUp(EditPartViewer viewer) {
147 DOMIntervalSet selection = null;
148
149 if (selection.getContentIds(getXMLAcces().getIdManager()).size() != 1) {
150 selection.clear();
151 this.getXMLGraphicalViewer().setSelection(selection);
152 }
153 Node node = selection.getIntervals().get(0).getContents().get(0);
154 Node nodeToSelect = node.getParentNode();
155
156 if (nodeToSelect == null)
157 return;
158 selection.clear();
159 DomPointer pointer = DomPointerFactory.create(nodeToSelect);
160 selection.union(new DOMInterval(pointer, pointer.getNextSibling()));
161
162 this.getXMLGraphicalViewer().setSelection(selection);
163 }
164
165 /***
166 * Selects first child of selected node(TODO LOW PRIORITY some alg to select
167 * not first child). If more nodes are selected, selects nothing.
168 */
169 protected void ScrollDown(EditPartViewer viewer) {
170 DOMIntervalSet selection = null;
171
172 if (selection.getContentIds(getXMLAcces().getIdManager()).size() != 1) {
173 selection.clear();
174 this.getXMLGraphicalViewer().setSelection(selection);
175 }
176 Node node = selection.getIntervals().get(0).getContents().get(0);
177 Node nodeToSelect = node.getChildNodes().item(0);
178
179 if (nodeToSelect == null)
180 return;
181 selection.clear();
182 DomPointer pointer = DomPointerFactory.create(nodeToSelect);
183 selection.union(new DOMInterval(pointer, pointer.getNextSibling()));
184
185 this.getXMLGraphicalViewer().setSelection(selection);
186 }
187
188 /***
189 * Delegates the scrolling to the DragTracker (if there is one). If not,
190 * invokes the super method.
191 *
192 * @see org.eclipse.gef.Tool#mouseWheelScrolled(org.eclipse.swt.widgets.Event,
193 * org.eclipse.gef.EditPartViewer)
194 */
195 @Override
196 public void mouseWheelScrolled(Event event, EditPartViewer viewer) {
197 if (getDragTracker() != null) {
198 getDragTracker().mouseWheelScrolled(event, viewer);
199 event.doit = false;
200 } else if (getFocusEditPart() instanceof XMLEditPart) {
201 if ((event.type == SWT.MouseWheel) && canScroll()) {
202 if (event.count > 0)
203 ScrollUp(viewer);
204 else if (event.count < 0)
205 ScrollDown(viewer);
206 }
207 } else
208 super.mouseWheelScrolled(event, viewer);
209
210 }
211
212 protected List<Integer> getKeysDown() {
213 return this.keysDown;
214 }
215
216 /***
217 * @param code
218 * KeyCode of pressed key
219 */
220 protected void addKey(Integer code) {
221 if (getKeysDown().contains(code))
222 return;
223 getKeysDown().add(code);
224 }
225
226 protected void removeKey(Integer code) {
227 if (getKeysDown().contains(code))
228 getKeysDown().remove(code);
229 else {
230
231
232
233 }
234
235 }
236
237 protected boolean canScroll() {
238 return ((getKeysDown().size() == 1) && (getKeysDown().get(0) == SWT.CTRL));
239 }
240
241 protected IXMLGraphicalViewer getXMLGraphicalViewer() {
242 return (IXMLGraphicalViewer) this.getCurrentViewer();
243 }
244
245 protected XMLAccess getXMLAcces() {
246 return ((XMLEditDomain) this.getDomain()).getXMLEditor().getXMLAccess();
247 }
248 }