blob: 6a140e8d847bf9d22e64c8f74e24923e5af40222 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2003 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.ui.internal.dialogs;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IContentProvider;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.ui.INewWizard;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchWizard;
import org.eclipse.ui.internal.dialogs.WorkbenchWizardElement;
import org.eclipse.ui.internal.dialogs.WorkbenchWizardNode;
import org.eclipse.ui.internal.WorkbenchMessages;
import org.eclipse.ui.internal.dialogs.DialogUtil;
import org.eclipse.ui.model.IWorkbenchAdapter;
import org.eclipse.ui.model.BaseWorkbenchContentProvider;
import org.eclipse.ui.model.WorkbenchAdapter;
import org.eclipse.ui.model.WorkbenchLabelProvider;
/**
*New wizard selection tab that allows the user to select a registered
*'New' wizard to be launched
*/
class NewWizardNewPage
implements ISelectionChangedListener, IDoubleClickListener {
private WizardCollectionElement wizardCategories;
private NewWizardSelectionPage page;
private IDialogSettings settings;
//Keep track of the wizards we have previously selected
private Hashtable selectedWizards = new Hashtable();
private TreeViewer categoryTreeViewer;
private TableViewer wizardSelectionViewer;
private final static int SIZING_LISTS_HEIGHT = 200;
private final static int SIZING_LISTS_WIDTH = 150;
// id constants
private final static String STORE_SELECTED_CATEGORY_ID = "NewWizardSelectionPage.STORE_SELECTED_CATEGORY_ID"; //$NON-NLS-1$
private final static String STORE_EXPANDED_CATEGORIES_ID = "NewWizardSelectionPage.STORE_EXPANDED_CATEGORIES_ID"; //$NON-NLS-1$
private final static String STORE_SELECTED_WIZARD_ID = "NewWizardSelectionPage.STORE_SELECTED_WIZARD_ID"; //$NON-NLS-1$
/**
* Create an instance of this class
*/
public NewWizardNewPage(
NewWizardSelectionPage mainPage,
IWorkbench aWorkbench,
WizardCollectionElement wizardCategories) {
this.page = mainPage;
this.wizardCategories = wizardCategories;
}
public void activate() {
page.setDescription(WorkbenchMessages.getString("NewWizardNewPage.description")); //$NON-NLS-1$
selectionChanged(
new SelectionChangedEvent(
wizardSelectionViewer,
(IStructuredSelection) wizardSelectionViewer.getSelection()));
}
/**
* Create this tab's visual components
*
* @return org.eclipse.swt.widgets.Control
* @param parent org.eclipse.swt.widgets.Composite
*/
protected Control createControl(Composite parent) {
Font wizardFont = parent.getFont();
// top level group
Composite outerContainer = new Composite(parent, SWT.NONE);
GridLayout layout = new GridLayout();
layout.numColumns = 2;
outerContainer.setLayout(layout);
outerContainer.setFont(wizardFont);
outerContainer.setLayoutData(
new GridData(
GridData.VERTICAL_ALIGN_FILL | GridData.HORIZONTAL_ALIGN_FILL));
// category tree pane...create SWT tree directly to
// get single selection mode instead of multi selection.
Tree tree =
new Tree(
outerContainer,
SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
categoryTreeViewer = new TreeViewer(tree);
GridData data = new GridData(GridData.FILL_BOTH);
data.widthHint = SIZING_LISTS_WIDTH;
boolean needsHint = DialogUtil.inRegularFontMode(parent);
//Only give a height hint if the dialog is going to be too small
if (needsHint) {
data.heightHint = SIZING_LISTS_HEIGHT;
}
categoryTreeViewer.getTree().setLayoutData(data);
categoryTreeViewer.setContentProvider(new BaseWorkbenchContentProvider());
categoryTreeViewer.setLabelProvider(new WorkbenchLabelProvider());
categoryTreeViewer.setSorter(NewWizardCollectionSorter.INSTANCE);
categoryTreeViewer.addSelectionChangedListener(this);
if (wizardCategories.getParent(wizardCategories) == null) {
categoryTreeViewer.setInput(wizardCategories);
} else
categoryTreeViewer.setInput(new RootElementProxy(wizardCategories));
tree.setFont(wizardFont);
// wizard actions pane...create SWT table directly to
// get single selection mode instead of multi selection.
Table table =
new Table(
outerContainer,
SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
wizardSelectionViewer = new TableViewer(table);
data = new GridData(GridData.FILL_BOTH);
data.widthHint = SIZING_LISTS_WIDTH;
//Only give a height hint if the dialog is going to be too small
if (needsHint) {
data.heightHint = SIZING_LISTS_HEIGHT;
}
wizardSelectionViewer.getTable().setLayoutData(data);
wizardSelectionViewer.setContentProvider(getWizardProvider());
wizardSelectionViewer.setLabelProvider(new WorkbenchLabelProvider());
wizardSelectionViewer.addSelectionChangedListener(this);
wizardSelectionViewer.addDoubleClickListener(this);
table.setFont(wizardFont);
restoreWidgetValues();
if (!categoryTreeViewer.getSelection().isEmpty())
// we only set focus if a selection was restored
categoryTreeViewer.getTree().setFocus();
return outerContainer;
}
/**
* Create a viewer pane in this group for the passed viewer.
*
* @param parent org.eclipse.swt.widgets.Composite
* @param width int
* @param height int
*/
protected Composite createViewPane(
Composite parent,
int width,
int height) {
Composite paneWindow = new Composite(parent, SWT.BORDER);
GridData spec = new GridData(GridData.FILL_BOTH);
spec.widthHint = width;
spec.heightHint = height;
paneWindow.setLayoutData(spec);
paneWindow.setLayout(new FillLayout());
return paneWindow;
}
/**
* A wizard in the wizard viewer has been double clicked.
* Treat it as a selection.
*/
public void doubleClick(DoubleClickEvent event) {
selectionChanged(
new SelectionChangedEvent(
wizardSelectionViewer,
wizardSelectionViewer.getSelection()));
page.advanceToNextPage();
}
/**
* Expands the wizard categories in this page's category viewer that were
* expanded last time this page was used. If a category that was previously
* expanded no longer exists then it is ignored.
*/
protected void expandPreviouslyExpandedCategories() {
String[] expandedCategoryPaths =
settings.getArray(STORE_EXPANDED_CATEGORIES_ID);
List categoriesToExpand = new ArrayList(expandedCategoryPaths.length);
for (int i = 0; i < expandedCategoryPaths.length; i++) {
WizardCollectionElement category =
wizardCategories.findChildCollection(
new Path(expandedCategoryPaths[i]));
if (category != null) // ie.- it still exists
categoriesToExpand.add(category);
}
if (!categoriesToExpand.isEmpty())
categoryTreeViewer.setExpandedElements(
categoriesToExpand.toArray());
}
/**
* Returns the single selected object contained in the passed selectionEvent,
* or <code>null</code> if the selectionEvent contains either 0 or 2+ selected
* objects.
*/
protected Object getSingleSelection(IStructuredSelection selection) {
return selection.size() == 1 ? selection.getFirstElement() : null;
}
/**
* Returns the content provider for this page.
*/
protected IContentProvider getWizardProvider() {
//want to get the wizards of the collection element
return new BaseWorkbenchContentProvider() {
public Object[] getChildren(Object o) {
if (o instanceof WizardCollectionElement) {
return ((WizardCollectionElement) o).getWizards();
}
return new Object[0];
}
};
}
/**
* Handle the (de)selection of wizard element(s)
*
* @param selectionEvent SelectionChangedEvent
*/
private void handleCategorySelection(SelectionChangedEvent selectionEvent) {
page.setErrorMessage(null);
page.setMessage(null);
Object currentSelection = wizardSelectionViewer.getInput();
Object selectedCategory =
getSingleSelection(
(IStructuredSelection) selectionEvent.getSelection());
if (currentSelection != selectedCategory) {
page.selectWizardNode(null);
wizardSelectionViewer.setInput(selectedCategory);
if (selectedCategory instanceof WizardCollectionElement) {
Object[] children =
((WizardCollectionElement) selectedCategory).getWizards();
if (children.length == 1)
selectWizard(children[0]);
}
}
}
/**
* Handle the (de)selection of wizard element(s)
*
* @param selectionEvent SelectionChangedEvent
*/
private void handleWizardSelection(SelectionChangedEvent selectionEvent) {
page.setErrorMessage(null);
WorkbenchWizardElement currentSelection =
(WorkbenchWizardElement) getSingleSelection(
(IStructuredSelection) selectionEvent
.getSelection());
// If no single selection, clear and return
if (currentSelection == null) {
page.setMessage(null);
page.selectWizardNode(null);
return;
}
WorkbenchWizardNode selectedNode;
if (selectedWizards.containsKey(currentSelection)) {
selectedNode =
(WorkbenchWizardNode) selectedWizards.get(currentSelection);
} else {
selectedNode = new WorkbenchWizardNode(page, currentSelection) {
public IWorkbenchWizard createWizard() throws CoreException {
return (INewWizard) wizardElement
.createExecutableExtension();
}
};
selectedWizards.put(currentSelection, selectedNode);
}
page.selectWizardNode(selectedNode);
page.setMessage((String) currentSelection.getDescription());
}
/**
* Set self's widgets to the values that they held last time this page was open
*
*/
protected void restoreWidgetValues() {
String[] expandedCategoryPaths =
settings.getArray(STORE_EXPANDED_CATEGORIES_ID);
if (expandedCategoryPaths == null)
return; // no stored values
expandPreviouslyExpandedCategories();
selectPreviouslySelectedCategoryAndWizard();
}
/**
* Store the current values of self's widgets so that they can
* be restored in the next instance of self
*
*/
public void saveWidgetValues() {
storeExpandedCategories();
storeSelectedCategoryAndWizard();
}
/**
* The user selected either new wizard category(s) or wizard element(s).
* Proceed accordingly.
*
* @param newSelection ISelection
*/
public void selectionChanged(SelectionChangedEvent selectionEvent) {
if (selectionEvent.getSelectionProvider().equals(categoryTreeViewer))
handleCategorySelection(selectionEvent);
else
handleWizardSelection(selectionEvent);
}
/**
* Selects the wizard category and wizard in this page that were selected
* last time this page was used. If a category or wizard that was previously
* selected no longer exists then it is ignored.
*/
protected void selectPreviouslySelectedCategoryAndWizard() {
String categoryId = (String) settings.get(STORE_SELECTED_CATEGORY_ID);
if (categoryId == null)
return;
WizardCollectionElement category =
wizardCategories.findChildCollection(new Path(categoryId));
if (category == null)
return; // category no longer exists, or has moved
StructuredSelection selection = new StructuredSelection(category);
categoryTreeViewer.setSelection(selection);
selectionChanged(
new SelectionChangedEvent(categoryTreeViewer, selection));
String wizardId = (String) settings.get(STORE_SELECTED_WIZARD_ID);
if (wizardId == null)
return;
WorkbenchWizardElement wizard = category.findWizard(wizardId, false);
if (wizard == null)
return; // wizard no longer exists, or has moved
selectWizard(wizard);
}
/**
* Select the supplied wizard element.
* @param wizard. Defined to be Object but really a
* <code>WorkbenchWizardElement</code>.If it is not
* in the list nothing will happen.
*/
private void selectWizard(Object wizard) {
StructuredSelection selection;
selection = new StructuredSelection(wizard);
wizardSelectionViewer.setSelection(selection);
selectionChanged(
new SelectionChangedEvent(wizardSelectionViewer, selection));
}
/**
* Set the dialog store to use for widget value storage and retrieval
*
* @param settings IDialogSettings
*/
public void setDialogSettings(IDialogSettings settings) {
this.settings = settings;
}
/**
* Stores the collection of currently-expanded categories in this page's dialog store,
* in order to recreate this page's state in the next instance of this page.
*/
protected void storeExpandedCategories() {
Object[] expandedElements = categoryTreeViewer.getExpandedElements();
String[] expandedElementPaths = new String[expandedElements.length];
for (int i = 0; i < expandedElements.length; ++i) {
expandedElementPaths[i] =
((WizardCollectionElement) expandedElements[i])
.getPath()
.toString();
}
settings.put(STORE_EXPANDED_CATEGORIES_ID, expandedElementPaths);
}
/**
* Stores the currently-selected category and wizard in this page's dialog store,
* in order to recreate this page's state in the next instance of this page.
*/
protected void storeSelectedCategoryAndWizard() {
WizardCollectionElement selectedCategory =
(WizardCollectionElement) getSingleSelection(
(IStructuredSelection) categoryTreeViewer
.getSelection());
if (selectedCategory != null) {
settings.put(
STORE_SELECTED_CATEGORY_ID,
selectedCategory.getPath().toString());
}
WorkbenchWizardElement selectedWizard =
(WorkbenchWizardElement) getSingleSelection(
(IStructuredSelection) wizardSelectionViewer
.getSelection());
if (selectedWizard != null) {
settings.put(STORE_SELECTED_WIZARD_ID, selectedWizard.getID());
}
}
private static final class RootElementProxy
extends WorkbenchAdapter
implements IAdaptable {
private WizardCollectionElement[] elements;
public RootElementProxy(WizardCollectionElement element) {
super();
//If the element has no wizard then it is an empty category
//and we should collapse
if (element.getWizards().length == 0) {
Object[] children = element.getChildren(null);
elements = new WizardCollectionElement[children.length];
System.arraycopy(children, 0, elements, 0, elements.length);
} else
elements = new WizardCollectionElement[] { element };
}
public Object getAdapter(Class adapter) {
if (adapter == IWorkbenchAdapter.class)
return this;
return null;
}
public Object[] getChildren(Object o) {
return elements;
}
}
}