View Javadoc

1   /*
2    * Copyright 1999-2006 Faculty of Mathematics, Physics and Informatics, Comenius
3    * University, Bratislava. This file is protected by the Mozilla Public License
4    * version 1.1 (the License); you may not use this file except in compliance
5    * with the License. You may obtain a copy of the License at
6    * http://euromath2.sourceforge.net/license.html Unless required by applicable
7    * law or agreed to in writing, software distributed under the License is
8    * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
9    * KIND, either express or implied. See the License for the specific language
10   * governing permissions and limitations under the License.
11   */
12  package sk.uniba.euromath.editor.xmlEditor.viewers;
13  
14  import java.util.ArrayList;
15  import java.util.List;
16  import java.util.Set;
17  
18  import org.eclipse.gef.EditPart;
19  import org.eclipse.gef.ui.parts.ScrollingGraphicalViewer;
20  
21  import sk.baka.ikslibs.ids.IDManager;
22  import sk.baka.ikslibs.interval.DOMIntervalSet;
23  import sk.uniba.euromath.document.XMLAccess;
24  import sk.uniba.euromath.editor.selections.DOMSelectionChangedEvent;
25  import sk.uniba.euromath.editor.selections.IDOMSelectionChangedListener;
26  import sk.uniba.euromath.editor.xmlEditor.IXMLEditPart;
27  import sk.uniba.euromath.editor.xmlEditor.IdVisualInfo;
28  import sk.uniba.euromath.editor.xmlEditor.XMLEditDomain;
29  import sk.uniba.euromath.editor.xmlEditor.XMLEditPartFactory;
30  import sk.uniba.euromath.editor.xmlEditor.XMLEditor;
31  
32  /***
33   * Scrolling graphical viewer capable of performing selections over XML.
34   * Selection object is {@link DOMIntervalSet}.
35   * 
36   * @author Martin Kollar
37   */
38  public class XMLScrollingGraphicalViewer extends ScrollingGraphicalViewer
39                  implements IXMLGraphicalViewer {
40  
41          private List<IDOMSelectionChangedListener> selectionChangedListeners = new ArrayList<IDOMSelectionChangedListener>();
42  
43          /***
44           * Guards selection listening. Prevents event-listen loops. Can listen
45           * only when equals zero.
46           */
47          private int canSelectionChangeListen = 0;
48  
49          /***
50           * Local selection for this viewer.
51           */
52          protected DOMIntervalSet selection = new DOMIntervalSet();
53  
54          /***
55           * Associated editor.s
56           */
57          private XMLEditor editor;
58  
59          /***
60           * Contructor.
61           * 
62           * @param editor
63           *                XMLEditor that uses this GraphicalViewer
64           */
65          public XMLScrollingGraphicalViewer(XMLEditor editor) {
66                  super();
67                  this.editor = editor;
68          }
69  
70          /***
71           * @param listener
72           *                new listener to be add from selectionChangedListeners
73           */
74          public void addSelectionChangedListener(
75                          IDOMSelectionChangedListener listener) {
76                  if (!(this.selectionChangedListeners.contains(listener)))
77                          this.selectionChangedListeners.add(listener);
78          }
79  
80          /***
81           * @param listener
82           *                listener to be removed from selectionChangedListeners
83           */
84          public void removeSelectionChangedListener(
85                          IDOMSelectionChangedListener listener) {
86                  this.selectionChangedListeners.remove(listener);
87          }
88  
89          /***
90           * @return globalSelection
91           */
92          public DOMIntervalSet getDOMSelection() {
93                  return this.editor.getDOMSelection();
94          }
95  
96          /***
97           * Deselects editparts with Ids, that were in previous selection and
98           * select editparts that are in DOMIntervalSet and sends this selection
99           * to IDOMSelectionListeners
100          * 
101          * @param selection
102          *                DOMIntervalSet containing DOMInetervals, that have to
103          *                be selected
104          */
105         public void setSelection(DOMIntervalSet selection) {
106                 // compute what should be deselected, what selected, and what
107                 // remains selected as is
108                 DOMIntervalSet noChange = new DOMIntervalSet(this.selection).intersect(selection, null);
109                 DOMIntervalSet deselect = new DOMIntervalSet(this.selection).subtract(noChange, null);
110                 DOMIntervalSet select = new DOMIntervalSet(selection).subtract(noChange, null);
111 
112                 IdVisualInfo visualInfo = ((XMLEditPartFactory) getEditPartFactory())
113                                 .getVisualInfo();
114 
115                 // deselect
116                 Set<IXMLEditPart> deselectParts = visualInfo
117                                 .getVisualParts(deselect
118                                                 .getContentIds(getIDManager()));
119                 for (IXMLEditPart editPart : deselectParts)
120                         deselect(editPart);
121 
122                 // select
123                 Set<IXMLEditPart> selectParts = visualInfo.getVisualParts(select
124                                 .getContentIds(getIDManager()));
125                 for (IXMLEditPart editPart : selectParts)
126                         select(editPart);
127 
128                 this.selection = selection;
129                 // fire selection change event
130                 fireSelectionChanged();
131         }
132 
133         /***
134          * Selection changed in some synchronized selection provider.
135          * Synchronize selection - set in this viewer same selection.
136          * 
137          * @param event
138          *                DOMSelectionChangedEvent that contains source of new
139          *                selection, that should be some XMLEditor and
140          *                DOMIntervalSet as selection
141          */
142         public void selectionChanged(DOMSelectionChangedEvent event) {
143                 // guards listening
144                 if (this.canSelectionChangeListen != 0)
145                         return;
146                 setSelection(event.getDOMSelection());
147         }
148 
149         /***
150          * Stops listening to selection change events.
151          */
152         protected void stopSelectionListening() {
153                 this.canSelectionChangeListen++;
154         }
155 
156         /***
157          * Starts listening to selection change events.
158          */
159         protected void startSelectionListening() {
160                 if (this.canSelectionChangeListen == 0)
161                         throw new IllegalArgumentException();
162                 this.canSelectionChangeListen--;
163         }
164 
165         /***
166          * Fires event to listeners when selection was changed.
167          */
168         @Override
169         protected void fireSelectionChanged() {
170                 // stop listening to avoid to receive by loop own event
171                 stopSelectionListening();
172                 DOMSelectionChangedEvent event = new DOMSelectionChangedEvent(
173                                 this, this.selection);
174                 for (IDOMSelectionChangedListener listener : this.selectionChangedListeners)
175                         listener.selectionChanged(event);
176                 startSelectionListening();
177         }
178 
179         /***
180          * Selects editpart.
181          * 
182          * @param editpart
183          *                EditPart that is going to be selected
184          */
185         @SuppressWarnings("unchecked")
186         @Override
187         public void select(EditPart editpart) {
188                 // super.select(editpart);
189                 editpart.setSelected(EditPart.SELECTED);
190 
191                 if (!(primGetSelectedEditParts().contains(editpart))) {
192                         primGetSelectedEditParts().add(editpart);
193                         // editpart.showSourceFeedback(new SelectionRequest());
194                 }
195 
196         }
197 
198         /***
199          * Deselects edit part.
200          * 
201          * @param editpart
202          *                EditPart that is going to be deselected
203          */
204         @Override
205         public void deselect(EditPart editpart) {
206                 // super.deselect(editpart);
207                 editpart.setSelected(EditPart.SELECTED_NONE);
208 
209                 if (primGetSelectedEditParts().contains(editpart)) {
210                         primGetSelectedEditParts().remove(editpart);
211                 }
212 
213         }
214 
215         /***
216          * Helper getter.
217          * 
218          * @return IDManager instance
219          */
220         protected IDManager getIDManager() {
221                 return ((XMLEditDomain) getEditDomain()).getXMLEditor()
222                                 .getXMLAccess().getIDManager();
223         }
224 
225         /***
226          * Helper getter.
227          * 
228          * @return XMLAccess instance
229          */
230         protected XMLAccess getXMLAccess() {
231                 return ((XMLEditDomain) getEditDomain()).getXMLEditor()
232                                 .getXMLAccess();
233         }
234 }