KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > part > DrillDownAdapter


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 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.ui.part;
12
13 import java.util.Arrays JavaDoc;
14 import java.util.List JavaDoc;
15
16 import org.eclipse.jface.action.Action;
17 import org.eclipse.jface.action.IMenuManager;
18 import org.eclipse.jface.action.IToolBarManager;
19 import org.eclipse.jface.viewers.ISelectionChangedListener;
20 import org.eclipse.jface.viewers.IStructuredSelection;
21 import org.eclipse.jface.viewers.SelectionChangedEvent;
22 import org.eclipse.jface.viewers.StructuredSelection;
23 import org.eclipse.jface.viewers.TreeViewer;
24 import org.eclipse.ui.ISharedImages;
25 import org.eclipse.ui.PlatformUI;
26 import org.eclipse.ui.internal.IWorkbenchGraphicConstants;
27 import org.eclipse.ui.internal.WorkbenchImages;
28 import org.eclipse.ui.internal.WorkbenchMessages;
29
30 /**
31  * Implements a simple web style navigation metaphor for a <code>TreeViewer</code>.
32  * Home, back, and "drill into" functions are supported for the viewer,
33  * <p>
34  * To use the <code>DrillDownAdapter</code> ..
35  * </p>
36  * <ul>
37  * <li>Create an instance of <code>TreeViewer</code>. </li>
38  * <li>Create a <code>DrillDownAdapter</code> for the viewer. </li>
39  * <li>Create a container for your viewer with a toolbar or a popup menu.
40  * Add actions for "goBack", "goHome", and "goInto" to either one by calling
41  * </code>addNavigationActions</code> with the popup menu or toolbar.</li>
42  * </ol>
43  * <p>
44  * If the input for the underlying viewer is changed by something other than the
45  * adapter the <code>reset</code> method should be called. This will clear
46  * the drill stack and update the navigation buttons to reflect the new
47  * state of the underlying viewer.
48  * </p>
49  * </p>
50  */

51 public class DrillDownAdapter implements ISelectionChangedListener {
52     private TreeViewer fChildTree;
53
54     private DrillStack fDrillStack;
55
56     private Action homeAction;
57
58     private Action backAction;
59
60     private Action forwardAction;
61
62     /**
63      * Allocates a new DrillDownTreePart.
64      *
65      * @param tree the target tree for refocusing
66      */

67     public DrillDownAdapter(TreeViewer tree) {
68         fDrillStack = new DrillStack();
69         fChildTree = tree;
70     }
71
72     /**
73      * Adds actions for "go back", "go home", and "go into" to a menu manager.
74      *
75      * @param manager is the target manager to update
76      */

77     public void addNavigationActions(IMenuManager manager) {
78         createActions();
79         manager.add(homeAction);
80         manager.add(backAction);
81         manager.add(forwardAction);
82         updateNavigationButtons();
83     }
84
85     /**
86      * Adds actions for "go back", "go home", and "go into" to a tool bar manager.
87      *
88      * @param toolBar is the target manager to update
89      */

90     public void addNavigationActions(IToolBarManager toolBar) {
91         createActions();
92         toolBar.add(homeAction);
93         toolBar.add(backAction);
94         toolBar.add(forwardAction);
95         updateNavigationButtons();
96     }
97
98     /**
99      * Returns whether expansion is possible for the current selection. This
100      * will only be true if it has children.
101      *
102      * @param element the object to test for expansion
103      * @return <code>true</code> if expansion is possible; otherwise
104      * return <code>false</code
105      */

106     public boolean canExpand(Object JavaDoc element) {
107         return fChildTree.isExpandable(element);
108     }
109
110     /**
111      * Returns whether "go back" is possible for child tree. This is only possible
112      * if the client has performed one or more drilling operations.
113      *
114      * @return <code>true</code> if "go back" is possible; <code>false</code> otherwise
115      */

116     public boolean canGoBack() {
117         return fDrillStack.canGoBack();
118     }
119
120     /**
121      * Returns whether "go home" is possible for child tree. This is only possible
122      * if the client has performed one or more drilling operations.
123      *
124      * @return <code>true</code> if "go home" is possible; <code>false</code> otherwise
125      */

126     public boolean canGoHome() {
127         return fDrillStack.canGoHome();
128     }
129
130     /**
131      * Returns whether "go into" is possible for child tree. This is only possible
132      * if the current selection in the client has one item and it has children.
133      *
134      * @return <code>true</code> if "go into" is possible; <code>false</code> otherwise
135      */

136     public boolean canGoInto() {
137         IStructuredSelection oSelection = (IStructuredSelection) fChildTree
138                 .getSelection();
139         if (oSelection == null || oSelection.size() != 1) {
140             return false;
141         }
142         Object JavaDoc anElement = oSelection.getFirstElement();
143         return canExpand(anElement);
144     }
145
146     /**
147      * Create the actions for navigation.
148      *
149      * @param tree the target tree for refocusing
150      */

151     private void createActions() {
152         // Only do this once.
153
if (homeAction != null) {
154             return;
155         }
156
157         // Home.
158
homeAction = new Action(WorkbenchMessages.GoHome_text) {
159             public void run() {
160                 goHome();
161             }
162         };
163         homeAction
164                 .setToolTipText(WorkbenchMessages.GoHome_toolTip);
165         homeAction
166                 .setImageDescriptor(WorkbenchImages
167                         .getImageDescriptor(IWorkbenchGraphicConstants.IMG_ETOOL_HOME_NAV));
168
169         // Back.
170
ISharedImages images = PlatformUI.getWorkbench().getSharedImages();
171         backAction = new Action(WorkbenchMessages.GoBack_text) {
172             public void run() {
173                 goBack();
174             }
175         };
176         backAction
177                 .setToolTipText(WorkbenchMessages.GoBack_toolTip);
178         backAction.setImageDescriptor(images
179                 .getImageDescriptor(ISharedImages.IMG_TOOL_BACK));
180         backAction.setDisabledImageDescriptor(images
181                 .getImageDescriptor(ISharedImages.IMG_TOOL_BACK_DISABLED));
182
183         // Forward.
184
forwardAction = new Action(WorkbenchMessages.GoInto_text) {
185             public void run() {
186                 goInto();
187             }
188         };
189         forwardAction.setToolTipText(WorkbenchMessages.GoInto_toolTip);
190         forwardAction.setImageDescriptor(images
191                 .getImageDescriptor(ISharedImages.IMG_TOOL_FORWARD));
192         forwardAction.setDisabledImageDescriptor(images
193                 .getImageDescriptor(ISharedImages.IMG_TOOL_FORWARD_DISABLED));
194
195         // Update the buttons when a selection change occurs.
196
fChildTree.addSelectionChangedListener(this);
197         updateNavigationButtons();
198     }
199
200     /**
201      * Expands the given items in the tree. The list of items passed should be
202      * derived by calling <code>getExpanded</code>.
203      *
204      * @param items is a list of items within the tree which should be expanded
205      */

206     private void expand(List JavaDoc items) {
207         fChildTree.setExpandedElements(items.toArray());
208     }
209
210     /**
211      * Returns a list of elements corresponding to expanded nodes in
212      * child tree.
213      *
214      * @return a list of expandd elements
215      */

216     private List JavaDoc getExpanded() {
217         return Arrays.asList(fChildTree.getExpandedElements());
218     }
219
220     /**
221      * Reverts the input for the tree back to the state when <code>goInto</code>
222      * was last called.
223      * <p>
224      * A frame is removed from the drill stack. Then that frame is used to reset the
225      * input and expansion state for the child tree.
226      * </p>
227      */

228     public void goBack() {
229         Object JavaDoc currentInput = fChildTree.getInput();
230         DrillFrame oFrame = fDrillStack.goBack();
231         Object JavaDoc input = oFrame.getElement();
232         fChildTree.setInput(input);
233         expand(oFrame.getExpansion());
234         // if there was a selection, it should have been preserved,
235
// but if not, select the element that was drilled into
236
if (fChildTree.getSelection().isEmpty()) {
237             fChildTree
238                     .setSelection(new StructuredSelection(currentInput), true);
239         }
240         updateNavigationButtons();
241     }
242
243     /**
244      * Reverts the input for the tree back to the state when the adapter was
245      * created.
246      * <p>
247      * All of the frames are removed from the drill stack. Then the oldest frame is
248      * used to reset the input and expansion state for the child tree.
249      * </p>
250      */

251     public void goHome() {
252         Object JavaDoc currentInput = fChildTree.getInput();
253         DrillFrame oFrame = fDrillStack.goHome();
254         Object JavaDoc input = oFrame.getElement();
255         fChildTree.setInput(input);
256         expand(oFrame.getExpansion());
257         // if there was a selection, it should have been preserved,
258
// but if not, select the element that was last drilled into
259
if (fChildTree.getSelection().isEmpty()) {
260             fChildTree
261                     .setSelection(new StructuredSelection(currentInput), true);
262         }
263         updateNavigationButtons();
264     }
265
266     /**
267      * Sets the input for the tree to the current selection.
268      * <p>
269      * The current input and expansion state are saved in a frame and added to the
270      * drill stack. Then the input for the tree is changed to be the current selection.
271      * The expansion state for the tree is maintained during the operation.
272      * </p><p>
273      * On return the client may revert back to the previous state by invoking
274      * <code>goBack</code> or <code>goHome</code>.
275      * </p>
276      */

277     public void goInto() {
278         IStructuredSelection sel = (IStructuredSelection) fChildTree
279                 .getSelection();
280         Object JavaDoc element = sel.getFirstElement();
281         goInto(element);
282     }
283
284     /**
285      * Sets the input for the tree to a particular item in the tree.
286      * <p>
287      * The current input and expansion state are saved in a frame and added to the
288      * drill stack. Then the input for the tree is changed to be <code>newInput</code>.
289      * The expansion state for the tree is maintained during the operation.
290      * </p><p>
291      * On return the client may revert back to the previous state by invoking
292      * <code>goBack</code> or <code>goHome</code>.
293      * </p>
294      *
295      * @param newInput the new input element
296      */

297     public void goInto(Object JavaDoc newInput) {
298         // If we can drill ..
299
if (canExpand(newInput)) {
300             // Save the old state.
301
Object JavaDoc oldInput = fChildTree.getInput();
302             List JavaDoc expandedList = getExpanded();
303             fDrillStack.add(new DrillFrame(oldInput, "null", expandedList));//$NON-NLS-1$
304

305             // Install the new state.
306
fChildTree.setInput(newInput);
307             expand(expandedList);
308             updateNavigationButtons();
309         }
310     }
311
312     /**
313      * Resets the drill down adapter.
314      * <p>
315      * This method is typically called when the input for the underlying view
316      * is reset by something other than the adapter.
317      * On return the drill stack has been cleared and the navigation buttons
318      * reflect the new state of the underlying viewer.
319      * </p>
320      */

321     public void reset() {
322         fDrillStack.reset();
323         updateNavigationButtons();
324     }
325
326     /**
327      * Updates the navigation buttons when a selection change occurs
328      * in the tree.
329      */

330     public void selectionChanged(SelectionChangedEvent event) {
331         updateNavigationButtons();
332     }
333
334     /**
335      * Updates the enabled state for each navigation button.
336      */

337     protected void updateNavigationButtons() {
338         if (homeAction != null) {
339             homeAction.setEnabled(canGoHome());
340             backAction.setEnabled(canGoBack());
341             forwardAction.setEnabled(canGoInto());
342         }
343     }
344 }
345
Popular Tags