| /******************************************************************************* |
| * Copyright (c) 2000, 2017 IBM Corporation and others. |
| * |
| * This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.team.internal.ui.preferences; |
| |
| import java.util.ArrayList; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Set; |
| |
| import org.eclipse.jface.dialogs.Dialog; |
| import org.eclipse.jface.dialogs.IInputValidator; |
| import org.eclipse.jface.dialogs.InputDialog; |
| import org.eclipse.jface.dialogs.MessageDialog; |
| import org.eclipse.jface.preference.PreferencePage; |
| import org.eclipse.jface.util.PropertyChangeEvent; |
| import org.eclipse.jface.viewers.ISelection; |
| import org.eclipse.jface.viewers.IStructuredSelection; |
| import org.eclipse.jface.window.Window; |
| import org.eclipse.swt.SWT; |
| 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.team.core.IFileContentManager; |
| import org.eclipse.team.core.IStringMapping; |
| import org.eclipse.team.core.Team; |
| import org.eclipse.team.internal.ui.IHelpContextIds; |
| import org.eclipse.team.internal.ui.PixelConverter; |
| import org.eclipse.team.internal.ui.SWTUtils; |
| import org.eclipse.team.internal.ui.TeamUIMessages; |
| import org.eclipse.team.internal.ui.TeamUIPlugin; |
| import org.eclipse.team.internal.ui.preferences.FileTypeTable.Item; |
| import org.eclipse.team.ui.TeamUI; |
| import org.eclipse.ui.IWorkbench; |
| import org.eclipse.ui.IWorkbenchPreferencePage; |
| import org.eclipse.ui.PlatformUI; |
| /** |
| * This preference page displays all patterns which determine whether a resource |
| * is to be treated as a text file or not. The page allows the user to add or |
| * remove entries from this table, and change their values from Text to Binary. |
| */ |
| public class TextPreferencePage extends PreferencePage implements IWorkbenchPreferencePage { |
| |
| private static final class ExtensionValidator implements IInputValidator { |
| @Override |
| public String isValid(String newText) { |
| if (newText.trim().length() == 0) |
| return ""; //$NON-NLS-1$ |
| if (!isComplete(newText)){ |
| return TeamUIMessages.TextPreferencePage_ExtensionNotCompleted; |
| } |
| newText = strip(newText); |
| if (newText.indexOf('*') >= 0) |
| return TeamUIMessages.TextPreferencePage_2; |
| if (newText.indexOf('.') >= 0) |
| return TeamUIMessages.TextPreferencePage_3; |
| return null; |
| } |
| |
| /** |
| * @param newText |
| * @return the text |
| */ |
| public String strip(String newText) { |
| newText= newText.trim(); |
| if (newText.startsWith("*")) //$NON-NLS-1$ |
| newText= newText.substring(1); |
| if (newText.startsWith(".")) //$NON-NLS-1$ |
| newText= newText.substring(1); |
| return newText; |
| } |
| |
| public boolean isComplete(String text){ |
| //Allowed formats of extension are: |
| // extension |
| // .extension |
| // *.extension |
| if (text.equals("*") || text.equals("*.") || text.equals(".")){ //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ |
| return false; |
| } |
| return true; |
| } |
| } |
| |
| private static final class FilenameValidator implements IInputValidator { |
| @Override |
| public String isValid(String newText) { |
| if (newText.trim().length() == 0) |
| return ""; //$NON-NLS-1$ |
| if (newText.indexOf('*') >= 0) |
| return TeamUIMessages.TextPreferencePage_5; |
| return null; |
| } |
| } |
| |
| // The input for the table viewer |
| private final List<Item> fItems; |
| |
| // Widgets |
| private Button fRemoveButton; |
| private Button fChangeButton; |
| |
| protected FileTypeTable fTable; |
| |
| public TextPreferencePage() { |
| fItems= new ArrayList<>(); |
| initializeItems(); |
| } |
| |
| private void initializeItems() { |
| |
| fItems.clear(); |
| |
| final IFileContentManager manager= Team.getFileContentManager(); |
| |
| final IStringMapping [] extensionInfoArray= manager.getExtensionMappings(); |
| final IStringMapping [] nameInfoArray= manager.getNameMappings(); |
| |
| Set fPluginNames= makeSetOfStrings(manager.getDefaultNameMappings()); |
| Set fPluginExtensions= makeSetOfStrings(manager.getDefaultExtensionMappings()); |
| |
| for (int i = 0; i < extensionInfoArray.length; i++) { |
| final IStringMapping info= extensionInfoArray[i]; |
| final FileTypeTable.Extension extension= new FileTypeTable.Extension(info.getString(), fPluginExtensions.contains(info.getString())); |
| extension.mode= info.getType(); |
| fItems.add(extension); |
| } |
| |
| for (int i = 0; i < nameInfoArray.length; i++) { |
| final IStringMapping info= nameInfoArray[i]; |
| final FileTypeTable.Name name= new FileTypeTable.Name(info.getString(), fPluginNames.contains(info.getString())); |
| name.mode= info.getType(); |
| fItems.add(name); |
| } |
| |
| } |
| |
| private static Set<String> makeSetOfStrings(IStringMapping [] mappings) { |
| final Set<String> set= new HashSet<>(mappings.length); |
| for (int i = 0; i < mappings.length; i++) { |
| set.add(mappings[i].getString()); |
| } |
| return set; |
| } |
| |
| @Override |
| public void init(IWorkbench workbench) { |
| } |
| |
| @Override |
| protected Control createContents(Composite parent) { |
| |
| initializeDialogUnits(parent); |
| |
| final PixelConverter converter= SWTUtils.createDialogPixelConverter(parent); |
| |
| final Composite composite= SWTUtils.createHVFillComposite(parent, SWTUtils.MARGINS_NONE, 2); |
| |
| fTable= new FileTypeTable(composite, fItems, false); |
| |
| fTable.getViewer().getControl().addListener(SWT.Selection, e -> handleSelection()); |
| |
| fTable.getViewer().addDoubleClickListener(event -> { |
| final ISelection selection = event.getSelection(); |
| if (selection == null || !(selection instanceof IStructuredSelection)) { |
| return; |
| } |
| fTable.getViewer().editElement(((IStructuredSelection)selection).getFirstElement(), 1); |
| }); |
| |
| final Composite buttonsComposite = new Composite(composite, SWT.NONE); |
| buttonsComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, false, false)); |
| buttonsComposite.setLayout(SWTUtils.createGridLayout(1, converter, SWTUtils.MARGINS_NONE)); |
| |
| final Button addExtensionButton = new Button(buttonsComposite, SWT.PUSH); |
| addExtensionButton.setText(TeamUIMessages.TextPreferencePage_add); |
| final Button addNameButton = new Button(buttonsComposite, SWT.PUSH); |
| addNameButton.setText(TeamUIMessages.TextPreferencePage_0); |
| fChangeButton = new Button(buttonsComposite, SWT.PUSH); |
| fChangeButton.setText(TeamUIMessages.TextPreferencePage_change); |
| fRemoveButton= new Button(buttonsComposite, SWT.PUSH); |
| fRemoveButton.setText(TeamUIMessages.TextPreferencePage_remove); |
| |
| SWTUtils.createLabel(composite, TeamUIMessages.TextPreferencePage_1, 2); |
| |
| /** |
| * Calculate and set the button size |
| */ |
| applyDialogFont(composite); |
| final int buttonWidth= SWTUtils.calculateControlSize(converter, new Button [] { addExtensionButton, addNameButton, fChangeButton, fRemoveButton }); |
| addExtensionButton.setLayoutData(SWTUtils.createGridData(buttonWidth, SWT.DEFAULT, SWT.FILL, SWT.FILL, false, false)); |
| addNameButton.setLayoutData(SWTUtils.createGridData(buttonWidth, SWT.DEFAULT, SWT.FILL, SWT.FILL, false, false)); |
| fChangeButton.setLayoutData(SWTUtils.createGridData(buttonWidth, SWT.DEFAULT, SWT.FILL, SWT.FILL, false, false)); |
| fRemoveButton.setLayoutData(SWTUtils.createGridData(buttonWidth, SWT.DEFAULT, SWT.FILL, SWT.FILL, false, false)); |
| |
| addExtensionButton.addListener(SWT.Selection, e -> addExtension()); |
| addNameButton.addListener(SWT.Selection, e -> addName()); |
| |
| fChangeButton.setEnabled(false); |
| fChangeButton.addListener(SWT.Selection, e -> changePattern()); |
| |
| fRemoveButton.setEnabled(false); |
| fRemoveButton.addListener(SWT.Selection, e -> removePattern()); |
| |
| Dialog.applyDialogFont(parent); |
| |
| // set F1 help |
| PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(), IHelpContextIds.FILE_TYPE_PREFERENCE_PAGE); |
| |
| return composite; |
| } |
| |
| @Override |
| protected void performDefaults() { |
| super.performDefaults(); |
| initializeItems(); |
| if (fTable != null) |
| fTable.getViewer().refresh(); |
| } |
| |
| /** |
| * Do anything necessary because the OK button has been pressed. |
| * |
| * @return whether it is okay to close the preference page |
| */ |
| @Override |
| public boolean performOk() { |
| final ArrayList<String> extensionsList= new ArrayList<>(); |
| final ArrayList<Integer> extensionsModesList= new ArrayList<>(); |
| |
| final ArrayList<String> namesList= new ArrayList<>(); |
| final ArrayList<Integer> namesModesList= new ArrayList<>(); |
| |
| for (final Iterator iter = fItems.iterator(); iter.hasNext();) { |
| final FileTypeTable.Item item= (FileTypeTable.Item) iter.next(); |
| |
| if (item instanceof FileTypeTable.Extension) { |
| extensionsList.add(item.name); |
| extensionsModesList.add(Integer.valueOf(item.mode)); |
| } else if (item instanceof FileTypeTable.Name) { |
| namesList.add(item.name); |
| namesModesList.add(Integer.valueOf(item.mode)); |
| } |
| } |
| |
| final String [] extensions= extensionsList.toArray(new String [extensionsList.size()]); |
| final String [] names= namesList.toArray(new String [namesList.size()]); |
| |
| final int [] extensionsModes= integerListToIntArray(extensionsModesList); |
| final int [] namesModes= integerListToIntArray(namesModesList); |
| |
| Team.getFileContentManager().setExtensionMappings(extensions, extensionsModes); |
| Team.getFileContentManager().setNameMappings(names, namesModes); |
| |
| TeamUIPlugin.broadcastPropertyChange(new PropertyChangeEvent(this, TeamUI.GLOBAL_FILE_TYPES_CHANGED, null, null)); |
| |
| return true; |
| } |
| |
| private static int [] integerListToIntArray(List integers) { |
| final int [] array= new int [integers.size()]; |
| int index= 0; |
| for (Iterator iter = integers.iterator(); iter.hasNext();) |
| array[index++]= ((Integer)iter.next()).intValue(); |
| return array; |
| } |
| |
| /** |
| * Add a new item to the table with the default type of Text. |
| */ |
| void addExtension() { |
| final ExtensionValidator validator = new ExtensionValidator(); |
| final InputDialog dialog = new InputDialog(getShell(), TeamUIMessages.TextPreferencePage_enterExtensionShort, TeamUIMessages.TextPreferencePage_enterExtensionLong, null, validator); // |
| if (dialog.open() != Window.OK) |
| return; |
| |
| final String extension = validator.strip(dialog.getValue()); |
| |
| // Check if the item already exists |
| final Iterator it = fItems.iterator(); |
| while (it.hasNext()) { |
| final FileTypeTable.Item item= (FileTypeTable.Item)it.next(); |
| if (item instanceof FileTypeTable.Extension && item.name.equals(extension)) { |
| MessageDialog.openWarning(getShell(), TeamUIMessages.TextPreferencePage_extensionExistsShort, TeamUIMessages.TextPreferencePage_extensionExistsLong); // |
| return; |
| } |
| } |
| final FileTypeTable.Item item= new FileTypeTable.Extension(extension, false); |
| fItems.add(item); |
| fTable.getViewer().refresh(); |
| } |
| |
| /** |
| * Add a new item to the table with the default type of Text. |
| */ |
| void addName() { |
| final InputDialog dialog = new InputDialog(getShell(), TeamUIMessages.TextPreferencePage_6, TeamUIMessages.TextPreferencePage_7, null, new FilenameValidator()); // |
| if (dialog.open() != Window.OK) |
| return; |
| |
| final String name = dialog.getValue(); |
| |
| // Check if the item already exists |
| final Iterator it = fItems.iterator(); |
| while (it.hasNext()) { |
| final FileTypeTable.Item item= (FileTypeTable.Item)it.next(); |
| if (item instanceof FileTypeTable.Name && item.name.equals(name)) { |
| MessageDialog.openWarning(getShell(), TeamUIMessages.TextPreferencePage_extensionExistsShort, TeamUIMessages.TextPreferencePage_extensionExistsLong); // |
| return; |
| } |
| } |
| final FileTypeTable.Item item= new FileTypeTable.Name(name, false); |
| fItems.add(item); |
| fTable.getViewer().refresh(); |
| } |
| |
| /** |
| * Remove the selected items from the table |
| */ |
| void removePattern() { |
| final IStructuredSelection selection = fTable.getSelection(); |
| if (selection == null) |
| return; |
| |
| for (final Iterator it = selection.iterator(); it.hasNext(); ) { |
| final FileTypeTable.Item item= (FileTypeTable.Item)it.next(); |
| if (item.contributed) |
| continue; |
| fItems.remove(item); |
| } |
| fTable.getViewer().refresh(); |
| handleSelection(); |
| } |
| /** |
| * Toggle the selected items' content types |
| */ |
| void changePattern() { |
| final IStructuredSelection selection = fTable.getSelection(); |
| if (selection == null) |
| return; |
| |
| for (final Iterator it = selection.iterator(); it.hasNext(); ) { |
| final FileTypeTable.Item item= (FileTypeTable.Item)it.next(); |
| item.mode= item.mode == Team.TEXT ? Team.BINARY : Team.TEXT; |
| fTable.getViewer().refresh(item); |
| } |
| } |
| |
| /** |
| * The table viewer selection has changed. Update the remove and change button enablement. |
| */ |
| void handleSelection() { |
| final boolean empty = fTable.getSelection().isEmpty(); |
| FileTypeTable.Item selectedItem = (Item) fTable.getSelection().getFirstElement(); |
| |
| fRemoveButton.setEnabled(!empty && !selectedItem.contributed); |
| fChangeButton.setEnabled(!empty); |
| } |
| } |