blob: 9cf079310c54d6d6d9aaeca0fdde6a6a795acb61 [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.*;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.PreferencePage;
import org.eclipse.swt.SWT;
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.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.ui.*;
import org.eclipse.ui.help.WorkbenchHelp;
import org.eclipse.ui.internal.*;
import org.eclipse.ui.internal.misc.Assert;
import org.eclipse.ui.internal.registry.*;
/**
* The file editors page presents the collection of file names and extensions
* for which the user has registered editors. It also lets the user add new
* internal or external (program) editors for a given file name and extension.
*
* The user can add an editor for either a specific file name and extension
* (e.g. report.doc), or for all file names of a given extension (e.g. *.doc)
*
* The set of registered editors is tracked by the EditorRegistery
* available from the workbench plugin.
*/
public class FileEditorsPreferencePage extends PreferencePage implements IWorkbenchPreferencePage, Listener {
protected Table resourceTypeTable;
protected Button addResourceTypeButton;
protected Button removeResourceTypeButton;
protected Table editorTable;
protected Button addEditorButton;
protected Button removeEditorButton;
protected Button defaultEditorButton;
protected Label editorLabel;
protected IWorkbench workbench;
protected List imagesToDispose;
protected Map editorsToImages;
/**
* Add a new resource type to the collection shown in the top of the page.
* This is typically called after the extension dialog is shown to the user.
*/
public void addResourceType(String newName, String newExtension) {
// Either a file name or extension must be provided
Assert.isTrue((newName != null && newName.length() != 0) ||
(newExtension != null && newExtension.length() != 0));
// Wild card only valid by itself (i.e. rep* is not valid)
// And must have an extension
int index = newName.indexOf('*');
if (index > -1) {
Assert.isTrue(index == 0 && newName.length() == 1);
Assert.isTrue(newExtension != null && newExtension.length() != 0);
}
// Find the index at which to insert the new entry.
String newFilename = (newName + (newExtension == null || newExtension.length() == 0 ?
"" : "." + newExtension)).toUpperCase();//$NON-NLS-1$ //$NON-NLS-2$
IFileEditorMapping resourceType;
TableItem[] items = resourceTypeTable.getItems();
boolean found = false;
int i = 0;
while (i < items.length && !found) {
resourceType = (IFileEditorMapping) items[i].getData();
int result = newFilename.compareToIgnoreCase(resourceType.getLabel());
if (result == 0) {
// Same resource type not allowed!
MessageDialog.openInformation(
getControl().getShell(),
WorkbenchMessages.getString("FileEditorPreference.existsTitle"), //$NON-NLS-1$
WorkbenchMessages.getString("FileEditorPreference.existsMessage")); //$NON-NLS-1$
return;
}
if (result < 0)
found = true;
else
i++;
}
// Create the new type and insert it
resourceType = new FileEditorMapping(newName, newExtension);
TableItem item = newResourceTableItem(resourceType, i, true);
resourceTypeTable.setFocus();
resourceTypeTable.showItem(item);
fillEditorTable();
}
/**
* Creates the page's UI content.
*/
protected Control createContents(Composite parent) {
imagesToDispose = new ArrayList();
editorsToImages = new HashMap(50);
Font font = parent.getFont();
// define container & its gridding
Composite pageComponent = new Composite(parent, SWT.NULL);
GridLayout layout = new GridLayout();
layout.numColumns = 2;
layout.marginWidth = 0;
layout.marginHeight = 0;
pageComponent.setLayout(layout);
GridData data = new GridData();
data.verticalAlignment = GridData.FILL;
data.horizontalAlignment = GridData.FILL;
pageComponent.setLayoutData(data);
pageComponent.setFont(font);
//layout the contents
//layout the top table & its buttons
Label label = new Label(pageComponent, SWT.LEFT);
label.setText(WorkbenchMessages.getString("FileEditorPreference.fileTypes")); //$NON-NLS-1$
data = new GridData();
data.horizontalAlignment = GridData.FILL;
data.horizontalSpan = 2;
label.setLayoutData(data);
label.setFont(font);
resourceTypeTable = new Table(pageComponent, SWT.SINGLE | SWT.BORDER | SWT.FULL_SELECTION);
resourceTypeTable.addListener(SWT.Selection, this);
resourceTypeTable.addListener(SWT.DefaultSelection, this);
data = new GridData(GridData.FILL_HORIZONTAL);
int availableRows = DialogUtil.availableRows(pageComponent);
data.heightHint = resourceTypeTable.getItemHeight()* (availableRows / 8);
resourceTypeTable.setLayoutData(data);
resourceTypeTable.setFont(font);
Composite groupComponent= new Composite(pageComponent, SWT.NULL);
GridLayout groupLayout = new GridLayout();
groupLayout.marginWidth = 0;
groupLayout.marginHeight = 0;
groupComponent.setLayout(groupLayout);
data = new GridData();
data.verticalAlignment = GridData.FILL;
data.horizontalAlignment = GridData.FILL;
groupComponent.setLayoutData(data);
groupComponent.setFont(font);
addResourceTypeButton = new Button(groupComponent, SWT.PUSH);
addResourceTypeButton.setText(WorkbenchMessages.getString("FileEditorPreference.add")); //$NON-NLS-1$
addResourceTypeButton.addListener(SWT.Selection, this);
addResourceTypeButton.setLayoutData(data);
addResourceTypeButton.setFont(font);
setButtonLayoutData(addResourceTypeButton);
removeResourceTypeButton = new Button(groupComponent, SWT.PUSH);
removeResourceTypeButton.setText(WorkbenchMessages.getString("FileEditorPreference.remove")); //$NON-NLS-1$
removeResourceTypeButton.addListener(SWT.Selection, this);
removeResourceTypeButton.setFont(font);
setButtonLayoutData(removeResourceTypeButton);
//Spacer
label = new Label(pageComponent, SWT.LEFT);
data = new GridData();
data.horizontalAlignment = GridData.FILL;
data.horizontalSpan = 2;
label.setLayoutData(data);
// layout the bottom table & its buttons
editorLabel = new Label(pageComponent, SWT.LEFT);
editorLabel.setText(WorkbenchMessages.getString("FileEditorPreference.associatedEditors")); //$NON-NLS-1$
data = new GridData();
data.horizontalAlignment = GridData.FILL;
data.horizontalSpan = 2;
editorLabel.setLayoutData(data);
editorLabel.setFont(font);
editorTable = new Table(pageComponent, SWT.SINGLE | SWT.BORDER);
editorTable.addListener(SWT.Selection, this);
editorTable.addListener(SWT.DefaultSelection, this);
data = new GridData(GridData.FILL_BOTH);
data.heightHint = editorTable.getItemHeight()*7;
editorTable.setLayoutData(data);
editorTable.setFont(font);
groupComponent = new Composite(pageComponent, SWT.NULL);
groupLayout = new GridLayout();
groupLayout.marginWidth = 0;
groupLayout.marginHeight = 0;
groupComponent.setLayout(groupLayout);
data = new GridData();
data.verticalAlignment = GridData.FILL;
data.horizontalAlignment = GridData.FILL;
groupComponent.setLayoutData(data);
groupComponent.setFont(font);
addEditorButton = new Button(groupComponent, SWT.PUSH);
addEditorButton.setText(WorkbenchMessages.getString("FileEditorPreference.addEditor")); //$NON-NLS-1$
addEditorButton.addListener(SWT.Selection, this);
addEditorButton.setLayoutData(data);
addEditorButton.setFont(font);
setButtonLayoutData(addEditorButton);
removeEditorButton = new Button(groupComponent, SWT.PUSH);
removeEditorButton.setText(WorkbenchMessages.getString("FileEditorPreference.removeEditor")); //$NON-NLS-1$
removeEditorButton.addListener(SWT.Selection, this);
removeEditorButton.setFont(font);
setButtonLayoutData(removeEditorButton);
defaultEditorButton= new Button(groupComponent, SWT.PUSH);
defaultEditorButton.setText(WorkbenchMessages.getString("FileEditorPreference.default")); //$NON-NLS-1$
defaultEditorButton.addListener(SWT.Selection, this);
defaultEditorButton.setFont(font);
setButtonLayoutData(defaultEditorButton);
fillResourceTypeTable();
if (resourceTypeTable.getItemCount() > 0) {
resourceTypeTable.setSelection(0);
}
fillEditorTable();
updateEnabledState();
WorkbenchHelp.setHelp(parent, IHelpContextIds.FILE_EDITORS_PREFERENCE_PAGE);
return pageComponent;
}
/**
* The preference page is going to be disposed. So deallocate all allocated
* SWT resources that aren't disposed automatically by disposing the page
* (i.e fonts, cursors, etc). Subclasses should reimplement this method to
* release their own allocated SWT resources.
*/
public void dispose() {
super.dispose();
if(imagesToDispose != null) {
for (Iterator e = imagesToDispose.iterator(); e.hasNext();) {
((Image)e.next()).dispose();
}
imagesToDispose = null;
}
if (editorsToImages != null) {
for (Iterator e = editorsToImages.values().iterator(); e.hasNext();) {
((Image)e.next()).dispose();
}
editorsToImages = null;
}
}
/**
* Hook method to get a page specific preference store. Reimplement this
* method if a page don't want to use its parent's preference store.
*/
protected IPreferenceStore doGetPreferenceStore() {
return WorkbenchPlugin.getDefault().getPreferenceStore();
}
protected void fillEditorTable() {
editorTable.removeAll();
FileEditorMapping resourceType = getSelectedResourceType();
if (resourceType != null) {
IEditorDescriptor[] array = resourceType.getEditors();
for (int i=0;i < array.length; i++) {
IEditorDescriptor editor = array[i];
TableItem item = new TableItem(editorTable, SWT.NULL);
item.setData(editor);
// Check if it is the default editor
String defaultString = null;
FileEditorMapping ext = getSelectedResourceType();
if (ext != null){
IEditorDescriptor preferredEditor = ext.getDefaultEditor();
if (preferredEditor == editor)
defaultString = WorkbenchMessages.getString("FileEditorPreference.defaultLabel"); //$NON-NLS-1$
}
if (defaultString != null) {
item.setText(editor.getLabel() + " " + defaultString); //$NON-NLS-1$
}
else {
item.setText(editor.getLabel());
}
item.setImage(getImage(editor));
}
}
}
/**
* Place the existing resource types in the table
*/
protected void fillResourceTypeTable() {
// Populate the table with the items
IFileEditorMapping[] array = WorkbenchPlugin.getDefault().getEditorRegistry().getFileEditorMappings();
for (int i = 0; i < array.length; i++) {
FileEditorMapping mapping = (FileEditorMapping) array[i];
mapping = (FileEditorMapping) mapping.clone(); // want a copy
newResourceTableItem(mapping, i, false);
}
}
/**
* Returns the image associated with the given editor.
*/
protected Image getImage(IEditorDescriptor editor) {
Image image = (Image)editorsToImages.get(editor);
if (image == null) {
image = editor.getImageDescriptor().createImage();
editorsToImages.put(editor, image);
}
return image;
}
protected FileEditorMapping getSelectedResourceType() {
TableItem[] items = resourceTypeTable.getSelection();
if (items.length > 0) {
return (FileEditorMapping)items[0].getData(); //Table is single select
} else {
return null;
}
}
protected IEditorDescriptor[] getAssociatedEditors(){
if (getSelectedResourceType() == null)
return null;
if (editorTable.getItemCount() > 0) {
ArrayList editorList = new ArrayList();
for (int i = 0; i < editorTable.getItemCount(); i++)
editorList.add(editorTable.getItem(i).getData());
return (IEditorDescriptor[])editorList.toArray(new IEditorDescriptor[editorList.size()]);
}
else
return null;
}
public void handleEvent(Event event) {
if (event.widget == addResourceTypeButton) {
promptForResourceType();
} else if (event.widget == removeResourceTypeButton) {
removeSelectedResourceType();
} else if (event.widget == addEditorButton) {
promptForEditor();
} else if (event.widget == removeEditorButton) {
removeSelectedEditor();
} else if (event.widget == defaultEditorButton) {
setSelectedEditorAsDefault();
} else if (event.widget == resourceTypeTable) {
fillEditorTable();
}
updateEnabledState();
}
/**
* @see IWorkbenchPreferencePage
*/
public void init(IWorkbench aWorkbench){
this.workbench = aWorkbench;
noDefaultAndApplyButton();
}
/*
* Create a new <code>TableItem</code> to represent the resource
* type editor description supplied.
*/
protected TableItem newResourceTableItem(IFileEditorMapping mapping, int index, boolean selected) {
Image image = mapping.getImageDescriptor().createImage(false);
if (image != null)
imagesToDispose.add(image);
TableItem item = new TableItem(resourceTypeTable, SWT.NULL, index);
if (image != null) {
item.setImage(image);
}
item.setText(mapping.getLabel());
item.setData(mapping);
if (selected) {
resourceTypeTable.setSelection(index);
}
return item;
}
/**
* This is a hook for sublcasses to do special things when the ok
* button is pressed.
* For example reimplement this method if you want to save the
* page's data into the preference bundle.
*/
public boolean performOk() {
TableItem[] items = resourceTypeTable.getItems();
FileEditorMapping[] resourceTypes = new FileEditorMapping[items.length];
for (int i = 0; i < items.length; i++) {
resourceTypes[i] = (FileEditorMapping)(items[i].getData());
}
EditorRegistry registry = (EditorRegistry)WorkbenchPlugin.getDefault().getEditorRegistry(); // cast to allow save to be called
registry.setFileEditorMappings(resourceTypes);
registry.saveAssociations();
return true;
}
public void promptForEditor() {
EditorSelectionDialog dialog = new EditorSelectionDialog(getControl().getShell());
dialog.setEditorsToFilter(getAssociatedEditors());
dialog.setMessage(WorkbenchMessages.format("Choose_the_editor_for_file", new Object[] {getSelectedResourceType().getLabel()})); //$NON-NLS-1$
if (dialog.open() == Dialog.OK) {
EditorDescriptor editor = (EditorDescriptor)dialog.getSelectedEditor();
if (editor != null) {
int i = editorTable.getItemCount();
boolean isEmpty = i < 1;
TableItem item = new TableItem(editorTable, SWT.NULL, i);
item.setData(editor);
if (isEmpty)
item.setText(editor.getLabel() + " " + WorkbenchMessages.getString("FileEditorPreference.defaultLabel")); //$NON-NLS-2$ //$NON-NLS-1$
else
item.setText(editor.getLabel());
item.setImage(getImage(editor));
editorTable.setSelection(i);
editorTable.setFocus();
getSelectedResourceType().addEditor(editor);
updateSelectedResourceType(); //in case of new default
}
}
}
public void promptForResourceType() {
FileExtensionDialog dialog = new FileExtensionDialog(getControl().getShell());
if (dialog.open() == Dialog.OK) {
String name = dialog.getName();
String extension = dialog.getExtension();
addResourceType(name, extension);
}
}
/**
* Remove the editor from the table
*/
public void removeSelectedEditor() {
TableItem[] items = editorTable.getSelection();
boolean defaultEditor = editorTable.getSelectionIndex() == 0;
if (items.length > 0) {
getSelectedResourceType().removeEditor((EditorDescriptor)items[0].getData());
items[0].dispose(); //Table is single selection
}
if (defaultEditor && editorTable.getItemCount() > 0){
TableItem item = editorTable.getItem(0);
if (item != null)
item.setText(((EditorDescriptor)(item.getData())).getLabel() + " " + WorkbenchMessages.getString("FileEditorPreference.defaultLabel")); //$NON-NLS-2$ //$NON-NLS-1$
}
}
/**
* Remove the type from the table
*/
public void removeSelectedResourceType() {
TableItem[] items = resourceTypeTable.getSelection();
if (items.length > 0) {
items[0].dispose(); //Table is single selection
}
//Clear out the editors too
editorTable.removeAll();
}
public void setSelectedEditorAsDefault() {
TableItem[] items = editorTable.getSelection();
if (items.length > 0) {
// First change the label of the old default
TableItem oldDefaultItem = editorTable.getItem(0);
oldDefaultItem.setText(((EditorDescriptor)oldDefaultItem.getData()).getLabel());
// Now set the new default
EditorDescriptor editor = (EditorDescriptor)items[0].getData();
getSelectedResourceType().setDefaultEditor(editor);
items[0].dispose(); //Table is single selection
TableItem item = new TableItem(editorTable, SWT.NULL, 0);
item.setData(editor);
item.setText(editor.getLabel() + " " + WorkbenchMessages.getString("FileEditorPreference.defaultLabel")); //$NON-NLS-2$ //$NON-NLS-1$
item.setImage(getImage(editor));
editorTable.setSelection(new TableItem[] {item});
}
}
public void updateEnabledState() {
//Update enabled state
boolean resourceTypeSelected = resourceTypeTable.getSelectionIndex() != -1;
boolean editorSelected = editorTable.getSelectionIndex() != -1;
removeResourceTypeButton.setEnabled(resourceTypeSelected);
editorLabel.setEnabled(resourceTypeSelected);
addEditorButton.setEnabled(resourceTypeSelected);
removeEditorButton.setEnabled(editorSelected);
defaultEditorButton.setEnabled(editorSelected);
}
public void updateSelectedResourceType() {
// TableItem item = resourceTypeTable.getSelection()[0]; //Single select
// Image image = ((IFileEditorMapping)item.getData()).getImageDescriptor().getImage();
// imagesToDispose.addElement(image);
// item.setImage(image);
}
}