KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > team > internal > ui > synchronize > AbstractTreeViewerAdvisor


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.team.internal.ui.synchronize;
12
13 import org.eclipse.compare.*;
14 import org.eclipse.core.resources.IResource;
15 import org.eclipse.core.runtime.IAdaptable;
16 import org.eclipse.jface.viewers.*;
17 import org.eclipse.swt.widgets.Tree;
18 import org.eclipse.swt.widgets.TreeItem;
19 import org.eclipse.team.core.synchronize.SyncInfo;
20 import org.eclipse.team.internal.ui.synchronize.actions.OpenInCompareAction;
21 import org.eclipse.team.ui.synchronize.*;
22 import org.eclipse.ui.*;
23
24 /**
25  * Abstract superclass for tree viewer advisors
26  */

27 public class AbstractTreeViewerAdvisor extends StructuredViewerAdvisor implements IAdaptable {
28
29     private ICompareNavigator nav;
30     private INavigatable navigatable;
31     
32     /**
33      * Interface used to implement navigation for tree viewers. This interface is used by
34      * {@link TreeViewerAdvisor#navigate(TreeViewer, boolean, boolean, boolean) to open}
35      * selections and navigate.
36      */

37     public interface ITreeViewerAccessor {
38         public void createChildren(TreeItem item);
39         public void openSelection();
40     }
41     
42     private class TreeCompareNavigator extends CompareNavigator {
43         
44         /* (non-Javadoc)
45          * @see org.eclipse.compare.CompareNavigator#getNavigatables()
46          */

47         protected INavigatable[] getNavigatables() {
48             INavigatable navigatable = getNavigatable();
49             return new INavigatable[] { navigatable };
50         }
51         
52         /* (non-Javadoc)
53          * @see org.eclipse.compare.CompareNavigator#selectChange(boolean)
54          */

55         public boolean selectChange(boolean next) {
56             if (getSubNavigator() != null) {
57                 if (getSubNavigator().hasChange(next)) {
58                     getSubNavigator().selectChange(next);
59                     return false;
60                 }
61             }
62             boolean noNextChange = super.selectChange(next);
63             if (!noNextChange) {
64                 // Check to see if the selected element can be opened.
65
// If it can't, try the next one
66
Object JavaDoc selectedObject = AbstractTreeViewerAdvisor.this.getFirstElement((IStructuredSelection)getViewer().getSelection());
67                 if (!hasCompareInput(selectedObject)) {
68                     return selectChange(next);
69                 }
70             }
71             return noNextChange;
72         }
73         
74         private boolean hasCompareInput(Object JavaDoc selectedObject) {
75             SyncInfo syncInfo = getSyncInfo(selectedObject);
76             if(syncInfo != null) {
77                 return syncInfo.getLocal().getType() == IResource.FILE;
78             }
79             ISynchronizeParticipant p = getConfiguration().getParticipant();
80             if (p instanceof ModelSynchronizeParticipant) {
81                 ModelSynchronizeParticipant msp = (ModelSynchronizeParticipant) p;
82                 return msp.hasCompareInputFor(selectedObject);
83             }
84             return true;
85         }
86
87         private SyncInfo getSyncInfo(Object JavaDoc obj) {
88             if (obj instanceof SyncInfoModelElement) {
89                 return ((SyncInfoModelElement) obj).getSyncInfo();
90             } else {
91                 return null;
92             }
93         }
94
95         /* (non-Javadoc)
96          * @see org.eclipse.compare.CompareNavigator#hasChange(boolean)
97          */

98         public boolean hasChange(boolean next) {
99             if (getSubNavigator() != null) {
100                 if (getSubNavigator().hasChange(next)) {
101                     return true;
102                 }
103             }
104             return super.hasChange(next);
105         }
106
107         private CompareNavigator getSubNavigator() {
108             IWorkbenchSite ws = AbstractTreeViewerAdvisor.this.getConfiguration().getSite().getWorkbenchSite();
109             if (ws instanceof IWorkbenchPartSite) {
110                 Object JavaDoc selectedObject = AbstractTreeViewerAdvisor.this.getFirstElement((IStructuredSelection)getViewer().getSelection());
111                 IEditorPart editor = OpenInCompareAction.findOpenCompareEditor((IWorkbenchPartSite)ws, selectedObject, getConfiguration().getParticipant());
112                 if(editor != null) {
113                     // if an existing editor is open on the current selection, use it
114
CompareEditorInput input = (CompareEditorInput)editor.getEditorInput();
115                     ICompareNavigator navigator = input.getNavigator();
116                     if (navigator instanceof TreeCompareNavigator) {
117                         // The input knows to use the global navigator.
118
// Assume it set the input navigator property
119
navigator = (ICompareNavigator)AbstractTreeViewerAdvisor.this.getConfiguration().getProperty(SynchronizePageConfiguration.P_INPUT_NAVIGATOR);
120                     }
121                     if (navigator instanceof CompareNavigator) {
122                         return (CompareNavigator) navigator;
123                         
124                     }
125                 }
126             }
127             return null;
128         }
129         
130     }
131     
132     private static boolean hasNextPrev(TreeViewer viewer, TreeItem item, boolean next) {
133         if (item == null || !(viewer instanceof ITreeViewerAccessor))
134             return false;
135         TreeItem children[] = null;
136         if (next) {
137             if (viewer.isExpandable(item.getData()))
138                 return true;
139             while(item != null) {
140                 TreeItem parent = item.getParentItem();
141                 if (parent != null)
142                     children = parent.getItems();
143                 else
144                     children = item.getParent().getItems();
145                 if (children != null && children.length > 0) {
146                     if (children[children.length - 1] != item) {
147                         // The item is not the last so there must be a next
148
return true;
149                     } else {
150                         // Set the parent as the item and go up one more level
151
item = parent;
152                     }
153                 }
154             }
155         } else {
156             while(item != null) {
157                 TreeItem parent = item.getParentItem();
158                 if (parent != null)
159                     children = parent.getItems();
160                 else
161                     children = item.getParent().getItems();
162                 if (children != null && children.length > 0) {
163                     if (children[0] != item) {
164                         // The item is not the first so there must be a previous
165
return true;
166                     } else {
167                         // Set the parent as the item and go up one more level
168
item = parent;
169                     }
170                 }
171             }
172         }
173         return false;
174     }
175     
176     private static TreeItem findNextPrev(TreeViewer viewer, TreeItem item, boolean next) {
177         if (item == null || !(viewer instanceof ITreeViewerAccessor))
178             return null;
179         TreeItem children[] = null;
180         ITreeViewerAccessor treeAccessor = (ITreeViewerAccessor) viewer;
181         if (!next) {
182             TreeItem parent = item.getParentItem();
183             if (parent != null)
184                 children = parent.getItems();
185             else
186                 children = item.getParent().getItems();
187             if (children != null && children.length > 0) {
188                 // goto previous child
189
int index = 0;
190                 for (; index < children.length; index++)
191                     if (children[index] == item)
192                         break;
193                 if (index > 0) {
194                     item = children[index - 1];
195                     while (true) {
196                         treeAccessor.createChildren(item);
197                         int n = item.getItemCount();
198                         if (n <= 0)
199                             break;
200                         item.setExpanded(true);
201                         item = item.getItems()[n - 1];
202                     }
203                     // previous
204
return item;
205                 }
206             }
207             // go up
208
return parent;
209         } else {
210             item.setExpanded(true);
211             treeAccessor.createChildren(item);
212             if (item.getItemCount() > 0) {
213                 // has children: go down
214
children = item.getItems();
215                 return children[0];
216             }
217             while (item != null) {
218                 children = null;
219                 TreeItem parent = item.getParentItem();
220                 if (parent != null)
221                     children = parent.getItems();
222                 else
223                     children = item.getParent().getItems();
224                 if (children != null && children.length > 0) {
225                     // goto next child
226
int index = 0;
227                     for (; index < children.length; index++)
228                         if (children[index] == item)
229                             break;
230                     if (index < children.length - 1) {
231                         // next
232
return children[index + 1];
233                     }
234                 }
235                 // go up
236
item = parent;
237             }
238         }
239         return item;
240     }
241
242     private static void setSelection(TreeViewer viewer, TreeItem ti, boolean fireOpen, boolean expandOnly) {
243         if (ti != null) {
244             Object JavaDoc data= ti.getData();
245             if (data != null) {
246                 // Fix for http://dev.eclipse.org/bugs/show_bug.cgi?id=20106
247
ISelection selection = new StructuredSelection(data);
248                 if (expandOnly) {
249                     viewer.expandToLevel(data, 0);
250                 } else {
251                     viewer.setSelection(selection, true);
252                     ISelection currentSelection = viewer.getSelection();
253                     if (fireOpen && currentSelection != null && selection.equals(currentSelection)) {
254                         if (viewer instanceof ITreeViewerAccessor) {
255                             ((ITreeViewerAccessor) viewer).openSelection();
256                         }
257                     }
258                 }
259             }
260         }
261     }
262
263     /**
264      * Selects the next (or previous) node of the current selection.
265      * If there is no current selection the first (last) node in the tree is selected.
266      * Wraps around at end or beginning.
267      * Clients may not override.
268      * @param viewer
269      *
270      * @param next if <code>true</code> the next node is selected, otherwise the previous node
271      * @param fireOpen
272      * @param expandOnly
273      * @return <code>true</code> if at end (or beginning)
274      */

275     public static boolean navigate(TreeViewer viewer, boolean next, boolean fireOpen, boolean expandOnly) {
276         Tree tree = viewer.getTree();
277         if (tree == null)
278             return false;
279         TreeItem item = getNextItem(viewer, next);
280         if (item != null)
281             setSelection(viewer, item, fireOpen, expandOnly);
282         return item == null;
283     }
284         
285     private static TreeItem getNextItem(TreeViewer viewer, boolean next) {
286         TreeItem item = getCurrentItem(viewer);
287         if (item != null) {
288             while (true) {
289                 item = findNextPrev(viewer, item, next);
290                 if (item == null)
291                     break;
292                 if (item.getItemCount() <= 0)
293                     break;
294             }
295         }
296         return item;
297     }
298
299     private static TreeItem getCurrentItem(TreeViewer viewer) {
300         Tree tree = viewer.getTree();
301         if (tree == null)
302             return null;
303         TreeItem item = null;
304         TreeItem children[] = tree.getSelection();
305         if (children != null && children.length > 0)
306             item = children[0];
307         if (item == null) {
308             children = tree.getItems();
309             if (children != null && children.length > 0) {
310                 item = children[0];
311                 if (item != null && item.getItemCount() <= 0) {
312                     return item;
313                 }
314             }
315         }
316         return item;
317     }
318     
319     private static boolean hasChange(TreeViewer viewer, boolean next) {
320         TreeItem item = getCurrentItem(viewer);
321         if (item != null) {
322             return hasNextPrev(viewer, item, next);
323         }
324         return false;
325     }
326
327     public AbstractTreeViewerAdvisor(ISynchronizePageConfiguration configuration) {
328         super(configuration);
329         ICompareNavigator nav = (ICompareNavigator)configuration.getProperty(SynchronizePageConfiguration.P_NAVIGATOR);
330         if (nav == null) {
331             configuration.setProperty(SynchronizePageConfiguration.P_NAVIGATOR, getAdapter(ICompareNavigator.class));
332         }
333         configuration.addActionContribution(new NavigationActionGroup());
334     }
335
336     /**
337      * Allow navigation in tree viewers.
338      *
339      * @param next if <code>true</code> then navigate forwards, otherwise navigate
340      * backwards.
341      * @return <code>true</code> if the end is reached, and <code>false</code> otherwise.
342      */

343     public boolean navigate(boolean next) {
344         return navigate((TreeViewer)getViewer(), next, false, false);
345     }
346     
347     protected boolean hasChange(boolean next) {
348         return hasChange((TreeViewer)getViewer(), next);
349     }
350
351     /* (non-Javadoc)
352      * Allow adding an advisor to the PartNavigator and support coordinated
353      * navigation between several objects.
354      * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
355      */

356     public Object JavaDoc getAdapter(Class JavaDoc adapter) {
357         if(adapter == ICompareNavigator.class) {
358             if(nav == null) {
359                 nav = new TreeCompareNavigator();
360             }
361             return nav;
362         }
363         if(adapter == INavigatable.class) {
364             return getNavigatable();
365         }
366         return null;
367     }
368
369     private synchronized INavigatable getNavigatable() {
370         if(navigatable == null) {
371             navigatable = new INavigatable() {
372                 public boolean selectChange(int flag) {
373                     if (flag == INavigatable.FIRST_CHANGE) {
374                         getViewer().setSelection(StructuredSelection.EMPTY);
375                         flag = INavigatable.NEXT_CHANGE;
376                     } else if (flag == INavigatable.LAST_CHANGE) {
377                         getViewer().setSelection(StructuredSelection.EMPTY);
378                         flag = INavigatable.PREVIOUS_CHANGE;
379                     }
380                     return navigate((TreeViewer)getViewer(), flag == INavigatable.NEXT_CHANGE, true, false);
381                 }
382             
383                 public boolean openSelectedChange() {
384                     Viewer v = getViewer();
385                     if (v instanceof ITreeViewerAccessor && !v.getControl().isDisposed()) {
386                         ITreeViewerAccessor tva = (ITreeViewerAccessor) v;
387                         tva.openSelection();
388                         return true;
389                     }
390                     return false;
391                 }
392                 public boolean hasChange(int changeFlag) {
393                     return AbstractTreeViewerAdvisor.this.hasChange(changeFlag == INavigatable.NEXT_CHANGE);
394                 }
395                 public Object JavaDoc getInput() {
396                     return getViewer().getInput();
397                 }
398             
399             };
400         }
401         return navigatable;
402     }
403
404     /**
405      * Handles a double-click event from the viewer. Expands or collapses a folder when double-clicked.
406      *
407      * @param viewer the viewer
408      * @param event the double-click event
409      */

410     protected boolean handleDoubleClick(StructuredViewer viewer, DoubleClickEvent event) {
411         if (super.handleDoubleClick(viewer, event)) return true;
412         IStructuredSelection selection = (IStructuredSelection) event.getSelection();
413         Object JavaDoc element = getFirstElementOrPath(selection);
414         AbstractTreeViewer treeViewer = (AbstractTreeViewer) getViewer();
415         if(element != null) {
416             if (treeViewer.getExpandedState(element)) {
417                 treeViewer.collapseToLevel(element, AbstractTreeViewer.ALL_LEVELS);
418             } else {
419                 expandToNextDiff(element);
420             }
421         }
422         return true;
423     }
424
425     private Object JavaDoc getFirstElementOrPath(IStructuredSelection selection) {
426         if (selection instanceof TreeSelection) {
427             TreeSelection ts = (TreeSelection) selection;
428             TreePath[] paths = ts.getPaths();
429             if (paths.length > 0)
430                 return paths[0];
431         }
432         Object JavaDoc element = selection.getFirstElement();
433         return element;
434     }
435     
436     private Object JavaDoc getFirstElement(IStructuredSelection selection) {
437         Object JavaDoc element = getFirstElementOrPath(selection);
438         if (element instanceof TreePath) {
439             TreePath path = (TreePath) element;
440             element = path.getLastSegment();
441         }
442         return element;
443     }
444
445     protected void expandToNextDiff(Object JavaDoc elementOrPath) {
446         AbstractTreeViewerAdvisor.navigate((TreeViewer)getViewer(), true /* next */, false /* no-open */, true /* only-expand */);
447     }
448 }
449
Popular Tags