1 /*******************************************************************************
2  * Copyright (c) 2000, 2018 IBM Corporation and others.
3  *
4  * This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License 2.0
6  * which accompanies this distribution, and is available at
7  * https://www.eclipse.org/legal/epl-2.0/
8  *
9  * SPDX-License-Identifier: EPL-2.0
10  *
11  * Contributors:
12  *     IBM Corporation - initial API and implementation
13  *******************************************************************************/
14 package org.eclipse.ui.internal.dialogs;
15 
16 import org.eclipse.jface.dialogs.IDialogSettings;
17 import org.eclipse.jface.viewers.DoubleClickEvent;
18 import org.eclipse.jface.viewers.IDoubleClickListener;
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.TableViewer;
24 import org.eclipse.jface.wizard.IWizardNode;
25 import org.eclipse.swt.SWT;
26 import org.eclipse.swt.graphics.Font;
27 import org.eclipse.swt.layout.GridData;
28 import org.eclipse.swt.layout.GridLayout;
29 import org.eclipse.swt.widgets.Composite;
30 import org.eclipse.swt.widgets.Control;
31 import org.eclipse.swt.widgets.Label;
32 import org.eclipse.swt.widgets.Table;
33 import org.eclipse.ui.IWorkbench;
34 import org.eclipse.ui.internal.WorkbenchMessages;
35 import org.eclipse.ui.model.AdaptableList;
36 import org.eclipse.ui.model.WorkbenchLabelProvider;
37 import org.eclipse.ui.model.WorkbenchViewerComparator;
38 
39 /**
40  * Abstract implementation of a wizard selection page which simply displays a
41  * list of specified wizard elements and allows the user to select one to be
42  * launched. Subclasses just need to provide a method which creates an
43  * appropriate wizard node based upon a user selection.
44  */
45 public abstract class WorkbenchWizardListSelectionPage extends WorkbenchWizardSelectionPage
46 		implements ISelectionChangedListener, IDoubleClickListener {
47 
48 	// id constants
49 	private static final String DIALOG_SETTING_SECTION_NAME = "WizardListSelectionPage."; //$NON-NLS-1$
50 
51 	private static final int SIZING_LISTS_HEIGHT = 200;
52 
53 	private static final String STORE_SELECTED_WIZARD_ID = DIALOG_SETTING_SECTION_NAME + "STORE_SELECTED_WIZARD_ID"; //$NON-NLS-1$
54 
55 	private TableViewer viewer;
56 
57 	private String message;
58 
59 	/**
60 	 * Creates a <code>WorkbenchWizardListSelectionPage</code>.
61 	 *
62 	 * @param aWorkbench       the current workbench
63 	 * @param currentSelection the workbench's current resource selection
64 	 * @param wizardElements   the collection of
65 	 *                         <code>WorkbenchWizardElements</code> to display for
66 	 *                         selection
67 	 * @param message          the message to display above the selection list
68 	 * @param triggerPointId   the trigger point id
69 	 */
WorkbenchWizardListSelectionPage(IWorkbench aWorkbench, IStructuredSelection currentSelection, AdaptableList wizardElements, String message, String triggerPointId)70 	protected WorkbenchWizardListSelectionPage(IWorkbench aWorkbench, IStructuredSelection currentSelection,
71 			AdaptableList wizardElements, String message, String triggerPointId) {
72 		super("singleWizardSelectionPage", aWorkbench, currentSelection, wizardElements, triggerPointId); //$NON-NLS-1$
73 		setDescription(WorkbenchMessages.WizardList_description);
74 		this.message = message;
75 	}
76 
77 	@Override
createControl(Composite parent)78 	public void createControl(Composite parent) {
79 
80 		Font font = parent.getFont();
81 
82 		// create composite for page.
83 		Composite outerContainer = new Composite(parent, SWT.NONE);
84 		outerContainer.setLayout(new GridLayout());
85 		outerContainer.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_FILL | GridData.HORIZONTAL_ALIGN_FILL));
86 		outerContainer.setFont(font);
87 
88 		Label messageLabel = new Label(outerContainer, SWT.NONE);
89 		messageLabel.setText(message);
90 		messageLabel.setFont(font);
91 
92 		createViewer(outerContainer);
93 		layoutTopControl(viewer.getControl());
94 
95 		restoreWidgetValues();
96 
97 		setControl(outerContainer);
98 	}
99 
100 	/**
101 	 * Create a new viewer in the parent.
102 	 *
103 	 * @param parent the parent <code>Composite</code>.
104 	 */
createViewer(Composite parent)105 	private void createViewer(Composite parent) {
106 		// Create a table for the list
107 		Table table = new Table(parent, SWT.BORDER);
108 		table.setFont(parent.getFont());
109 
110 		// the list viewer
111 		viewer = new TableViewer(table);
112 		viewer.setContentProvider(new WizardContentProvider());
113 		viewer.setLabelProvider(new WorkbenchLabelProvider());
114 		viewer.setComparator(new WorkbenchViewerComparator());
115 		viewer.addSelectionChangedListener(this);
116 		viewer.addDoubleClickListener(this);
117 		viewer.setInput(wizardElements);
118 	}
119 
120 	/**
121 	 * Returns an <code>IWizardNode</code> representing the specified workbench
122 	 * wizard which has been selected by the user. <b>Subclasses </b> must override
123 	 * this abstract implementation.
124 	 *
125 	 * @param element the wizard element that an <code>IWizardNode</code> is needed
126 	 *                for
127 	 * @return org.eclipse.jface.wizards.IWizardNode
128 	 */
createWizardNode(WorkbenchWizardElement element)129 	protected abstract IWizardNode createWizardNode(WorkbenchWizardElement element);
130 
131 	/**
132 	 * An item in a viewer has been double-clicked.
133 	 */
134 	@Override
doubleClick(DoubleClickEvent event)135 	public void doubleClick(DoubleClickEvent event) {
136 		selectionChanged(new SelectionChangedEvent(event.getViewer(), event.getViewer().getSelection()));
137 		getContainer().showPage(getNextPage());
138 	}
139 
140 	/**
141 	 * Layout the top control.
142 	 *
143 	 * @param control the control.
144 	 * @since 3.0
145 	 */
layoutTopControl(Control control)146 	private void layoutTopControl(Control control) {
147 		GridData data = new GridData(GridData.FILL_BOTH);
148 
149 		int availableRows = DialogUtil.availableRows(control.getParent());
150 
151 		// Only give a height hint if the dialog is going to be too small
152 		if (availableRows > 50) {
153 			data.heightHint = SIZING_LISTS_HEIGHT;
154 		} else {
155 			data.heightHint = availableRows * 3;
156 		}
157 
158 		control.setLayoutData(data);
159 
160 	}
161 
162 	/**
163 	 * Uses the dialog store to restore widget values to the values that they held
164 	 * last time this wizard was used to completion.
165 	 */
restoreWidgetValues()166 	private void restoreWidgetValues() {
167 
168 		IDialogSettings settings = getDialogSettings();
169 		if (settings == null) {
170 			return;
171 		}
172 
173 		String wizardId = settings.get(STORE_SELECTED_WIZARD_ID);
174 		WorkbenchWizardElement wizard = findWizard(wizardId);
175 		if (wizard == null) {
176 			return;
177 		}
178 
179 		StructuredSelection selection = new StructuredSelection(wizard);
180 		viewer.setSelection(selection);
181 	}
182 
183 	/**
184 	 * Since Finish was pressed, write widget values to the dialog store so that
185 	 * they will persist into the next invocation of this wizard page
186 	 */
saveWidgetValues()187 	public void saveWidgetValues() {
188 		IStructuredSelection sel = viewer.getStructuredSelection();
189 		if (sel.size() > 0) {
190 			WorkbenchWizardElement selectedWizard = (WorkbenchWizardElement) sel.getFirstElement();
191 			getDialogSettings().put(STORE_SELECTED_WIZARD_ID, selectedWizard.getId());
192 		}
193 	}
194 
195 	/**
196 	 * Notes the newly-selected wizard element and updates the page accordingly.
197 	 *
198 	 * @param event the selection changed event
199 	 */
200 	@Override
selectionChanged(SelectionChangedEvent event)201 	public void selectionChanged(SelectionChangedEvent event) {
202 		setErrorMessage(null);
203 		IStructuredSelection selection = event.getStructuredSelection();
204 		WorkbenchWizardElement currentWizardSelection = (WorkbenchWizardElement) selection.getFirstElement();
205 		if (currentWizardSelection == null) {
206 			setMessage(null);
207 			setSelectedNode(null);
208 			return;
209 		}
210 
211 		setSelectedNode(createWizardNode(currentWizardSelection));
212 		setMessage(currentWizardSelection.getDescription());
213 	}
214 }
215