blob: 9a2361397fe053fc493aba012156af8337b13acd [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2012, 2019 Stephan Wahlbrink and others.
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License 2.0 which is available at
# https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
# which is available at https://www.apache.org/licenses/LICENSE-2.0.
#
# SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
#
# Contributors:
# Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
#=============================================================================*/
package org.eclipse.statet.internal.r.ui.datafilterview;
import static org.eclipse.statet.ecommons.ui.actions.HandlerContributionItem.NO_COMMAND_ID;
import java.util.List;
import java.util.Map;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.IHandler2;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IWorkbenchCommandConstants;
import org.eclipse.ui.commands.IElementUpdater;
import org.eclipse.ui.handlers.IHandlerService;
import org.eclipse.ui.menus.CommandContributionItem;
import org.eclipse.ui.menus.CommandContributionItemParameter;
import org.eclipse.ui.menus.UIElement;
import org.eclipse.ui.part.IPageSite;
import org.eclipse.ui.part.Page;
import org.eclipse.statet.ecommons.ui.SharedUIResources;
import org.eclipse.statet.ecommons.ui.actions.HandlerContributionItem;
import org.eclipse.statet.ecommons.ui.dialogs.DialogUtils;
import org.eclipse.statet.ecommons.ui.util.DNDUtils;
import org.eclipse.statet.ecommons.ui.util.LayoutUtils;
import org.eclipse.statet.ecommons.ui.util.UIAccess;
import org.eclipse.statet.ecommons.ui.workbench.WorkbenchUIUtils;
import org.eclipse.statet.base.ui.contentfilter.IFilterPage;
import org.eclipse.statet.internal.r.ui.RUIPlugin;
import org.eclipse.statet.internal.r.ui.dataeditor.RDataEditor;
import org.eclipse.statet.internal.r.ui.dataeditor.RDataTableContentDescription;
import org.eclipse.statet.internal.r.ui.datafilter.FilterSet;
import org.eclipse.statet.internal.r.ui.datafilter.IFilterListener;
import org.eclipse.statet.ltk.ui.sourceediting.ISourceEditorCommandIds;
import org.eclipse.statet.r.ui.dataeditor.IRDataTableInput;
import org.eclipse.statet.r.ui.dataeditor.IRDataTableListener;
import org.eclipse.statet.r.ui.dataeditor.RDataTableComposite;
public class RDataFilterPage extends Page implements IFilterPage {
private static final String EXPAND_ALL_COMMAND_ID= IWorkbenchCommandConstants.NAVIGATE_EXPAND_ALL;
private static final String COLLAPSE_ALL_COMMAND_ID= IWorkbenchCommandConstants.NAVIGATE_COLLAPSE_ALL;
private static final String COPY_EXPR_COMMAND_ID= ISourceEditorCommandIds.COPY_ELEMENT_NAME;
private class ExpandCollapseAllHandler extends AbstractHandler {
private final boolean expanded;
public ExpandCollapseAllHandler(final boolean expanded) {
this.expanded= expanded;
}
@Override
public Object execute(final ExecutionEvent event) throws ExecutionException {
RDataFilterPage.this.scrollComposite.setRedraw(false);
RDataFilterPage.this.scrollComposite.setDelayedReflow(true);
try {
final List<VariableComposite> variables= RDataFilterPage.this.container.getVariables();
for (final VariableComposite variable : variables) {
variable.setExpanded(this.expanded);
}
}
finally {
RDataFilterPage.this.scrollComposite.setDelayedReflow(false);
RDataFilterPage.this.scrollComposite.reflow(true);
RDataFilterPage.this.scrollComposite.setRedraw(true);
}
return null;
}
}
private class DisableFiltersHandler extends AbstractHandler implements IElementUpdater {
public DisableFiltersHandler() {
}
@Override
public void updateElement(final UIElement element, final Map parameters) {
WorkbenchUIUtils.aboutToUpdateCommandsElements(this, element);
try {
final FilterSet filterSet= RDataFilterPage.this.container.getFilterSet();
element.setChecked(!filterSet.getEnabled());
}
finally {
WorkbenchUIUtils.finalizeUpdateCommandsElements(this);
}
}
@Override
public Object execute(final ExecutionEvent event) throws ExecutionException {
final FilterSet filterSet= RDataFilterPage.this.container.getFilterSet();
filterSet.setEnabled(!filterSet.getEnabled());
return null;
}
}
private class CopyFilterExpr extends AbstractHandler {
public CopyFilterExpr() {
}
@Override
public Object execute(final ExecutionEvent event) throws ExecutionException {
final FilterSet filterSet= RDataFilterPage.this.container.getFilterSet();
final String rExpression= filterSet.getFilterRExpression(null, 0);
if (rExpression != null) {
final Clipboard clipboard= new Clipboard(RDataFilterPage.this.composite.getDisplay());
try {
return DNDUtils.setContent(clipboard,
new Object[] { rExpression },
new Transfer[] { TextTransfer.getInstance() });
}
finally {
clipboard.dispose();
}
}
return null;
}
}
private Composite composite;
private ScrolledPageComposite scrollComposite;
private Text filterText;
private VariableContainer container;
private IFilterListener filterPostListener;
private final RDataEditor editor;
private IRDataTableListener rDataTableListener;
private HandlerContributionItem disableItem;
public RDataFilterPage(final RDataEditor editor) {
this.editor= editor;
}
public RDataEditor getDataEditor() {
return this.editor;
}
protected IDialogSettings getDialogSettings() {
return DialogUtils.getDialogSettings(RUIPlugin.getInstance(), "RDataFilterPage"); //$NON-NLS-1$
}
@Override
public void init(final IPageSite pageSite) {
super.init(pageSite);
final IHandlerService handlerService= pageSite.getService(IHandlerService.class);
final IToolBarManager toolBarManager= pageSite.getActionBars().getToolBarManager();
final IMenuManager menuManager= pageSite.getActionBars().getMenuManager();
{ final IHandler2 handler= new ExpandCollapseAllHandler(true);
handlerService.activateHandler(EXPAND_ALL_COMMAND_ID, handler);
}
{ final IHandler2 handler= new ExpandCollapseAllHandler(false);
handlerService.activateHandler(COLLAPSE_ALL_COMMAND_ID, handler);
toolBarManager.add(new HandlerContributionItem(new CommandContributionItemParameter(pageSite,
null, COLLAPSE_ALL_COMMAND_ID, null,
null, null, null,
null, null, null,
HandlerContributionItem.STYLE_PUSH, null, false),
handler));
}
{ final IHandler2 handler= new DisableFiltersHandler();
this.disableItem= new HandlerContributionItem(new CommandContributionItemParameter(pageSite,
null, NO_COMMAND_ID, null,
SharedUIResources.getImages().getDescriptor(SharedUIResources.LOCTOOL_DISABLE_FILTER_IMAGE_ID), null, null,
Messages.Variables_DisableFilters_label, null, null,
HandlerContributionItem.STYLE_CHECK, null, false),
handler);
toolBarManager.add(this.disableItem);
}
{ final IHandler2 handler= new CopyFilterExpr();
handlerService.activateHandler(COPY_EXPR_COMMAND_ID, handler);
menuManager.add(new CommandContributionItem(new CommandContributionItemParameter(pageSite,
null, COPY_EXPR_COMMAND_ID, null,
null, null, null,
Messages.Variables_CopyExpr_label, null, null,
CommandContributionItem.STYLE_PUSH, null, false )));
}
}
@Override
public void createControl(final Composite parent) {
this.composite= new Composite(parent, SWT.NONE);
this.composite.setLayout(LayoutUtils.newCompositeGrid(1));
this.scrollComposite= new ScrolledPageComposite(this.composite, SWT.V_SCROLL);
this.scrollComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
this.container= new VariableContainer(getSite(), this.scrollComposite);
this.filterText= new Text(this.composite, SWT.LEFT_TO_RIGHT | SWT.READ_ONLY);
this.filterText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
this.container.getFilterSet().addListener(new IFilterListener() {
@Override
public void filterChanged() {
if (!UIAccess.isOkToUse(RDataFilterPage.this.filterText)) {
return;
}
RDataFilterPage.this.disableItem.update();
final String rExpression= RDataFilterPage.this.container.getFilterSet().getFilterRExpression();
RDataFilterPage.this.filterText.setText((rExpression != null) ? rExpression : ""); //$NON-NLS-1$
}
});
this.disableItem.update();
init();
}
protected void init() {
this.rDataTableListener= new IRDataTableListener() {
@Override
public void inputChanged(final IRDataTableInput input, final RDataTableContentDescription description) {
if (description != null) {
RDataFilterPage.this.container.updateInput(description);
}
}
};
this.editor.getRDataTable().addTableListener(this.rDataTableListener);
this.filterPostListener= new IFilterListener() {
@Override
public void filterChanged() {
final RDataTableComposite rDataTable= RDataFilterPage.this.editor.getRDataTable();
if (!UIAccess.isOkToUse(rDataTable)) {
return;
}
if (rDataTable.getDescription() == RDataFilterPage.this.container.getDescription()) {
final FilterSet filterSet= RDataFilterPage.this.container.getFilterSet();
if (filterSet.getEnabled()) {
rDataTable.setFilter(RDataFilterPage.this.container.getFilterSet().getFilterRExpression());
}
else {
rDataTable.setFilter(null);
}
}
}
};
this.container.getFilterSet().addPostListener(this.filterPostListener);
}
@Override
public Control getControl() {
return this.composite;
}
@Override
public void setFocus() {
this.scrollComposite.getContent().setFocus();
}
@Override
public void dispose() {
super.dispose();
RDataTableComposite rDataTable= this.editor.getRDataTable();
if (!UIAccess.isOkToUse(rDataTable)) {
rDataTable= null;
}
if (this.rDataTableListener != null && rDataTable != null) {
rDataTable.removeTableListener(this.rDataTableListener);
this.rDataTableListener= null;
}
if (this.filterPostListener != null) {
this.container.getFilterSet().removePostListener(this.filterPostListener);
this.filterPostListener= null;
}
if (rDataTable != null) {
rDataTable.setFilter(null);
}
this.container.dispose();
}
}