001: /*******************************************************************************
002: * Copyright (c) 2000, 2005 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 net.refractions.udig.internal.ui.operations;
011:
012: import java.util.ArrayList;
013: import java.util.Iterator;
014:
015: import net.refractions.udig.internal.ui.TransferStrategy;
016: import net.refractions.udig.ui.internal.Messages;
017: import net.refractions.udig.ui.operations.OpAction;
018:
019: import org.eclipse.jface.dialogs.Dialog;
020: import org.eclipse.jface.dialogs.IDialogConstants;
021: import org.eclipse.jface.dialogs.IDialogSettings;
022: import org.eclipse.jface.viewers.DoubleClickEvent;
023: import org.eclipse.jface.viewers.IDoubleClickListener;
024: import org.eclipse.jface.viewers.ISelectionChangedListener;
025: import org.eclipse.jface.viewers.IStructuredSelection;
026: import org.eclipse.jface.viewers.SelectionChangedEvent;
027: import org.eclipse.jface.viewers.StructuredSelection;
028: import org.eclipse.jface.viewers.TreeViewer;
029: import org.eclipse.swt.SWT;
030: import org.eclipse.swt.layout.GridData;
031: import org.eclipse.swt.widgets.Button;
032: import org.eclipse.swt.widgets.Composite;
033: import org.eclipse.swt.widgets.Control;
034: import org.eclipse.swt.widgets.Shell;
035: import org.eclipse.ui.internal.WorkbenchPlugin;
036:
037: /**
038: * The Run Operation Dialog
039: */
040: public class RunOperationDialog extends Dialog implements
041: ISelectionChangedListener, IDoubleClickListener {
042:
043: private static final String DIALOG_SETTING_SECTION_NAME = "RunOperationDialog"; //$NON-NLS-1$
044:
045: private static final int LIST_HEIGHT = 300;
046:
047: private static final int LIST_WIDTH = 250;
048:
049: private static final String STORE_EXPANDED_CATEGORIES_ID = DIALOG_SETTING_SECTION_NAME
050: + ".STORE_EXPANDED_CATEGORIES_ID"; //$NON-NLS-1$
051:
052: private static final String STORE_SELECTED_OPERATION_ID = DIALOG_SETTING_SECTION_NAME
053: + ".STORE_SELECTED_OPERATION_ID"; //$NON-NLS-1$
054:
055: private TreeViewer tree;
056:
057: private Button okButton;
058:
059: private OpAction[] opActions = new OpAction[0];
060:
061: private OperationMenuFactory opMenuFactory;
062:
063: public RunOperationDialog(Shell parentShell,
064: OperationMenuFactory opMenuFactory) {
065: super (parentShell);
066: this .opMenuFactory = opMenuFactory;
067: setShellStyle(getShellStyle() | SWT.RESIZE);
068: }
069:
070: /**
071: * This method is called if a button has been pressed.
072: */
073: protected void buttonPressed(int buttonId) {
074: if (buttonId == IDialogConstants.OK_ID)
075: saveWidgetValues();
076: super .buttonPressed(buttonId);
077: }
078:
079: /**
080: * Notifies that the cancel button of this dialog has been pressed.
081: */
082: protected void cancelPressed() {
083: opActions = new OpAction[0];
084: super .cancelPressed();
085: }
086:
087: /*
088: * (non-Javadoc)
089: *
090: * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell)
091: */
092: protected void configureShell(Shell shell) {
093: super .configureShell(shell);
094: shell.setText(Messages.RunOperationDialog_run_operation);
095: }
096:
097: /**
098: * Adds buttons to this dialog's button bar.
099: * <p>
100: * The default implementation of this framework method adds standard ok and
101: * cancel buttons using the <code>createButton</code> framework method.
102: * Subclasses may override.
103: * </p>
104: *
105: * @param parent the button bar composite
106: */
107: protected void createButtonsForButtonBar(Composite parent) {
108: okButton = createButton(parent, IDialogConstants.OK_ID,
109: IDialogConstants.OK_LABEL, true);
110: createButton(parent, IDialogConstants.CANCEL_ID,
111: IDialogConstants.CANCEL_LABEL, false);
112: updateButtons();
113: }
114:
115: /**
116: * Creates and returns the contents of the upper part of this dialog (above
117: * the button bar).
118: *
119: * @param parent the parent composite to contain the dialog area
120: * @return the dialog area control
121: */
122: protected Control createDialogArea(Composite parent) {
123: // Run super.
124: Composite composite = (Composite) super
125: .createDialogArea(parent);
126: composite.setFont(parent.getFont());
127:
128: createViewer(composite);
129:
130: layoutTopControl(tree.getControl());
131:
132: // Restore the last state
133: restoreWidgetValues();
134:
135: // Return results.
136: return composite;
137: }
138:
139: /**
140: * Create a new viewer in the parent.
141: *
142: * @param parent the parent <code>Composite</code>.
143: */
144: private void createViewer(Composite parent) {
145: tree = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL
146: | SWT.V_SCROLL | SWT.BORDER);
147: tree.setLabelProvider(new OperationLabelProvider());
148: tree.setContentProvider(new OperationContentProvider());
149: tree.setSorter(new OperationSorter());
150: tree.setInput(opMenuFactory);
151: tree.addSelectionChangedListener(this );
152: tree.addDoubleClickListener(this );
153: tree.getTree().setFont(parent.getFont());
154: }
155:
156: /*
157: * (non-Javadoc)
158: *
159: * @see org.eclipse.jface.viewers.IDoubleClickListener#doubleClick(org.eclipse.jface.viewers.DoubleClickEvent)
160: */
161: public void doubleClick(DoubleClickEvent event) {
162: IStructuredSelection s = (IStructuredSelection) event
163: .getSelection();
164: Object element = s.getFirstElement();
165: if (tree.isExpandable(element)) {
166: tree.setExpandedState(element, !tree
167: .getExpandedState(element));
168: } else if (opActions.length > 0) {
169: saveWidgetValues();
170: setReturnCode(OK);
171: close();
172: }
173: }
174:
175: /**
176: * Return the dialog store to cache values into
177: */
178: protected IDialogSettings getDialogSettings() {
179: IDialogSettings workbenchSettings = WorkbenchPlugin
180: .getDefault().getDialogSettings();
181: IDialogSettings section = workbenchSettings
182: .getSection(DIALOG_SETTING_SECTION_NAME);
183: if (section == null)
184: section = workbenchSettings
185: .addNewSection(DIALOG_SETTING_SECTION_NAME);
186: return section;
187: }
188:
189: public OpAction[] getSelection() {
190:
191: OpAction[] copy = new OpAction[opActions.length];
192: System.arraycopy(opActions, 0, copy, 0, opActions.length);
193: return copy;
194: }
195:
196: /**
197: * Layout the top control.
198: *
199: * @param control the control.
200: */
201: private void layoutTopControl(Control control) {
202: GridData spec = new GridData(GridData.FILL_BOTH);
203: spec.widthHint = LIST_WIDTH;
204: spec.heightHint = LIST_HEIGHT;
205: control.setLayoutData(spec);
206: }
207:
208: /**
209: * Use the dialog store to restore widget values to the values that they
210: * held last time this dialog was used to completion.
211: */
212: protected void restoreWidgetValues() {
213: IDialogSettings settings = getDialogSettings();
214:
215: String[] expandedCategoryIds = settings
216: .getArray(STORE_EXPANDED_CATEGORIES_ID);
217: if (expandedCategoryIds == null)
218: return;
219:
220: ArrayList categoriesToExpand = new ArrayList(
221: expandedCategoryIds.length);
222: for (int i = 0; i < expandedCategoryIds.length; i++) {
223: OperationCategory category = opMenuFactory
224: .findCategory(expandedCategoryIds[i]);
225: if (category != null) // ie.- it still exists
226: categoriesToExpand.add(category);
227: }
228:
229: if (!categoriesToExpand.isEmpty())
230: tree.setExpandedElements(categoriesToExpand.toArray());
231:
232: String selectedOperationID = settings
233: .get(STORE_SELECTED_OPERATION_ID);
234: if (selectedOperationID != null) {
235: OpAction action = opMenuFactory.find(selectedOperationID);
236: if (action != null) {
237: tree
238: .setSelection(new StructuredSelection(action),
239: true);
240: }
241: }
242: }
243:
244: /**
245: * Since OK was pressed, write widget values to the dialog store so that
246: * they will persist into the next invocation of this dialog
247: */
248: protected void saveWidgetValues() {
249: IDialogSettings settings = getDialogSettings();
250:
251: // Collect the ids of the all expanded categories
252: Object[] expandedElements = tree.getExpandedElements();
253: String[] expandedCategoryIds = new String[expandedElements.length];
254: for (int i = 0; i < expandedElements.length; ++i)
255: expandedCategoryIds[i] = ((OperationCategory) expandedElements[i])
256: .getId();
257:
258: // Save them for next time.
259: settings.put(STORE_EXPANDED_CATEGORIES_ID, expandedCategoryIds);
260:
261: String selectedOperationID = ""; //$NON-NLS-1$
262: if (opActions.length > 0) {
263: // in the case of a multi-selection, it's probably less confusing
264: // to store just the first rather than the whole multi-selection
265: selectedOperationID = opActions[0].getId();
266: }
267: settings.put(STORE_SELECTED_OPERATION_ID, selectedOperationID);
268: }
269:
270: /**
271: * Notifies that the selection has changed.
272: *
273: * @param event event object describing the change
274: */
275: public void selectionChanged(SelectionChangedEvent event) {
276: updateSelection(event);
277: updateButtons();
278: }
279:
280: /**
281: * Update the button enablement state.
282: */
283: protected void updateButtons() {
284: if (okButton != null) {
285: okButton.setEnabled(getSelection().length > 0);
286: }
287: }
288:
289: /**
290: * Update the selection object.
291: */
292: protected void updateSelection(SelectionChangedEvent event) {
293: ArrayList descs = new ArrayList();
294: IStructuredSelection sel = (IStructuredSelection) event
295: .getSelection();
296: for (Iterator i = sel.iterator(); i.hasNext();) {
297: Object o = i.next();
298: if (o instanceof OpAction) {
299: descs.add(o);
300: }
301: }
302: opActions = new OpAction[descs.size()];
303: descs.toArray(opActions);
304: }
305: }
|