/******************************************************************************* * Copyright (c) 2000, 2007 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation * Benjamin Muskalla - Bug 29633 [EditorMgmt] "Open" menu should * have Open With-->Other *******************************************************************************/ package org.eclipse.ui.dialogs; import java.util.ArrayList; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Cursor; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableItem; import org.eclipse.ui.IEditorDescriptor; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.internal.IWorkbenchHelpContextIds; import org.eclipse.ui.internal.WorkbenchMessages; import org.eclipse.ui.internal.WorkbenchPlugin; import org.eclipse.ui.internal.registry.EditorDescriptor; import org.eclipse.ui.internal.registry.EditorRegistry; /** * This class is used to allow the user to select a dialog from the set of * internal and external editors. * @since 3.3 * */ public final class EditorSelectionDialog extends Dialog { private EditorDescriptor selectedEditor; private Button externalButton; private Table editorTable; private Button browseExternalEditorsButton; private Button internalButton; private Button okButton; private static final String STORE_ID_INTERNAL_EXTERNAL = "EditorSelectionDialog.STORE_ID_INTERNAL_EXTERNAL";//$NON-NLS-1$ private String message = WorkbenchMessages.EditorSelection_chooseAnEditor; // collection of IEditorDescriptor private IEditorDescriptor[] externalEditors; private IEditorDescriptor[] internalEditors; private Image[] externalEditorImages; private Image[] internalEditorImages; private IEditorDescriptor[] editorsToFilter; private DialogListener listener = new DialogListener(); private static final String[] Executable_Filters; private static final int TABLE_WIDTH = 200; static { if (SWT.getPlatform().equals("win32")) {//$NON-NLS-1$ Executable_Filters = new String[] { "*.exe", "*.bat", "*.*" };//$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } else { Executable_Filters = new String[] { "*" }; //$NON-NLS-1$ } } /** * Create an instance of this class. * * @param parentShell * the parent shell */ public EditorSelectionDialog(Shell parentShell) { super(parentShell); } /** * This method is called if a button has been pressed. */ protected void buttonPressed(int buttonId) { if (buttonId == IDialogConstants.OK_ID) { saveWidgetValues(); } super.buttonPressed(buttonId); } /** * Close the window. */ public boolean close() { if (internalEditorImages != null) { for (int i = 0; i < internalEditorImages.length; i++) { internalEditorImages[i].dispose(); } internalEditorImages = null; } if (externalEditorImages != null) { for (int i = 0; i < externalEditorImages.length; i++) { externalEditorImages[i].dispose(); } externalEditorImages = null; } return super.close(); } /* * (non-Javadoc) Method declared in Window. */ protected void configureShell(Shell shell) { super.configureShell(shell); shell.setText(WorkbenchMessages.EditorSelection_title); PlatformUI.getWorkbench().getHelpSystem().setHelp(shell, IWorkbenchHelpContextIds.EDITOR_SELECTION_DIALOG); } /** * Creates and returns the contents of the upper part of the dialog (above * the button bar). * * Subclasses should overide. * * @param parent * the parent composite to contain the dialog area * @return the dialog area control */ protected Control createDialogArea(Composite parent) { Font font = parent.getFont(); // create main group Composite contents = (Composite) super.createDialogArea(parent); ((GridLayout) contents.getLayout()).numColumns = 2; // begin the layout Label textLabel = new Label(contents, SWT.NONE); textLabel.setText(message); GridData data = new GridData(); data.horizontalSpan = 2; textLabel.setLayoutData(data); textLabel.setFont(font); internalButton = new Button(contents, SWT.RADIO | SWT.LEFT); internalButton.setText(WorkbenchMessages.EditorSelection_internal); internalButton.addListener(SWT.Selection, listener); data = new GridData(); data.horizontalSpan = 1; internalButton.setLayoutData(data); internalButton.setFont(font); externalButton = new Button(contents, SWT.RADIO | SWT.LEFT); externalButton.setText(WorkbenchMessages.EditorSelection_external); externalButton.addListener(SWT.Selection, listener); data = new GridData(); data.horizontalSpan = 1; externalButton.setLayoutData(data); externalButton.setFont(font); editorTable = new Table(contents, SWT.SINGLE | SWT.BORDER); editorTable.addListener(SWT.Selection, listener); editorTable.addListener(SWT.DefaultSelection, listener); editorTable.addListener(SWT.MouseDoubleClick, listener); data = new GridData(); data.widthHint = convertHorizontalDLUsToPixels(TABLE_WIDTH); data.horizontalAlignment = GridData.FILL; data.grabExcessHorizontalSpace = true; data.verticalAlignment = GridData.FILL; data.grabExcessVerticalSpace = true; data.horizontalSpan = 2; editorTable.setLayoutData(data); editorTable.setFont(font); data.heightHint = editorTable.getItemHeight() * 12; browseExternalEditorsButton = new Button(contents, SWT.PUSH); browseExternalEditorsButton .setText(WorkbenchMessages.EditorSelection_browse); browseExternalEditorsButton.addListener(SWT.Selection, listener); data = new GridData(); int widthHint = convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH); data.widthHint = Math.max(widthHint, browseExternalEditorsButton .computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x); browseExternalEditorsButton.setLayoutData(data); browseExternalEditorsButton.setFont(font); restoreWidgetValues(); // Place buttons to the appropriate state fillEditorTable(); updateEnableState(); return contents; } protected void fillEditorTable() { editorTable.removeAll(); editorTable.update(); IEditorDescriptor[] editors; Image[] images; if (internalButton.getSelection()) { editors = getInternalEditors(); images = internalEditorImages; } else { editors = getExternalEditors(); images = externalEditorImages; } // 1FWHIEX: ITPUI:WINNT - Need to call setRedraw editorTable.setRedraw(false); for (int i = 0; i < editors.length; i++) { TableItem item = new TableItem(editorTable, SWT.NULL); item.setData(editors[i]); item.setText(editors[i].getLabel()); item.setImage(images[i]); } editorTable.setRedraw(true); } /** * Return the dialog store to cache values into */ protected IDialogSettings getDialogSettings() { IDialogSettings workbenchSettings = WorkbenchPlugin.getDefault() .getDialogSettings(); IDialogSettings section = workbenchSettings .getSection("EditorSelectionDialog");//$NON-NLS-1$ if (section == null) { section = workbenchSettings.addNewSection("EditorSelectionDialog");//$NON-NLS-1$ } return section; } /** * Get a list of registered programs from the OS */ protected IEditorDescriptor[] getExternalEditors() { if (externalEditors == null) { // Since this can take a while, show the busy // cursor. If the dialog is not yet visible, // then use the parent shell. Control shell = getShell(); if (!shell.isVisible()) { Control topShell = shell.getParent(); if (topShell != null) { shell = topShell; } } Cursor busy = new Cursor(shell.getDisplay(), SWT.CURSOR_WAIT); shell.setCursor(busy); // Get the external editors available EditorRegistry reg = (EditorRegistry) WorkbenchPlugin.getDefault() .getEditorRegistry(); externalEditors = reg.getSortedEditorsFromOS(); externalEditors = filterEditors(externalEditors); externalEditorImages = getImages(externalEditors); // Clean up shell.setCursor(null); busy.dispose(); } return externalEditors; } /** * Returns an array of editors which have been filtered according to the * array of editors in the editorsToFilter instance variable. * * @param editors * an array of editors to filter * @return a filtered array of editors */ protected IEditorDescriptor[] filterEditors(IEditorDescriptor[] editors) { if ((editors == null) || (editors.length < 1)) { return editors; } if ((editorsToFilter == null) || (editorsToFilter.length < 1)) { return editors; } ArrayList filteredList = new ArrayList(); for (int i = 0; i < editors.length; i++) { boolean add = true; for (int j = 0; j < editorsToFilter.length; j++) { if (editors[i].getId().equals(editorsToFilter[j].getId())) { add = false; } } if (add) { filteredList.add(editors[i]); } } return (IEditorDescriptor[]) filteredList .toArray(new IEditorDescriptor[filteredList.size()]); } /** * Returns an array of images for the given array of editors */ protected Image[] getImages(IEditorDescriptor[] editors) { Image[] images = new Image[editors.length]; for (int i = 0; i < editors.length; i++) { images[i] = editors[i].getImageDescriptor().createImage(); } return images; } /** * Returns the internal editors */ protected IEditorDescriptor[] getInternalEditors() { if (internalEditors == null) { EditorRegistry reg = (EditorRegistry) WorkbenchPlugin.getDefault() .getEditorRegistry(); internalEditors = reg.getSortedEditorsFromPlugins(); internalEditors = filterEditors(internalEditors); internalEditorImages = getImages(internalEditors); } return internalEditors; } /** * Return the editor the user selected * * @return the selected editor */ public IEditorDescriptor getSelectedEditor() { return selectedEditor; } protected void promptForExternalEditor() { FileDialog dialog = new FileDialog(getShell(), SWT.OPEN | SWT.PRIMARY_MODAL); dialog.setFilterExtensions(Executable_Filters); String result = dialog.open(); if (result != null) { EditorDescriptor editor = EditorDescriptor.createForProgram(result); // pretend we had obtained it from the list of os registered editors TableItem ti = new TableItem(editorTable, SWT.NULL); ti.setData(editor); ti.setText(editor.getLabel()); Image image = editor.getImageDescriptor().createImage(); ti.setImage(image); // need to pass an array to setSelection -- 1FSKYVO: SWT:ALL - // inconsistent setSelection api on Table editorTable.setSelection(new TableItem[] { ti }); editorTable.showSelection(); editorTable.setFocus(); selectedEditor = editor; /* * add to our collection of cached external editors in case the user * flips back and forth between internal/external */ IEditorDescriptor[] newEditors = new IEditorDescriptor[externalEditors.length + 1]; System.arraycopy(externalEditors, 0, newEditors, 0, externalEditors.length); newEditors[newEditors.length - 1] = editor; externalEditors = newEditors; Image[] newImages = new Image[externalEditorImages.length + 1]; System.arraycopy(externalEditorImages, 0, newImages, 0, externalEditorImages.length); newImages[newImages.length - 1] = image; externalEditorImages = newImages; } } /** * Handle a double click event on the list */ protected void handleDoubleClickEvent() { buttonPressed(IDialogConstants.OK_ID); } /** * Use the dialog store to restore widget values to the values that they * held last time this wizard was used to completion */ protected void restoreWidgetValues() { IDialogSettings settings = getDialogSettings(); boolean wasExternal = settings.getBoolean(STORE_ID_INTERNAL_EXTERNAL); internalButton.setSelection(!wasExternal); externalButton.setSelection(wasExternal); } /** * Since Finish was pressed, write widget values to the dialog store so that * they will persist into the next invocation of this wizard page */ protected void saveWidgetValues() { IDialogSettings settings = getDialogSettings(); // record whether use was viewing internal or external editors settings .put(STORE_ID_INTERNAL_EXTERNAL, !internalButton.getSelection()); } /** * Set the message displayed by this message dialog * * @param aMessage * the message */ public void setMessage(String aMessage) { message = aMessage; } /** * Set the editors which will not appear in the dialog. * * @param editors * an array of editors */ public void setEditorsToFilter(IEditorDescriptor[] editors) { editorsToFilter = editors; } /** * Update enabled state. */ protected void updateEnableState() { boolean enableExternal = externalButton.getSelection(); browseExternalEditorsButton.setEnabled(enableExternal); updateOkButton(); } protected void createButtonsForButtonBar(Composite parent) { okButton = createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true); createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false); // initially there is no selection so OK button should not be enabled okButton.setEnabled(false); } /** * Update the button enablement state. */ protected void updateOkButton() { // Buttons are null during dialog creation if (okButton == null) { return; } // If there is no selection, do not enable OK button if (editorTable.getSelectionCount() == 0) { okButton.setEnabled(false); return; } // At this point, there is a selection okButton.setEnabled(selectedEditor != null); } private class DialogListener implements Listener { /* * (non-Javadoc) * * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event) */ public void handleEvent(Event event) { if (event.type == SWT.MouseDoubleClick) { handleDoubleClickEvent(); return; } if (event.widget == externalButton) { fillEditorTable(); } else if (event.widget == browseExternalEditorsButton) { promptForExternalEditor(); } else if (event.widget == editorTable) { if (editorTable.getSelectionIndex() != -1) { selectedEditor = (EditorDescriptor) editorTable .getSelection()[0].getData(); } else { selectedEditor = null; okButton.setEnabled(false); } } updateEnableState(); } } }