001: /*******************************************************************************
002: * Copyright (c) 2005, 2006 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.List;
014:
015: import org.eclipse.core.runtime.CoreException;
016: import org.eclipse.core.runtime.Path;
017: import org.eclipse.jface.dialogs.Dialog;
018: import org.eclipse.jface.viewers.DoubleClickEvent;
019: import org.eclipse.jface.viewers.ISelection;
020: import org.eclipse.jface.viewers.IStructuredSelection;
021: import org.eclipse.jface.viewers.StructuredSelection;
022: import org.eclipse.jface.viewers.TreeViewer;
023: import org.eclipse.jface.wizard.IWizardNode;
024: import org.eclipse.jface.wizard.IWizardPage;
025: import org.eclipse.swt.SWT;
026: import org.eclipse.swt.graphics.Font;
027: import org.eclipse.swt.layout.GridData;
028: import org.eclipse.swt.layout.GridLayout;
029: import org.eclipse.swt.widgets.Composite;
030: import org.eclipse.swt.widgets.Control;
031: import org.eclipse.swt.widgets.Label;
032: import org.eclipse.ui.IWorkbench;
033: import org.eclipse.ui.IWorkbenchWizard;
034: import org.eclipse.ui.activities.ITriggerPoint;
035: import org.eclipse.ui.activities.WorkbenchActivityHelper;
036: import org.eclipse.ui.dialogs.FilteredTree;
037: import org.eclipse.ui.internal.WorkbenchMessages;
038: import org.eclipse.ui.model.AdaptableList;
039: import org.eclipse.ui.model.WorkbenchLabelProvider;
040: import org.eclipse.ui.wizards.IWizardCategory;
041: import org.eclipse.ui.wizards.IWizardDescriptor;
042:
043: /**
044: * Abstract wizard page class from which an import or export wizard can be chosen.
045: *
046: * @since 3.2
047: *
048: */
049: public abstract class ImportExportPage extends
050: WorkbenchWizardSelectionPage {
051: protected static final String DIALOG_SETTING_SECTION_NAME = "ImportExportPage."; //$NON-NLS-1$
052:
053: // tree viewer of wizard selections
054: private TreeViewer treeViewer;
055:
056: /*
057: * Class to create a control that shows a categorized tree of wizard types.
058: */
059: protected class CategorizedWizardSelectionTree {
060: private final static int SIZING_LISTS_HEIGHT = 200;
061:
062: private IWizardCategory wizardCategories;
063: private String message;
064: private TreeViewer viewer;
065:
066: /**
067: * Constructor for CategorizedWizardSelectionTree
068: *
069: * @param categories root wizard category for the wizard type
070: * @param msg message describing what the user should choose from the tree.
071: */
072: protected CategorizedWizardSelectionTree(
073: IWizardCategory categories, String msg) {
074: this .wizardCategories = categories;
075: this .message = msg;
076: }
077:
078: /**
079: * Create the tree viewer and a message describing what the user should choose
080: * from the tree.
081: *
082: * @param parent Composite on which the tree viewer is to be created
083: * @return Comoposite with all widgets
084: */
085: protected Composite createControl(Composite parent) {
086: Font font = parent.getFont();
087:
088: // create composite for page.
089: Composite outerContainer = new Composite(parent, SWT.NONE);
090: outerContainer.setLayout(new GridLayout());
091: outerContainer.setLayoutData(new GridData(
092: GridData.FILL_BOTH));
093: outerContainer.setFont(font);
094:
095: Label messageLabel = new Label(outerContainer, SWT.NONE);
096: if (message != null) {
097: messageLabel.setText(message);
098: }
099: messageLabel.setFont(font);
100:
101: createFilteredTree(outerContainer);
102: layoutTopControl(viewer.getControl());
103:
104: return outerContainer;
105: }
106:
107: /**
108: * Create the categorized tree viewer.
109: *
110: * @param parent
111: */
112: private void createFilteredTree(Composite parent) {
113: // Create a FilteredTree for the categories and wizards
114: FilteredTree filteredTree = new FilteredTree(parent,
115: SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL
116: | SWT.BORDER, new WizardPatternFilter());
117: viewer = filteredTree.getViewer();
118: filteredTree.setFont(parent.getFont());
119:
120: viewer.setContentProvider(new WizardContentProvider());
121: viewer.setLabelProvider(new WorkbenchLabelProvider());
122: viewer
123: .setComparator(DataTransferWizardCollectionComparator.INSTANCE);
124:
125: ArrayList inputArray = new ArrayList();
126: boolean expandTop = false;
127:
128: if (wizardCategories != null) {
129: if (wizardCategories.getParent() == null) {
130: IWizardCategory[] children = wizardCategories
131: .getCategories();
132: for (int i = 0; i < children.length; i++) {
133: inputArray.add(children[i]);
134: }
135: } else {
136: expandTop = true;
137: inputArray.add(wizardCategories);
138: }
139: }
140:
141: // ensure the category is expanded. If there is a remembered expansion it will be set later.
142: if (expandTop) {
143: viewer.setAutoExpandLevel(2);
144: }
145:
146: AdaptableList input = new AdaptableList(inputArray);
147:
148: // filter wizard list according to capabilities that are enabled
149: viewer.addFilter(new WizardActivityFilter());
150:
151: viewer.setInput(input);
152: }
153:
154: /**
155: *
156: * @return the categorized tree viewer
157: */
158: protected TreeViewer getViewer() {
159: return viewer;
160: }
161:
162: /**
163: * Layout for the given control.
164: *
165: * @param control
166: */
167: private void layoutTopControl(Control control) {
168: GridData data = new GridData(GridData.FILL_BOTH);
169:
170: int availableRows = DialogUtil.availableRows(control
171: .getParent());
172:
173: //Only give a height hint if the dialog is going to be too small
174: if (availableRows > 50) {
175: data.heightHint = SIZING_LISTS_HEIGHT;
176: } else {
177: data.heightHint = availableRows * 3;
178: }
179:
180: control.setLayoutData(data);
181: }
182: }
183:
184: /**
185: * Constructor for import/export wizard page.
186: *
187: * @param aWorkbench current workbench
188: * @param currentSelection current selection
189: */
190: protected ImportExportPage(IWorkbench aWorkbench,
191: IStructuredSelection currentSelection) {
192: super (
193: "importExportPage", aWorkbench, currentSelection, null, null); //$NON-NLS-1$
194: setTitle(WorkbenchMessages.Select);
195: }
196:
197: /*
198: * (non-Javadoc)
199: * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite)
200: */
201: public void createControl(Composite parent) {
202: Font font = parent.getFont();
203:
204: // create composite for page.
205: Composite outerContainer = new Composite(parent, SWT.NONE);
206: outerContainer.setLayout(new GridLayout());
207: outerContainer.setLayoutData(new GridData(GridData.FILL_BOTH));
208: outerContainer.setFont(font);
209:
210: Composite comp = createTreeViewer(outerContainer);
211:
212: Dialog.applyDialogFont(comp);
213:
214: restoreWidgetValues();
215:
216: setControl(outerContainer);
217:
218: initialize();
219: }
220:
221: /**
222: * Create the tree viewer from which a wizard is selected.
223: */
224: protected abstract Composite createTreeViewer(Composite parent);
225:
226: /**
227: * Method to call when an item in one of the lists is double-clicked.
228: * Shows the first page of the selected wizard or expands a collapsed
229: * tree.
230: * @param event
231: */
232: protected void treeDoubleClicked(DoubleClickEvent event) {
233: ISelection selection = event.getViewer().getSelection();
234: IStructuredSelection ss = (IStructuredSelection) selection;
235: listSelectionChanged(ss);
236:
237: Object element = ss.getFirstElement();
238: TreeViewer v = (TreeViewer) event.getViewer();
239: if (v.isExpandable(element)) {
240: v.setExpandedState(element, !v.getExpandedState(element));
241: } else if (element instanceof WorkbenchWizardElement) {
242: if (canFlipToNextPage()) {
243: getContainer().showPage(getNextPage());
244: }
245: }
246: getContainer().showPage(getNextPage());
247: }
248:
249: /*
250: * Update the wizard's message based on the given (selected) wizard element.
251: */
252: private void updateSelectedNode(WorkbenchWizardElement wizardElement) {
253: setErrorMessage(null);
254: if (wizardElement == null) {
255: updateMessage();
256: setSelectedNode(null);
257: return;
258: }
259:
260: setSelectedNode(createWizardNode(wizardElement));
261: setMessage(wizardElement.getDescription());
262: }
263:
264: /*
265: * Update the wizard's message based on the currently selected tab
266: * and the selected wizard on that tab.
267: */
268: protected void updateMessage() {
269: TreeViewer viewer = getTreeViewer();
270: if (viewer != null) {
271: ISelection selection = viewer.getSelection();
272: IStructuredSelection ss = (IStructuredSelection) selection;
273: Object sel = ss.getFirstElement();
274: if (sel instanceof WorkbenchWizardElement) {
275: updateSelectedNode((WorkbenchWizardElement) sel);
276: } else {
277: setSelectedNode(null);
278: }
279: } else {
280: setMessage(null);
281: }
282: }
283:
284: /*
285: * Method to call whenever the selection in one of the lists has changed.
286: * Updates the wizard's message to relect the description of the currently
287: * selected wizard.
288: */
289: protected void listSelectionChanged(ISelection selection) {
290: setErrorMessage(null);
291: IStructuredSelection ss = (IStructuredSelection) selection;
292: Object sel = ss.getFirstElement();
293: if (sel instanceof WorkbenchWizardElement) {
294: WorkbenchWizardElement currentWizardSelection = (WorkbenchWizardElement) sel;
295: updateSelectedNode(currentWizardSelection);
296: } else {
297: updateSelectedNode(null);
298: }
299: }
300:
301: /*
302: * Create a wizard node given a wizard's descriptor.
303: */
304: private IWizardNode createWizardNode(IWizardDescriptor element) {
305: return new WorkbenchWizardNode(this , element) {
306: public IWorkbenchWizard createWizard() throws CoreException {
307: return wizardElement.createWizard();
308: }
309: };
310: }
311:
312: /**
313: * Uses the dialog store to restore widget values to the values that they
314: * held last time this wizard was used to completion.
315: */
316: protected void restoreWidgetValues() {
317: updateMessage();
318: }
319:
320: /**
321: * Expands the wizard categories in this page's category viewer that were
322: * expanded last time this page was used. If a category that was previously
323: * expanded no longer exists then it is ignored.
324: */
325: protected void expandPreviouslyExpandedCategories(String setting,
326: IWizardCategory wizardCategories, TreeViewer viewer) {
327: String[] expandedCategoryPaths = getDialogSettings().getArray(
328: setting);
329: if (expandedCategoryPaths == null
330: || expandedCategoryPaths.length == 0) {
331: return;
332: }
333:
334: List categoriesToExpand = new ArrayList(
335: expandedCategoryPaths.length);
336:
337: if (wizardCategories != null) {
338: for (int i = 0; i < expandedCategoryPaths.length; i++) {
339: IWizardCategory category = wizardCategories
340: .findCategory(new Path(expandedCategoryPaths[i]));
341: if (category != null) {
342: categoriesToExpand.add(category);
343: }
344: }
345: }
346:
347: if (!categoriesToExpand.isEmpty()) {
348: viewer.setExpandedElements(categoriesToExpand.toArray());
349: }
350:
351: }
352:
353: /**
354: * Selects the wizard category and wizard in this page that were selected
355: * last time this page was used. If a category or wizard that was
356: * previously selected no longer exists then it is ignored.
357: */
358: protected void selectPreviouslySelected(String setting,
359: IWizardCategory wizardCategories, final TreeViewer viewer) {
360: String selectedId = getDialogSettings().get(setting);
361: if (selectedId == null) {
362: return;
363: }
364:
365: if (wizardCategories == null) {
366: return;
367: }
368:
369: Object selected = wizardCategories.findCategory(new Path(
370: selectedId));
371:
372: if (selected == null) {
373: selected = wizardCategories.findWizard(selectedId);
374:
375: if (selected == null) {
376: // if we cant find either a category or a wizard, abort.
377: return;
378: }
379: }
380:
381: viewer.setSelection(new StructuredSelection(selected), true);
382: }
383:
384: /**
385: * Stores the collection of currently-expanded categories in this page's
386: * dialog store, in order to recreate this page's state in the next
387: * instance of this page.
388: */
389: protected void storeExpandedCategories(String setting,
390: TreeViewer viewer) {
391: Object[] expandedElements = viewer.getExpandedElements();
392: List expandedElementPaths = new ArrayList(
393: expandedElements.length);
394: for (int i = 0; i < expandedElements.length; ++i) {
395: if (expandedElements[i] instanceof IWizardCategory) {
396: expandedElementPaths
397: .add(((IWizardCategory) expandedElements[i])
398: .getPath().toString());
399: }
400: }
401: getDialogSettings()
402: .put(
403: setting,
404: (String[]) expandedElementPaths
405: .toArray(new String[expandedElementPaths
406: .size()]));
407: }
408:
409: /**
410: * Stores the currently-selected element in this page's dialog store, in
411: * order to recreate this page's state in the next instance of this page.
412: */
413: protected void storeSelectedCategoryAndWizard(String setting,
414: TreeViewer viewer) {
415: Object selected = ((IStructuredSelection) viewer.getSelection())
416: .getFirstElement();
417:
418: if (selected != null) {
419: if (selected instanceof IWizardCategory) {
420: getDialogSettings().put(
421: setting,
422: ((IWizardCategory) selected).getPath()
423: .toString());
424: } else {
425: // else its a wizard
426: getDialogSettings().put(setting,
427: ((IWizardDescriptor) selected).getId());
428: }
429: }
430: }
431:
432: /**
433: * When Finish is pressed, write widget values to the dialog store so
434: * that they will persist into the next invocation of the wizard page.
435: *
436: */
437: public void saveWidgetValues() {
438: // do nothing by default - subclasses should override
439: }
440:
441: /*
442: * (non-Javadoc)
443: * @see org.eclipse.jface.wizard.IWizardPage#getNextPage()
444: */
445: public IWizardPage getNextPage() {
446: ITriggerPoint triggerPoint = getTriggerPoint();
447:
448: if (triggerPoint == null
449: || WorkbenchActivityHelper.allowUseOf(triggerPoint,
450: getSelectedNode())) {
451: return super .getNextPage();
452: }
453: return null;
454: }
455:
456: /**
457: * Get the trigger point for the wizard type, if one exists.
458: *
459: * @return the wizard's trigger point
460: */
461: protected ITriggerPoint getTriggerPoint() {
462: return null; // default implementation
463: }
464:
465: /**
466: * Set the tree viewer that is used for this wizard selection page.
467: *
468: * @param viewer
469: */
470: protected void setTreeViewer(TreeViewer viewer) {
471: treeViewer = viewer;
472: }
473:
474: /**
475: * Get the tree viewer that is used for this wizard selection page.
476: *
477: * @return tree viewer used for this wizard's selection page
478: */
479: protected TreeViewer getTreeViewer() {
480: return treeViewer;
481: }
482:
483: /**
484: * Perform any initialization of the wizard page that needs to be done
485: * after widgets are created and main control is set.
486: */
487: protected void initialize() {
488: // do nothing by default
489: }
490: }
|