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.GraphicalViewerImpl;
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   * Graphical viewer capable of performing selections over XML. Selection object
34   * is {@link DOMIntervalSet}. 
35   * @author Martin Kollar
36   */
37  public class XMLGraphicalViewerImpl extends GraphicalViewerImpl implements
38                  IXMLGraphicalViewer {
39  
40          private List<IDOMSelectionChangedListener> selectionChangedListeners = new ArrayList<IDOMSelectionChangedListener>();
41  
42          /***
43           * Guards selection listening. Prevents event-listen loops. Can listen
44           * only when equals zero.
45           */
46          private int canSelectionChangeListen = 0;
47  
48          /***
49           * Local selection for this viewer.
50           */
51          protected DOMIntervalSet selection = new DOMIntervalSet();
52  
53          /***
54           * Associated editor.s
55           */
56          private XMLEditor editor;
57  
58          /***
59           * Contructor.
60           * 
61           * @param editor
62           *                XMLEditor that uses this GraphicalViewer
63           */
64          public XMLGraphicalViewerImpl(XMLEditor editor) {
65                  super();
66                  this.editor = editor;
67          }
68  
69          /***
70           * @param listener
71           *                new listener to be add from selectionChangedListeners
72           */
73          public void addSelectionChangedListener(
74                          IDOMSelectionChangedListener listener) {
75                  if (!(this.selectionChangedListeners.contains(listener)))
76                          this.selectionChangedListeners.add(listener);
77          }
78  
79          /***
80           * @param listener
81           *                listener to be removed from selectionChangedListeners
82           */
83          public void removeSelectionChangedListener(
84                          IDOMSelectionChangedListener listener) {
85                  this.selectionChangedListeners.remove(listener);
86          }
87  
88          /***
89           * @return globalSelection
90           */
91          public DOMIntervalSet getDOMSelection() {
92                  return this.editor.getDOMSelection();
93          }
94  
95          /***
96           * Deselects editparts with Ids, that were in previous selection and
97           * select editparts that are in DOMIntervalSet and sends this selection
98           * to IDOMSelectionListeners
99           * 
100          * @param selection
101          *                DOMIntervalSet containing DOMInetervals, that have to
102          *                be selected
103          */
104         public void setSelection(DOMIntervalSet selection) {
105                 // compute what should be deselected, what selected, and what
106                 // remains selected as is
107                 DOMIntervalSet noChange = new DOMIntervalSet(this.selection).intersect(selection, null);
108                 DOMIntervalSet deselect = new DOMIntervalSet(this.selection).subtract(noChange, null);
109                 DOMIntervalSet select = new DOMIntervalSet(selection).subtract(noChange, null);
110 
111                 IdVisualInfo visualInfo = ((XMLEditPartFactory) getEditPartFactory())
112                                 .getVisualInfo();
113 
114                 // deselect
115                 Set<IXMLEditPart> deselectParts = visualInfo
116                                 .getVisualParts(deselect
117                                                 .getContentIds(getIDManager()));
118                 for (IXMLEditPart editPart : deselectParts)
119                         deselect(editPart);
120 
121                 // select
122                 Set<IXMLEditPart> selectParts = visualInfo.getVisualParts(select
123                                 .getContentIds(getIDManager()));
124                 for (IXMLEditPart editPart : selectParts)
125                         select(editPart);
126 
127                 this.selection = selection;
128                 // fire selection change event
129                 fireSelectionChanged();
130         }
131 
132         /***
133          * Selection changed in some synchronized selection provider.
134          * Synchronize selection - set in this viewer same selection.
135          * 
136          * @param event
137          *                DOMSelectionChangedEvent that contains source of new
138          *                selection, that should be some XMLEditor and
139          *                DOMIntervalSet as selection
140          */
141         public void selectionChanged(DOMSelectionChangedEvent event) {
142                 // guards listening
143                 if (this.canSelectionChangeListen != 0)
144                         return;
145                 setSelection(event.getDOMSelection());
146         }
147 
148         /***
149          * Stops listening to selection change events.
150          */
151         protected void stopSelectionListening() {
152                 this.canSelectionChangeListen++;
153         }
154 
155         /***
156          * Starts listening to selection change events.
157          */
158         protected void startSelectionListening() {
159                 if (this.canSelectionChangeListen == 0)
160                         throw new IllegalArgumentException();
161                 this.canSelectionChangeListen--;
162         }
163 
164         /***
165          * Fires event to listeners when selection was changed.
166          */
167         @Override
168         protected void fireSelectionChanged() {
169                 // stop listening to avoid to receive by loop own event
170                 stopSelectionListening();
171                 DOMSelectionChangedEvent event = new DOMSelectionChangedEvent(
172                                 this, this.selection);
173                 for (IDOMSelectionChangedListener listener : this.selectionChangedListeners)
174                         listener.selectionChanged(event);
175                 startSelectionListening();
176         }
177 
178         /***
179          * Selects editpart.
180          * 
181          * @param editpart
182          *                EditPart that is going to be selected
183          */
184         @SuppressWarnings("unchecked")
185         @Override
186         public void select(EditPart editpart) {
187                 // super.select(editpart);
188                 editpart.setSelected(EditPart.SELECTED);
189 
190                 if (!(primGetSelectedEditParts().contains(editpart))) {
191                         primGetSelectedEditParts().add(editpart);
192                         // editpart.showSourceFeedback(new SelectionRequest());
193                 }
194 
195         }
196 
197         /***
198          * Deselects edit part.
199          * 
200          * @param editpart
201          *                EditPart that is going to be deselected
202          */
203         @Override
204         public void deselect(EditPart editpart) {
205                 // super.deselect(editpart);
206                 editpart.setSelected(EditPart.SELECTED_NONE);
207 
208                 if (primGetSelectedEditParts().contains(editpart)) {
209                         primGetSelectedEditParts().remove(editpart);
210                 }
211 
212         }
213 
214         /***
215          * Helper getter.
216          * 
217          * @return IDManager instance
218          */
219         protected IDManager getIDManager() {
220                 return ((XMLEditDomain) getEditDomain()).getXMLEditor()
221                                 .getXMLAccess().getIDManager();
222         }
223 
224         /***
225          * Helper getter.
226          * 
227          * @return XMLAccess instance
228          */
229         protected XMLAccess getXMLAccess() {
230                 return ((XMLEditDomain) getEditDomain()).getXMLEditor()
231                                 .getXMLAccess();
232         }
233 }