View Javadoc

1   /*
2    * Copyright 1999-2006 Faculty of Mathematics, Physics
3    * and Informatics, Comenius University, Bratislava. This file is protected by
4    * the Mozilla Public License version 1.1 (the License); you may not use this
5    * file except in compliance with the License. You may obtain a copy of the
6    * License at http://euromath2.sourceforge.net/license.html Unless required by
7    * applicable law or agreed to in writing, software distributed under the
8    * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
9    * OF ANY KIND, either express or implied. See the License for the specific
10   * language governing permissions and limitations under the License.
11   */
12  package sk.uniba.euromath.editor.textEditor.tools;
13  
14  import java.util.Collection;
15  import java.util.Collections;
16  
17  import org.eclipse.core.runtime.IStatus;
18  import org.eclipse.draw2d.Cursors;
19  import org.eclipse.draw2d.geometry.Point;
20  import org.eclipse.gef.EditPart;
21  import org.eclipse.gef.Request;
22  import org.eclipse.gef.tools.DragEditPartsTracker;
23  import org.w3c.dom.DOMException;
24  import org.w3c.dom.Node;
25  
26  import sk.baka.ikslibs.interval.DOMInterval;
27  import sk.baka.ikslibs.interval.DOMIntervalSet;
28  import sk.baka.ikslibs.ptr.DomPointer;
29  import sk.baka.ikslibs.ptr.DomPointerFactory;
30  import sk.uniba.euromath.EuroMath;
31  import sk.uniba.euromath.document.XMLAccess;
32  import sk.uniba.euromath.editor.textEditor.ITextPieceKeeper;
33  import sk.uniba.euromath.editor.textEditor.editParts.TextEditPart;
34  import sk.uniba.euromath.editor.textEditor.requests.caretRequests.DeactivateCaretRequest;
35  import sk.uniba.euromath.editor.textEditor.requests.editTextRequests.ActivateTextEditingRequest;
36  import sk.uniba.euromath.editor.xmlEditor.XMLEditDomain;
37  import sk.uniba.euromath.editor.xmlEditor.viewers.IXMLGraphicalViewer;
38  
39  /***
40   * Works with ITextPieceKeeper and IDOMIntervalSet that represents selection.
41   * Supports selecting by mouse.
42   * During selecting Caret is deactivated and selection is showed through IXMLGraphicalViewer.
43   * After selecting is finished, sets the selection to IXMLGraphicalViewer.
44   * 
45   * @author TV refactored by Martin Kollar on 22.5.2006
46   */
47  public class TextDragTracker extends DragEditPartsTracker {
48  
49  	private DOMInterval localSelection;
50  	
51      /***
52       * @param owner
53       * @param startLocation
54       *            location where this DragTracker starts it work
55       */
56      public TextDragTracker(EditPart owner, Point startLocation) {
57          super(owner);
58          // setTargetEditPart(getSourceEditPart());
59          setDefaultCursor(Cursors.IBEAM);
60          if (startLocation != null)
61              setStartLocation(startLocation);
62      }
63  
64  
65      /***
66       * Activates text editing. Activates TextTool.
67       * 
68       * @see org.eclipse.gef.tools.AbstractTool#handleDoubleClick(int)
69       * 
70       * @param button
71       *            which button was double-clicked
72       */
73      @Override
74      protected boolean handleDoubleClick(int button) {
75          EditPart caretTarget = null;
76          if (button == 1) {
77              caretTarget = getCurrentViewer().findObjectAt(getLocation());
78              if ((caretTarget != null)
79                      && (caretTarget instanceof ITextPieceKeeper)) {
80  
81                  Point loc = getLocation().getCopy();
82                  ((ITextPieceKeeper) caretTarget).getTextLocator()
83                          .translateToRelative(loc);
84                  int caretIndex = ((ITextPieceKeeper) caretTarget)
85                          .getTextLocator().getCharIndexAtPos(loc);
86  
87                  Request activation = new ActivateTextEditingRequest(
88                          (ITextPieceKeeper) caretTarget, caretIndex,
89                          getCurrentViewer().getEditDomain());
90                  caretTarget.performRequest(activation);
91                  return true;
92              }
93          }
94          // return (caretTarget != null) ? true :
95          // super.handleDoubleClick(button);
96          return false;
97      }
98  
99  
100     @Override
101     protected boolean handleButtonDown(int button) {
102         // selecting is controlled by left mouse button drags
103         if (button != 1) {
104             // TODO Studva state invalid - how it is controlled if to handle as
105             // drag in selected tool?
106             setState(STATE_INVALID);
107             return false;
108         }
109 
110         stateTransition(STATE_INITIAL, STATE_DRAG);
111         return true;
112     }
113 
114     /***
115      * @see org.eclipse.gef.tools.AbstractTool#handleDragStarted()
116      */
117     @Override
118     protected boolean handleDragStarted() {
119         if (super.handleDragStarted()) {
120 
121         	performInitSelection();
122         	
123             EditPart caretTarget = getCurrentViewer().findObjectAt(
124                     getLocation());
125             caretTarget.performRequest(new DeactivateCaretRequest());
126 
127             return true;
128         }
129         return false;
130     }
131 
132     /***
133      * @see DragEditPartsTracker
134      * @return the list of objects to be excluded as targets
135      */
136     @Override
137     protected Collection getExclusionSet() {
138         return Collections.EMPTY_LIST;
139     }
140 
141     protected boolean handleDrag() {
142     	DomPointer from = this.localSelection.from;
143     	DomPointer to = mouseLocationToDomPointer();
144     	this.localSelection = new DOMInterval(from,to);
145     	processLocalSelection(false);
146     	
147     	return true;
148     }
149 
150     /***
151      * @see org.eclipse.gef.tools.DragEditPartsTracker#performDrag() is called
152      *      when the draging ends.
153      */
154     @Override
155     protected void performDrag() {
156         super.performDrag();
157         processLocalSelection(true);
158     }
159 
160     /***
161      * select editparts depending on events from user
162      */
163     protected void performSelection() {
164         if (hasSelectionOccurred())
165             return;
166         setFlag(FLAG_SELECTION_PERFORMED, true);
167         processLocalSelection(true);
168     }
169 
170 
171 
172     protected boolean handleButtonUp(int button) {
173         super.handleButtonUp(button);
174 
175         EditPart caretTarget = null;
176         if (button == 1) {
177             caretTarget = getCurrentViewer().findObjectAt(getLocation());
178             if ((caretTarget != null)
179                     && (caretTarget instanceof ITextPieceKeeper)) {
180 
181                 Point loc = getLocation().getCopy();
182                 ((ITextPieceKeeper) caretTarget).getTextLocator()
183                         .translateToRelative(loc);
184                 int caretIndex = ((ITextPieceKeeper) caretTarget)
185                         .getTextLocator().getCharIndexAtPos(loc);
186 
187                 Request activation = new ActivateTextEditingRequest(
188                         (ITextPieceKeeper) caretTarget, caretIndex,
189                         getCurrentViewer().getEditDomain());
190                 caretTarget.performRequest(activation);
191             }
192         }
193 
194         return true;
195     }
196 
197     /***
198      * When selection ends, <code>commit</code> should be <code>true</code>
199      * 
200      * @param commit if <code>true</code>, then sets to GraphicalViewer processed selection
201      * 			othervise tell GraphicalViewer only to show processed selection
202      */
203     protected void processLocalSelection(boolean commit){
204     	DOMIntervalSet processedSelection = null;
205     	
206         // Control is not pressed and Shift is not pressed
207         if ( (!getCurrentInput().isControlKeyDown()) && (!getCurrentInput().isShiftKeyDown()) ) {
208         	processedSelection = new DOMIntervalSet(this.localSelection);
209         }
210         
211         // Control is pressed and Shift is NOT pressed
212         if ( (getCurrentInput().isControlKeyDown()) && (!getCurrentInput().isShiftKeyDown()) ){
213         	DOMIntervalSet globalSelection = getXMLGraphicalViewer().getDOMSelection();
214         	
215         	//make XOR
216         	//TODO Kollar : check it
217         	DOMIntervalSet intersection = globalSelection.subtract(this.localSelection);
218         	DOMIntervalSet local = (new DOMIntervalSet(this.localSelection)).subtract(intersection);
219         	globalSelection.union(local);
220         	
221         	processedSelection = globalSelection;
222         }
223         
224         // Shift is pressed
225         if (getCurrentInput().isShiftKeyDown()){
226         	DOMIntervalSet globalSelection = getXMLGraphicalViewer().getDOMSelection();
227         	globalSelection.union(this.localSelection);
228         	
229         	processedSelection = globalSelection;
230         }
231         
232        if (processedSelection == null)
233     	   throw new IllegalStateException("DOMIntervalSet is null!");
234    		
235        if (commit)
236     	   getXMLGraphicalViewer().setSelection(processedSelection);
237        else
238     	   getXMLGraphicalViewer().showSelection(processedSelection);
239     }
240     
241     protected void performInitSelection(){
242     	DomPointer start = mouseLocationToDomPointer();
243     	this.localSelection = new DOMInterval(start,start);   	
244     }
245     
246     protected DomPointer mouseLocationToDomPointer(){
247     	EditPart caretTarget = getCurrentViewer().findObjectAt(getLocation());
248         if ((caretTarget != null)
249                 && (caretTarget instanceof ITextPieceKeeper)) {
250 
251             Point loc = getLocation().getCopy();
252             ((ITextPieceKeeper) caretTarget).getTextLocator()
253                     .translateToRelative(loc);
254             int caretIndex = ((ITextPieceKeeper) caretTarget)
255                     .getTextLocator().getCharIndexAtPos(loc);
256             caretIndex = ((ITextPieceKeeper) caretTarget).getTextPieceInfo().getOffset() + caretIndex;
257             
258             try {
259             	Node node = getXMLAccess().getIdManager().getNodeNull(((ITextPieceKeeper) caretTarget).
260             		getTextPieceInfo().getNodeID()).item(0);
261             	return  DomPointerFactory.create(node, caretIndex);
262             } catch (DOMException e) {
263                 EuroMath.log(IStatus.ERROR, 0, "Invalid state of Euromath.", e);
264             }
265             
266         }
267         
268         return null;
269     }
270     
271     protected IXMLGraphicalViewer getXMLGraphicalViewer() {
272         return (IXMLGraphicalViewer) getCurrentViewer();
273     }
274    
275     protected XMLAccess getXMLAccess() {
276         return ((XMLEditDomain) getDomain()).getXMLEditor().getXMLAccess();
277     }
278     
279     /***
280      * @return sourceEditPart
281      */
282     public TextEditPart getTextEditPart() {
283         return (TextEditPart) getSourceEditPart();
284     }
285 
286 }