blob: a32b1cc86c4a7e21b0eeca8493188e00442397df [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2008, 2019 Freescale Semiconductor 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:
* Serge Beauchamp (Freescale Semiconductor) - [252996] initial API and implementation
* IBM Corporation - ongoing implementation
* Lars Vogel <Lars.Vogel@gmail.com> - Bug 430694
* Mickael Istria (Red Hat Inc.) - Bug 486901
* - [Cleanup] Avoid useless string instances
* Alexander Fedorov <alexander.fedorov@arsysop.ru> - Bug 548799
*******************************************************************************/
package org.eclipse.ui.internal.ide.dialogs;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.StringReader;
import java.lang.reflect.Field;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.TreeMap;
import org.eclipse.core.internal.resources.FilterDescriptor;
import org.eclipse.core.resources.FileInfoMatcherDescription;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFilterMatcherDescriptor;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceFilterDescription;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.resources.filtermatchers.AbstractFileInfoMatcher;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.TrayDialog;
import org.eclipse.jface.fieldassist.TextContentAdapter;
import org.eclipse.jface.layout.TreeColumnLayout;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.resource.ResourceLocator;
import org.eclipse.jface.text.FindReplaceDocumentAdapterContentProposalProvider;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.CheckboxCellEditor;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.ComboBoxCellEditor;
import org.eclipse.jface.viewers.ICellModifier;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.StyledCellLabelProvider;
import org.eclipse.jface.viewers.StyledString;
import org.eclipse.jface.viewers.StyledString.Styler;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.jface.viewers.ViewerDropAdapter;
import org.eclipse.jface.window.Window;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.ByteArrayTransfer;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DragSourceEvent;
import org.eclipse.swt.dnd.DragSourceListener;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.dnd.TransferData;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.FontMetrics;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.TextStyle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.DateTime;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.swt.widgets.Widget;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.fieldassist.ContentAssistCommandAdapter;
import org.eclipse.ui.ide.dialogs.UIResourceFilterDescription;
import org.eclipse.ui.internal.ide.IDEWorkbenchMessages;
import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
import org.eclipse.ui.internal.ide.IIDEHelpContextIds;
import org.eclipse.ui.internal.ide.misc.FileInfoAttributesMatcher;
import org.eclipse.ui.internal.ide.misc.StringFileInfoMatcher;
/**
* A widget group that displays resource filters. Includes buttons to edit,
* remove existing filters and create new ones.
*/
public class ResourceFilterGroup {
private Button addButton;
private Button addGroupButton;
private Button removeButton;
private Button upButton;
private Button downButton;
private Button editButton;
private TreeViewer filterView;
private TreeContentProvider filterViewContentProvider;
private Filters filters;
private UIResourceFilterDescription[] initialFilters = new UIResourceFilterDescription[0];
private LabelProvider labelProvider;
private Font boldFont;
private Font plainFont;
private Image fileIcon;
private Image folderIcon;
private Image fileFolderIcon;
private Image includeIcon;
private Image excludeIcon;
private Image inheritableIcon;
private boolean tableViewCellEditorAdequatlyUsable;
private Shell shell;
private IContainer nonExistantResource = getNonExistantResource();
private IContainer resource = nonExistantResource;
/**
*
*/
public ResourceFilterGroup() {
ResourceLocator.imageDescriptorFromBundle(IDEWorkbenchPlugin.IDE_WORKBENCH,
"$nl$/icons/full/obj16/fileType_filter.png").ifPresent(d -> fileIcon = d.createImage()); //$NON-NLS-1$
ResourceLocator.imageDescriptorFromBundle(IDEWorkbenchPlugin.IDE_WORKBENCH,
"$nl$/icons/full/obj16/folderType_filter.png").ifPresent(d -> folderIcon = d.createImage()); //$NON-NLS-1$
ResourceLocator
.imageDescriptorFromBundle(IDEWorkbenchPlugin.IDE_WORKBENCH,
"$nl$/icons/full/obj16/fileFolderType_filter.png") //$NON-NLS-1$
.ifPresent(d -> fileFolderIcon = d.createImage());
ResourceLocator.imageDescriptorFromBundle(IDEWorkbenchPlugin.IDE_WORKBENCH,
"$nl$/icons/full/obj16/includeMode_filter.png").ifPresent(d -> includeIcon = d.createImage()); //$NON-NLS-1$
ResourceLocator.imageDescriptorFromBundle(IDEWorkbenchPlugin.IDE_WORKBENCH,
"$nl$/icons/full/obj16/excludeMode_filter.png").ifPresent(d -> excludeIcon = d.createImage()); //$NON-NLS-1$
ResourceLocator.imageDescriptorFromBundle(IDEWorkbenchPlugin.IDE_WORKBENCH,
"$nl$/icons/full/obj16/inheritable_filter.png").ifPresent(d -> inheritableIcon = d.createImage()); //$NON-NLS-1$
}
Image getImage(String string, int i) {
if (string.equals(FilterTypeUtil.MODE))
return new Image[] { includeIcon, excludeIcon, inheritableIcon }[i];
if (string.equals(FilterTypeUtil.TARGET))
return new Image[] { fileIcon, folderIcon, fileFolderIcon }[i];
return null;
}
/**
* Set the IContainer resource to edit
*
* @param res
* the container resource
*/
public void setContainer(IContainer res) {
resource = res;
}
private IContainer getNonExistantResource() {
String projectName = "nonExistantProject_"; //$NON-NLS-1$
IProject p = ResourcesPlugin.getWorkspace().getRoot().getProject(
projectName);
int iteration = 0;
while (p.exists()) {
p = ResourcesPlugin.getWorkspace().getRoot().getProject(
projectName + iteration);
iteration++;
}
return p;
}
class Filters extends FilterCopy {
public Filters(IContainer resource) {
try {
children = new LinkedList<>();
for (IResourceFilterDescription filter : resource.getFilters()) {
FilterCopy copy = new FilterCopy(UIResourceFilterDescription.wrap(filter));
copy = convertLegacyMatchers(copy);
addChild(copy);
}
} catch (CoreException e) {
ErrorDialog.openError(shell, NLS.bind(
IDEWorkbenchMessages.InternalError, null), e
.getLocalizedMessage(), e.getStatus());
}
}
public Filters(IResourceFilterDescription filters[]) {
children = new LinkedList<>();
if (filters != null) {
for (IResourceFilterDescription filter : filters)
addChild(new FilterCopy(UIResourceFilterDescription.wrap(filter)));
}
}
public Filters(UIResourceFilterDescription filters[]) {
children = new LinkedList<>();
if (filters != null) {
for (UIResourceFilterDescription filter : filters)
addChild(new FilterCopy(filter));
}
}
boolean changed = false;
public LinkedList<FilterCopy> trash = new LinkedList<>();
public void add(FilterCopy newFilter) {
super.addChild(newFilter);
changed = true;
}
public void remove(FilterCopy filter) {
super.removeChild(filter);
if (filter.original != null)
trash.add(filter);
changed = true;
}
public void moveUp(UIResourceFilterDescription filter) {
FilterCopy[] content = getChildren();
for (int i = 1; i < content.length; i++) {
if (content[i] == filter) {
FilterCopy tmp = content[i - 1];
content[i - 1] = content[i];
content[i] = tmp;
}
}
children = new LinkedList<>(Arrays.asList(content));
changed = true;
}
public void moveDown(UIResourceFilterDescription filter) {
FilterCopy[] content = getChildren();
for (int i = 0; i < (content.length - 1); i++) {
if (content[i] == filter) {
FilterCopy tmp = content[i + 1];
content[i + 1] = content[i];
content[i] = tmp;
}
}
children = new LinkedList<>(Arrays.asList(content));
changed = true;
}
@Override
public int getChildrenLimit() {
return Integer.MAX_VALUE;
}
@Override
protected void argumentsChanged() {
changed = true;
}
@Override
public boolean hasChanged() {
if (changed)
return true;
Iterator<FilterCopy> it = children.iterator();
while (it.hasNext()) {
FilterCopy filter = it.next();
if (filter.hasChanged())
return true;
}
return false;
}
public boolean isFirst(FilterCopy o) {
if (children.size() > 0)
return children.getFirst().equals(o);
return false;
}
public boolean isLast(FilterCopy o) {
if (children.size() > 0)
return children.getLast().equals(o);
return false;
}
@Override
public void removeAll() {
if (children.size() > 0) {
super.removeAll();
changed = true;
}
}
}
static String includeOnlyGroup = "INCLUDE_ONLY_GROUP"; //$NON-NLS-1$
static String excludeAllGroup = "EXCLUDE_ALL_GROUP"; //$NON-NLS-1$
class TreeContentProvider implements ITreeContentProvider {
@Override
public Object[] getChildren(Object parentElement) {
if (parentElement == filters) {
if (filters.getChildren().length > 0)
return new Object[] {includeOnlyGroup, excludeAllGroup};
return new Object[0];
}
if (parentElement instanceof String) {
ArrayList<FilterCopy> list = new ArrayList<>();
int mask = parentElement.equals(includeOnlyGroup) ? IResourceFilterDescription.INCLUDE_ONLY:
IResourceFilterDescription.EXCLUDE_ALL;
for (FilterCopy filterCopy : filters.getChildren()) {
if ((filterCopy.getType() & mask) != 0)
list.add(filterCopy);
}
return list.toArray();
}
if (parentElement instanceof FilterCopy)
return ((FilterCopy) parentElement).getChildren();
return null;
}
@Override
public Object getParent(Object element) {
if (element instanceof String)
return filters;
if (element instanceof FilterCopy) {
FilterCopy filterCopy = (FilterCopy) element;
if (filterCopy.getParent() != null && filterCopy.getParent() != filters)
return filterCopy.getParent();
return ((filterCopy.getType() & IResourceFilterDescription.INCLUDE_ONLY) != 0) ? includeOnlyGroup: excludeAllGroup;
}
return null;
}
@Override
public boolean hasChildren(Object element) {
if (element instanceof FilterCopy || element instanceof String) {
Object[] children = getChildren(element);
return children != null && children.length > 0;
}
return false;
}
@Override
public Object[] getElements(Object inputElement) {
return getChildren(inputElement);
}
@Override
public void dispose() {
}
@Override
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
}
}
class LabelProvider extends StyledCellLabelProvider {
private final Styler fBoldStyler;
private final Styler fPlainStyler;
FilterTypeUtil util;
TreeMap<Object, ICustomFilterArgumentUI> customfilterArgumentMap = new TreeMap<>();
public LabelProvider() {
util = new FilterTypeUtil();
fBoldStyler= new Styler() {
@Override
public void applyStyles(TextStyle textStyle) {
textStyle.font= boldFont;
}
};
fPlainStyler= new Styler() {
@Override
public void applyStyles(TextStyle textStyle) {
textStyle.font= plainFont;
}
};
ICustomFilterArgumentUI ui = new MultiMatcherCustomFilterArgumentUI(null, null, null);
customfilterArgumentMap.put(ui.getID(), ui);
ui = new DefaultCustomFilterArgumentUI(null, null, null);
customfilterArgumentMap.put(ui.getID(), ui);
}
ICustomFilterArgumentUI getUI(String descriptorID) {
ICustomFilterArgumentUI result = customfilterArgumentMap.get(descriptorID);
if (result == null)
return result = customfilterArgumentMap.get(""); //default ui //$NON-NLS-1$
return result;
}
String getColumnID(int index) {
return (String) filterView.getColumnProperties()[index];
}
public boolean isPartialFilter(Object element) {
FilterCopy copy = (FilterCopy) element;
return copy.isUnderAGroupFilter();
}
@Override
public void update(ViewerCell cell) {
int columnIndex = cell.getColumnIndex();
String column = getColumnID(columnIndex);
FilterCopy filter = null;
Object element = cell.getElement();
if (element instanceof String) {
if (column.equals(FilterTypeUtil.MODE)) {
cell.setImage(getImage(FilterTypeUtil.MODE, element.equals(includeOnlyGroup) ? 0:1));
}
if (column.equals(FilterTypeUtil.MODE)) {
if (element.equals(includeOnlyGroup))
cell.setText(NLS
.bind(
IDEWorkbenchMessages.ResourceFilterPage_includeOnlyColumn,
null));
else
cell.setText(NLS
.bind(
IDEWorkbenchMessages.ResourceFilterPage_excludeAllColumn,
null));
}
}
else {
filter = (FilterCopy) element;
if (column.equals(FilterTypeUtil.MODE)) {
StyledString styledString = getStyleColumnText(filter);
if (!isPartialFilter(filter)) {
Object isInheritable = FilterTypeUtil.getValue(filter, FilterTypeUtil.INHERITABLE);
if (((Boolean)isInheritable).booleanValue())
styledString.append(" " + IDEWorkbenchMessages.ResourceFilterPage_recursive); //$NON-NLS-1$
}
cell.setText(styledString.toString());
cell.setStyleRanges(styledString.getStyleRanges());
if (!isPartialFilter(filter)) {
Image[] images = { fileIcon, folderIcon, fileFolderIcon };
Object index = FilterTypeUtil.getValue(filter, FilterTypeUtil.TARGET);
cell.setImage(images[((Integer) index).intValue()]);
}
}
}
super.update(cell);
}
private StyledString getStyleColumnText(FilterCopy filter) {
if ((filter.getChildrenLimit() > 0)) {
String whiteSpace = " "; //$NON-NLS-1$;
String expression = getFilterTypeName(filter);
boolean isUnaryOperator = filter.getId().equals("org.eclipse.ui.ide.notFilterMatcher"); //$NON-NLS-1$
StyledString buffer = new StyledString();
if (isUnaryOperator) {
buffer.append("NOT ", fBoldStyler); //$NON-NLS-1$
expression = "OR"; //$NON-NLS-1$
}
buffer.append("(", fBoldStyler); //$NON-NLS-1$
Object [] children = filterViewContentProvider.getChildren(filter);
for (int i = 0; i < children.length; i++) {
buffer.append(getStyleColumnText((FilterCopy) children[i]));
if ((i + 1) < children.length) {
buffer.append(whiteSpace, fPlainStyler);
buffer.append(expression, fBoldStyler);
buffer.append(whiteSpace, fPlainStyler);
}
}
if (children.length < 2 && !isUnaryOperator) {
if (children.length == 1)
buffer.append(whiteSpace, fPlainStyler);
buffer.append(expression, fBoldStyler);
}
buffer.append(")", fBoldStyler); //$NON-NLS-1$
return buffer;
}
ICustomFilterArgumentUI ui = getUI(filter.getId());
return ui.formatStyledText(filter, fPlainStyler, fBoldStyler);
}
@Override
protected void measure(Event event, Object element) {
super.measure(event, element);
}
private String getFilterTypeName(FilterCopy filter) {
IFilterMatcherDescriptor desc = FilterTypeUtil.getDescriptor(filter
.getId());
if (desc != null)
return desc.getName();
return ""; //$NON-NLS-1$
}
}
class CellModifier implements ICellModifier {
@Override
public boolean canModify(Object element, String property) {
FilterCopy filter = (FilterCopy) element;
if (property.equals(FilterTypeUtil.ARGUMENTS)
&& !filter.hasStringArguments())
return false;
return true;
}
@Override
public Object getValue(Object element, String property) {
FilterCopy filter = (FilterCopy) element;
return FilterTypeUtil.getValue(filter, property);
}
@Override
public void modify(Object element, String property, Object value) {
FilterCopy filter = (FilterCopy) ((TableItem) element).getData();
FilterTypeUtil.setValue(filter, property, value);
filterView.refresh(filter);
}
}
/**
* Creates the widget group. Callers must call <code>dispose</code> when the
* group is no longer needed.
*
* @param parent
* the widget parent
* @return container of the widgets
*/
public Control createContents(Composite parent) {
Font font = parent.getFont();
shell = parent.getShell();
if (resource == null) {
Label label = new Label(parent, SWT.NONE);
label.setText(NLS.bind(
IDEWorkbenchMessages.ResourceFilterPage_noResource, null));
label.setFont(font);
return label;
}
if (resource == nonExistantResource)
filters = new Filters(initialFilters);
else
filters = new Filters(resource);
Composite composite = new Composite(parent, SWT.NONE);
GridLayout layout = new GridLayout();
layout.marginWidth = 0;
layout.marginHeight = 0;
layout.numColumns = 2;
composite.setLayout(layout);
GridData data = new GridData(GridData.FILL_BOTH);
data.grabExcessHorizontalSpace = true;
data.grabExcessVerticalSpace = true;
composite.setLayoutData(data);
composite.setFont(font);
Label label = new Label(composite, 0);
label.setText(NLS.bind(IDEWorkbenchMessages.ResourceFilterPage_title,
null));
data = new GridData(GridData.FILL);
data.horizontalSpan = 2;
label.setLayoutData(data);
label.setFont(font);
createViewerGroup(composite);
createButtonGroup(composite);
refreshEnablement();
return composite;
}
private void createViewerGroup(Composite parent) {
Composite tableComposite = new Composite(parent, SWT.NONE);
GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
data.grabExcessHorizontalSpace = true;
data.grabExcessVerticalSpace = true;
tableComposite.setLayoutData(data);
filterView = new TreeViewer(tableComposite, SWT.FULL_SELECTION | SWT.BORDER
| SWT.H_SCROLL);
data = new GridData(SWT.FILL, SWT.FILL, true, true);
data.grabExcessHorizontalSpace = true;
data.grabExcessVerticalSpace = true;
filterView.getTree().setLayoutData(data);
filterView.setColumnProperties(FilterTypeUtil.columnNames);
plainFont = filterView.getTree().getFont();
FontData[] boldFontData= getModifiedFontData(plainFont.getFontData(), SWT.BOLD);
boldFont = new Font(Display.getCurrent(), boldFontData);
filterView.setAutoExpandLevel(2);
filterViewContentProvider = new TreeContentProvider();
filterView.setContentProvider(filterViewContentProvider);
filterView.setInput(filters);
filterView.getTree().setFont(parent.getFont());
filterView.addSelectionChangedListener(event -> refreshEnablement());
TreeColumn modeColumn = new TreeColumn(filterView.getTree(), 0);
modeColumn
.setText(NLS
.bind(
IDEWorkbenchMessages.ResourceFilterPage_columnFilterDescription,
null));
modeColumn.setData(FilterTypeUtil.MODE);
modeColumn.setResizable(true);
modeColumn.setMoveable(false);
filterView.getTree().setHeaderVisible(false);
filterView.getTree().showColumn(filterView.getTree().getColumn(0));
labelProvider = new LabelProvider();
filterView.setLabelProvider(labelProvider);
CellEditor[] editors = new CellEditor[5];
editors[0] = new ComboBoxCellEditor(filterView.getTree(),
FilterTypeUtil.getFilterNames(false), SWT.READ_ONLY);
editors[1] = new ComboBoxCellEditor(filterView.getTree(),
FilterTypeUtil.getModes(), SWT.READ_ONLY);
editors[2] = new ComboBoxCellEditor(filterView.getTree(),
FilterTypeUtil.getTargets(), SWT.READ_ONLY);
editors[3] = new CheckboxCellEditor(filterView.getTree());
editors[4] = new TextCellEditor(filterView.getTree());
if (tableViewCellEditorAdequatlyUsable) {
filterView.setCellEditors(editors);
filterView.setCellModifier(new CellModifier());
}
filterView.getTree().addMouseListener(new MouseListener() {
@Override
public void mouseDoubleClick(MouseEvent e) {
if (!handleEdit()) {
ISelection selection = filterView.getSelection();
if (selection instanceof IStructuredSelection) {
if (((IStructuredSelection) selection).size() > 0) {
Object firstElement = ((IStructuredSelection) selection).getFirstElement();
filterView.setExpandedState(firstElement, !filterView.getExpandedState(firstElement));
}
}
}
}
@Override
public void mouseDown(MouseEvent e) {
}
@Override
public void mouseUp(MouseEvent e) {
}
});
FilterCopyDrag drag = new FilterCopyDrag();
int ops = DND.DROP_MOVE;
Transfer[] transfers = new Transfer[] { filterCopyTransfer };
filterView.addDragSupport(ops, transfers, drag);
filterView.addDropSupport(ops, transfers,
new FilterCopyDrop(filterView));
filterView.getTree().addMenuDetectListener(e -> {
MenuManager mgr = new MenuManager();
mgr.add(addSubFilterAction);
mgr.add(addSubGroupFilterAction);
mgr.add(new Separator());
mgr.add(new EditFilterAction());
mgr.add(new RemoveFilterAction());
filterView.getControl().setMenu(
mgr.createContextMenu(filterView.getControl()));
});
TreeColumnLayout layout = new TreeColumnLayout();
tableComposite.setLayout( layout );
layout.setColumnData( modeColumn, new ColumnWeightData(100));
filterView.setSelection(new StructuredSelection(includeOnlyGroup));
}
private static FontData[] getModifiedFontData(FontData[] originalData, int additionalStyle) {
FontData[] styleData = new FontData[originalData.length];
for (int i = 0; i < styleData.length; i++) {
FontData base = originalData[i];
styleData[i] = new FontData(base.getName(), base.getHeight(), base.getStyle() | additionalStyle);
}
return styleData;
}
class EditFilterAction extends Action {
public EditFilterAction() {
setText(NLS
.bind(IDEWorkbenchMessages.ResourceFilterPage_editFilterActionLabel,
null));
}
@Override
public void run() {
handleEdit();
}
@Override
public boolean isEnabled() {
ISelection selection = filterView.getSelection();
if (selection instanceof IStructuredSelection) {
if (((IStructuredSelection) selection).size() > 0) {
Object firstElement = ((IStructuredSelection) selection)
.getFirstElement();
return firstElement instanceof FilterCopy;
}
}
return false;
}
}
class RemoveFilterAction extends Action {
public RemoveFilterAction() {
setText(NLS
.bind(IDEWorkbenchMessages.ResourceFilterPage_removeFilterActionLabel,
null));
}
@Override
public void run() {
handleRemove();
}
@Override
public boolean isEnabled() {
ISelection selection = filterView.getSelection();
if (selection instanceof IStructuredSelection) {
return ((IStructuredSelection) selection).size() > 0; }
return false;
}
}
Action addSubFilterAction = new AddSubFilterAction(false);
class AddSubFilterAction extends Action {
boolean createGroupOnly;
public AddSubFilterAction(boolean createGroupOnly) {
this.createGroupOnly = createGroupOnly;
setText(NLS
.bind(createGroupOnly ?
IDEWorkbenchMessages.ResourceFilterPage_addSubFilterGroupActionLabel:
IDEWorkbenchMessages.ResourceFilterPage_addSubFilterActionLabel,
null));
}
@Override
public void run() {
ISelection selection = filterView.getSelection();
if (selection instanceof IStructuredSelection) {
Object firstElement = ((IStructuredSelection) selection)
.getFirstElement();
handleAdd(firstElement, createGroupOnly);
}
}
@Override
public boolean isEnabled() {
ISelection selection = filterView.getSelection();
if (selection instanceof IStructuredSelection) {
Object firstElement = ((IStructuredSelection) selection)
.getFirstElement();
return isAddEnabled(firstElement);
}
return false;
}
}
private void handleAdd(boolean createGroupOnly) {
Object selectedObject = null;
ISelection selection = filterView.getSelection();
if (selection instanceof IStructuredSelection) {
IStructuredSelection structuredSelection = ((IStructuredSelection) selection);
selectedObject = structuredSelection.getFirstElement();
}
handleAdd(selectedObject, createGroupOnly);
}
private void handleAdd(Object selection, boolean createGroupOnly) {
if (selection == null) {
FilterCopy newFilter = new FilterCopy();
FilterEditDialog dialog = new FilterEditDialog(resource, ResourceFilterGroup.this, shell,
newFilter, createGroupOnly, true);
if (dialog.open() == Window.OK) {
addToTopLevelFilters(newFilter);
refreshAndSelect(newFilter);
}
}
else if (selection instanceof FilterCopy) {
FilterCopy filter = (FilterCopy) selection;
if (filter.getChildrenLimit() > 0) {
FilterCopy newFilter = new FilterCopy();
newFilter.setParent(filter);
FilterTypeUtil.setValue(newFilter, FilterTypeUtil.MODE, FilterTypeUtil.getValue(filter, FilterTypeUtil.MODE));
FilterEditDialog dialog = new FilterEditDialog(resource, ResourceFilterGroup.this, shell,
newFilter, createGroupOnly, true);
if (dialog.open() == Window.OK) {
filter.addChild(newFilter);
refreshAndSelect(newFilter);
}
}
else {
FilterCopy newFilter = new FilterCopy();
FilterEditDialog dialog = new FilterEditDialog(resource, ResourceFilterGroup.this, shell,
newFilter, createGroupOnly, true);
if (dialog.open() == Window.OK) {
addToTopLevelFilters(newFilter);
refreshAndSelect(newFilter);
}
}
}
else if (selection instanceof String) {
FilterCopy newFilter = new FilterCopy();
FilterTypeUtil.setValue(newFilter, FilterTypeUtil.MODE, selection.equals(includeOnlyGroup) ? 0 : 1);
FilterEditDialog dialog = new FilterEditDialog(resource, ResourceFilterGroup.this, shell,
newFilter, createGroupOnly, true);
if (dialog.open() == Window.OK) {
addToTopLevelFilters(newFilter);
refreshAndSelect(newFilter);
}
}
}
private void refreshAndSelect(FilterCopy newFilter) {
filterView.refresh();
filterView.reveal(newFilter);
}
private boolean isAddEnabled(Object selection) {
if (selection == null)
return true;
if (selection instanceof FilterCopy) {
FilterCopy filter = (FilterCopy) selection;
return filter.getChildrenLimit() > 0;
}
if (selection instanceof String)
return true;
return false;
}
private void addToTopLevelFilters(FilterCopy newFilter) {
int value = ((Integer) FilterTypeUtil.getValue(newFilter, FilterTypeUtil.MODE)).intValue();
Object[] existingChildren = filterViewContentProvider.getChildren(value == 0? includeOnlyGroup:excludeAllGroup);
filters.add(newFilter);
filterView.refresh();
if (existingChildren.length == 0)
filterView.setExpandedState(newFilter, true);
}
Action addSubGroupFilterAction = new AddSubFilterAction(true);
class FilterCopyDrop extends ViewerDropAdapter {
protected FilterCopyDrop(Viewer viewer) {
super(viewer);
}
@Override
public boolean performDrop(Object data) {
Object target = getCurrentTarget();
if (target == null)
target = filters;
FilterCopy[] toDrop = (FilterCopy[]) data;
if (target instanceof FilterCopy) {
for (FilterCopy filterToDrop : toDrop)
if (filterToDrop.equals(target)
|| ((FilterCopy) target).hasParent(filterToDrop))
return false;
}
for (FilterCopy filterToDrop : toDrop) {
if (target instanceof Filters)
filters.add(filterToDrop);
if (target instanceof String) {
FilterTypeUtil.setValue(filterToDrop, FilterTypeUtil.MODE, target.equals(includeOnlyGroup) ? 0 : 1);
addToTopLevelFilters(filterToDrop);
}
if (target instanceof FilterCopy)
((FilterCopy) target).addChild(filterToDrop);
filterView.refresh();
filterView.reveal(filterToDrop);
}
return true;
}
@Override
public boolean validateDrop(Object target, int operation,
TransferData transferType) {
if (filterCopyTransfer.isSupportedType(transferType)) {
if (target instanceof FilterCopy)
return ((FilterCopy) target).canAcceptDrop();
return true;
}
return false;
}
}
class FilterCopyDrag implements DragSourceListener {
@Override
public void dragFinished(DragSourceEvent event) {
if (event.detail == DND.DROP_MOVE) {
// nothing
}
}
@Override
public void dragSetData(DragSourceEvent event) {
if (filterCopyTransfer.isSupportedType(event.dataType)) {
event.data = getFilterCopySelection();
}
}
@Override
public void dragStart(DragSourceEvent event) {
if (getFilterCopySelection().length == 0)
event.doit = false;
}
}
private void createButtonGroup(Composite parent) {
Composite composite = new Composite(parent, SWT.NONE);
GridLayout layout = new GridLayout();
layout.marginWidth = 0;
layout.marginHeight = 0;
layout.numColumns = 1;
composite.setLayout(layout);
GridData data = new GridData(SWT.FILL, SWT.FILL, false, false);
composite.setLayoutData(data);
composite.setFont(parent.getFont());
addButton = new Button(composite, SWT.PUSH);
addButton.setText(NLS.bind(
IDEWorkbenchMessages.ResourceFilterPage_addButtonLabel, null));
data = new GridData(SWT.FILL, SWT.FILL, false, false);
addButton.setLayoutData(data);
setButtonDimensionHint(addButton);
addButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
handleAdd(false);
}
});
addGroupButton = new Button(composite, SWT.PUSH);
addGroupButton.setText(NLS.bind(
IDEWorkbenchMessages.ResourceFilterPage_addGroupButtonLabel, null));
data = new GridData(SWT.FILL, SWT.FILL, false, false);
addGroupButton.setLayoutData(data);
setButtonDimensionHint(addGroupButton);
addGroupButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
handleAdd(true);
}
});
editButton = new Button(composite, SWT.PUSH);
editButton.setText(NLS.bind(
IDEWorkbenchMessages.ResourceFilterPage_editButtonLabel, null));
data = new GridData(SWT.FILL, SWT.FILL, false, false);
editButton.setLayoutData(data);
setButtonDimensionHint(editButton);
editButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
handleEdit();
}
});
removeButton = new Button(composite, SWT.PUSH);
removeButton
.setText(NLS
.bind(
IDEWorkbenchMessages.ResourceFilterPage_removeButtonLabel,
null));
data = new GridData(SWT.FILL, SWT.FILL, false, false);
removeButton.setLayoutData(data);
setButtonDimensionHint(removeButton);
removeButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
handleRemove();
}
});
}
private void refreshEnablement() {
if (addButton != null) {
ISelection selection = filterView.getSelection();
IStructuredSelection structuredSelection = null;
if (selection instanceof IStructuredSelection)
structuredSelection = ((IStructuredSelection) selection);
removeButton.setEnabled(structuredSelection != null
&& structuredSelection.size() > 0 && !(structuredSelection.getFirstElement() instanceof String));
editButton.setEnabled(structuredSelection != null
&& structuredSelection.size() == 1
&& (structuredSelection.getFirstElement() instanceof FilterCopy));
if (upButton != null)
upButton.setEnabled(structuredSelection != null
&& (structuredSelection.size() > 0)
&& !isFirst(structuredSelection.getFirstElement()));
if (downButton != null)
downButton.setEnabled(structuredSelection != null
&& (structuredSelection.size() > 0)
&& !isLast(structuredSelection.getFirstElement()));
}
}
private boolean isFirst(Object o) {
return filters.isFirst((FilterCopy) o);
}
private boolean isLast(Object o) {
return filters.isLast((FilterCopy) o);
}
private boolean handleEdit() {
ISelection selection = filterView.getSelection();
if (selection instanceof IStructuredSelection) {
Object firstElement = ((IStructuredSelection) selection)
.getFirstElement();
if (firstElement instanceof String) {
handleAdd(firstElement, false);
return true;
}
if (firstElement instanceof FilterCopy) {
FilterCopy filter = (FilterCopy) firstElement;
FilterCopy copy = new FilterCopy(filter);
copy.setParent(filter.getParent());
boolean isGroup = filter.getChildrenLimit() > 0;
FilterEditDialog dialog = new FilterEditDialog(resource, this, shell, copy, isGroup, false);
if (dialog.open() == Window.OK) {
if (copy.hasChanged()) {
filter.copy(copy);
filterView.refresh();
}
}
return true;
}
}
return false;
}
private FilterCopy[] getFilterCopySelection() {
ISelection selection = filterView.getSelection();
IStructuredSelection structuredSelection = null;
if (selection instanceof IStructuredSelection) {
structuredSelection = ((IStructuredSelection) selection);
FilterCopy[] tmp = new FilterCopy[structuredSelection.size()];
System.arraycopy(structuredSelection.toArray(), 0, tmp, 0,
tmp.length);
return tmp;
}
return new FilterCopy[0];
}
private void handleRemove() {
ISelection selection = filterView.getSelection();
if (selection instanceof IStructuredSelection) {
for (Object element : (IStructuredSelection) selection) {
if (element instanceof FilterCopy) {
FilterCopy filter = (FilterCopy) element;
filter.getParent().removeChild(filter);
}
else {
int mask = element.equals(includeOnlyGroup) ? IResourceFilterDescription.INCLUDE_ONLY:
IResourceFilterDescription.EXCLUDE_ALL;
for (FilterCopy filterCopy : filters.getChildren()) {
if ((filterCopy.getType() & mask) != 0)
filters.removeChild(filterCopy);
}
}
}
filterView.refresh();
}
}
private static void setButtonDimensionHint(Button button) {
Assert.isNotNull(button);
Object gd = button.getLayoutData();
if (gd instanceof GridData) {
((GridData) gd).widthHint = getButtonWidthHint(button);
((GridData) gd).horizontalAlignment = GridData.FILL;
}
}
private static int getButtonWidthHint(Button button) {
button.setFont(JFaceResources.getDialogFont());
FontMetrics fontMetrics;
GC gc = new GC(button);
try {
gc.setFont(button.getFont());
fontMetrics = gc.getFontMetrics();
} finally {
gc.dispose();
}
int widthHint = Dialog.convertHorizontalDLUsToPixels(fontMetrics,
IDialogConstants.BUTTON_WIDTH);
return Math.max(widthHint, button.computeSize(SWT.DEFAULT, SWT.DEFAULT,
true).x);
}
/**
* Apply the default state of the resource.
*/
public void performDefaults() {
if (resource == null)
return;
filters = new Filters(resource);
filters.removeAll();
filterView.setInput(filters);
filterView.refresh();
}
/**
* @return the filters that were configured on this resource
*/
public UIResourceFilterDescription[] getFilters() {
FilterCopy[] newFilters = filters.getChildren();
UIResourceFilterDescription[] result = new UIResourceFilterDescription[newFilters.length];
System.arraycopy(newFilters, 0, result, 0, newFilters.length);
return result;
}
/**
* @param filters
*/
public void setFilters(IResourceFilterDescription[] filters) {
initialFilters = new UIResourceFilterDescription[filters.length];
for (int i = 0; i < filters.length; i++)
initialFilters[i] = UIResourceFilterDescription.wrap(filters[i]);
}
/**
* @param filters
*/
public void setFilters(UIResourceFilterDescription[] filters) {
initialFilters = filters;
}
/**
* Apply the read only state and the encoding to the resource.
*
* @return true if the filters changed
*/
public boolean performOk() {
if (filters.hasChanged()) {
if (resource == null)
return true;
try {
if (resource != nonExistantResource) {
IResourceFilterDescription[] oldFilters = resource.getFilters();
for (IResourceFilterDescription oldFilter : oldFilters) {
oldFilter.delete(IResource.BACKGROUND_REFRESH,
new NullProgressMonitor());
}
FilterCopy[] newFilters = filters.getChildren();
for (FilterCopy newFilter : newFilters) {
resource.createFilter(newFilter.getType(),
newFilter.getFileInfoMatcherDescription(),
IResource.BACKGROUND_REFRESH,
new NullProgressMonitor());
}
}
} catch (CoreException e) {
ErrorDialog.openError(shell, NLS.bind(
IDEWorkbenchMessages.InternalError, null), e
.getLocalizedMessage(), e.getStatus());
}
}
return true;
}
/**
* Disposes the group's resources.
*/
public void dispose() {
disposeIcons();
if (boldFont != null) {
boldFont.dispose();
}
}
private void disposeIcons() {
Field[] fields = getClass().getDeclaredFields();
for (Field field : fields) {
Class<?> cls = field.getType();
if (cls.equals(Image.class)) {
Image img;
try {
img = (Image) field.get(this);
if (img != null) {
img.dispose();
field.set(this, null);
}
} catch (IllegalArgumentException | IllegalAccessException e) {
IDEWorkbenchPlugin.log(e.getMessage(), e);
}
}
}
}
private FilterCopyTransfer filterCopyTransfer = new FilterCopyTransfer();
class FilterCopyTransfer extends ByteArrayTransfer {
private FilterCopyTransfer() {
}
@Override
public void javaToNative(Object object, TransferData transferData) {
if (object == null || !(object instanceof FilterCopy[]))
return;
if (isSupportedType(transferData)) {
FilterCopy[] myTypes = (FilterCopy[]) object;
try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buffer;
try (DataOutputStream writeOut = new DataOutputStream(out)) {
writeOut.writeInt(myTypes.length);
for (FilterCopy myType : myTypes)
writeOut.writeInt(myType.getSerialNumber());
buffer = out.toByteArray();
}
super.javaToNative(buffer, transferData);
} catch (IOException e) {
}
}
}
@Override
public Object nativeToJava(TransferData transferData) {
if (isSupportedType(transferData)) {
byte[] buffer = (byte[]) super.nativeToJava(transferData);
if (buffer == null)
return null;
FilterCopy[] myData;
try {
ByteArrayInputStream in = new ByteArrayInputStream(buffer);
try (DataInputStream readIn = new DataInputStream(in)) {
int size = readIn.readInt();
LinkedList<FilterCopy> droppedFilters = new LinkedList<>();
for (int i = 0; i < size; i++) {
int serialNumber = readIn.readInt();
FilterCopy tmp = filters
.findBySerialNumber(serialNumber);
if (tmp != null)
droppedFilters.add(tmp);
}
myData = droppedFilters
.toArray(new FilterCopy[0]);
}
} catch (IOException ex) {
return null;
}
return myData;
}
return null;
}
private final String MYTYPENAME = "org.eclipse.ui.ide.internal.filterCopy"; //$NON-NLS-1$
private final int MYTYPEID = registerType(MYTYPENAME);
@Override
protected String[] getTypeNames() {
return new String[] { MYTYPENAME };
}
@Override
protected int[] getTypeIds() {
return new int[] { MYTYPEID };
}
}
}
class FilterTypeUtil {
static String ID = "id"; //$NON-NLS-1$
static String TARGET = "target"; //$NON-NLS-1$
static String MODE = "mode"; //$NON-NLS-1$
static String ARGUMENTS = "arguments"; //$NON-NLS-1$
static String INHERITABLE = "inheritable"; //$NON-NLS-1$
static String[] columnNames = new String[] { MODE, TARGET, INHERITABLE };
static String[] getModes() {
return new String[] {
NLS.bind(IDEWorkbenchMessages.ResourceFilterPage_includeOnly,
null),
NLS.bind(IDEWorkbenchMessages.ResourceFilterPage_excludeAll,
null) };
}
public static void setValue(FilterCopy filter, String property, Object value) {
if (property.equals(FilterTypeUtil.ID)) {
IFilterMatcherDescriptor descriptor;
if (value instanceof Integer) {
int selection = ((Integer) value).intValue();
descriptor = FilterTypeUtil.getDescriptorFromIndex(selection);
} else
descriptor = FilterTypeUtil.getDescriptorByName((String) value);
if (descriptor != null)
filter.setId(descriptor.getId());
}
if (property.equals(FilterTypeUtil.MODE)) {
int selection = ((Integer) value).intValue();
int type = filter.getType()
& ~(IResourceFilterDescription.INCLUDE_ONLY | IResourceFilterDescription.EXCLUDE_ALL);
if (selection == 0)
filter.setType(type | IResourceFilterDescription.INCLUDE_ONLY);
else
filter.setType(type | IResourceFilterDescription.EXCLUDE_ALL);
}
if (property.equals(FilterTypeUtil.TARGET)) {
int selection = ((Integer) value).intValue();
int type = filter.getType()
& ~(IResourceFilterDescription.FILES | IResourceFilterDescription.FOLDERS);
if (selection == 0)
filter.setType(type | IResourceFilterDescription.FILES);
if (selection == 1)
filter.setType(type | IResourceFilterDescription.FOLDERS);
if (selection == 2)
filter.setType(type | IResourceFilterDescription.FILES
| IResourceFilterDescription.FOLDERS);
}
if (property.equals(FilterTypeUtil.INHERITABLE)) {
int type = filter.getType() & ~IResourceFilterDescription.INHERITABLE;
if (((Boolean) value).booleanValue())
filter.setType(type | IResourceFilterDescription.INHERITABLE);
else
filter.setType(type);
}
if (property.equals(FilterTypeUtil.ARGUMENTS)) {
filter.setArguments(value.equals("") ? null : value); //$NON-NLS-1$
}
}
static IFilterMatcherDescriptor getDescriptor(String id) {
IFilterMatcherDescriptor[] descriptors = ResourcesPlugin.getWorkspace()
.getFilterMatcherDescriptors();
for (IFilterMatcherDescriptor descriptor : descriptors) {
if (descriptor.getId().equals(id))
return descriptor;
}
return null;
}
static int getDescriptorIndex(String id) {
IFilterMatcherDescriptor descriptors[] = ResourcesPlugin.getWorkspace()
.getFilterMatcherDescriptors();
for (int i = 0; i < descriptors.length; i++) {
if (descriptors[i].getId().equals(id))
return i;
}
return -1;
}
static Object getValue(UIResourceFilterDescription filter, String property) {
if (property.equals(ID)) {
String id = filter.getFileInfoMatcherDescription().getId();
return getDescriptorIndex(id);
}
if (property.equals(MODE)) {
if ((filter.getType() & IResourceFilterDescription.INCLUDE_ONLY) != 0)
return 0;
return 1;
}
if (property.equals(TARGET)) {
boolean includeFiles = (filter.getType() & IResourceFilterDescription.FILES) != 0;
boolean includeFolders = (filter.getType() & IResourceFilterDescription.FOLDERS) != 0;
if (includeFiles && includeFolders)
return 2;
if (includeFiles)
return 0;
if (includeFolders)
return 1;
}
if (property.equals(INHERITABLE))
return Boolean.valueOf(
(filter.getType() & IResourceFilterDescription.INHERITABLE) != 0);
if (property.equals(ARGUMENTS))
return filter.getFileInfoMatcherDescription().getArguments() != null ? filter.getFileInfoMatcherDescription().getArguments() : ""; //$NON-NLS-1$
return null;
}
static String[] getTargets() {
return new String[] {
NLS.bind(IDEWorkbenchMessages.ResourceFilterPage_files, null),
NLS.bind(IDEWorkbenchMessages.ResourceFilterPage_folders, null),
NLS
.bind(
IDEWorkbenchMessages.ResourceFilterPage_filesAndFolders,
null) };
}
static String[] getFilterNames(boolean groupOnly) {
IFilterMatcherDescriptor[] descriptors = ResourcesPlugin.getWorkspace()
.getFilterMatcherDescriptors();
sortDescriptors(descriptors);
LinkedList<String> names = new LinkedList<>();
for (IFilterMatcherDescriptor descriptor : descriptors) {
// remove legacy filters
if (descriptor.getId().equals(DefaultCustomFilterArgumentUI.REGEX_FILTER_ID))
continue;
if (descriptor.getId().equals(StringFileInfoMatcher.ID))
continue;
boolean isGroup = descriptor.getArgumentType().equals(
IFilterMatcherDescriptor.ARGUMENT_TYPE_FILTER_MATCHER)
|| descriptor.getArgumentType().equals(
IFilterMatcherDescriptor.ARGUMENT_TYPE_FILTER_MATCHERS);
if (isGroup == groupOnly)
names.add(descriptor.getName());
}
return names.toArray(new String[0]);
}
/**
* @param descriptors
*/
private static void sortDescriptors(IFilterMatcherDescriptor[] descriptors) {
Arrays.sort(descriptors, (arg0, arg1) -> {
if (arg0.getId().equals(FileInfoAttributesMatcher.ID))
return -1;
if (arg1.getId().equals(FileInfoAttributesMatcher.ID))
return 1;
return arg0.getId().compareTo(arg1.getId());
});
}
static String getDefaultFilterID() {
IFilterMatcherDescriptor descriptors[] = ResourcesPlugin.getWorkspace()
.getFilterMatcherDescriptors();
sortDescriptors(descriptors);
for (IFilterMatcherDescriptor descriptor : descriptors) {
if (descriptor.getArgumentType().equals(
IFilterMatcherDescriptor.ARGUMENT_TYPE_STRING))
return descriptor.getId();
}
return descriptors[0].getId();
}
static IFilterMatcherDescriptor getDescriptorFromIndex(int index) {
IFilterMatcherDescriptor descriptors[] = ResourcesPlugin.getWorkspace()
.getFilterMatcherDescriptors();
return descriptors[index];
}
static IFilterMatcherDescriptor getDescriptorByName(String name) {
IFilterMatcherDescriptor[] descriptors = ResourcesPlugin.getWorkspace()
.getFilterMatcherDescriptors();
for (IFilterMatcherDescriptor descriptor : descriptors) {
if (descriptor.getName().equals(name))
return descriptor;
}
return null;
}
FilterTypeUtil() {}
}
class FilterCopy extends UIResourceFilterDescription {
Object arguments = null;
String id = null;
IPath path = null;
IProject project = null;
int type = 0;
FilterCopy parent = null;
LinkedList<FilterCopy> children = null;
UIResourceFilterDescription original = null;
int serialNumber = ++lastSerialNumber;
static private int lastSerialNumber = 0;
public FilterCopy(UIResourceFilterDescription filter) {
internalCopy(filter);
original = filter;
}
protected FilterCopy convertLegacyMatchers(FilterCopy copy) {
if (copy.getId().equals(DefaultCustomFilterArgumentUI.REGEX_FILTER_ID) ||
copy.getId().equals(StringFileInfoMatcher.ID)) {
String pattern = (String) copy.getArguments();
FileInfoAttributesMatcher.Argument argument = new FileInfoAttributesMatcher.Argument();
argument.key = FileInfoAttributesMatcher.KEY_NAME;
argument.operator = FileInfoAttributesMatcher.OPERATOR_MATCHES;
argument.pattern = pattern;
argument.regularExpression = copy.getId().equals(DefaultCustomFilterArgumentUI.REGEX_FILTER_ID);
String encodedArgument = FileInfoAttributesMatcher.encodeArguments(argument);
FilterTypeUtil.setValue(copy, FilterTypeUtil.ID, FileInfoAttributesMatcher.ID);
FilterTypeUtil.setValue(copy, FilterTypeUtil.ARGUMENTS, encodedArgument);
}
return copy;
}
public void removeAll() {
initializeChildren();
Iterator<FilterCopy> it = children.iterator();
while (it.hasNext()) {
FilterCopy child = it.next();
if (child.parent == this)
child.parent = null;
}
children.clear();
serializeChildren();
}
public void setParent(FilterCopy parent) {
this.parent = parent;
}
public boolean canAcceptDrop() {
int limit = getChildrenLimit();
if (limit > 0) {
FilterCopy[] tmp = getChildren();
return (tmp == null) || (tmp.length < limit);
}
return false;
}
public boolean hasParent(FilterCopy filterCopy) {
FilterCopy filter = this;
do {
if (filter.equals(filterCopy))
return true;
filter = filter.getParent();
} while (filter != null);
return false;
}
public FilterCopy getParent() {
return parent;
}
public void copy(UIResourceFilterDescription filter) {
internalCopy(filter);
argumentsChanged();
}
private void internalCopy(UIResourceFilterDescription filter) {
children = null;
id = filter.getFileInfoMatcherDescription().getId();
path = filter.getPath();
project = filter.getProject();
type = filter.getType();
arguments = filter.getFileInfoMatcherDescription().getArguments();
if (arguments instanceof FileInfoMatcherDescription[]) {
FileInfoMatcherDescription[] descs = (FileInfoMatcherDescription[]) arguments;
FilterCopy [] tmp = new FilterCopy[descs.length];
for (int i = 0; i < tmp.length; i++)
tmp[i] = new FilterCopy(this, descs[i]);
arguments = tmp;
}
}
public boolean hasChanged() {
if (original != null) {
return !((arguments == null ? (original.getFileInfoMatcherDescription().getArguments() == null)
: arguments.equals(original.getFileInfoMatcherDescription().getArguments()))
&& id.equals(original.getFileInfoMatcherDescription().getId()) && type == original
.getType());
}
return true;
}
public FilterCopy() {
path = null;
project = null;
type = IResourceFilterDescription.FILES | IResourceFilterDescription.INCLUDE_ONLY;
id = FilterTypeUtil.getDefaultFilterID();
}
/**
* @param parent
* @param description
*/
public FilterCopy(FilterCopy parent, FileInfoMatcherDescription description) {
children = null;
id = description.getId();
path = parent.getPath();
project = parent.getProject();
type = parent.getType();
arguments = description.getArguments();
if (arguments instanceof FileInfoMatcherDescription[]) {
FileInfoMatcherDescription[] descs = (FileInfoMatcherDescription[]) arguments;
FilterCopy [] tmp = new FilterCopy[descs.length];
for (int i = 0; i < tmp.length; i++)
tmp[i] = new FilterCopy(parent, descs[i]);
arguments = tmp;
}
}
public Object getArguments() {
return arguments;
}
public String getId() {
return id;
}
@Override
public IPath getPath() {
return path;
}
@Override
public IProject getProject() {
return project;
}
@Override
public int getType() {
return type;
}
public void setArguments(Object arguments) {
this.arguments = arguments;
argumentsChanged();
}
public void setId(String id) {
this.id = id;
}
public void setPath(IPath path) {
this.path = path;
}
public void setProject(IProject project) {
this.project = project;
}
public void setType(int type) {
this.type = type;
}
public boolean hasStringArguments() {
IFilterMatcherDescriptor descriptor = FilterTypeUtil.getDescriptor(id);
if (descriptor != null)
return descriptor.getArgumentType().equals(
IFilterMatcherDescriptor.ARGUMENT_TYPE_STRING);
return false;
}
public int getChildrenLimit() {
IFilterMatcherDescriptor descriptor = FilterTypeUtil.getDescriptor(id);
if (descriptor != null) {
if (descriptor.getArgumentType().equals(
IFilterMatcherDescriptor.ARGUMENT_TYPE_FILTER_MATCHER))
return 1;
if (descriptor.getArgumentType().equals(
IFilterMatcherDescriptor.ARGUMENT_TYPE_FILTER_MATCHERS))
return Integer.MAX_VALUE;
}
return 0;
}
@Override
public boolean equals(Object o) {
if (!(o instanceof FilterCopy))
return false;
FilterCopy filter = (FilterCopy) o;
return serialNumber == filter.serialNumber;
}
public int getSerialNumber() {
return serialNumber;
}
public FilterCopy findBySerialNumber(int number) {
LinkedList<FilterCopy> pending = new LinkedList<>();
pending.add(this);
while (!pending.isEmpty()) {
FilterCopy filter = pending.getFirst();
pending.removeFirst();
if (filter.serialNumber == number)
return filter;
FilterCopy[] tmp = filter.getChildren();
if (tmp != null)
pending.addAll(Arrays.asList(tmp));
}
return null;
}
public FilterCopy[] getChildren() {
if (getChildrenLimit() > 0) {
initializeChildren();
return children.toArray(new FilterCopy[0]);
}
return null;
}
protected void initializeChildren() {
if (children == null) {
if (getChildrenLimit() > 0) {
children = new LinkedList<>();
Object arguments = getArguments();
if (arguments instanceof IResourceFilterDescription[]) {
IResourceFilterDescription[] filters = (IResourceFilterDescription[]) arguments;
for (IResourceFilterDescription filter : filters) {
FilterCopy child = new FilterCopy(UIResourceFilterDescription.wrap(filter));
child.parent = this;
children.add(child);
}
}
if (arguments instanceof FilterCopy[]) {
FilterCopy[] filters = (FilterCopy[]) arguments;
if (filters != null)
for (FilterCopy filter : filters) {
FilterCopy child = filter;
child.parent = this;
children.add(child);
}
}
}
}
}
protected void addChild(FilterCopy child) {
initializeChildren();
if (child.getParent() != null)
child.getParent().removeChild(child);
children.add(child);
child.parent = this;
serializeChildren();
}
protected void removeChild(FilterCopy child) {
initializeChildren();
children.remove(child);
if (child.parent == this)
child.parent = null;
serializeChildren();
}
protected void serializeChildren() {
initializeChildren();
argumentsChanged();
}
protected void argumentsChanged() {
initializeChildren();
if (children != null)
arguments = children.toArray(new FilterCopy[0]);
FilterCopy up = parent;
while (up != null) {
up.serializeChildren();
up = up.parent;
}
}
public boolean isUnderAGroupFilter() {
// a partial filter is a filter that is located under a group, but not
// the root group
if (parent != null) {
if ((parent.getChildrenLimit() > 0) && (parent.getParent() != null))
return true;
}
return false;
}
@Override
public FileInfoMatcherDescription getFileInfoMatcherDescription() {
Object arg = FilterCopy.this.getArguments();
if (arg instanceof FilterCopy []) {
FilterCopy [] filterCopies = (FilterCopy []) arg;
FileInfoMatcherDescription[] descriptions = new FileInfoMatcherDescription[filterCopies.length];
for (int i = 0; i < descriptions.length; i++)
descriptions[i] = filterCopies[i].getFileInfoMatcherDescription();
arg = descriptions;
}
return new FileInfoMatcherDescription(getId(), arg);
}
}
class FilterEditDialog extends TrayDialog {
private FilterCopy filter;
protected Button filesButton;
protected Button foldersButton;
protected Button filesAndFoldersButton;
protected Combo idCombo;
protected Composite idComposite;
protected Button includeButton;
protected Button excludeButton;
protected Composite argumentComposite;
protected Button inherited;
protected FilterTypeUtil util;
protected boolean createGroupOnly;
protected boolean creatingNewFilter;
protected ResourceFilterGroup filterGroup;
protected IResource resource;
TreeMap<Object, ICustomFilterArgumentUI> customfilterArgumentMap = new TreeMap<>();
ICustomFilterArgumentUI currentCustomFilterArgumentUI = new ICustomFilterArgumentUI() {
@Override
public Object getID() {return "dummy";} //$NON-NLS-1$
@Override
public void create(Composite argumentComposite, Font font) {}
@Override
public void dispose() {}
@Override
public void selectionChanged() {}
@Override
public String validate() {return null;}
@Override
public StyledString formatStyledText(FilterCopy filter,
Styler fPlainStyler, Styler fBoldStyler) {return null;}
};
/**
* Constructor for FilterEditDialog.
* @param resource
* @param filterGroup
* @param parentShell
* @param filter
* @param createGroupOnly
* @param creatingNewFilter
*/
public FilterEditDialog(IResource resource, ResourceFilterGroup filterGroup, Shell parentShell, FilterCopy filter, boolean createGroupOnly, boolean creatingNewFilter) {
super(parentShell);
this.resource = resource;
this.creatingNewFilter = creatingNewFilter;
this.filterGroup = filterGroup;
this.filter = filter;
this.createGroupOnly = createGroupOnly;
util = new FilterTypeUtil();
ICustomFilterArgumentUI ui = new MultiMatcherCustomFilterArgumentUI(this, parentShell, filter);
customfilterArgumentMap.put(ui.getID(), ui);
ui = new DefaultCustomFilterArgumentUI(this, parentShell, filter);
customfilterArgumentMap.put(ui.getID(), ui);
}
@Override
protected Control createDialogArea(Composite parent) {
GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
parent.setLayoutData(data);
Font font = parent.getFont();
Composite composite = new Composite(parent, SWT.NONE);
GridLayout layout = new GridLayout();
layout.numColumns = 1;
layout.marginHeight = 0;
layout.marginWidth = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
layout.verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING);
layout.horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
composite.setLayout(layout);
data = new GridData(SWT.FILL, SWT.FILL, true, true);
composite.setLayoutData(data);
composite.setFont(font);
Dialog.applyDialogFont(composite);
PlatformUI.getWorkbench().getHelpSystem().setHelp(getShell(),
IIDEHelpContextIds.EDIT_RESOURCE_FILTER_PROPERTY_PAGE);
if (!filter.isUnderAGroupFilter()) {
Composite topComposite = new Composite(composite, SWT.NONE);
layout = new GridLayout();
layout.numColumns = 1;
layout.marginHeight = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN);
layout.marginWidth = 0;
layout.marginBottom = 0;
layout.verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING);
layout.horizontalSpacing = 0; // convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
topComposite.setLayout(layout);
data = new GridData(SWT.FILL, SWT.FILL, true, false);
topComposite.setLayoutData(data);
topComposite.setFont(font);
createModeArea(font, topComposite);
createTargetArea(font, topComposite);
createIdArea(font, topComposite);
}
else {
layout.marginHeight = convertHorizontalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN);
createIdArea(font, composite);
}
return composite;
}
@Override
protected Control createButtonBar(Composite parent) {
Label label = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL);
label.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
Composite composite = new Composite(parent, SWT.NONE);
GridLayout layout = new GridLayout();
layout.marginWidth = 0;
layout.marginHeight = 0;
layout.horizontalSpacing = 0;
composite.setLayout(layout);
composite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
composite.setFont(parent.getFont());
// create help control if needed
if (isHelpAvailable()) {
Control helpControl = createHelpControl(composite);
((GridData) helpControl.getLayoutData()).horizontalIndent = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
}
Control buttonSection = dialogCreateButtonBar(composite);
((GridData) buttonSection.getLayoutData()).grabExcessHorizontalSpace = true;
return composite;
}
private Control dialogCreateButtonBar(Composite parent) {
Composite composite = new Composite(parent, SWT.NONE);
// create a layout with spacing and margins appropriate for the font
// size.
GridLayout layout = new GridLayout();
layout.numColumns = 0; // this is incremented by createButton
layout.makeColumnsEqualWidth = true;
layout.marginWidth = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
layout.marginHeight = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN);
layout.horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
layout.verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING);
composite.setLayout(layout);
GridData data = new GridData(GridData.HORIZONTAL_ALIGN_END
| GridData.VERTICAL_ALIGN_CENTER);
composite.setLayoutData(data);
composite.setFont(parent.getFont());
// Add the buttons to the button bar.
createButtonsForButtonBar(composite);
return composite;
}
/**
* @param font
* @param composite
*/
private void createInheritableArea(Font font, Composite composite) {
Composite inheritableComposite = createGroup(font, composite, NLS.bind(
IDEWorkbenchMessages.ResourceFilterPage_columnFilterMode,
null), false, false, 1);
GridLayout layout = (GridLayout) inheritableComposite.getLayout();
layout.marginBottom = 0;
layout.marginTop = 0;
layout.marginHeight = 0;
layout.marginWidth = 0;
layout.verticalSpacing = 0;
layout.marginLeft = 0;
inheritableComposite.setLayout(layout);
GridData data;
inherited = new Button(inheritableComposite, SWT.CHECK);
String label;
label = IDEWorkbenchMessages.ResourceFilterPage_applyRecursivelyToFolderStructure;
inherited
.setText(NLS
.bind(
label,
resource.getName()));
data = new GridData(SWT.FILL, SWT.CENTER, true, false);
data.horizontalSpan = 1;
inherited.setLayoutData(data);
inherited.setFont(font);
inherited.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
FilterTypeUtil.setValue(filter, FilterTypeUtil.INHERITABLE,
Boolean.valueOf(inherited.getSelection()));
}
});
inherited.setSelection((((Boolean) FilterTypeUtil.getValue(filter,
FilterTypeUtil.INHERITABLE)).booleanValue()));
}
private void createModeArea(Font font, Composite composite) {
GridData data;
Composite modeComposite = createGroup(font, composite, NLS.bind(
IDEWorkbenchMessages.ResourceFilterPage_columnFilterMode,
null), true, true, 1);
String[] modes = FilterTypeUtil.getModes();
includeButton = new Button(modeComposite, SWT.RADIO);
includeButton.setText(modes[0]);
data = new GridData(SWT.FILL, SWT.CENTER, true, false);
includeButton.setLayoutData(data);
includeButton.setFont(font);
includeButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
FilterTypeUtil.setValue(filter, FilterTypeUtil.MODE, 0);
}
});
includeButton.setSelection(((Integer) FilterTypeUtil.getValue(
filter, FilterTypeUtil.MODE)).intValue() == 0);
excludeButton = new Button(modeComposite, SWT.RADIO);
excludeButton.setText(modes[1]);
data = new GridData(SWT.FILL, SWT.CENTER, true, false);
excludeButton.setLayoutData(data);
excludeButton.setFont(font);
excludeButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
FilterTypeUtil.setValue(filter, FilterTypeUtil.MODE, 1);
}
});
excludeButton.setSelection(((Integer) FilterTypeUtil.getValue(
filter, FilterTypeUtil.MODE)).intValue() == 1);
}
private void createIdArea(Font font, Composite composite) {
if (createGroupOnly) {
idComposite = createGroup(font, composite, "", //$NON-NLS-1$
true, true, 1);
createMatcherCombo(idComposite, font);
GridData data = new GridData(SWT.FILL, SWT.CENTER, true, false);
idCombo.setLayoutData(data);
}
else {
String [] matchers = FilterTypeUtil.getFilterNames(createGroupOnly);
boolean hasMoreThanOneMatcher = matchers.length > 1;
if (hasMoreThanOneMatcher) {
createMatcherCombo(composite, font);
GridData data = new GridData(SWT.LEFT, SWT.CENTER, false, false);
idCombo.setLayoutData(data);
}
idComposite = createGroup(font, composite,
hasMoreThanOneMatcher ? IDEWorkbenchMessages.ResourceFilterPage_details: matchers[0],
true, true, 1);
GridLayout layout = (GridLayout) idComposite.getLayout();
layout.marginBottom = 0;
layout.marginTop = 0;
layout.marginWidth = 0;
layout.marginHeight = 0;
layout.verticalSpacing = 0;
idComposite.setLayout(layout);
}
argumentComposite = new Composite(idComposite, SWT.NONE);
setupPatternLine();
}
private void createMatcherCombo(Composite composite, Font font) {
GridData data;
idCombo = new Combo(composite, SWT.READ_ONLY);
idCombo.setItems(FilterTypeUtil.getFilterNames(createGroupOnly));
data = new GridData(SWT.LEFT, SWT.CENTER, true, false);
idCombo.setLayoutData(data);
idCombo.setFont(font);
idCombo.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
FilterTypeUtil.setValue(filter, FilterTypeUtil.ID, idCombo
.getItem(idCombo.getSelectionIndex()));
if (filter.hasStringArguments())
filter.setArguments(""); //$NON-NLS-1$
setupPatternLine();
currentCustomFilterArgumentUI.selectionChanged();
getShell().layout(true);
Point size = getShell().computeSize(SWT.DEFAULT, SWT.DEFAULT);
Point shellSize = getShell().getSize();
size.x = Math.max(size.x, shellSize.x);
size.y = Math.max(size.y, shellSize.y);
getShell().setSize(size);
getShell().redraw();
}
});
idCombo.select(0);
selectComboItem(filter.getId());
FilterTypeUtil.setValue(filter, FilterTypeUtil.ID, idCombo
.getItem(idCombo.getSelectionIndex()));
}
ICustomFilterArgumentUI getUI(String descriptorID) {
ICustomFilterArgumentUI result = customfilterArgumentMap.get(descriptorID);
if (result == null)
return result = customfilterArgumentMap.get(""); //default ui //$NON-NLS-1$
return result;
}
private void setupPatternLine() {
IFilterMatcherDescriptor descriptor;
if (createGroupOnly) {
String item = idCombo.getItem(idCombo.getSelectionIndex());
descriptor = FilterTypeUtil.getDescriptorByName(item);
}
else
descriptor = FilterTypeUtil.getDescriptor(filter.getId());
Font font = idComposite.getFont();
ICustomFilterArgumentUI customFilterArgumentUI = getUI(descriptor.getId());
if (!currentCustomFilterArgumentUI.getID().equals(customFilterArgumentUI.getID())) {
currentCustomFilterArgumentUI.dispose();
currentCustomFilterArgumentUI = customFilterArgumentUI;
currentCustomFilterArgumentUI.create(argumentComposite, font);
}
}
/**
*
*/
private void selectComboItem(String filterID) {
IFilterMatcherDescriptor descriptor = ResourcesPlugin.getWorkspace()
.getFilterMatcherDescriptor(filterID);
if (descriptor != null) {
String [] items = idCombo.getItems();
for (int i = 0; i < items.length; i++) {
if (items[i].equals(descriptor.getName())) {
idCombo.select(i);
break;
}
}
}
}
/**
* @param font
* @param composite
* @return the group
*/
private Composite createGroup(Font font, Composite composite, String text,
boolean grabExcessVerticalSpace, boolean group, int columnCounts) {
GridLayout layout;
GridData data;
Composite modeComposite;
if (group) {
Group modeGroup = new Group(composite, SWT.NONE);
modeGroup.setText(text);
modeComposite = modeGroup;
} else {
modeComposite = new Composite(composite, SWT.NONE);
}
layout = new GridLayout();
layout.verticalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
layout.marginLeft = 2;
layout.marginWidth = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
layout.numColumns = columnCounts;
modeComposite.setLayout(layout);
data = new GridData(SWT.FILL, SWT.FILL, true, grabExcessVerticalSpace);
modeComposite.setLayoutData(data);
modeComposite.setFont(font);
return modeComposite;
}
/**
* @param font
* @param composite
*/
private void createTargetArea(Font font, Composite composite) {
GridData data;
Composite targetComposite = createGroup(font, composite,
NLS.bind(IDEWorkbenchMessages.ResourceFilterPage_columnFilterTarget, null), false, true, 1);
String[] targets = FilterTypeUtil.getTargets();
filesButton = new Button(targetComposite, SWT.RADIO);
filesButton.setText(targets[0]);
data = new GridData(SWT.LEFT, SWT.CENTER, false, false);
filesButton.setLayoutData(data);
filesButton.setFont(font);
foldersButton = new Button(targetComposite, SWT.RADIO);
foldersButton.setText(targets[1]);
data = new GridData(SWT.LEFT, SWT.CENTER, false, false);
foldersButton.setLayoutData(data);
foldersButton.setFont(font);
filesAndFoldersButton = new Button(targetComposite, SWT.RADIO);
filesAndFoldersButton.setText(targets[2]);
data = new GridData(SWT.LEFT, SWT.CENTER, false, false);
filesAndFoldersButton.setLayoutData(data);
filesAndFoldersButton.setFont(font);
filesButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
FilterTypeUtil.setValue(filter, FilterTypeUtil.TARGET, 0);
}
});
foldersButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
FilterTypeUtil.setValue(filter, FilterTypeUtil.TARGET, 1);
}
});
filesAndFoldersButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
FilterTypeUtil.setValue(filter, FilterTypeUtil.TARGET, 2);
}
});
filesButton.setSelection(((Integer) FilterTypeUtil.getValue(filter,
FilterTypeUtil.TARGET)).intValue() == 0);
foldersButton.setSelection(((Integer) FilterTypeUtil.getValue(filter,
FilterTypeUtil.TARGET)).intValue() == 1);
filesAndFoldersButton.setSelection(((Integer) FilterTypeUtil.getValue(
filter, FilterTypeUtil.TARGET)).intValue() == 2);
createInheritableArea(font, targetComposite);
}
@Override
protected Control createContents(Composite parent) {
Control control = super.createContents(parent);
initialize();
update();
return control;
}
public void updateFinishControls() {
if (getButton(OK) != null) {
if (currentCustomFilterArgumentUI != null)
getButton(OK).setEnabled(currentCustomFilterArgumentUI.validate() == null);
else
getButton(OK).setEnabled(true);
}
}
@Override
protected boolean isResizable() {
return true;
}
@Override
protected void configureShell(Shell newShell) {
String title = null;
if (creatingNewFilter) {
if (resource.getType() == IResource.PROJECT)
title = NLS.bind(IDEWorkbenchMessages.ResourceFilterPage_newFilterDialogTitleProject, resource.getName());
else
title = NLS.bind(IDEWorkbenchMessages.ResourceFilterPage_newFilterDialogTitleFolder, resource.getName());
}
else
title = IDEWorkbenchMessages.ResourceFilterPage_editFilterDialogTitle;
newShell.setText(title);
super.configureShell(newShell);
}
private void initialize() {
}
protected void update() {
}
@Override
protected void okPressed() {
// see if the initialize causes an exception
if (filter.hasStringArguments()) {
IFilterMatcherDescriptor desc = resource.getWorkspace().getFilterMatcherDescriptor(filter.getId());
if (desc != null) {
try {
currentCustomFilterArgumentUI.validate();
AbstractFileInfoMatcher matcher = ((FilterDescriptor) desc).createFilter();
matcher.initialize(resource.getProject(), filter.getArguments());
} catch (CoreException e) {
IWorkbenchWindow window = PlatformUI.getWorkbench()
.getActiveWorkbenchWindow();
if (window != null) {
ErrorDialog.openError(window.getShell(), IDEWorkbenchMessages.ResourceFilterPage_editFilterDialogTitle,
e.getMessage(), e.getStatus());
}
return;
}
}
}
super.okPressed();
}
public int getVerticalDLUsToPixel(int flag) {
return convertVerticalDLUsToPixels(flag);
}
public IResource getResource() {
return resource;
}
public int getHorizontalDLUsToPixel(int flag) {
return convertHorizontalDLUsToPixels(flag);
}
}
interface ICustomFilterArgumentUI {
/**
* @return the descriptor ID
*/
Object getID();
/**
* @param filter
* @param fPlainStyler
* @param fBoldStyler
* @return the formatted StyledText
*/
StyledString formatStyledText(FilterCopy filter, Styler fPlainStyler,
Styler fBoldStyler);
/**
* @return null if there's no issue
*
*/
String validate();
/**
*
*/
void selectionChanged();
/**
* @param argumentComposite
* @param font
*/
void create(Composite argumentComposite, Font font);
/**
*
*/
void dispose();
}
class MultiMatcherCustomFilterArgumentUI implements ICustomFilterArgumentUI {
/**
* This is the minimum year that is accepted by {@link DateTime#setYear}.
*/
private static final int DateTime_MIN_YEAR = 1752;
Shell shell;
FilterCopy filter;
protected Button argumentsCaseSensitive;
protected Button argumentsRegularExpresion;
protected Text arguments;
protected DateTime argumentsDate;
protected Combo argumentsBoolean;
protected Label argumentsLabel;
protected Label description;
protected ContentAssistCommandAdapter fContentAssistField;
protected Combo multiKey;
protected Combo multiOperator;
protected Composite multiArgumentComposite;
protected Composite conditionComposite;
protected Composite descriptionComposite;
protected Composite stringArgumentComposite;
protected Composite stringTextArgumentComposite;
protected Composite attributeStringArgumentComposite;
protected Class<?> intiantiatedKeyOperatorType = null;
protected TreeMap<String, String> valueCache = new TreeMap<>();
protected boolean initializationComplete = false;
protected FilterEditDialog dialog;
protected Label dummyLabel1;
protected Label dummyLabel2;
protected static GregorianCalendar gregorianCalendar = new GregorianCalendar();
/**
* @param dialog
* @param parentShell
* @param filter
*/
public MultiMatcherCustomFilterArgumentUI(FilterEditDialog dialog, Shell parentShell,
FilterCopy filter) {
this.shell = parentShell;
this.dialog = dialog;
this.filter = filter;
}
@Override
public Object getID() {
return FileInfoAttributesMatcher.ID;
}
@Override
public void dispose() {
Widget list[] = new Widget[] {multiKey, multiOperator, multiArgumentComposite, stringArgumentComposite, stringTextArgumentComposite, arguments, argumentsLabel, argumentsCaseSensitive, argumentsRegularExpresion, attributeStringArgumentComposite, description, conditionComposite, descriptionComposite, dummyLabel1, dummyLabel2};
for (Widget widget : list) {
if (widget != null) {
widget.dispose();
}
}
multiKey = null;
multiOperator = null;
multiArgumentComposite = null;
arguments = null;
argumentsLabel = null;
fContentAssistField = null;
intiantiatedKeyOperatorType = null;
stringArgumentComposite = null;
stringTextArgumentComposite = null;
argumentsCaseSensitive = null;
argumentsRegularExpresion = null;
attributeStringArgumentComposite = null;
description = null;
conditionComposite = null;
descriptionComposite = null;
dummyLabel1 = null;
dummyLabel2 = null;
initializationComplete = false;
}
@Override
public void create(Composite argumentComposite, Font font) {
shell = argumentComposite.getShell();
GridLayout layout = new GridLayout();
layout.numColumns = 1;
layout.marginWidth = 0;
layout.marginHeight = 0;
layout.horizontalSpacing = 0;
layout.verticalSpacing = 0;
argumentComposite.setLayout(layout);
GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
argumentComposite.setLayoutData(data);
argumentComposite.setFont(font);
conditionComposite = new Composite(argumentComposite, SWT.NONE);
layout = new GridLayout();
layout.numColumns = 2;
layout.marginWidth = 0;
layout.marginHeight = 0;
layout.horizontalSpacing = 0;
conditionComposite.setLayout(layout);
conditionComposite.setFont(font);
data = new GridData(SWT.FILL, SWT.FILL, true, true);
conditionComposite.setLayoutData(data);
createCustomArgumentsArea(font, conditionComposite);
descriptionComposite = new Composite(argumentComposite, SWT.NONE);
layout = new GridLayout();
layout.numColumns = 1;
layout.marginWidth = dialog.getHorizontalDLUsToPixel(IDialogConstants.HORIZONTAL_MARGIN);
layout.marginHeight = dialog.getVerticalDLUsToPixel(IDialogConstants.VERTICAL_SPACING);
layout.horizontalSpacing = 0;
descriptionComposite.setLayout(layout);
descriptionComposite.setFont(font);
data = new GridData(SWT.FILL, SWT.FILL, true, true);
descriptionComposite.setLayoutData(data);
createDescriptionArea(font, descriptionComposite);
initializationComplete = true;
}
/**
* @param font
* @param composite
*/
private void createDescriptionArea(Font font, Composite composite) {
GridData data;
description = new Label(composite, SWT.LEFT | SWT.WRAP);
data = new GridData(SWT.FILL, SWT.BEGINNING, true, true);
data.horizontalSpan = 3;
description.setLayoutData(data);
description.setFont(font);
setupDescriptionText(null);
}
private void setupDescriptionText(String errorString) {
if (description != null) {
if (errorString != null) {
// take only the first line of the error string
BufferedReader reader = new BufferedReader(new StringReader(errorString));
try {
String tmp = reader.readLine();
if (tmp != null)
errorString = tmp;
} catch (IOException e) {
}
description.setForeground(shell.getDisplay().getSystemColor(SWT.COLOR_RED));
description.setText(errorString);
} else {
description.setForeground(shell.getDisplay().getSystemColor(SWT.COLOR_BLACK));
String selectedKey = MultiMatcherLocalization.getMultiMatcherKey(multiKey.getText());
String selectedOperator = MultiMatcherLocalization.getMultiMatcherKey(multiOperator.getText());
Class<?> selectedKeyOperatorType = FileInfoAttributesMatcher.getTypeForKey(selectedKey,
selectedOperator);
description.setText(""); //$NON-NLS-1$
if (selectedKeyOperatorType.equals(String.class)) {
if (!argumentsRegularExpresion.getSelection())
description.setText(NLS.bind(
IDEWorkbenchMessages.ResourceFilterPage_multiMatcher_Matcher, null));
}
if (selectedKeyOperatorType.equals(Integer.class)) {
if (selectedKey.equals(FileInfoAttributesMatcher.KEY_LAST_MODIFIED) || selectedKey.equals(FileInfoAttributesMatcher.KEY_CREATED))
description.setText(NLS.bind(
IDEWorkbenchMessages.ResourceFilterPage_multiMatcher_TimeInterval, null));
else
description.setText(NLS.bind(
IDEWorkbenchMessages.ResourceFilterPage_multiMatcher_FileLength, null));
}
}
shell.layout(true, true);
}
}
private void createCustomArgumentsArea(Font font, Composite composite) {
GridData data;
multiArgumentComposite = new Composite(composite, SWT.NONE);
GridLayout layout = new GridLayout();
layout.numColumns = 3;
layout.marginWidth = dialog.getHorizontalDLUsToPixel(IDialogConstants.HORIZONTAL_MARGIN);
layout.horizontalSpacing = dialog.getHorizontalDLUsToPixel(IDialogConstants.HORIZONTAL_SPACING);
layout.marginTop = dialog.getVerticalDLUsToPixel(IDialogConstants.VERTICAL_SPACING);
layout.marginHeight = 0;
multiArgumentComposite.setLayout(layout);
multiArgumentComposite.setFont(font);
data = new GridData(SWT.FILL, SWT.FILL, true, true);
multiArgumentComposite.setLayoutData(data);
multiKey = new Combo(multiArgumentComposite, SWT.READ_ONLY);
multiKey.setItems(getMultiMatcherKeys());
data = new GridData(SWT.LEFT, SWT.TOP, false, false);
multiKey.setLayoutData(data);
multiKey.setFont(font);
multiKey.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
setupMultiOperatorAndField(true);
storeMultiSelection();
}
});
// calculate max combo width
ArrayList<String> allOperators = new ArrayList<>();
String[] keys = getMultiMatcherKeys();
for (String key : keys) {
allOperators.addAll(Arrays.asList(getLocalOperatorsForKey(MultiMatcherLocalization.getMultiMatcherKey(key))));
}
Combo tmp = new Combo(multiArgumentComposite, SWT.READ_ONLY);
tmp.setItems(allOperators.toArray(new String[0]));
int maxWidth = tmp.computeSize(SWT.DEFAULT, SWT.DEFAULT).x;
tmp.dispose();
multiOperator = new Combo(multiArgumentComposite, SWT.READ_ONLY);
data = new GridData(SWT.LEFT, SWT.TOP, false, false);
data.widthHint = maxWidth;
multiOperator.setLayoutData(data);
multiOperator.setFont(font);
multiOperator.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
setupMultiOperatorAndField(false);
storeMultiSelection();
}
});
FileInfoAttributesMatcher.Argument argument = FileInfoAttributesMatcher.decodeArguments((String) filter.getArguments());
String local = MultiMatcherLocalization.getLocalMultiMatcherKey(argument.key);
int index = multiKey.indexOf(local);
if (index != -1)
multiKey.select(index);
else
multiKey.select(0);
setupMultiOperatorAndField(true);
}
private void setupMultiOperatorAndField(boolean updateOperator) {
boolean isUsingRegularExpression = false;
String selectedKey = MultiMatcherLocalization.getMultiMatcherKey(multiKey.getText());
if (updateOperator) {
String[] operators = getLocalOperatorsForKey(selectedKey);
multiOperator.setItems(operators);
FileInfoAttributesMatcher.Argument argument = FileInfoAttributesMatcher.decodeArguments((String) filter.getArguments());
String local = MultiMatcherLocalization.getLocalMultiMatcherKey(argument.operator);
int index = multiOperator.indexOf(local);
if (index != -1)
multiOperator.select(index);
else
multiOperator.select(0);
}
String selectedOperator = MultiMatcherLocalization.getMultiMatcherKey(multiOperator.getText());
Class<?> selectedKeyOperatorType = FileInfoAttributesMatcher.getTypeForKey(selectedKey, selectedOperator);
if (intiantiatedKeyOperatorType != null) {
if (arguments != null) {
arguments.dispose();
arguments = null;
}
if (attributeStringArgumentComposite != null) {
attributeStringArgumentComposite.dispose();
attributeStringArgumentComposite = null;
}
if (stringArgumentComposite != null) {
stringArgumentComposite.dispose();
stringArgumentComposite = null;
}
if (argumentsBoolean != null) {
argumentsBoolean.dispose();
argumentsBoolean = null;
}
if (argumentsDate != null) {
argumentsDate.dispose();
argumentsDate = null;
}
if (argumentsRegularExpresion != null) {
argumentsRegularExpresion.dispose();
argumentsRegularExpresion = null;
}
if (argumentsCaseSensitive != null) {
argumentsCaseSensitive.dispose();
argumentsCaseSensitive = null;
}
if (dummyLabel1 != null) {
dummyLabel1.dispose();
dummyLabel1 = null;
}
if (dummyLabel2 != null) {
dummyLabel2.dispose();
dummyLabel2 = null;
}
fContentAssistField = null;
FileInfoAttributesMatcher.Argument argument = FileInfoAttributesMatcher.decodeArguments((String) filter.getArguments());
valueCache.put(intiantiatedKeyOperatorType.getName(), argument.pattern);
argument.pattern = valueCache.get(selectedKeyOperatorType.getName());
if (argument.pattern == null)
argument.pattern = ""; //$NON-NLS-1$
filter.setArguments(FileInfoAttributesMatcher.encodeArguments(argument));
}
if (selectedKeyOperatorType.equals(String.class)) {
arguments = new Text(multiArgumentComposite, SWT.SINGLE | SWT.BORDER);
GridData data= new GridData(SWT.FILL, SWT.FILL, true, false);
data.widthHint = 150;
arguments.setLayoutData(data);
arguments.setFont(multiArgumentComposite.getFont());
arguments.addModifyListener(e -> validateInputText());
dummyLabel1 = new Label(multiArgumentComposite, SWT.NONE);
data = new GridData(SWT.LEFT, SWT.CENTER, true, true);
dummyLabel1.setText(""); //$NON-NLS-1$
data.horizontalSpan = 1;
dummyLabel1.setLayoutData(data);
dummyLabel2 = new Label(multiArgumentComposite, SWT.NONE);
data = new GridData(SWT.LEFT, SWT.CENTER, true, true);
dummyLabel2.setText(""); //$NON-NLS-1$
data.horizontalSpan = 1;
dummyLabel2.setLayoutData(data);
stringArgumentComposite = new Composite(multiArgumentComposite, SWT.NONE);
GridLayout layout = new GridLayout();
layout.numColumns = 2;
layout.marginWidth = 0;
layout.marginTop = dialog.getVerticalDLUsToPixel(IDialogConstants.VERTICAL_SPACING) / 2;
layout.marginHeight = 0;
layout.marginBottom = 0;
stringArgumentComposite.setLayout(layout);
data = new GridData(SWT.FILL, SWT.CENTER, true, true);
data.horizontalSpan = 1;
stringArgumentComposite.setLayoutData(data);
stringArgumentComposite.setFont(multiArgumentComposite.getFont());
argumentsCaseSensitive = new Button(stringArgumentComposite, SWT.CHECK);
argumentsCaseSensitive.setText(NLS.bind(
IDEWorkbenchMessages.ResourceFilterPage_caseSensitive, null));
data = new GridData(SWT.LEFT, SWT.CENTER, false, false);
argumentsCaseSensitive.setLayoutData(data);
argumentsCaseSensitive.setFont(multiArgumentComposite.getFont());
argumentsRegularExpresion = new Button(stringArgumentComposite, SWT.CHECK);
argumentsRegularExpresion.setText(NLS.bind(
IDEWorkbenchMessages.ResourceFilterPage_regularExpression, null));
data = new GridData(SWT.LEFT, SWT.CENTER, false, false);
data.minimumWidth = 100;
argumentsRegularExpresion.setLayoutData(data);
argumentsRegularExpresion.setFont(multiArgumentComposite.getFont());
if (filter.hasStringArguments()) {
FileInfoAttributesMatcher.Argument argument = FileInfoAttributesMatcher.decodeArguments((String) filter.getArguments());
arguments.setText(argument.pattern);
isUsingRegularExpression = argument.regularExpression;
argumentsCaseSensitive.setSelection(argument.caseSensitive);
argumentsRegularExpresion.setSelection(argument.regularExpression);
}
arguments.addModifyListener(e -> storeMultiSelection());
argumentsRegularExpresion.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
setupDescriptionText(null);
storeMultiSelection();
if (fContentAssistField != null)
fContentAssistField.setEnabled(argumentsRegularExpresion.getSelection());
}
});
argumentsCaseSensitive.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
storeMultiSelection();
}
});
TextContentAdapter contentAdapter= new TextContentAdapter();
FindReplaceDocumentAdapterContentProposalProvider findProposer= new FindReplaceDocumentAdapterContentProposalProvider(true);
fContentAssistField= new ContentAssistCommandAdapter(
arguments,
contentAdapter,
findProposer,
null,
new char[] {'\\', '[', '('},
true);
}
if (selectedKeyOperatorType.equals(Integer.class)) {
GridData data;
arguments = new Text(multiArgumentComposite, SWT.SINGLE | SWT.BORDER);
data= new GridData(SWT.FILL, SWT.FILL, true, false);
data.widthHint = 150;
arguments.setLayoutData(data);
arguments.setFont(multiArgumentComposite.getFont());
arguments.addModifyListener(e -> validateInputText());
if (filter.hasStringArguments()) {
FileInfoAttributesMatcher.Argument argument = FileInfoAttributesMatcher.decodeArguments((String) filter.getArguments());
if (selectedKey.equals(FileInfoAttributesMatcher.KEY_LAST_MODIFIED) || selectedKey.equals(FileInfoAttributesMatcher.KEY_CREATED))
arguments.setText(convertToEditableTimeInterval(argument.pattern));
else
arguments.setText(convertToEditableLength(argument.pattern));
}
arguments.addModifyListener(e -> storeMultiSelection());
}
if (selectedKeyOperatorType.equals(Date.class)) {
GridData data;
argumentsDate = new DateTime(multiArgumentComposite, SWT.DATE | SWT.MEDIUM | SWT.BORDER);
data= new GridData(SWT.FILL, SWT.FILL, true, false);
argumentsDate.setLayoutData(data);
argumentsDate.setFont(multiArgumentComposite.getFont());
argumentsDate.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
storeMultiSelection();
}
});
if (filter.hasStringArguments()) {
FileInfoAttributesMatcher.Argument argument = FileInfoAttributesMatcher.decodeArguments((String) filter.getArguments());
Date date;
Calendar calendar = Calendar.getInstance();
try {
date = new Date(Long.parseLong(argument.pattern));
calendar.setTime(date);
} catch (NumberFormatException e1) {
date = new Date();
calendar.setTime(date);
argument.pattern = Long.toString(calendar.getTimeInMillis());
}
argumentsDate.setDay(calendar.get(Calendar.DAY_OF_MONTH));
argumentsDate.setMonth(calendar.get(Calendar.MONTH));
argumentsDate.setYear(getDateYear(calendar));
}
}
if (selectedKeyOperatorType.equals(Boolean.class)) {
GridData data;
argumentsBoolean = new Combo(multiArgumentComposite, SWT.READ_ONLY);
data = new GridData(SWT.FILL, SWT.TOP, true, false);
argumentsBoolean.setLayoutData(data);
argumentsBoolean.setFont(multiArgumentComposite.getFont());
argumentsBoolean.setItems(MultiMatcherLocalization.getLocalMultiMatcherKey(Boolean.TRUE.toString()),
MultiMatcherLocalization.getLocalMultiMatcherKey(Boolean.FALSE.toString()));
argumentsBoolean.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
storeMultiSelection();
}
});
if (filter.hasStringArguments()) {
FileInfoAttributesMatcher.Argument argument = FileInfoAttributesMatcher.decodeArguments((String) filter.getArguments());
if (argument.pattern.isEmpty())
argumentsBoolean.select(0);
else
argumentsBoolean.select(Boolean.parseBoolean(argument.pattern) ? 0:1);
}
}
intiantiatedKeyOperatorType = selectedKeyOperatorType;
if (fContentAssistField != null)
fContentAssistField.setEnabled(isUsingRegularExpression);
shell.layout(true, true);
if (initializationComplete) {
Point size = shell.computeSize(SWT.DEFAULT, SWT.DEFAULT);
Point shellSize = shell.getSize();
size.x = Math.max(size.x, shellSize.x);
size.y = Math.max(size.y, shellSize.y);
if ((size.x > shellSize.x) || (size.y > shellSize.y))
shell.setSize(size);
}
shell.redraw();
setupDescriptionText(null);
}
private String[] timeIntervalPrefixes = {"s", "m", "h", "d"}; //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ //$NON-NLS-4$
private double[] timeIntervalScale = {60, 60, 24};
private String convertToEditableTimeInterval(String string) {
if (string.isEmpty())
return string;
long value;
try {
value = Long.parseLong(string);
} catch (NumberFormatException e) {
value = 0;
}
if (value == 0)
return Long.toString(0);
for (int i = 0; i < timeIntervalPrefixes.length - 1; i++) {
if (value % timeIntervalScale[i] != 0)
return Long.toString(value) + timeIntervalPrefixes[i];
value /= timeIntervalScale[i];
}
return Long.toString(value) + timeIntervalPrefixes[timeIntervalPrefixes.length - 1];
}
private String convertFromEditableTimeInterval(String string) {
if (string.isEmpty())
return string;
for (int i = 1; i < timeIntervalPrefixes.length; i++) {
if (string.endsWith(timeIntervalPrefixes[i])) {
long value = Long.parseLong(string.substring(0, string.length() - 1));
for (int j = 0; j < i; j++)
value *= timeIntervalScale[j];
return Long.toString(value);
}
}
// seems equivalent to "return string", but it throws an exception if the string doesn't contain a valid number
return Long.toString(Long.parseLong(string));
}
private String[] lengthPrefixes = { "", "k", "m", "g" }; //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$
// converts "32768" to "32k"
private String convertToEditableLength(String string) {
if (string.isEmpty())
return string;
long value;
try {
value = Long.parseLong(string);
} catch (NumberFormatException e) {
value = 0;
}
if (value == 0)
return Long.toString(0);
for (int i = 0; i < lengthPrefixes.length; i++) {
if (value % 1024 != 0)
return Long.toString(value) + lengthPrefixes[i];
if ((i + 1) < lengthPrefixes.length)
value /= 1024;
}
return Long.toString(value) + lengthPrefixes[lengthPrefixes.length - 1];
}
// converts "32k" to "32768"
private String convertFromEditableLength(String string) throws NumberFormatException {
if (string.isEmpty())
return string;
for (int i = 1; i < lengthPrefixes.length; i++) {
if (string.endsWith(lengthPrefixes[i])) {
long value = Long.parseLong(string.substring(0, string.length() - 1));
value *= Math.pow(1024, i);
return Long.toString(value);
}
}
// seems equivalent to "return string", but it throws an exception if the string doesn't contain a valid number
return Long.toString(Long.parseLong(string));
}
private int getDateYear(Calendar calendar) {
Date calendarDate = calendar.getTime();
int calendarYear = calendar.get(Calendar.YEAR);
if (calendarYear >= DateTime_MIN_YEAR) {
return calendarYear;
}
gregorianCalendar.setTime(calendarDate);
return gregorianCalendar.get(Calendar.YEAR);
}
private int getCalendarYear() {
Calendar calendar = Calendar.getInstance();
int calendarYear = calendar.get(Calendar.YEAR);
int dateYear = argumentsDate.getYear();
if (calendarYear >= DateTime_MIN_YEAR) {
return dateYear;
}
gregorianCalendar.setTime(new Date());
int currentYear = gregorianCalendar.get(Calendar.YEAR);
return dateYear = calendarYear + (dateYear - currentYear);
}
private void storeMultiSelection() {
if (intiantiatedKeyOperatorType != null) {
String selectedKey = MultiMatcherLocalization.getMultiMatcherKey(multiKey.getText());
String selectedOperator = MultiMatcherLocalization.getMultiMatcherKey(multiOperator.getText());
FileInfoAttributesMatcher.Argument argument = new FileInfoAttributesMatcher.Argument();
argument.key = selectedKey;
argument.operator = selectedOperator;
if (intiantiatedKeyOperatorType.equals(Date.class) && argumentsDate != null) {
Calendar calendar = Calendar.getInstance();
calendar.set(getCalendarYear(), argumentsDate.getMonth(), argumentsDate.getDay());
argument.pattern = Long.toString(calendar.getTimeInMillis());
}
if (intiantiatedKeyOperatorType.equals(String.class) && arguments != null) {
argument.pattern = arguments.getText();
if (argumentsRegularExpresion != null)
argument.regularExpression = argumentsRegularExpresion.getSelection();
if (argumentsCaseSensitive != null)
argument.caseSensitive = argumentsCaseSensitive.getSelection();
}
if (intiantiatedKeyOperatorType.equals(Integer.class) && arguments != null) {
try {
if (selectedKey.equals(FileInfoAttributesMatcher.KEY_LAST_MODIFIED) || selectedKey.equals(FileInfoAttributesMatcher.KEY_CREATED))
argument.pattern = convertFromEditableTimeInterval(arguments.getText());
else
argument.pattern = convertFromEditableLength(arguments.getText());
} catch (NumberFormatException e) {
argument.pattern = arguments.getText();
}
}
if (intiantiatedKeyOperatorType.equals(Boolean.class) && argumentsBoolean != null)
argument.pattern = MultiMatcherLocalization.getMultiMatcherKey(argumentsBoolean.getText());
String encodedArgument = FileInfoAttributesMatcher.encodeArguments(argument);
FilterTypeUtil.setValue(filter, FilterTypeUtil.ARGUMENTS, encodedArgument);
}
}
private String[] getLocalOperatorsForKey(String key) {
String [] operators = FileInfoAttributesMatcher.getOperatorsForKey(key);
String[] result = new String[operators.length];
for (int i = 0; i < operators.length; i++)
result[i] = MultiMatcherLocalization.getLocalMultiMatcherKey(operators[i]);
return result;
}
private String[] getMultiMatcherKeys() {
ArrayList<String> list = new ArrayList<>();
list.add(MultiMatcherLocalization.getLocalMultiMatcherKey(FileInfoAttributesMatcher.KEY_NAME));
list.add(MultiMatcherLocalization.getLocalMultiMatcherKey(FileInfoAttributesMatcher.KEY_PROPJECT_RELATIVE_PATH));
list.add(MultiMatcherLocalization.getLocalMultiMatcherKey(FileInfoAttributesMatcher.KEY_LOCATION));
list.add(MultiMatcherLocalization.getLocalMultiMatcherKey(FileInfoAttributesMatcher.KEY_LAST_MODIFIED));
if (FileInfoAttributesMatcher.supportCreatedKey())
list.add(MultiMatcherLocalization.getLocalMultiMatcherKey(FileInfoAttributesMatcher.KEY_CREATED));
list.add(MultiMatcherLocalization.getLocalMultiMatcherKey(FileInfoAttributesMatcher.KEY_LENGTH));
list.add(MultiMatcherLocalization.getLocalMultiMatcherKey(FileInfoAttributesMatcher.KEY_IS_READONLY));
if (!Platform.getOS().equals(Platform.OS_WIN32))
list.add(MultiMatcherLocalization.getLocalMultiMatcherKey(FileInfoAttributesMatcher.KEY_IS_SYMLINK));
return list.toArray(new String[0]);
}
@Override
public void selectionChanged() {
}
void validateInputText() {
setupDescriptionText(validate());
dialog.updateFinishControls();
}
@Override
public String validate() {
String message = null;
if (intiantiatedKeyOperatorType != null) {
String selectedKey = MultiMatcherLocalization.getMultiMatcherKey(multiKey.getText());
String selectedOperator = MultiMatcherLocalization.getMultiMatcherKey(multiOperator.getText());
FileInfoAttributesMatcher.Argument argument = new FileInfoAttributesMatcher.Argument();
argument.key = selectedKey;
argument.operator = selectedOperator;
if (intiantiatedKeyOperatorType.equals(String.class) && arguments != null) {
argument.pattern = arguments.getText();
if (argumentsRegularExpresion != null)
argument.regularExpression = argumentsRegularExpresion.getSelection();
if (argumentsCaseSensitive != null)
argument.caseSensitive = argumentsCaseSensitive.getSelection();
String encodedArgument = FileInfoAttributesMatcher.encodeArguments(argument);
FilterCopy copy = new FilterCopy(filter);
FilterTypeUtil.setValue(copy, FilterTypeUtil.ARGUMENTS, encodedArgument);
IFilterMatcherDescriptor desc = dialog.getResource().getWorkspace().getFilterMatcherDescriptor(copy.getId());
if (desc != null) {
try {
AbstractFileInfoMatcher matcher = ((FilterDescriptor) desc).createFilter();
matcher.initialize(dialog.getResource().getProject(), copy.getArguments());
} catch (CoreException e) {
message = e.getMessage();
}
}
}
if (intiantiatedKeyOperatorType.equals(Integer.class) && arguments != null) {
if (selectedKey.equals(FileInfoAttributesMatcher.KEY_LAST_MODIFIED) || selectedKey.equals(FileInfoAttributesMatcher.KEY_CREATED)) {
try {
convertFromEditableTimeInterval(arguments.getText());
} catch (NumberFormatException e) {
message = NLS.bind(
IDEWorkbenchMessages.ResourceFilterPage_multiMatcher_InvalidTimeInterval, arguments.getText());
}
}
else {
try {
convertFromEditableLength(arguments.getText());
} catch (NumberFormatException e) {
message = NLS.bind(
IDEWorkbenchMessages.ResourceFilterPage_multiMatcher_InvalidFileLength, arguments.getText());
}
}
}
if (intiantiatedKeyOperatorType.equals(Boolean.class) && argumentsBoolean != null) {
}
}
return message;
}
@Override
public StyledString formatStyledText(FilterCopy filter,
Styler fPlainStyler, Styler fBoldStyler) {
return new StyledString(formatMultiMatcherArgument(filter), fPlainStyler);
}
private String formatMultiMatcherArgument(FilterCopy filter) {
String argumentString = (String) filter.getArguments();
FileInfoAttributesMatcher.Argument argument = FileInfoAttributesMatcher.decodeArguments(argumentString);
StringBuilder builder = new StringBuilder();
builder.append(MultiMatcherLocalization.getLocalMultiMatcherKey(argument.key));
builder.append(' ');
builder.append(MultiMatcherLocalization.getLocalMultiMatcherKey(argument.operator));
builder.append(' ');
Class<?> type = FileInfoAttributesMatcher.getTypeForKey(argument.key, argument.operator);
if (type.equals(String.class))
builder.append(argument.pattern);
if (type.equals(Boolean.class))
builder.append(MultiMatcherLocalization.getLocalMultiMatcherKey(argument.pattern));
if (type.equals(Integer.class)) {
if (argument.key.equals(FileInfoAttributesMatcher.KEY_LAST_MODIFIED) || argument.key.equals(FileInfoAttributesMatcher.KEY_CREATED))
builder.append(convertToEditableTimeInterval(argument.pattern));
else
builder.append(convertToEditableLength(argument.pattern));
}
if (type.equals(Date.class))
builder.append(DateFormat.getDateInstance().format(new Date(Long.parseLong(argument.pattern))));
return builder.toString();
}
}
class DefaultCustomFilterArgumentUI implements ICustomFilterArgumentUI {
protected Shell shell;
protected FilterCopy filter;
protected Text arguments;
protected Label argumentsLabel;
protected Label description;
protected ContentAssistCommandAdapter fContentAssistField;
protected FilterEditDialog dialog;
public static final String REGEX_FILTER_ID = "org.eclipse.core.resources.regexFilterMatcher"; //$NON-NLS-1$
/**
* @param dialog
* @param parentShell
* @param filter
*/
public DefaultCustomFilterArgumentUI(FilterEditDialog dialog, Shell parentShell, FilterCopy filter) {
this.shell = parentShell;
this.dialog = dialog;
this.filter = filter;
}
@Override
public Object getID() {
return ""; //$NON-NLS-1$
}
@Override
public void dispose() {
Widget list[] = new Widget[] {arguments, argumentsLabel, description};
for (Widget widget : list) {
if (widget != null) {
widget.dispose();
}
}
arguments = null;
argumentsLabel = null;
fContentAssistField = null;
description = null;
}
@Override
public void create(Composite argumentComposite, Font font) {
shell = argumentComposite.getShell();
GridLayout layout = new GridLayout();
layout.numColumns = 2;
layout.marginWidth = dialog.getVerticalDLUsToPixel(IDialogConstants.HORIZONTAL_MARGIN);
argumentComposite.setLayout(layout);
GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
argumentComposite.setLayoutData(data);
argumentComposite.setFont(font);
if (filter.hasStringArguments())
createArgumentsArea(font, argumentComposite);
createDescriptionArea(font, argumentComposite);
if (fContentAssistField != null)
fContentAssistField.setEnabled(filter.getId().equals(REGEX_FILTER_ID));
argumentComposite.layout(true);
}
private void createArgumentsArea(Font font, Composite composite) {
GridData data;
argumentsLabel = addLabel(composite, NLS.bind(
IDEWorkbenchMessages.ResourceFilterPage_columnFilterPattern,
null));
arguments = new Text(composite, SWT.SINGLE | SWT.BORDER);
data = new GridData(SWT.FILL, SWT.CENTER, true, false);
arguments.setLayoutData(data);
arguments.setFont(font);
arguments.addModifyListener(e -> FilterTypeUtil.setValue(filter, FilterTypeUtil.ARGUMENTS,
arguments.getText()));
if (filter.hasStringArguments())
arguments.setText((String) FilterTypeUtil.getValue(filter,
FilterTypeUtil.ARGUMENTS));
arguments.setEnabled(filter.hasStringArguments());
setArgumentLabelEnabled();
TextContentAdapter contentAdapter= new TextContentAdapter();
FindReplaceDocumentAdapterContentProposalProvider findProposer= new FindReplaceDocumentAdapterContentProposalProvider(true);
fContentAssistField= new ContentAssistCommandAdapter(
arguments,
contentAdapter,
findProposer,
null,
new char[] {'\\', '[', '('},
true);
}
private void setArgumentLabelEnabled() {
if (argumentsLabel != null) {
Color color = argumentsLabel.getDisplay().getSystemColor(
filter.hasStringArguments() ? SWT.COLOR_BLACK : SWT.COLOR_GRAY);
argumentsLabel.setForeground(color);
}
}
Label addLabel(Composite composite, String text) {
String delimiter = ":"; //$NON-NLS-1$
Font font = composite.getFont();
Label label = new Label(composite, SWT.LEFT);
label.setText(text + delimiter);
GridData data = new GridData(SWT.LEFT, SWT.CENTER, false, false);
label.setLayoutData(data);
label.setFont(font);
return label;
}
@Override
public void selectionChanged() {
if (arguments != null)
arguments.setEnabled(filter.hasStringArguments());
setArgumentLabelEnabled();
if (fContentAssistField != null)
fContentAssistField.setEnabled(filter.getId().equals(REGEX_FILTER_ID));
description.setText(FilterTypeUtil
.getDescriptor(filter.getId()).getDescription());
}
/**
* @param font
* @param composite
*/
private void createDescriptionArea(Font font, Composite composite) {
GridData data;
description = new Label(composite, SWT.LEFT | SWT.WRAP);
description.setText(FilterTypeUtil.getDescriptor(filter.getId())
.getDescription());
data = new GridData(SWT.FILL, SWT.BEGINNING, true, true);
data.widthHint = 300;
data.heightHint = 40;
data.horizontalSpan = 2;
description.setLayoutData(data);
description.setFont(font);
}
@Override
public String validate(){
return null;
}
@Override
public StyledString formatStyledText(FilterCopy filter,
Styler fPlainStyler, Styler fBoldStyler) {
return new StyledString(filter.getArguments() != null ? filter.getArguments().toString() :
"", fPlainStyler); //$NON-NLS-1$
}
}
class MultiMatcherLocalization {
static String[][] multiMatcherKey = {
{FileInfoAttributesMatcher.KEY_NAME, IDEWorkbenchMessages.ResourceFilterPage_multiKeyName},
{FileInfoAttributesMatcher.KEY_PROPJECT_RELATIVE_PATH, IDEWorkbenchMessages.ResourceFilterPage_multiKeyProjectRelativePath},
{FileInfoAttributesMatcher.KEY_LOCATION, IDEWorkbenchMessages.ResourceFilterPage_multiKeyLocation},
{FileInfoAttributesMatcher.KEY_LAST_MODIFIED, IDEWorkbenchMessages.ResourceFilterPage_multiKeyLastModified},
{FileInfoAttributesMatcher.KEY_CREATED, IDEWorkbenchMessages.ResourceFilterPage_multiKeyCreated},
{FileInfoAttributesMatcher.KEY_LENGTH, IDEWorkbenchMessages.ResourceFilterPage_multiKeyLength},
{FileInfoAttributesMatcher.KEY_IS_READONLY, IDEWorkbenchMessages.ResourceFilterPage_multiKeyReadOnly},
{FileInfoAttributesMatcher.KEY_IS_SYMLINK, IDEWorkbenchMessages.ResourceFilterPage_multiKeySymLink},
{FileInfoAttributesMatcher.OPERATOR_AFTER, IDEWorkbenchMessages.ResourceFilterPage_multiAfter},
{FileInfoAttributesMatcher.OPERATOR_BEFORE, IDEWorkbenchMessages.ResourceFilterPage_multiBefore},
{FileInfoAttributesMatcher.OPERATOR_EQUALS, IDEWorkbenchMessages.ResourceFilterPage_multiEquals},
{FileInfoAttributesMatcher.OPERATOR_MATCHES, IDEWorkbenchMessages.ResourceFilterPage_multiMatches},
{FileInfoAttributesMatcher.OPERATOR_LARGER_THAN, IDEWorkbenchMessages.ResourceFilterPage_multiLargerThan},
{FileInfoAttributesMatcher.OPERATOR_SMALLER_THAN, IDEWorkbenchMessages.ResourceFilterPage_multiSmallerThan},
{FileInfoAttributesMatcher.OPERATOR_WITHIN, IDEWorkbenchMessages.ResourceFilterPage_multiWithin},
{Boolean.TRUE.toString(), IDEWorkbenchMessages.ResourceFilterPage_true},
{Boolean.FALSE.toString(), IDEWorkbenchMessages.ResourceFilterPage_false}
};
static public String getLocalMultiMatcherKey(String key) {
for (String[] matcherKey : multiMatcherKey) {
if (matcherKey[0].equals(key))
return matcherKey[1];
}
return null;
}
static public String getMultiMatcherKey(String local) {
for (String[] matcherKey : multiMatcherKey) {
if (matcherKey[1].equals(local))
return matcherKey[0];
}
return null;
}
}