in src/application/org.openjdk.jmc.ui/src/main/java/org/openjdk/jmc/ui/misc/FilterEditor.java [320:439]
public <M> FilterEditor(org.eclipse.swt.widgets.Composite parent, Consumer<IItemFilter> onChange,
IItemFilter initial, Supplier<Collection<IAttribute<?>>> attributeSupplier,
AttributeValueProvider attributeValueProvider, Function<String, java.awt.Color> typeColorProvider,
int style) {
this.attributeSupplier = attributeSupplier;
this.attributeValueProvider = attributeValueProvider;
this.tree = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION | style);
this.onChange = onChange;
tree.setContentProvider(new FilterArrayContentProvider());
FocusTracker.enableFocusTracking(tree.getTree());
initializeCellFocus();
addColumn(tree, Messages.FilterEditor_COLUMN_ATTRIBUTE, 150, new NameLabelProvider(typeColorProvider),
new AttributeEditingSupport(tree));
addColumn(tree, Messages.FilterEditor_COLUMN_OPERATION, 100, new OperationLabelProvider(),
new OperationEditingSupport(tree));
addColumn(tree, Messages.FilterEditor_COLUMN_VALUE, 500, new ValueLabelProvider(),
new ValueEditingSupport(tree));
mm = MCContextMenuManager.create(tree.getControl());
showColumnHeadersAction = ActionToolkit.checkAction(this::toggleColumnHeaders,
Messages.FilterEditor_ACTION_SHOW_COLUMN_HEADERS, null);
mm.appendToGroup(MCContextMenuManager.GROUP_VIEWER_SETUP, showColumnHeadersAction);
mm.appendToGroup(MCContextMenuManager.GROUP_NEW, ActionToolkit.forListSelection(tree,
Messages.FilterEditor_ACTION_COMBINE_OR, false, forNonEmptyFilterSelection(filters -> {
Set<Object> expanded = asSet(tree.getExpandedElements());
expanded.add(FilterNodeToolkit.wrapFilters(root, filters, true));
tree.setInput(root);
tree.setExpandedElements(expanded.toArray());
notifyListener();
})));
mm.appendToGroup(MCContextMenuManager.GROUP_NEW, ActionToolkit.forListSelection(tree,
Messages.FilterEditor_ACTION_COMBINE_AND, false, forNonEmptyFilterSelection(filters -> {
Set<Object> expanded = asSet(tree.getExpandedElements());
expanded.add(FilterNodeToolkit.wrapFilters(root, filters, false));
tree.setInput(root);
tree.setExpandedElements(expanded.toArray());
notifyListener();
})));
mm.appendToGroup(MCContextMenuManager.GROUP_NEW,
ActionToolkit.forListSelection(tree, Messages.FilterEditor_ACTION_REMOVE, false,
(List<FilterNode> selection) -> onlyCompositeNodesSelected(selection) ? () -> {
Object[] expanded = tree.getExpandedElements();
for (FilterNode node : selection) {
FilterNodeToolkit.unwrapFilter(root, (CompositeNode) node);
}
tree.setInput(root);
tree.setExpandedElements(expanded);
notifyListener();
} : null));
// FIXME: This action does not update its enablement until it has been unselected and reselected (list selection has changed)
mm.appendToGroup(MCContextMenuManager.GROUP_NEW,
ActionToolkit.forListSelection(tree, Messages.FilterEditor_ACTION_NEGATE, true,
(List<FilterNode> filters) -> filtersNegatable(filters) ? () -> {
for (FilterNode filter : filters) {
if (filter instanceof CompositeNode) {
CompositeNode composite = (CompositeNode) filter;
composite.negated = !composite.negated;
} else if (isAttributeFilter(filter)) {
AttributeFilter<M> attributeFilter = asAttributeFilterM(filter);
M value = attributeFilter instanceof AttributeValue
? ((AttributeValue<M>) attributeFilter).getValue() : null;
Kind kind = attributeFilter.getKind();
Kind newKind = kind.negate();
if (newKind != null) {
((LeafNode) filter).filter = buildFilter(newKind,
attributeFilter.getAttribute(), value);
}
}
}
notifyListener();
} : null));
IAction cutAction = ActionToolkit.forListSelection(tree, null, false,
forNonEmptyFilterSelection(this::cutNodes));
ActionToolkit.convertToCommandAction(cutAction, IWorkbenchCommandConstants.EDIT_CUT);
InFocusHandlerActivator.install(tree.getControl(), cutAction);
mm.appendToGroup(MCContextMenuManager.GROUP_EDIT, cutAction);
IAction copyAction = ActionToolkit.forListSelection(tree, null, false,
forNonEmptyFilterSelection(this::copyNodes));
ActionToolkit.convertToCommandAction(copyAction, IWorkbenchCommandConstants.EDIT_COPY);
InFocusHandlerActivator.install(tree.getControl(), copyAction);
mm.appendToGroup(MCContextMenuManager.GROUP_EDIT, copyAction);
IAction pasteAction = ActionToolkit.forListSelection(tree, null, false,
(List<FilterNode> selection) -> (selection.size() <= 1) ? () -> pasteNodes(selection) : null);
ActionToolkit.convertToCommandAction(pasteAction, IWorkbenchCommandConstants.EDIT_PASTE);
InFocusHandlerActivator.install(tree.getControl(), pasteAction);
mm.appendToGroup(MCContextMenuManager.GROUP_EDIT, pasteAction);
IAction removeAction = ActionToolkit.forTreeSelection(tree, null, false,
selection -> selection.isEmpty() || selection.getFirstElement() instanceof EmptyNode ? null
: () -> deleteNodes(selection));
ActionToolkit.convertToCommandAction(removeAction, IWorkbenchCommandConstants.EDIT_DELETE);
InFocusHandlerActivator.install(tree.getControl(), removeAction);
mm.appendToGroup(MCContextMenuManager.GROUP_EDIT, removeAction);
mm.appendToGroup(MCContextMenuManager.GROUP_EDIT,
ActionToolkit.action(this::clearNodes, Messages.FilterEditor_ACTION_CLEAR_ALL));
if (initial instanceof Composite && !((Composite) initial).isUnion()) {
for (IItemFilter f : ((Composite) initial).getFilters()) {
root.children.add(buildTreeNode(f));
}
} else if (initial != null) {
root.children.add(buildTreeNode(initial));
}
Transfer[] localTransfer = new Transfer[] {LocalSelectionTransfer.getTransfer()};
tree.addDragSupport(DND.DROP_MOVE | DND.DROP_COPY, localTransfer,
DndToolkit.createLocalDragSource(tree, this::deleteNodes));
ViewerDropAdapter dropTarget = DndToolkit.createLocalDropListTarget(tree, CompositeNode.class, FilterNode.class,
this::performDrop, this::validateDrop);
dropTarget.setFeedbackEnabled(false);
tree.addDropSupport(DND.DROP_MOVE | DND.DROP_COPY, localTransfer, dropTarget);
ColumnViewerToolTipSupport.enableFor(tree);
tree.setInput(root);
}