blob: 3ba6be474ca8297f6c543c6fc8bc6b1a89285a93 [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2013, 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.r.ui.editors;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExecutableExtension;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.search.ui.NewSearchUI;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.handlers.HandlerUtil;
import org.eclipse.statet.ecommons.ui.workbench.WorkbenchUIUtils;
import org.eclipse.statet.internal.r.ui.search.RElementSearch;
import org.eclipse.statet.internal.r.ui.search.RElementSearchQuery;
import org.eclipse.statet.ltk.model.core.elements.ISourceUnit;
import org.eclipse.statet.ltk.ui.LTKUI;
import org.eclipse.statet.ltk.ui.sourceediting.ISourceEditor;
import org.eclipse.statet.ltk.ui.util.LTKSelectionUtils;
import org.eclipse.statet.ltk.ui.util.LTKWorkbenchUIUtil;
import org.eclipse.statet.r.core.model.IRSourceUnit;
import org.eclipse.statet.r.core.model.RElementAccess;
import org.eclipse.statet.r.core.model.RElementName;
import org.eclipse.statet.r.core.refactoring.RElementSearchProcessor;
import org.eclipse.statet.r.core.refactoring.RElementSearchProcessor.Mode;
import org.eclipse.statet.r.core.refactoring.RRefactoringAdapter;
import org.eclipse.statet.r.core.rsource.ast.RAstNode;
import org.eclipse.statet.r.ui.RUI;
public class RElementSearchHandler extends AbstractHandler implements IExecutableExtension {
public static RElementSearchProcessor.Mode parScope2Mode(final String par) {
if (par == LTKUI.SEARCH_SCOPE_WORKSPACE_PARAMETER_VALUE) {
return Mode.WORKSPACE;
}
if (par == LTKUI.SEARCH_SCOPE_PROJECT_PARAMETER_VALUE) {
return Mode.CURRENT_PROJECT;
}
if (par == LTKUI.SEARCH_SCOPE_FILE_PARAMETER_VALUE) {
return Mode.CURRENT_FILE;
}
return null;
}
private String commandId;
private final RRefactoringAdapter ltkAdapter= new RRefactoringAdapter();
public RElementSearchHandler(final String commandId) {
this.commandId= commandId;
}
public RElementSearchHandler() {
}
@Override
public void setInitializationData(final IConfigurationElement config,
final String propertyName, final Object data) throws CoreException {
if (this.commandId != null) {
return;
}
final String s= config.getAttribute("commandId"); //$NON-NLS-1$
if (s != null && !s.isEmpty()) {
this.commandId= s.intern();
}
}
@Override
public Object execute(final ExecutionEvent event) throws ExecutionException {
final IWorkbenchPart part= HandlerUtil.getActivePart(event);
final Mode mode= parScope2Mode(event.getParameter(LTKUI.SEARCH_SCOPE_PARAMETER_ID));
if (part == null || mode == null) {
return null;
}
final ISelection selection= WorkbenchUIUtils.getCurrentSelection(event.getApplicationContext());
IStatus status= null;
if (selection instanceof ITextSelection) {
final ITextSelection textSelection= (ITextSelection) selection;
final ISourceEditor editor= part.getAdapter(ISourceEditor.class);
if (editor != null) {
final ISourceUnit su= editor.getSourceUnit();
if (su instanceof IRSourceUnit) {
final IProgressMonitor monitor= new NullProgressMonitor();
final RAstNode node= this.ltkAdapter.searchPotentialNameNode(su,
LTKSelectionUtils.toTextRegion(textSelection), false, monitor );
if (node != null) {
final RElementAccess mainAccess= RElementAccess.getMainElementAccessOfNameNode(node);
final RElementAccess subAccess= RElementAccess.getElementAccessOfNameNode(node);
if (mainAccess != null && subAccess != null) {
final RElementName name= RElementName.create(mainAccess, subAccess.getNextSegment(), false);
status= startSearch(name, (IRSourceUnit) su, mainAccess, mode);
}
}
}
}
}
if (status == null) {
status= new Status(IStatus.ERROR, RUI.BUNDLE_ID,
"The operation is unavailable on the current selection." );
}
if (status.getSeverity() == IStatus.ERROR) {
LTKWorkbenchUIUtil.indicateStatus(status, event);
}
return status;
}
protected IStatus startSearch(final RElementName name,
final IRSourceUnit sourceUnit, final RElementAccess mainAccess,
final Mode mode) {
final RElementSearch searchProcessor= new RElementSearch(name, sourceUnit, mainAccess,
mode, (this.commandId == LTKUI.SEARCH_WRITE_ELEMENT_ACCESS_COMMAND_ID) );
if (searchProcessor.getStatus().getSeverity() >= IStatus.ERROR
|| searchProcessor.getMode() == Mode.LOCAL_FRAME) {
return null; // default error message
}
if (searchProcessor.getMode() != mode && searchProcessor.getMode() == Mode.CURRENT_FILE) {
return new Status(IStatus.ERROR, RUI.BUNDLE_ID,
"The search scope is not available for the current selection." );
}
final RElementSearchQuery query= new RElementSearchQuery(searchProcessor);
NewSearchUI.runQueryInBackground(query);
return Status.OK_STATUS;
}
}