blob: ff78c8e2c2022dd0b42dd410085ad9ef9b77ac75 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 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
*******************************************************************************/
package org.eclipse.ui.internal.dialogs;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.core.runtime.content.IContentTypeManager;
import org.eclipse.jface.preference.PreferencePage;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.ListViewer;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.jface.window.Window;
import org.eclipse.osgi.util.NLS;
import org.eclipse.osgi.util.TextProcessor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
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.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.PreferenceLinkArea;
import org.eclipse.ui.internal.IWorkbenchHelpContextIds;
import org.eclipse.ui.internal.WorkbenchMessages;
import org.eclipse.ui.internal.WorkbenchPlugin;
import org.eclipse.ui.internal.misc.StatusUtil;
import org.eclipse.ui.internal.util.Util;
import org.eclipse.ui.preferences.IWorkbenchPreferenceContainer;
import org.eclipse.ui.statushandlers.StatusManager;
/**
* Preference page that allows manipulation of core content types. Unlike most
* preference pages, it does not work on the preference store itself but rather
* the content type manager. As such, there are no apply/default buttons and all
* changes made take effect immediately.
*
* @since 3.1
*/
public class ContentTypesPreferencePage extends PreferencePage implements
IWorkbenchPreferencePage {
private ListViewer fileAssociationViewer;
private Button removeButton;
private TreeViewer contentTypesViewer;
private Button addButton;
private Button editButton;
private Text charsetField;
private Button setButton;
private IWorkbench workbench;
private class Spec {
String name;
String ext;
boolean isPredefined;
int sortValue;
/*
* (non-Javadoc)
*
* @see java.lang.Object#toString()
*/
public String toString() {
String toString;
if (name != null) {
toString = name;
} else {
toString = "*." + ext; //$NON-NLS-1$
}
if (isPredefined) {
toString = NLS.bind(
WorkbenchMessages.ContentTypes_lockedFormat, toString);
}
return toString;
}
}
private class FileSpecComparator extends ViewerComparator {
public int category(Object element) {
// only Spec objects in here - unchecked cast
return ((Spec) element).sortValue;
}
}
private class FileSpecLabelProvider extends LabelProvider {
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.viewers.LabelProvider#getText(java.lang.Object)
*/
public String getText(Object element) {
String label = super.getText(element);
return TextProcessor.process(label, "*."); //$NON-NLS-1$
}
}
private class FileSpecContentProvider implements IStructuredContentProvider {
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.viewers.IContentProvider#dispose()
*/
public void dispose() {
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer,
* java.lang.Object, java.lang.Object)
*/
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
*/
public Object[] getElements(Object inputElement) {
IContentType contentType = (IContentType) inputElement;
String[] userextfileSpecs = contentType
.getFileSpecs(IContentType.FILE_EXTENSION_SPEC
| IContentType.IGNORE_PRE_DEFINED);
String[] usernamefileSpecs = contentType
.getFileSpecs(IContentType.FILE_NAME_SPEC
| IContentType.IGNORE_PRE_DEFINED);
String[] preextfileSpecs = contentType
.getFileSpecs(IContentType.FILE_EXTENSION_SPEC
| IContentType.IGNORE_USER_DEFINED);
String[] prenamefileSpecs = contentType
.getFileSpecs(IContentType.FILE_NAME_SPEC
| IContentType.IGNORE_USER_DEFINED);
return createSpecs(userextfileSpecs, usernamefileSpecs,
preextfileSpecs, prenamefileSpecs);
}
private Object[] createSpecs(String[] userextfileSpecs,
String[] usernamefileSpecs, String[] preextfileSpecs,
String[] prenamefileSpecs) {
List returnValues = new ArrayList();
for (int i = 0; i < usernamefileSpecs.length; i++) {
Spec spec = new Spec();
spec.name = usernamefileSpecs[i];
spec.isPredefined = false;
spec.sortValue = 0;
returnValues.add(spec);
}
for (int i = 0; i < prenamefileSpecs.length; i++) {
Spec spec = new Spec();
spec.name = prenamefileSpecs[i];
spec.isPredefined = true;
spec.sortValue = 1;
returnValues.add(spec);
}
for (int i = 0; i < userextfileSpecs.length; i++) {
Spec spec = new Spec();
spec.ext = userextfileSpecs[i];
spec.isPredefined = false;
spec.sortValue = 2;
returnValues.add(spec);
}
for (int i = 0; i < preextfileSpecs.length; i++) {
Spec spec = new Spec();
spec.ext = preextfileSpecs[i];
spec.isPredefined = true;
spec.sortValue = 3;
returnValues.add(spec);
}
return returnValues.toArray();
}
}
private class ContentTypesLabelProvider extends LabelProvider {
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.viewers.LabelProvider#getText(java.lang.Object)
*/
public String getText(Object element) {
IContentType contentType = (IContentType) element;
return contentType.getName();
}
}
private class ContentTypesContentProvider implements ITreeContentProvider {
private IContentTypeManager manager;
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object)
*/
public Object[] getChildren(Object parentElement) {
List elements = new ArrayList();
IContentType baseType = (IContentType) parentElement;
IContentType[] contentTypes = manager.getAllContentTypes();
for (int i = 0; i < contentTypes.length; i++) {
IContentType type = contentTypes[i];
if (Util.equals(type.getBaseType(), baseType)) {
elements.add(type);
}
}
return elements.toArray();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object)
*/
public Object getParent(Object element) {
IContentType contentType = (IContentType) element;
return contentType.getBaseType();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object)
*/
public boolean hasChildren(Object element) {
return getChildren(element).length > 0;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
*/
public Object[] getElements(Object inputElement) {
return getChildren(null);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.viewers.IContentProvider#dispose()
*/
public void dispose() {
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer,
* java.lang.Object, java.lang.Object)
*/
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
manager = (IContentTypeManager) newInput;
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.preference.PreferencePage#createContents(org.eclipse.swt.widgets.Composite)
*/
protected Control createContents(Composite parent) {
Composite composite = new Composite(parent, SWT.NONE);
GridLayout layout = new GridLayout(2, false);
layout.marginHeight = layout.marginWidth = 0;
composite.setLayout(layout);
PreferenceLinkArea contentTypeArea = new PreferenceLinkArea(
composite,
SWT.NONE,
"org.eclipse.ui.preferencePages.FileEditors", WorkbenchMessages.ContentTypes_FileEditorsRelatedLink,//$NON-NLS-1$
(IWorkbenchPreferenceContainer) getContainer(), null);
GridData data = new GridData(GridData.FILL_HORIZONTAL
| GridData.GRAB_HORIZONTAL);
contentTypeArea.getControl().setLayoutData(data);
createContentTypesTree(composite);
createFileAssociations(composite);
createCharset(composite);
workbench.getHelpSystem().setHelp(parent,
IWorkbenchHelpContextIds.CONTENT_TYPES_PREFERENCE_PAGE);
applyDialogFont(composite);
return composite;
}
private void createCharset(final Composite parent) {
Composite composite = new Composite(parent, SWT.NONE);
GridLayout layout = new GridLayout(3, false);
layout.marginHeight = layout.marginWidth = 0;
GridData compositeData = new GridData(GridData.FILL_HORIZONTAL);
compositeData.horizontalSpan = 2;
composite.setLayoutData(compositeData);
composite.setLayout(layout);
Label label = new Label(composite, SWT.NONE);
label.setFont(parent.getFont());
label.setText(WorkbenchMessages.ContentTypes_characterSetLabel);
charsetField = new Text(composite, SWT.SINGLE | SWT.BORDER);
charsetField.setFont(parent.getFont());
charsetField.setEnabled(false);
GridData data = new GridData(GridData.FILL_HORIZONTAL);
charsetField.setLayoutData(data);
setButton = new Button(composite, SWT.PUSH);
setButton.setFont(parent.getFont());
setButton
.setText(WorkbenchMessages.ContentTypes_characterSetUpdateLabel);
setButton.setEnabled(false);
setButtonLayoutData(setButton);
setButton.addSelectionListener(new SelectionAdapter() {
/*
* (non-Javadoc)
*
* @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
*/
public void widgetSelected(SelectionEvent e) {
try {
String text = charsetField.getText().trim();
if (text.length() == 0) {
text = null;
}
getSelectedContentType().setDefaultCharset(text);
setButton.setEnabled(false);
} catch (CoreException e1) {
StatusUtil.handleStatus(e1.getStatus(), StatusManager.SHOW,
parent.getShell());
}
}
});
charsetField.addKeyListener(new KeyAdapter() {
/*
* (non-Javadoc)
*
* @see org.eclipse.swt.events.KeyAdapter#keyReleased(org.eclipse.swt.events.KeyEvent)
*/
public void keyReleased(KeyEvent e) {
IContentType contentType = getSelectedContentType();
String charset = contentType.getDefaultCharset();
if (charset == null) {
charset = ""; //$NON-NLS-1$
}
setButton.setEnabled(!charset.equals(charsetField.getText()));
}
});
}
/**
* @param composite
*/
private void createFileAssociations(final Composite composite) {
{
Label label = new Label(composite, SWT.NONE);
label.setText(WorkbenchMessages.ContentTypes_fileAssociationsLabel);
GridData data = new GridData();
data.horizontalSpan = 2;
label.setLayoutData(data);
}
{
fileAssociationViewer = new ListViewer(composite);
fileAssociationViewer.setComparator(new FileSpecComparator());
fileAssociationViewer.getControl().setFont(composite.getFont());
fileAssociationViewer
.setContentProvider(new FileSpecContentProvider());
fileAssociationViewer.setLabelProvider(new FileSpecLabelProvider());
GridData data = new GridData(GridData.FILL_BOTH);
data.horizontalSpan = 1;
fileAssociationViewer.getControl().setLayoutData(data);
fileAssociationViewer
.addSelectionChangedListener(new ISelectionChangedListener() {
public void selectionChanged(SelectionChangedEvent event) {
IStructuredSelection selection = (IStructuredSelection) event
.getSelection();
if (selection.isEmpty()) {
editButton.setEnabled(false);
removeButton.setEnabled(false);
return;
}
boolean enabled = true;
List elements = selection.toList();
for (Iterator i = elements.iterator(); i.hasNext();) {
Spec spec = (Spec) i.next();
if (spec.isPredefined) {
enabled = false;
}
}
editButton.setEnabled(enabled && selection.size() == 1);
removeButton.setEnabled(enabled);
}
});
}
{
Composite buttonArea = new Composite(composite, SWT.NONE);
GridLayout layout = new GridLayout(1, false);
layout.marginHeight = layout.marginWidth = 0;
buttonArea.setLayout(layout);
GridData data = new GridData(GridData.VERTICAL_ALIGN_BEGINNING);
buttonArea.setLayoutData(data);
addButton = new Button(buttonArea, SWT.PUSH);
addButton.setFont(composite.getFont());
addButton
.setText(WorkbenchMessages.ContentTypes_fileAssociationsAddLabel);
addButton.setEnabled(false);
setButtonLayoutData(addButton);
addButton.addSelectionListener(new SelectionAdapter() {
/*
* (non-Javadoc)
*
* @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
*/
public void widgetSelected(SelectionEvent e) {
Shell shell = composite.getShell();
IContentType selectedContentType = getSelectedContentType();
FileExtensionDialog dialog = new FileExtensionDialog(
shell,
WorkbenchMessages.ContentTypes_addDialog_title,
IWorkbenchHelpContextIds.FILE_EXTENSION_DIALOG,
WorkbenchMessages.ContentTypes_addDialog_messageHeader,
WorkbenchMessages.ContentTypes_addDialog_message,
WorkbenchMessages.ContentTypes_addDialog_label);
if (dialog.open() == Window.OK) {
String name = dialog.getName();
String extension = dialog.getExtension();
try {
if (name.equals("*")) { //$NON-NLS-1$
selectedContentType.addFileSpec(extension,
IContentType.FILE_EXTENSION_SPEC);
} else {
selectedContentType
.addFileSpec(
name
+ (extension.length() > 0 ? ('.' + extension)
: ""), //$NON-NLS-1$
IContentType.FILE_NAME_SPEC);
}
} catch (CoreException ex) {
StatusUtil.handleStatus(ex.getStatus(),
StatusManager.SHOW, shell);
WorkbenchPlugin.log(ex);
} finally {
fileAssociationViewer.refresh(false);
}
}
}
});
editButton = new Button(buttonArea, SWT.PUSH);
editButton.setFont(composite.getFont());
editButton
.setText(WorkbenchMessages.ContentTypes_fileAssociationsEditLabel);
editButton.setEnabled(false);
setButtonLayoutData(editButton);
editButton.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
Shell shell = composite.getShell();
IContentType selectedContentType = getSelectedContentType();
Spec spec = getSelectedSpecs()[0];
FileExtensionDialog dialog = new FileExtensionDialog(
shell,
WorkbenchMessages.ContentTypes_editDialog_title,
IWorkbenchHelpContextIds.FILE_EXTENSION_DIALOG,
WorkbenchMessages.ContentTypes_editDialog_messageHeader,
WorkbenchMessages.ContentTypes_editDialog_message,
WorkbenchMessages.ContentTypes_editDialog_label);
if (spec.name == null) {
dialog.setInitialValue("*." + spec.ext); //$NON-NLS-1$
} else {
dialog.setInitialValue(spec.name);
}
if (dialog.open() == Window.OK) {
String name = dialog.getName();
String extension = dialog.getExtension();
try {
// remove the original spec
if (spec.name != null) {
selectedContentType.removeFileSpec(spec.name,
IContentType.FILE_NAME_SPEC);
} else if (spec.ext != null) {
selectedContentType.removeFileSpec(spec.ext,
IContentType.FILE_EXTENSION_SPEC);
}
// add the new one
if (name.equals("*")) { //$NON-NLS-1$
selectedContentType.addFileSpec(extension,
IContentType.FILE_EXTENSION_SPEC);
} else {
selectedContentType
.addFileSpec(
name
+ (extension.length() > 0 ? ('.' + extension)
: ""), //$NON-NLS-1$
IContentType.FILE_NAME_SPEC);
}
} catch (CoreException ex) {
StatusUtil.handleStatus(ex.getStatus(),
StatusManager.SHOW, shell);
WorkbenchPlugin.log(ex);
} finally {
fileAssociationViewer.refresh(false);
}
}
}
});
removeButton = new Button(buttonArea, SWT.PUSH);
removeButton.setEnabled(false);
removeButton
.setText(WorkbenchMessages.ContentTypes_fileAssociationsRemoveLabel);
setButtonLayoutData(removeButton);
removeButton.addSelectionListener(new SelectionAdapter() {
/*
* (non-Javadoc)
*
* @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
*/
public void widgetSelected(SelectionEvent event) {
IContentType contentType = getSelectedContentType();
Spec[] specs = getSelectedSpecs();
MultiStatus result = new MultiStatus(PlatformUI.PLUGIN_ID,
0, new IStatus[0],
WorkbenchMessages.ContentTypes_errorDialogMessage,
null);
for (int i = 0; i < specs.length; i++) {
Spec spec = specs[i];
try {
if (spec.name != null) {
contentType.removeFileSpec(spec.name,
IContentType.FILE_NAME_SPEC);
} else if (spec.ext != null) {
contentType.removeFileSpec(spec.ext,
IContentType.FILE_EXTENSION_SPEC);
}
} catch (CoreException e) {
result.add(e.getStatus());
}
}
if (!result.isOK()) {
StatusUtil.handleStatus(result, StatusManager.SHOW,
composite.getShell());
}
fileAssociationViewer.refresh(false);
}
});
}
}
protected Spec[] getSelectedSpecs() {
List list = ((IStructuredSelection) fileAssociationViewer
.getSelection()).toList();
return (Spec[]) list.toArray(new Spec[list.size()]);
}
protected IContentType getSelectedContentType() {
return (IContentType) ((IStructuredSelection) contentTypesViewer
.getSelection()).getFirstElement();
}
/**
* @param composite
*/
private void createContentTypesTree(Composite composite) {
{
Label label = new Label(composite, SWT.NONE);
label.setFont(composite.getFont());
label.setText(WorkbenchMessages.ContentTypes_contentTypesLabel);
GridData data = new GridData();
data.horizontalSpan = 2;
label.setLayoutData(data);
}
{
contentTypesViewer = new TreeViewer(composite, SWT.SINGLE
| SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
contentTypesViewer.getControl().setFont(composite.getFont());
contentTypesViewer
.setContentProvider(new ContentTypesContentProvider());
contentTypesViewer
.setLabelProvider(new ContentTypesLabelProvider());
contentTypesViewer.setComparator(new ViewerComparator());
contentTypesViewer.setInput(Platform.getContentTypeManager());
GridData data = new GridData(GridData.FILL_BOTH);
data.horizontalSpan = 2;
contentTypesViewer.getControl().setLayoutData(data);
contentTypesViewer
.addSelectionChangedListener(new ISelectionChangedListener() {
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
*/
public void selectionChanged(SelectionChangedEvent event) {
IContentType contentType = (IContentType) ((IStructuredSelection) event
.getSelection()).getFirstElement();
fileAssociationViewer.setInput(contentType);
if (contentType != null) {
String charset = contentType
.getDefaultCharset();
if (charset == null) {
charset = ""; //$NON-NLS-1$
}
charsetField.setText(charset);
} else {
charsetField.setText(""); //$NON-NLS-1$
}
charsetField.setEnabled(contentType != null);
addButton.setEnabled(contentType != null);
setButton.setEnabled(false);
}
});
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench)
*/
public void init(IWorkbench workbench) {
this.workbench = workbench;
noDefaultAndApplyButton();
}
}