KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > actions > PerspectiveMenu


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.actions;
12
13 import com.ibm.icu.text.Collator;
14 import java.util.ArrayList JavaDoc;
15 import java.util.Collections JavaDoc;
16 import java.util.Comparator JavaDoc;
17 import java.util.HashMap JavaDoc;
18 import java.util.Iterator JavaDoc;
19 import java.util.List JavaDoc;
20 import java.util.Map JavaDoc;
21
22 import org.eclipse.jface.action.Action;
23 import org.eclipse.jface.action.ContributionItem;
24 import org.eclipse.jface.action.IAction;
25 import org.eclipse.jface.action.IContributionItem;
26 import org.eclipse.jface.action.IMenuListener;
27 import org.eclipse.jface.action.IMenuManager;
28 import org.eclipse.jface.action.MenuManager;
29 import org.eclipse.jface.action.Separator;
30 import org.eclipse.jface.window.Window;
31 import org.eclipse.swt.SWT;
32 import org.eclipse.swt.events.SelectionEvent;
33 import org.eclipse.swt.widgets.Event;
34 import org.eclipse.swt.widgets.Menu;
35 import org.eclipse.swt.widgets.MenuItem;
36 import org.eclipse.ui.IPerspectiveDescriptor;
37 import org.eclipse.ui.IPerspectiveRegistry;
38 import org.eclipse.ui.IWorkbenchPage;
39 import org.eclipse.ui.IWorkbenchWindow;
40 import org.eclipse.ui.activities.WorkbenchActivityHelper;
41 import org.eclipse.ui.internal.WorkbenchMessages;
42 import org.eclipse.ui.internal.dialogs.SelectPerspectiveDialog;
43
44 /**
45  * A menu for perspective selection.
46  * <p>
47  * A <code>PerspectiveMenu</code> is used to populate a menu with
48  * perspective shortcut items. If the user selects one of these items
49  * an action is performed for the selected perspective.
50  * </p><p>
51  * The visible perspective items within the menu are dynamic and reflect the
52  * available set generated by each subclass. The default available set consists
53  * of the perspective shortcut list of the current perspective.
54  * </p><p>
55  * This class is abstract. Subclasses must implement the <code>run</code> method,
56  * which performs a specialized action for the selected perspective.
57  * </p>
58  */

59 public abstract class PerspectiveMenu extends ContributionItem {
60     private IPerspectiveRegistry reg;
61
62     private IWorkbenchWindow window;
63
64     private boolean showActive = false;
65
66     private boolean dirty = true;
67
68     private IMenuListener menuListener = new IMenuListener() {
69         public void menuAboutToShow(IMenuManager manager) {
70             manager.markDirty();
71             dirty = true;
72         }
73     };
74
75     private Comparator JavaDoc comparator = new Comparator JavaDoc() {
76         private Collator collator = Collator.getInstance();
77
78         public int compare(Object JavaDoc ob1, Object JavaDoc ob2) {
79             IPerspectiveDescriptor d1 = (IPerspectiveDescriptor) ob1;
80             IPerspectiveDescriptor d2 = (IPerspectiveDescriptor) ob2;
81             return collator.compare(d1.getLabel(), d2.getLabel());
82         }
83     };
84
85     /**
86      * The translatable message to show when there are no perspectives.
87      *
88      * @since 3.1
89      */

90     private static final String JavaDoc NO_TARGETS_MSG = WorkbenchMessages.Workbench_showInNoPerspectives;
91
92     /**
93      * The map of perspective identifiers (String) to actions
94      * (OpenPerspectiveAction). This map may be empty, but it is never
95      * <code>null</code>.
96      *
97      * @since 3.1
98      */

99     private Map JavaDoc actions = new HashMap JavaDoc();
100
101     /**
102      * The action for that allows the user to choose any perspective to open.
103      *
104      * @since 3.1
105      */

106     private Action openOtherAction = new Action(WorkbenchMessages.PerspectiveMenu_otherItem) {
107         public final void runWithEvent(final Event event) {
108             runOther(new SelectionEvent(event));
109         }
110     };
111
112
113     /**
114      * Constructs a new instance of <code>PerspectiveMenu</code>.
115      *
116      * @param window the window containing this menu
117      * @param id the menu id
118      */

119     public PerspectiveMenu(IWorkbenchWindow window, String JavaDoc id) {
120         super(id);
121         this.window = window;
122         reg = window.getWorkbench().getPerspectiveRegistry();
123         openOtherAction
124                 .setActionDefinitionId("org.eclipse.ui.perspectives.showPerspective"); //$NON-NLS-1$
125
}
126
127     /*
128      * (non-Javadoc) Fills the menu with perspective items.
129      */

130     public void fill(Menu menu, int index) {
131         if (getParent() instanceof MenuManager) {
132             ((MenuManager) getParent()).addMenuListener(menuListener);
133         }
134
135         if (!dirty) {
136             return;
137         }
138
139         final MenuManager manager = new MenuManager();
140         fillMenu(manager);
141         final IContributionItem items[] = manager.getItems();
142         if (items.length == 0) {
143             MenuItem item = new MenuItem(menu, SWT.NONE, index++);
144             item.setText(NO_TARGETS_MSG);
145             item.setEnabled(false);
146         } else {
147             for (int i = 0; i < items.length; i++) {
148                 items[i].fill(menu, index++);
149             }
150         }
151         dirty = false;
152     }
153
154     /**
155      * Fills the given menu manager with all the open perspective actions
156      * appropriate for the currently active perspective. Filtering is applied to
157      * the actions based on the activities and capabilities mechanism.
158      *
159      * @param manager
160      * The menu manager that should receive the menu items; must not
161      * be <code>null</code>.
162      * @since 3.1
163      */

164     private final void fillMenu(final MenuManager manager) {
165         // Clear out the manager so that we have a blank slate.
166
manager.removeAll();
167
168         // Collect and sort perspective descriptors.
169
final List JavaDoc persps = getPerspectiveItems();
170         Collections.sort(persps, comparator);
171
172         /*
173          * Convert the perspective descriptors to actions, and filter out
174          * actions using the activity/capability mechanism.
175          */

176         final List JavaDoc actions = new ArrayList JavaDoc(persps.size());
177         for (Iterator JavaDoc i = persps.iterator(); i.hasNext();) {
178             final IPerspectiveDescriptor descriptor = (IPerspectiveDescriptor) i
179                     .next();
180             final IAction action = getAction(descriptor.getId());
181             if (action != null) {
182                 if (WorkbenchActivityHelper.filterItem(action)) {
183                     continue;
184                 }
185                 actions.add(action);
186             }
187         }
188
189         // Go through and add each of the actions to the menu manager.
190
for (Iterator JavaDoc i = actions.iterator(); i.hasNext();) {
191             manager.add((IAction) i.next());
192         }
193
194         // Add a separator and then "Other..."
195
if (actions.size() > 0) {
196             manager.add(new Separator());
197         }
198         manager.add(openOtherAction);
199     }
200
201     /**
202      * Returns the action for the given perspective id. This is a lazy cache. If
203      * the action does not already exist, then it is created. If there is no
204      * perspective with the given identifier, then the action is not created.
205      *
206      * @param id
207      * The identifier of the perspective for which the action should
208      * be retrieved.
209      * @return The action for the given identifier; or <code>null</code> if
210      * there is no perspective with the given identifier.
211      * @since 3.1
212      */

213     private final IAction getAction(final String JavaDoc id) {
214         IAction action = (IAction) actions.get(id);
215         if (action == null) {
216             IPerspectiveDescriptor descriptor = reg.findPerspectiveWithId(id);
217             if (descriptor != null) {
218                 action = new OpenPerspectiveAction(window, descriptor, this);
219                 action.setActionDefinitionId(id);
220                 actions.put(id, action);
221             }
222         }
223         return action;
224     }
225
226     /* (non-Javadoc)
227      * Returns the perspective shortcut items for the active perspective.
228      *
229      * @return a list of <code>IPerspectiveDescriptor</code> items
230      */

231     private ArrayList JavaDoc getPerspectiveShortcuts() {
232         ArrayList JavaDoc list = new ArrayList JavaDoc();
233
234         IWorkbenchPage page = window.getActivePage();
235         if (page == null) {
236             return list;
237         }
238
239         String JavaDoc[] ids = page.getPerspectiveShortcuts();
240
241         for (int i = 0; i < ids.length; i++) {
242             IPerspectiveDescriptor desc = reg.findPerspectiveWithId(ids[i]);
243             if (desc != null && !list.contains(desc)) {
244                 if (WorkbenchActivityHelper.filterItem(desc)) {
245                     continue;
246                 }
247                 list.add(desc);
248             }
249         }
250
251         return list;
252     }
253
254     /**
255      * Returns the available list of perspectives to display in the menu.
256      * <p>
257      * By default, the list contains the perspective shortcuts
258      * for the current perspective.
259      * </p><p>
260      * Subclasses can override this method to return a different list.
261      * </p>
262      *
263      * @return an <code>ArrayList<code> of perspective items <code>IPerspectiveDescriptor</code>
264      */

265     protected ArrayList JavaDoc getPerspectiveItems() {
266         /* Allow the user to see all the perspectives they have
267          * selected via Customize Perspective. Bugzilla bug #23445 */

268         ArrayList JavaDoc shortcuts = getPerspectiveShortcuts();
269         ArrayList JavaDoc list = new ArrayList JavaDoc(shortcuts.size());
270
271         // Add perspective shortcuts from the active perspective
272
int size = shortcuts.size();
273         for (int i = 0; i < size; i++) {
274             if (!list.contains(shortcuts.get(i))) {
275                 list.add(shortcuts.get(i));
276             }
277         }
278
279         return list;
280     }
281
282     /**
283      * Returns whether the menu item representing the active perspective
284      * will have a check mark.
285      *
286      * @return <code>true</code> if a check mark is shown, <code>false</code> otherwise
287      */

288     protected boolean getShowActive() {
289         return showActive;
290     }
291
292     /**
293      * Returns the window for this menu.
294      *
295      * @return the window
296      */

297     protected IWorkbenchWindow getWindow() {
298         return window;
299     }
300
301     /* (non-Javadoc)
302      * Returns whether this menu is dynamic.
303      */

304     public boolean isDirty() {
305         return dirty;
306     }
307
308     /* (non-Javadoc)
309      * Returns whether this menu is dynamic.
310      */

311     public boolean isDynamic() {
312         return true;
313     }
314
315     /**
316      * Runs an action for a particular perspective. The behavior of the
317      * action is defined by the subclass.
318      *
319      * @param desc the selected perspective
320      */

321     protected abstract void run(IPerspectiveDescriptor desc);
322
323     /**
324      * Runs an action for a particular perspective. The behavior of the action
325      * is defined by the subclass. By default, this just calls
326      * <code>run(IPerspectiveDescriptor)</code>.
327      *
328      * @param desc
329      * the selected perspective
330      * @param event
331      * SelectionEvent - the event send along with the selection
332      * callback
333      */

334     protected void run(IPerspectiveDescriptor desc, SelectionEvent event) {
335         //Do a run without the event by default
336
run(desc);
337     }
338
339     /* (non-Javadoc)
340      * Show the "other" dialog, select a perspective, and run it. Pass on the selection
341      * event should the meny need it.
342      */

343     void runOther(SelectionEvent event) {
344         SelectPerspectiveDialog dlg = new SelectPerspectiveDialog(window
345                 .getShell(), reg);
346         dlg.open();
347         if (dlg.getReturnCode() == Window.CANCEL) {
348             return;
349         }
350         IPerspectiveDescriptor desc = dlg.getSelection();
351         if (desc != null) {
352             run(desc, event);
353         }
354     }
355
356     /**
357      * Sets the showActive flag. If <code>showActive == true</code> then the
358      * active perspective is hilighted with a check mark.
359      *
360      * @param b the new showActive flag
361      */

362     protected void showActive(boolean b) {
363         showActive = b;
364     }
365 }
366
Popular Tags