/*=============================================================================#
# Copyright (c) 2013-2016 Stephan Wahlbrink (WalWare.de) and others.
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Eclipse Public License v1.0
# which accompanies this distribution, and is available at
# http://www.eclipse.org/legal/epl-v10.html
#
# Contributors:
# Stephan Wahlbrink - initial API and implementation
#=============================================================================*/
package de.walware.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.text.Region;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.search.ui.NewSearchUI;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.handlers.HandlerUtil;
import de.walware.ecommons.ltk.core.model.ISourceUnit;
import de.walware.ecommons.ltk.ui.LTKUI;
import de.walware.ecommons.ltk.ui.sourceediting.ISourceEditor;
import de.walware.ecommons.ltk.ui.util.LTKWorkbenchUIUtil;
import de.walware.ecommons.workbench.ui.WorkbenchUIUtil;
import de.walware.statet.r.core.model.IRSourceUnit;
import de.walware.statet.r.core.model.RElementAccess;
import de.walware.statet.r.core.model.RElementName;
import de.walware.statet.r.core.refactoring.RElementSearchProcessor;
import de.walware.statet.r.core.refactoring.RElementSearchProcessor.Mode;
import de.walware.statet.r.core.refactoring.RRefactoringAdapter;
import de.walware.statet.r.core.rsource.ast.RAstNode;
import de.walware.statet.r.internal.ui.search.RElementSearch;
import de.walware.statet.r.internal.ui.search.RElementSearchQuery;
import de.walware.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_NAME));
if (part == null || mode == null) {
return null;
}
final ISelection selection= WorkbenchUIUtil.getCurrentSelection(event.getApplicationContext());
IStatus status= null;
if (selection instanceof ITextSelection) {
final ITextSelection textSelection= (ITextSelection) selection;
final ISourceEditor editor= (ISourceEditor) 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,
new Region(textSelection.getOffset(), textSelection.getLength()),
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.PLUGIN_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.PLUGIN_ID,
"The search scope is not available for the current selection." );
}
final RElementSearchQuery query= new RElementSearchQuery(searchProcessor);
NewSearchUI.runQueryInBackground(query);
return Status.OK_STATUS;
}
}