001: /*******************************************************************************
002: * Copyright (c) 2000, 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: * Benjamin Muskalla - Bug 29633 [EditorMgmt] "Open" menu should
011: * have Open With-->Other
012: *******************************************************************************/package org.eclipse.ui.dialogs;
013:
014: import java.util.ArrayList;
015:
016: import org.eclipse.jface.dialogs.Dialog;
017: import org.eclipse.jface.dialogs.IDialogConstants;
018: import org.eclipse.jface.dialogs.IDialogSettings;
019: import org.eclipse.swt.SWT;
020: import org.eclipse.swt.graphics.Cursor;
021: import org.eclipse.swt.graphics.Font;
022: import org.eclipse.swt.graphics.Image;
023: import org.eclipse.swt.layout.GridData;
024: import org.eclipse.swt.layout.GridLayout;
025: import org.eclipse.swt.widgets.Button;
026: import org.eclipse.swt.widgets.Composite;
027: import org.eclipse.swt.widgets.Control;
028: import org.eclipse.swt.widgets.Event;
029: import org.eclipse.swt.widgets.FileDialog;
030: import org.eclipse.swt.widgets.Label;
031: import org.eclipse.swt.widgets.Listener;
032: import org.eclipse.swt.widgets.Shell;
033: import org.eclipse.swt.widgets.Table;
034: import org.eclipse.swt.widgets.TableItem;
035: import org.eclipse.ui.IEditorDescriptor;
036: import org.eclipse.ui.PlatformUI;
037: import org.eclipse.ui.internal.IWorkbenchHelpContextIds;
038: import org.eclipse.ui.internal.WorkbenchMessages;
039: import org.eclipse.ui.internal.WorkbenchPlugin;
040: import org.eclipse.ui.internal.registry.EditorDescriptor;
041: import org.eclipse.ui.internal.registry.EditorRegistry;
042:
043: /**
044: * This class is used to allow the user to select a dialog from the set of
045: * internal and external editors.
046: * @since 3.3
047: *
048: */
049:
050: public final class EditorSelectionDialog extends Dialog {
051: private EditorDescriptor selectedEditor;
052:
053: private Button externalButton;
054:
055: private Table editorTable;
056:
057: private Button browseExternalEditorsButton;
058:
059: private Button internalButton;
060:
061: private Button okButton;
062:
063: private static final String STORE_ID_INTERNAL_EXTERNAL = "EditorSelectionDialog.STORE_ID_INTERNAL_EXTERNAL";//$NON-NLS-1$
064:
065: private String message = WorkbenchMessages.EditorSelection_chooseAnEditor;
066:
067: // collection of IEditorDescriptor
068: private IEditorDescriptor[] externalEditors;
069:
070: private IEditorDescriptor[] internalEditors;
071:
072: private Image[] externalEditorImages;
073:
074: private Image[] internalEditorImages;
075:
076: private IEditorDescriptor[] editorsToFilter;
077:
078: private DialogListener listener = new DialogListener();
079:
080: private static final String[] Executable_Filters;
081:
082: private static final int TABLE_WIDTH = 200;
083: static {
084: if (SWT.getPlatform().equals("win32")) {//$NON-NLS-1$
085: Executable_Filters = new String[] { "*.exe", "*.bat", "*.*" };//$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
086: } else {
087: Executable_Filters = new String[] { "*" }; //$NON-NLS-1$
088: }
089: }
090:
091: /**
092: * Create an instance of this class.
093: *
094: * @param parentShell
095: * the parent shell
096: */
097: public EditorSelectionDialog(Shell parentShell) {
098: super (parentShell);
099: }
100:
101: /**
102: * This method is called if a button has been pressed.
103: */
104: protected void buttonPressed(int buttonId) {
105: if (buttonId == IDialogConstants.OK_ID) {
106: saveWidgetValues();
107: }
108: super .buttonPressed(buttonId);
109: }
110:
111: /**
112: * Close the window.
113: */
114: public boolean close() {
115: if (internalEditorImages != null) {
116: for (int i = 0; i < internalEditorImages.length; i++) {
117: internalEditorImages[i].dispose();
118: }
119: internalEditorImages = null;
120: }
121: if (externalEditorImages != null) {
122: for (int i = 0; i < externalEditorImages.length; i++) {
123: externalEditorImages[i].dispose();
124: }
125: externalEditorImages = null;
126: }
127: return super .close();
128: }
129:
130: /*
131: * (non-Javadoc) Method declared in Window.
132: */
133: protected void configureShell(Shell shell) {
134: super .configureShell(shell);
135: shell.setText(WorkbenchMessages.EditorSelection_title);
136: PlatformUI.getWorkbench().getHelpSystem().setHelp(shell,
137: IWorkbenchHelpContextIds.EDITOR_SELECTION_DIALOG);
138: }
139:
140: /**
141: * Creates and returns the contents of the upper part of the dialog (above
142: * the button bar).
143: *
144: * Subclasses should overide.
145: *
146: * @param parent
147: * the parent composite to contain the dialog area
148: * @return the dialog area control
149: */
150: protected Control createDialogArea(Composite parent) {
151: Font font = parent.getFont();
152: // create main group
153: Composite contents = (Composite) super .createDialogArea(parent);
154: ((GridLayout) contents.getLayout()).numColumns = 2;
155:
156: // begin the layout
157: Label textLabel = new Label(contents, SWT.NONE);
158: textLabel.setText(message);
159: GridData data = new GridData();
160: data.horizontalSpan = 2;
161: textLabel.setLayoutData(data);
162: textLabel.setFont(font);
163:
164: internalButton = new Button(contents, SWT.RADIO | SWT.LEFT);
165: internalButton
166: .setText(WorkbenchMessages.EditorSelection_internal);
167: internalButton.addListener(SWT.Selection, listener);
168: data = new GridData();
169: data.horizontalSpan = 1;
170: internalButton.setLayoutData(data);
171: internalButton.setFont(font);
172:
173: externalButton = new Button(contents, SWT.RADIO | SWT.LEFT);
174: externalButton
175: .setText(WorkbenchMessages.EditorSelection_external);
176: externalButton.addListener(SWT.Selection, listener);
177: data = new GridData();
178: data.horizontalSpan = 1;
179: externalButton.setLayoutData(data);
180: externalButton.setFont(font);
181:
182: editorTable = new Table(contents, SWT.SINGLE | SWT.BORDER);
183: editorTable.addListener(SWT.Selection, listener);
184: editorTable.addListener(SWT.DefaultSelection, listener);
185: editorTable.addListener(SWT.MouseDoubleClick, listener);
186: data = new GridData();
187: data.widthHint = convertHorizontalDLUsToPixels(TABLE_WIDTH);
188: data.horizontalAlignment = GridData.FILL;
189: data.grabExcessHorizontalSpace = true;
190: data.verticalAlignment = GridData.FILL;
191: data.grabExcessVerticalSpace = true;
192: data.horizontalSpan = 2;
193: editorTable.setLayoutData(data);
194: editorTable.setFont(font);
195: data.heightHint = editorTable.getItemHeight() * 12;
196:
197: browseExternalEditorsButton = new Button(contents, SWT.PUSH);
198: browseExternalEditorsButton
199: .setText(WorkbenchMessages.EditorSelection_browse);
200: browseExternalEditorsButton
201: .addListener(SWT.Selection, listener);
202: data = new GridData();
203: int widthHint = convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH);
204: data.widthHint = Math.max(widthHint,
205: browseExternalEditorsButton.computeSize(SWT.DEFAULT,
206: SWT.DEFAULT, true).x);
207: browseExternalEditorsButton.setLayoutData(data);
208: browseExternalEditorsButton.setFont(font);
209:
210: restoreWidgetValues(); // Place buttons to the appropriate state
211:
212: fillEditorTable();
213:
214: updateEnableState();
215:
216: return contents;
217: }
218:
219: protected void fillEditorTable() {
220: editorTable.removeAll();
221: editorTable.update();
222: IEditorDescriptor[] editors;
223: Image[] images;
224: if (internalButton.getSelection()) {
225: editors = getInternalEditors();
226: images = internalEditorImages;
227: } else {
228: editors = getExternalEditors();
229: images = externalEditorImages;
230: }
231:
232: // 1FWHIEX: ITPUI:WINNT - Need to call setRedraw
233: editorTable.setRedraw(false);
234: for (int i = 0; i < editors.length; i++) {
235: TableItem item = new TableItem(editorTable, SWT.NULL);
236: item.setData(editors[i]);
237: item.setText(editors[i].getLabel());
238: item.setImage(images[i]);
239: }
240: editorTable.setRedraw(true);
241: }
242:
243: /**
244: * Return the dialog store to cache values into
245: */
246:
247: protected IDialogSettings getDialogSettings() {
248: IDialogSettings workbenchSettings = WorkbenchPlugin
249: .getDefault().getDialogSettings();
250: IDialogSettings section = workbenchSettings
251: .getSection("EditorSelectionDialog");//$NON-NLS-1$
252: if (section == null) {
253: section = workbenchSettings
254: .addNewSection("EditorSelectionDialog");//$NON-NLS-1$
255: }
256: return section;
257: }
258:
259: /**
260: * Get a list of registered programs from the OS
261: */
262: protected IEditorDescriptor[] getExternalEditors() {
263: if (externalEditors == null) {
264: // Since this can take a while, show the busy
265: // cursor. If the dialog is not yet visible,
266: // then use the parent shell.
267: Control shell = getShell();
268: if (!shell.isVisible()) {
269: Control topShell = shell.getParent();
270: if (topShell != null) {
271: shell = topShell;
272: }
273: }
274: Cursor busy = new Cursor(shell.getDisplay(),
275: SWT.CURSOR_WAIT);
276: shell.setCursor(busy);
277: // Get the external editors available
278: EditorRegistry reg = (EditorRegistry) WorkbenchPlugin
279: .getDefault().getEditorRegistry();
280: externalEditors = reg.getSortedEditorsFromOS();
281: externalEditors = filterEditors(externalEditors);
282: externalEditorImages = getImages(externalEditors);
283: // Clean up
284: shell.setCursor(null);
285: busy.dispose();
286: }
287: return externalEditors;
288: }
289:
290: /**
291: * Returns an array of editors which have been filtered according to the
292: * array of editors in the editorsToFilter instance variable.
293: *
294: * @param editors
295: * an array of editors to filter
296: * @return a filtered array of editors
297: */
298: protected IEditorDescriptor[] filterEditors(
299: IEditorDescriptor[] editors) {
300: if ((editors == null) || (editors.length < 1)) {
301: return editors;
302: }
303:
304: if ((editorsToFilter == null) || (editorsToFilter.length < 1)) {
305: return editors;
306: }
307:
308: ArrayList filteredList = new ArrayList();
309: for (int i = 0; i < editors.length; i++) {
310: boolean add = true;
311: for (int j = 0; j < editorsToFilter.length; j++) {
312: if (editors[i].getId().equals(
313: editorsToFilter[j].getId())) {
314: add = false;
315: }
316: }
317: if (add) {
318: filteredList.add(editors[i]);
319: }
320: }
321:
322: return (IEditorDescriptor[]) filteredList
323: .toArray(new IEditorDescriptor[filteredList.size()]);
324: }
325:
326: /**
327: * Returns an array of images for the given array of editors
328: */
329: protected Image[] getImages(IEditorDescriptor[] editors) {
330: Image[] images = new Image[editors.length];
331: for (int i = 0; i < editors.length; i++) {
332: images[i] = editors[i].getImageDescriptor().createImage();
333: }
334: return images;
335: }
336:
337: /**
338: * Returns the internal editors
339: */
340: protected IEditorDescriptor[] getInternalEditors() {
341: if (internalEditors == null) {
342: EditorRegistry reg = (EditorRegistry) WorkbenchPlugin
343: .getDefault().getEditorRegistry();
344: internalEditors = reg.getSortedEditorsFromPlugins();
345: internalEditors = filterEditors(internalEditors);
346: internalEditorImages = getImages(internalEditors);
347: }
348: return internalEditors;
349: }
350:
351: /**
352: * Return the editor the user selected
353: *
354: * @return the selected editor
355: */
356: public IEditorDescriptor getSelectedEditor() {
357: return selectedEditor;
358: }
359:
360: protected void promptForExternalEditor() {
361: FileDialog dialog = new FileDialog(getShell(), SWT.OPEN
362: | SWT.PRIMARY_MODAL);
363: dialog.setFilterExtensions(Executable_Filters);
364: String result = dialog.open();
365: if (result != null) {
366: EditorDescriptor editor = EditorDescriptor
367: .createForProgram(result);
368: // pretend we had obtained it from the list of os registered editors
369: TableItem ti = new TableItem(editorTable, SWT.NULL);
370: ti.setData(editor);
371: ti.setText(editor.getLabel());
372: Image image = editor.getImageDescriptor().createImage();
373: ti.setImage(image);
374:
375: // need to pass an array to setSelection -- 1FSKYVO: SWT:ALL -
376: // inconsistent setSelection api on Table
377: editorTable.setSelection(new TableItem[] { ti });
378: editorTable.showSelection();
379: editorTable.setFocus();
380: selectedEditor = editor;
381:
382: /*
383: * add to our collection of cached external editors in case the user
384: * flips back and forth between internal/external
385: */
386: IEditorDescriptor[] newEditors = new IEditorDescriptor[externalEditors.length + 1];
387: System.arraycopy(externalEditors, 0, newEditors, 0,
388: externalEditors.length);
389: newEditors[newEditors.length - 1] = editor;
390: externalEditors = newEditors;
391:
392: Image[] newImages = new Image[externalEditorImages.length + 1];
393: System.arraycopy(externalEditorImages, 0, newImages, 0,
394: externalEditorImages.length);
395: newImages[newImages.length - 1] = image;
396: externalEditorImages = newImages;
397: }
398: }
399:
400: /**
401: * Handle a double click event on the list
402: */
403: protected void handleDoubleClickEvent() {
404: buttonPressed(IDialogConstants.OK_ID);
405: }
406:
407: /**
408: * Use the dialog store to restore widget values to the values that they
409: * held last time this wizard was used to completion
410: */
411: protected void restoreWidgetValues() {
412: IDialogSettings settings = getDialogSettings();
413: boolean wasExternal = settings
414: .getBoolean(STORE_ID_INTERNAL_EXTERNAL);
415: internalButton.setSelection(!wasExternal);
416: externalButton.setSelection(wasExternal);
417: }
418:
419: /**
420: * Since Finish was pressed, write widget values to the dialog store so that
421: * they will persist into the next invocation of this wizard page
422: */
423: protected void saveWidgetValues() {
424: IDialogSettings settings = getDialogSettings();
425: // record whether use was viewing internal or external editors
426: settings.put(STORE_ID_INTERNAL_EXTERNAL, !internalButton
427: .getSelection());
428: }
429:
430: /**
431: * Set the message displayed by this message dialog
432: *
433: * @param aMessage
434: * the message
435: */
436: public void setMessage(String aMessage) {
437: message = aMessage;
438: }
439:
440: /**
441: * Set the editors which will not appear in the dialog.
442: *
443: * @param editors
444: * an array of editors
445: */
446: public void setEditorsToFilter(IEditorDescriptor[] editors) {
447: editorsToFilter = editors;
448: }
449:
450: /**
451: * Update enabled state.
452: */
453: protected void updateEnableState() {
454: boolean enableExternal = externalButton.getSelection();
455: browseExternalEditorsButton.setEnabled(enableExternal);
456: updateOkButton();
457: }
458:
459: protected void createButtonsForButtonBar(Composite parent) {
460: okButton = createButton(parent, IDialogConstants.OK_ID,
461: IDialogConstants.OK_LABEL, true);
462: createButton(parent, IDialogConstants.CANCEL_ID,
463: IDialogConstants.CANCEL_LABEL, false);
464: // initially there is no selection so OK button should not be enabled
465: okButton.setEnabled(false);
466:
467: }
468:
469: /**
470: * Update the button enablement state.
471: */
472: protected void updateOkButton() {
473: // Buttons are null during dialog creation
474: if (okButton == null) {
475: return;
476: }
477: // If there is no selection, do not enable OK button
478: if (editorTable.getSelectionCount() == 0) {
479: okButton.setEnabled(false);
480: return;
481: }
482: // At this point, there is a selection
483: okButton.setEnabled(selectedEditor != null);
484: }
485:
486: private class DialogListener implements Listener {
487:
488: /*
489: * (non-Javadoc)
490: *
491: * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event)
492: */
493: public void handleEvent(Event event) {
494: if (event.type == SWT.MouseDoubleClick) {
495: handleDoubleClickEvent();
496: return;
497: }
498: if (event.widget == externalButton) {
499: fillEditorTable();
500: } else if (event.widget == browseExternalEditorsButton) {
501: promptForExternalEditor();
502: } else if (event.widget == editorTable) {
503: if (editorTable.getSelectionIndex() != -1) {
504: selectedEditor = (EditorDescriptor) editorTable
505: .getSelection()[0].getData();
506: } else {
507: selectedEditor = null;
508: okButton.setEnabled(false);
509: }
510: }
511: updateEnableState();
512: }
513:
514: }
515: }
|