diff options
author | Mickael Istria | 2017-08-05 14:50:13 +0000 |
---|---|---|
committer | Mickael Istria | 2017-08-30 18:14:53 +0000 |
commit | 27d9147d1936b26b7c4adf326993f921e48d00b4 (patch) | |
tree | 0d1906d4b5e11e7892972dfb99d55d771aac6744 | |
parent | 201acc62528eb9a99de52cff85b7b49abf8a2925 (diff) | |
download | eclipse.platform.ui-27d9147d1936b26b7c4adf326993f921e48d00b4.tar.gz eclipse.platform.ui-27d9147d1936b26b7c4adf326993f921e48d00b4.tar.xz eclipse.platform.ui-27d9147d1936b26b7c4adf326993f921e48d00b4.zip |
Bug 263316 - Associate content-type with file name patternI20170904-0230I20170903-2000I20170902-1500I20170901-2000I20170831-2000I20170830-2000
Change-Id: I231eda25903ccd6ad66802cf4aec16ec1232d0d6
Signed-off-by: Mickael Istria <mistria@redhat.com>
2 files changed, 314 insertions, 71 deletions
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/dialogs/ContentTypeFilenameAssociationDialog.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/dialogs/ContentTypeFilenameAssociationDialog.java new file mode 100644 index 00000000000..6bba1fbf35e --- /dev/null +++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/dialogs/ContentTypeFilenameAssociationDialog.java @@ -0,0 +1,239 @@ +/******************************************************************************* + * Copyright (c) 2000, 2017 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 + * Mickael Istria (Red Hat Inc.) - [263316] Specialization for content-types + *******************************************************************************/ +package org.eclipse.ui.internal.dialogs; + +import org.eclipse.core.runtime.content.IContentType; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.jface.dialogs.TitleAreaDialog; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.layout.LayoutConstants; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +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.PlatformUI; +import org.eclipse.ui.internal.WorkbenchMessages; +import org.eclipse.ui.internal.WorkbenchPlugin; + +/** + * This class is used to prompt the user for a file name & extension. + */ +public class ContentTypeFilenameAssociationDialog extends TitleAreaDialog { + + private static final String DIALOG_SETTINGS_SECTION = "ContentTypeFilenameAssociationDialog"; //$NON-NLS-1$ + + private String filename = ""; //$NON-NLS-1$ + + private String initialValue; + + private Text filenameField; + + private Button okButton; + + private String title; + + private String helpContextId; + + private final String headerTitle; + + private final String message2; + + private final String label; + + /** + * Spec type according to the input text. Can be + * {@link IContentType#FILE_NAME_SPEC}, + * {@link IContentType#FILE_EXTENSION_SPEC}, + * {@link IContentType#FILE_PATTERN_SPEC} + */ + private int specType; + + /** + * Constructs a new file extension dialog. + * + * @param parentShell the parent shell + * @param title the dialog title + * @param helpContextId the help context for this dialog + * @param headerTitle the dialog header + * @param message the dialog message + * @param label the label for the "file type" field + * @since 3.4 + */ + public ContentTypeFilenameAssociationDialog(Shell parentShell, String title, String helpContextId, String headerTitle, String message, String label) { + super(parentShell); + this.title = title; + this.helpContextId = helpContextId; + this.headerTitle = headerTitle; + message2 = message; + this.label = label; + + setShellStyle(getShellStyle() | SWT.SHEET); + } + + @Override + protected void configureShell(Shell shell) { + super.configureShell(shell); + shell.setText(title); + PlatformUI.getWorkbench().getHelpSystem().setHelp(shell, helpContextId); + } + + + @Override + protected Control createDialogArea(Composite parent) { + Composite parentComposite = (Composite) super.createDialogArea(parent); + + Composite contents = new Composite(parentComposite, SWT.NONE); + contents.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + setTitle(headerTitle); + setMessage(message2); + + new Label(contents, SWT.LEFT) + .setText(label); + + filenameField = new Text(contents, SWT.SINGLE | SWT.BORDER); + if (initialValue != null) { + filenameField.setText(initialValue); + } + filenameField.addModifyListener(event -> { + if (event.widget == filenameField) { + filename = filenameField.getText().trim(); + okButton.setEnabled(validateFileType()); + } + }); + filenameField.setFocus(); + + Dialog.applyDialogFont(parentComposite); + + Point defaultMargins = LayoutConstants.getMargins(); + GridLayoutFactory.fillDefaults().numColumns(2).margins( + defaultMargins.x, defaultMargins.y).generateLayout(contents); + + return contents; + } + + + @Override + protected void createButtonsForButtonBar(Composite parent) { + okButton = createButton(parent, IDialogConstants.OK_ID, + IDialogConstants.OK_LABEL, true); + okButton.setEnabled(false); + createButton(parent, IDialogConstants.CANCEL_ID, + IDialogConstants.CANCEL_LABEL, false); + } + + /** + * Validate the user input for a file type + */ + private boolean validateFileType() { + // We need kernel api to validate the extension or a filename + + // check for empty name and extension + if (filename.length() == 0) { + setErrorMessage(null); + return false; + } + + // check for empty extension if there is no name + int index = filename.lastIndexOf('.'); + if (index == filename.length() - 1) { + if (index == 0 || (index == 1 && filename.charAt(0) == '*')) { + setErrorMessage(WorkbenchMessages.FileExtension_extensionEmptyMessage); + return false; + } + } + + // check for characters before * + // or no other characters + // or next chatacter not '.' + // or another * + index = filename.indexOf('*'); + if (index > -1) { + if (filename.length() == 1) { + setErrorMessage(WorkbenchMessages.FileExtension_extensionEmptyMessage); + return false; + } + } + + if (hasWildcards(filename)) { + this.specType = IContentType.FILE_PATTERN_SPEC; // start with most general, then refine + int extPrefix = filename.indexOf("*."); //$NON-NLS-1$ + if (extPrefix == 0) { + String ext = filename.substring(2); + if (!hasWildcards(ext)) { + this.specType = IContentType.FILE_EXTENSION_SPEC; + } + } + } else { + this.specType = IContentType.FILE_NAME_SPEC; + } + setErrorMessage(null); + return true; + } + + private static boolean hasWildcards(String s) { + return s.contains("?") || s.contains("*"); //$NON-NLS-1$ //$NON-NLS-2$ + } + + /** + * Sets the initial value that should be prepopulated in this dialog. + * + * @param initialValue + * the value to be displayed to the user + * @since 3.4 + */ + public void setInitialValue(String initialValue) { + this.initialValue = initialValue; + } + + @Override + protected IDialogSettings getDialogBoundsSettings() { + IDialogSettings settings = WorkbenchPlugin.getDefault().getDialogSettings(); + IDialogSettings section = settings.getSection(DIALOG_SETTINGS_SECTION); + if (section == null) section = settings.addNewSection(DIALOG_SETTINGS_SECTION); + return section; + } + + @Override + protected boolean isResizable() { + return true; + } + + /** + * @return the text for the spec. For the case of extensions, it's only the + * extension (without <code>*.</code> prefix. In other cases, it's the + * whole expression. + */ + public String getSpecText() { + if (this.specType == IContentType.FILE_EXTENSION_SPEC) { + return filename.substring(2); + } + return filename; + } + + /** + * @return the spec type according to the input text. Can be + * {@link IContentType#FILE_NAME_SPEC}, + * {@link IContentType#FILE_EXTENSION_SPEC}, + * {@link IContentType#FILE_PATTERN_SPEC} + */ + public int getSpecType() { + return this.specType; + } +} diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/dialogs/ContentTypesPreferencePage.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/dialogs/ContentTypesPreferencePage.java index beca307db7e..2262b49874b 100644 --- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/dialogs/ContentTypesPreferencePage.java +++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/dialogs/ContentTypesPreferencePage.java @@ -114,29 +114,56 @@ public class ContentTypesPreferencePage extends PreferencePage implements private Set<Image> disposableEditorIcons = new HashSet<>(); private class Spec { - String name; - - String ext; - - boolean isPredefined; - - int sortValue; + /** + * the spec text: file name, extension or pattern + */ + final String text; + + /** + * one of {@link IContentType#FILE_NAME_SPEC}, + * {@link IContentType#FILE_EXTENSION_SPEC}, + * {@link IContentType#FILE_PATTERN_SPEC} + */ + final int type; + + final boolean isPredefined; + + final int sortValue; + + /** + * @param specText + * the spec text (filename, extension or pattern) + * @param specType + * one of {@link IContentType#FILE_NAME_SPEC}, + * {@link IContentType#FILE_EXTENSION_SPEC}, + * {@link IContentType#FILE_PATTERN_SPEC} + * @param isPredefined + * true if predefined, false is user-defined + * @param sortValue + */ + public Spec(String specText, int specType, boolean isPredefined, int sortValue) { + if (specType != IContentType.FILE_NAME_SPEC && specType != IContentType.FILE_EXTENSION_SPEC + && specType != IContentType.FILE_PATTERN_SPEC) { + throw new IllegalArgumentException("Invalid specType"); //$NON-NLS-1$ + } + this.type = specType; + this.text = specText; + this.isPredefined = isPredefined; + this.sortValue = sortValue; + } @Override public String toString() { - String toString; - if (name != null) { - toString = name; - } else { - toString = "*." + ext; //$NON-NLS-1$ + if (this.type == IContentType.FILE_EXTENSION_SPEC) { + return "*." + this.text; //$NON-NLS-1$ } - - return toString; + return this.text; } public boolean getPredefined() { return isPredefined; } + } private class FileSpecComparator extends ViewerComparator { @@ -179,48 +206,50 @@ public class ContentTypesPreferencePage extends PreferencePage implements .getFileSpecs(IContentType.FILE_EXTENSION_SPEC | IContentType.IGNORE_USER_DEFINED); String[] prenamefileSpecs = contentType .getFileSpecs(IContentType.FILE_NAME_SPEC | IContentType.IGNORE_USER_DEFINED); + String[] userPatternFileSpecs = contentType + .getFileSpecs(IContentType.FILE_PATTERN_SPEC | IContentType.IGNORE_PRE_DEFINED); + String[] prePatternFileSpecs = contentType + .getFileSpecs(IContentType.FILE_PATTERN_SPEC | IContentType.IGNORE_USER_DEFINED); - return createSpecs(userextfileSpecs, usernamefileSpecs, - preextfileSpecs, prenamefileSpecs); + return createSpecs(userextfileSpecs, usernamefileSpecs, userPatternFileSpecs, + preextfileSpecs, prenamefileSpecs, prePatternFileSpecs); } - private Object[] createSpecs(String[] userextfileSpecs, - String[] usernamefileSpecs, String[] preextfileSpecs, - String[] prenamefileSpecs) { - List returnValues = new ArrayList(); + private Spec[] createSpecs(String[] userextfileSpecs, + String[] usernamefileSpecs, String[] userPatternFileSpecs, String[] preextfileSpecs, + String[] prenamefileSpecs, String[] prePatternFileSpecs) { + List<Spec> returnValues = new ArrayList<>(); for (String usernamefileSpec : usernamefileSpecs) { - Spec spec = new Spec(); - spec.name = usernamefileSpec; - spec.isPredefined = false; - spec.sortValue = 0; + Spec spec = new Spec(usernamefileSpec, IContentType.FILE_NAME_SPEC, false, 0); returnValues.add(spec); } for (String prenamefileSpec : prenamefileSpecs) { - Spec spec = new Spec(); - spec.name = prenamefileSpec; - spec.isPredefined = true; - spec.sortValue = 1; + Spec spec = new Spec(prenamefileSpec, IContentType.FILE_NAME_SPEC, true, 1); returnValues.add(spec); } for (String userextfileSpec : userextfileSpecs) { - Spec spec = new Spec(); - spec.ext = userextfileSpec; - spec.isPredefined = false; - spec.sortValue = 2; + Spec spec = new Spec(userextfileSpec, IContentType.FILE_EXTENSION_SPEC, false, 2); returnValues.add(spec); } for (String preextfileSpec : preextfileSpecs) { - Spec spec = new Spec(); - spec.ext = preextfileSpec; - spec.isPredefined = true; - spec.sortValue = 3; + Spec spec = new Spec(preextfileSpec, IContentType.FILE_EXTENSION_SPEC, true, 3); + returnValues.add(spec); + } + + for (String userPatternFileSpec : userPatternFileSpecs) { + Spec spec = new Spec(userPatternFileSpec, IContentType.FILE_PATTERN_SPEC, false, 4); returnValues.add(spec); } - return returnValues.toArray(); + for (String prePatternFileSpec : prePatternFileSpecs) { + Spec spec = new Spec(prePatternFileSpec, IContentType.FILE_PATTERN_SPEC, true, 5); + returnValues.add(spec); + } + + return returnValues.toArray(new Spec[returnValues.size()]); } } @@ -507,20 +536,14 @@ public class ContentTypesPreferencePage extends PreferencePage implements addButton.addSelectionListener(widgetSelectedAdapter(e -> { Shell shell = composite.getShell(); IContentType selectedContentType = getSelectedContentType(); - FileExtensionDialog dialog = new FileExtensionDialog(shell, WorkbenchMessages.ContentTypes_addDialog_title, + ContentTypeFilenameAssociationDialog dialog = new ContentTypeFilenameAssociationDialog(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); - } + selectedContentType.addFileSpec(dialog.getSpecText(), dialog.getSpecType()); } catch (CoreException ex) { StatusUtil.handleStatus(ex.getStatus(), StatusManager.SHOW, shell); WorkbenchPlugin.log(ex); @@ -539,33 +562,18 @@ public class ContentTypesPreferencePage extends PreferencePage implements Shell shell = composite.getShell(); IContentType selectedContentType = getSelectedContentType(); Spec spec = getSelectedSpecs()[0]; - FileExtensionDialog dialog = new FileExtensionDialog(shell, WorkbenchMessages.ContentTypes_editDialog_title, + ContentTypeFilenameAssociationDialog dialog = new ContentTypeFilenameAssociationDialog(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); - } + dialog.setInitialValue(spec.toString()); 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); - } - + selectedContentType.removeFileSpec(spec.text, spec.type); // 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); - } + selectedContentType.addFileSpec(dialog.getSpecText(), dialog.getSpecType()); } catch (CoreException ex) { StatusUtil.handleStatus(ex.getStatus(), StatusManager.SHOW, shell); WorkbenchPlugin.log(ex); @@ -586,11 +594,7 @@ public class ContentTypesPreferencePage extends PreferencePage implements WorkbenchMessages.ContentTypes_errorDialogMessage, null); for (Spec spec : specs) { 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); - } + contentType.removeFileSpec(spec.text, spec.type); } catch (CoreException e) { result.add(e.getStatus()); } |