001: /*******************************************************************************
002: * Copyright (c) 2004, 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.ui.internal.dialogs;
011:
012: import java.util.ArrayList;
013: import java.util.HashSet;
014: import java.util.Iterator;
015: import java.util.List;
016: import java.util.Set;
017:
018: import org.eclipse.core.commands.IHandler;
019: import org.eclipse.jface.action.Action;
020: import org.eclipse.jface.action.ActionContributionItem;
021: import org.eclipse.jface.action.IAction;
022: import org.eclipse.jface.action.IContributionItem;
023: import org.eclipse.jface.action.IMenuCreator;
024: import org.eclipse.jface.action.ToolBarManager;
025: import org.eclipse.jface.commands.ActionHandler;
026: import org.eclipse.osgi.util.NLS;
027: import org.eclipse.swt.widgets.Control;
028: import org.eclipse.swt.widgets.Menu;
029: import org.eclipse.swt.widgets.ToolBar;
030: import org.eclipse.ui.ActiveShellExpression;
031: import org.eclipse.ui.ISharedImages;
032: import org.eclipse.ui.PlatformUI;
033: import org.eclipse.ui.handlers.IHandlerActivation;
034: import org.eclipse.ui.handlers.IHandlerService;
035: import org.eclipse.ui.internal.WorkbenchMessages;
036: import org.eclipse.ui.internal.WorkbenchPlugin;
037:
038: /**
039: * History for navigating preference pages.
040: *
041: * @since 3.1
042: */
043: class PreferencePageHistory {
044:
045: /**
046: * The history toolbar.
047: */
048: private ToolBarManager historyToolbar;
049:
050: /**
051: * A list of preference history domain elements that stores the history of
052: * the visited preference pages.
053: */
054: private List history = new ArrayList();
055:
056: /**
057: * Stores the current entry into <code>history</code> and
058: * <code>historyLabels</code>.
059: */
060: private int historyIndex = -1;
061:
062: /**
063: * The preference dialog we implement the history for.
064: */
065: private final FilteredPreferenceDialog dialog;
066:
067: /**
068: * The handler submission for these controls.
069: */
070: private Set activations = new HashSet();
071:
072: /**
073: * Creates a new history for the given dialog.
074: *
075: * @param dialog
076: * the preference dialog to create a history for
077: */
078: public PreferencePageHistory(FilteredPreferenceDialog dialog) {
079: this .dialog = dialog;
080: }
081:
082: /**
083: * Returns the preference page path (for now: its id) for the history at
084: * <code>index</code>.
085: *
086: * @param index
087: * the index into the history
088: * @return the preference page path at <code>index</code> or
089: * <code>null</code> if <code>index</code> is not a valid
090: * history index
091: */
092: private PreferenceHistoryEntry getHistoryEntry(int index) {
093: if (index >= 0 && index < history.size()) {
094: return (PreferenceHistoryEntry) history.get(index);
095: }
096: return null;
097: }
098:
099: /**
100: * Adds the preference page path and its label to the page history.
101: *
102: * @param entry
103: * the preference page history entry
104: */
105: public void addHistoryEntry(PreferenceHistoryEntry entry) {
106: if (historyIndex == -1
107: || !history.get(historyIndex).equals(entry)) {
108: history.subList(historyIndex + 1, history.size()).clear();
109: history.add(entry);
110: historyIndex++;
111: updateHistoryControls();
112: }
113: }
114:
115: /**
116: * Sets the current page to be the one corresponding to the given index in
117: * the page history.
118: *
119: * @param index
120: * the index into the page history
121: */
122: private void jumpToHistory(int index) {
123: if (index >= 0 && index < history.size()) {
124: historyIndex = index;
125: dialog.setCurrentPageId(getHistoryEntry(index).getId());
126: }
127: updateHistoryControls();
128: }
129:
130: /**
131: * Updates the history controls.
132: *
133: */
134: private void updateHistoryControls() {
135: historyToolbar.update(false);
136: IContributionItem[] items = historyToolbar.getItems();
137: for (int i = 0; i < items.length; i++) {
138: items[i].update(IAction.ENABLED);
139: items[i].update(IAction.TOOL_TIP_TEXT);
140: }
141: }
142:
143: /**
144: * Creates the history toolbar and initializes <code>historyToolbar</code>.
145: *
146: * @param historyBar
147: * @param manager
148: * @return the control of the history toolbar
149: */
150: public ToolBar createHistoryControls(ToolBar historyBar,
151: ToolBarManager manager) {
152:
153: historyToolbar = manager;
154: /**
155: * Superclass of the two for-/backward actions for the history.
156: */
157: abstract class HistoryNavigationAction extends Action implements
158: IMenuCreator {
159: private Menu lastMenu;
160:
161: protected final static int MAX_ENTRIES = 5;
162:
163: HistoryNavigationAction() {
164: super ("", IAction.AS_DROP_DOWN_MENU); //$NON-NLS-1$
165: }
166:
167: public IMenuCreator getMenuCreator() {
168: return this ;
169: }
170:
171: public void dispose() {
172: if (lastMenu != null) {
173: lastMenu.dispose();
174: lastMenu = null;
175: }
176: }
177:
178: public Menu getMenu(Control parent) {
179: if (lastMenu != null) {
180: lastMenu.dispose();
181: }
182: lastMenu = new Menu(parent);
183: createEntries(lastMenu);
184: return lastMenu;
185:
186: }
187:
188: public Menu getMenu(Menu parent) {
189: return null;
190: }
191:
192: protected void addActionToMenu(Menu parent, IAction action) {
193: ActionContributionItem item = new ActionContributionItem(
194: action);
195: item.fill(parent, -1);
196: }
197:
198: protected abstract void createEntries(Menu menu);
199: }
200:
201: /**
202: * Menu entry for the toolbar dropdowns. Instances are direct-jump
203: * entries in the navigation history.
204: */
205: class HistoryItemAction extends Action {
206:
207: private final int index;
208:
209: HistoryItemAction(int index, String label) {
210: super (label, IAction.AS_PUSH_BUTTON);
211: this .index = index;
212: }
213:
214: public void run() {
215: jumpToHistory(index);
216: }
217: }
218:
219: HistoryNavigationAction backward = new HistoryNavigationAction() {
220: public void run() {
221: jumpToHistory(historyIndex - 1);
222: }
223:
224: public boolean isEnabled() {
225: boolean enabled = historyIndex > 0;
226: if (enabled) {
227: setToolTipText(NLS
228: .bind(
229: WorkbenchMessages.NavigationHistoryAction_backward_toolTipName,
230: getHistoryEntry(historyIndex - 1)
231: .getLabel()));
232: }
233: return enabled;
234: }
235:
236: protected void createEntries(Menu menu) {
237: int limit = Math.max(0, historyIndex - MAX_ENTRIES);
238: for (int i = historyIndex - 1; i >= limit; i--) {
239: IAction action = new HistoryItemAction(i,
240: getHistoryEntry(i).getLabel());
241: addActionToMenu(menu, action);
242: }
243: }
244: };
245: backward
246: .setText(WorkbenchMessages.NavigationHistoryAction_backward_text);
247: backward
248: .setActionDefinitionId("org.eclipse.ui.navigate.backwardHistory"); //$NON-NLS-1$
249: backward.setImageDescriptor(WorkbenchPlugin.getDefault()
250: .getSharedImages().getImageDescriptor(
251: ISharedImages.IMG_TOOL_BACK));
252: backward.setDisabledImageDescriptor(WorkbenchPlugin
253: .getDefault().getSharedImages().getImageDescriptor(
254: ISharedImages.IMG_TOOL_BACK_DISABLED));
255: registerKeybindings(backward);
256: historyToolbar.add(backward);
257:
258: HistoryNavigationAction forward = new HistoryNavigationAction() {
259: public void run() {
260: jumpToHistory(historyIndex + 1);
261: }
262:
263: public boolean isEnabled() {
264: boolean enabled = historyIndex < history.size() - 1;
265: if (enabled) {
266: setToolTipText(NLS
267: .bind(
268: WorkbenchMessages.NavigationHistoryAction_forward_toolTipName,
269: getHistoryEntry(historyIndex + 1)
270: .getLabel()));
271: }
272: return enabled;
273: }
274:
275: protected void createEntries(Menu menu) {
276: int limit = Math.min(history.size(), historyIndex
277: + MAX_ENTRIES + 1);
278: for (int i = historyIndex + 1; i < limit; i++) {
279: IAction action = new HistoryItemAction(i,
280: getHistoryEntry(i).getLabel());
281: addActionToMenu(menu, action);
282: }
283: }
284: };
285: forward
286: .setText(WorkbenchMessages.NavigationHistoryAction_forward_text);
287: forward
288: .setActionDefinitionId("org.eclipse.ui.navigate.forwardHistory"); //$NON-NLS-1$
289: forward.setImageDescriptor(WorkbenchPlugin.getDefault()
290: .getSharedImages().getImageDescriptor(
291: ISharedImages.IMG_TOOL_FORWARD));
292: forward.setDisabledImageDescriptor(WorkbenchPlugin.getDefault()
293: .getSharedImages().getImageDescriptor(
294: ISharedImages.IMG_TOOL_FORWARD_DISABLED));
295: registerKeybindings(forward);
296: historyToolbar.add(forward);
297:
298: return historyBar;
299: }
300:
301: /**
302: * Registers the given action with the workbench command support.
303: *
304: * @param action
305: * the action to register.
306: */
307: private void registerKeybindings(IAction action) {
308: final IHandler handler = new ActionHandler(action);
309: final IHandlerService handlerService = (IHandlerService) PlatformUI
310: .getWorkbench().getService(IHandlerService.class);
311: final IHandlerActivation activation = handlerService
312: .activateHandler(action.getActionDefinitionId(),
313: handler, new ActiveShellExpression(dialog
314: .getShell()));
315: activations.add(activation);
316: }
317:
318: /**
319: * Dispose the receiver and clear out the references.
320: *
321: */
322: public void dispose() {
323: final IHandlerService handlerService = (IHandlerService) PlatformUI
324: .getWorkbench().getService(IHandlerService.class);
325: final Iterator iterator = activations.iterator();
326: while (iterator.hasNext()) {
327: handlerService
328: .deactivateHandler((IHandlerActivation) iterator
329: .next());
330: }
331: activations.clear();
332:
333: }
334:
335: }
|