blob: 984d9262594a0c296c32f25ab60c2b6a611fc3d3 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2009 IBM Corporation 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:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.internal.ui.search;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.commands.ActionHandler;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.IPartListener2;
import org.eclipse.ui.IWorkbenchCommandConstants;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPartReference;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.handlers.IHandlerService;
import org.eclipse.ui.part.IPageSite;
import org.eclipse.ui.texteditor.ITextEditor;
import org.eclipse.search.ui.NewSearchUI;
import org.eclipse.search.ui.text.AbstractTextSearchResult;
import org.eclipse.search.ui.text.AbstractTextSearchViewPage;
import org.eclipse.search.ui.text.Match;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.ITypeRoot;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.ui.JavaUI;
import org.eclipse.jdt.ui.SharedASTProvider;
import org.eclipse.jdt.internal.ui.JavaPlugin;
import org.eclipse.jdt.internal.ui.actions.AbstractToggleLinkingAction;
import org.eclipse.jdt.internal.ui.viewsupport.ColoringLabelProvider;
import org.eclipse.jdt.internal.ui.viewsupport.ISelectionListenerWithAST;
import org.eclipse.jdt.internal.ui.viewsupport.SelectionListenerWithASTManager;
public class OccurrencesSearchResultPage extends AbstractTextSearchViewPage {
private static final String DIALOGSTORE_LINKEDITORS= "TypeHierarchyViewPart.linkeditors"; //$NON-NLS-1$
private TextSearchTableContentProvider fContentProvider;
private boolean fLinkingEnabled;
private AbstractToggleLinkingAction fToggleLinkingAction;
private LinkWithEditorListener fLinkWithEditorListener;
private class LinkWithEditorListener implements IPartListener2, ISelectionListenerWithAST {
private ITextEditor fActiveEditor;
private boolean fIsVisible;
public void install(IWorkbenchPage page) {
page.addPartListener(this);
fIsVisible= page.isPartVisible(getViewPart());
if (fIsVisible) {
installOnActiveEditor(page);
}
}
private void installOnActiveEditor(IWorkbenchPage page) {
IEditorPart activeEditor= page.getActiveEditor();
if (activeEditor instanceof ITextEditor) {
editorActive(activeEditor);
ISelection selection= activeEditor.getSite().getSelectionProvider().getSelection();
ITypeRoot typeRoot= JavaUI.getEditorInputTypeRoot(activeEditor.getEditorInput());
if (typeRoot != null && selection instanceof ITextSelection) {
CompilationUnit astRoot= SharedASTProvider.getAST(typeRoot, SharedASTProvider.WAIT_ACTIVE_ONLY, null);
if (astRoot != null) {
preformEditorSelectionChanged((ITextSelection) selection, astRoot);
}
}
}
}
private void uninstallOnActiveEditor() {
if (fActiveEditor != null) {
SelectionListenerWithASTManager.getDefault().removeListener(fActiveEditor, this);
fActiveEditor= null;
}
}
public void uninstall(IWorkbenchPage page) {
page.removePartListener(this);
uninstallOnActiveEditor();
}
public void partActivated(IWorkbenchPartReference partRef) {
if (fIsVisible && partRef instanceof IEditorReference) {
editorActive(((IEditorReference) partRef).getEditor(true));
}
}
private void editorActive(IEditorPart editor) {
if (editor instanceof ITextEditor) {
if (editor != fActiveEditor) {
setInput(null, null);
}
fActiveEditor= (ITextEditor) editor;
SelectionListenerWithASTManager.getDefault().addListener(fActiveEditor, this);
}
}
public void partDeactivated(IWorkbenchPartReference partRef) {
}
public void selectionChanged(IEditorPart part, ITextSelection selection, CompilationUnit astRoot) {
preformEditorSelectionChanged(selection, astRoot);
}
public void partVisible(IWorkbenchPartReference partRef) {
if (NewSearchUI.SEARCH_VIEW_ID.equals(partRef.getId()) && partRef.getPart(true) == getViewPart()) {
if (fActiveEditor == null) {
fIsVisible= true;
}
}
}
public void partHidden(IWorkbenchPartReference partRef) {
if (NewSearchUI.SEARCH_VIEW_ID.equals(partRef.getId()) && partRef.getPart(true) == getViewPart()) {
fIsVisible= false;
uninstallOnActiveEditor();
} else if (partRef instanceof IEditorReference && partRef.getPart(true) == fActiveEditor) {
uninstallOnActiveEditor();
}
}
public void partBroughtToTop(IWorkbenchPartReference partRef) {
}
public void partClosed(IWorkbenchPartReference partRef) {
if (partRef instanceof IEditorReference && partRef.getPart(true) == fActiveEditor) {
uninstallOnActiveEditor();
}
}
public void partInputChanged(IWorkbenchPartReference partRef) {
}
public void partOpened(IWorkbenchPartReference partRef) {
}
}
private class ToggleLinkingAction extends AbstractToggleLinkingAction {
@Override
public void run() {
setLinkingEnabled(isChecked());
}
}
public OccurrencesSearchResultPage() {
super(AbstractTextSearchViewPage.FLAG_LAYOUT_FLAT);
fLinkWithEditorListener= new LinkWithEditorListener();
fLinkingEnabled= false;
fToggleLinkingAction= new ToggleLinkingAction();
fToggleLinkingAction.setActionDefinitionId(IWorkbenchCommandConstants.NAVIGATE_TOGGLE_LINK_WITH_EDITOR);
}
@Override
public void init(IPageSite pageSite) {
super.init(pageSite);
// wait until site is set
setLinkingEnabled(getDialogSettings().getBoolean(DIALOGSTORE_LINKEDITORS));
}
@Override
public void dispose() {
if (fLinkingEnabled) {
fLinkWithEditorListener.uninstall(getSite().getPage());
}
super.dispose();
}
@Override
protected void fillToolbar(IToolBarManager tbm) {
super.fillToolbar(tbm);
tbm.add(fToggleLinkingAction);
}
@Override
public void createControl(Composite parent) {
super.createControl(parent);
IActionBars bars= getSite().getActionBars();
IMenuManager menu= bars.getMenuManager();
menu.add(fToggleLinkingAction);
IHandlerService handlerService= (IHandlerService) getSite().getService(IHandlerService.class);
handlerService.activateHandler(IWorkbenchCommandConstants.NAVIGATE_TOGGLE_LINK_WITH_EDITOR, new ActionHandler(fToggleLinkingAction));
}
/*
* @see org.eclipse.search.ui.text.AbstractTextSearchViewPage#showMatch(org.eclipse.search.ui.text.Match, int, int)
*/
@Override
protected void showMatch(Match match, int currentOffset, int currentLength, boolean activate) throws PartInitException {
JavaElementLine element= (JavaElementLine) match.getElement();
IJavaElement javaElement= element.getJavaElement();
try {
IEditorPart editor= JavaUI.openInEditor(javaElement, false, false);
if (editor instanceof ITextEditor) {
ITextEditor textEditor= (ITextEditor) editor;
textEditor.selectAndReveal(currentOffset, currentLength);
}
// activating at the end avoids an outdated selection event from JavaUI.openInEditor(..):
if (editor != null && activate)
editor.getEditorSite().getPage().activate(editor);
} catch (PartInitException e1) {
return;
} catch (JavaModelException e1) {
return;
}
}
/*
* @see org.eclipse.search.ui.text.AbstractTextSearchViewPage#elementsChanged(java.lang.Object[])
*/
@Override
protected void elementsChanged(Object[] objects) {
if (fContentProvider != null)
fContentProvider.elementsChanged(objects);
}
/*
* @see org.eclipse.search.ui.text.AbstractTextSearchViewPage#clear()
*/
@Override
protected void clear() {
if (fContentProvider != null)
fContentProvider.clear();
}
/*
* @see org.eclipse.search.ui.text.AbstractTextSearchViewPage#configureTreeViewer(org.eclipse.jface.viewers.TreeViewer)
*/
@Override
protected void configureTreeViewer(TreeViewer viewer) {
throw new IllegalStateException("Doesn't support tree mode."); //$NON-NLS-1$
}
/*
* @see org.eclipse.search.ui.text.AbstractTextSearchViewPage#configureTableViewer(org.eclipse.jface.viewers.TableViewer)
*/
@Override
protected void configureTableViewer(TableViewer viewer) {
viewer.setComparator(new ViewerComparator() {
@Override
public int compare(Viewer v, Object e1, Object e2) {
JavaElementLine jel1= (JavaElementLine) e1;
JavaElementLine jel2= (JavaElementLine) e2;
return jel1.getLine() - jel2.getLine();
}
});
viewer.setLabelProvider(new ColoringLabelProvider(new OccurrencesSearchLabelProvider(this)));
fContentProvider= new TextSearchTableContentProvider();
viewer.setContentProvider(fContentProvider);
}
public boolean isLinkingEnabled() {
return fLinkingEnabled;
}
public void setLinkingEnabled(boolean enabled) {
if (fLinkingEnabled != enabled) {
fLinkingEnabled= enabled;
fToggleLinkingAction.setChecked(enabled);
getDialogSettings().put(DIALOGSTORE_LINKEDITORS, enabled);
if (enabled) {
fLinkWithEditorListener.install(getSite().getPage());
} else {
fLinkWithEditorListener.uninstall(getSite().getPage());
}
}
}
private IDialogSettings getDialogSettings() {
return JavaPlugin.getDefault().getDialogSettingsSection("OccurrencesSearchResultPage"); //$NON-NLS-1$
}
private void preformEditorSelectionChanged(ITextSelection selection, CompilationUnit astRoot) {
if (!isLinkingEnabled()) {
return;
}
IOccurrencesFinder finder;
AbstractTextSearchResult input= getInput();
if (input == null) {
finder= new OccurrencesFinder();
} else {
String id= ((OccurrencesSearchQuery) input.getQuery()).getFinderId();
if (id == OccurrencesFinder.ID) {
finder= new OccurrencesFinder();
} else if (id == ExceptionOccurrencesFinder.ID) {
finder= new ExceptionOccurrencesFinder();
} else {
finder= new ImplementOccurrencesFinder();
}
}
int offset= selection.getOffset();
int length= selection.getLength();
if (finder.initialize(astRoot, offset, length) == null) {
final OccurrencesSearchQuery query= new OccurrencesSearchQuery(finder, astRoot.getTypeRoot());
query.run(null);
OccurrencesSearchResult result= (OccurrencesSearchResult) query.getSearchResult();
final JavaElementLine line= getMatchingLine(result, offset, length);
getSite().getShell().getDisplay().asyncExec(new Runnable() {
public void run() {
setInput(query.getSearchResult(), line == null ? null : new StructuredSelection(line));
}
});
}
}
private static JavaElementLine getMatchingLine(OccurrencesSearchResult result, int offset, int length) {
Object[] elements= result.getElements();
for (int i= 0; i < elements.length; i++) {
JavaElementLine line= (JavaElementLine) elements[i];
Match[] matches= result.getMatches(line);
for (int j= 0; j < matches.length; j++) {
OccurrenceMatch match= (OccurrenceMatch) matches[j];
if (match.getOriginalOffset() <= offset && offset + length <= match.getOriginalOffset() + match.getOriginalLength()) {
return line;
}
}
}
return null;
}
}