///******************************************************************************* // * Copyright (c) 2000, 2007 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.search.ui.text; // //import java.util.ArrayList; //import java.util.HashSet; //import java.util.Iterator; //import java.util.Set; // //import org.eclipse.core.runtime.Assert; //import org.eclipse.core.runtime.IProgressMonitor; //import org.eclipse.core.runtime.ISafeRunnable; //import org.eclipse.core.runtime.IStatus; //import org.eclipse.core.runtime.SafeRunner; //import org.eclipse.core.runtime.Status; // //import org.eclipse.swt.SWT; //import org.eclipse.swt.layout.FillLayout; //import org.eclipse.swt.layout.GridData; //import org.eclipse.swt.widgets.Composite; //import org.eclipse.swt.widgets.Control; //import org.eclipse.swt.widgets.Display; //import org.eclipse.swt.widgets.Menu; //import org.eclipse.swt.widgets.Table; //import org.eclipse.swt.widgets.TableItem; // //import org.eclipse.jface.action.Action; //import org.eclipse.jface.action.IAction; //import org.eclipse.jface.action.IMenuListener; //import org.eclipse.jface.action.IMenuManager; //import org.eclipse.jface.action.IToolBarManager; //import org.eclipse.jface.action.MenuManager; //import org.eclipse.jface.dialogs.ErrorDialog; //import org.eclipse.jface.dialogs.IDialogSettings; //import org.eclipse.jface.util.OpenStrategy; //import org.eclipse.jface.viewers.DecoratingLabelProvider; //import org.eclipse.jface.viewers.IBaseLabelProvider; //import org.eclipse.jface.viewers.IOpenListener; //import org.eclipse.jface.viewers.ISelection; //import org.eclipse.jface.viewers.ISelectionChangedListener; //import org.eclipse.jface.viewers.ISelectionProvider; //import org.eclipse.jface.viewers.IStructuredSelection; //import org.eclipse.jface.viewers.ITreeContentProvider; //import org.eclipse.jface.viewers.OpenEvent; //import org.eclipse.jface.viewers.SelectionChangedEvent; //import org.eclipse.jface.viewers.StructuredViewer; //import org.eclipse.jface.viewers.TableViewer; //import org.eclipse.jface.viewers.TreeViewer; //import org.eclipse.jface.viewers.Viewer; // //import org.eclipse.jface.text.IRegion; //import org.eclipse.jface.text.Position; //import org.eclipse.jface.text.Region; // //import org.eclipse.ui.IActionBars; //import org.eclipse.ui.IMemento; //import org.eclipse.ui.IWorkbenchWindow; //import org.eclipse.ui.PartInitException; //import org.eclipse.ui.PlatformUI; //import org.eclipse.ui.actions.ActionFactory; //import org.eclipse.ui.part.IPageSite; //import org.eclipse.ui.part.Page; //import org.eclipse.ui.part.PageBook; //import org.eclipse.ui.progress.UIJob; //import org.eclipse.ui.texteditor.IUpdate; //import org.eclipse.ui.texteditor.IWorkbenchActionDefinitionIds; // //import org.eclipse.search.ui.IContextMenuConstants; //import org.eclipse.search.ui.IQueryListener; //import org.eclipse.search.ui.ISearchQuery; //import org.eclipse.search.ui.ISearchResult; //import org.eclipse.search.ui.ISearchResultListener; //import org.eclipse.search.ui.ISearchResultPage; //import org.eclipse.search.ui.ISearchResultViewPart; //import org.eclipse.search.ui.NewSearchUI; //import org.eclipse.search.ui.SearchResultEvent; // //import org.eclipse.search.internal.ui.CopyToClipboardAction; //import org.eclipse.search.internal.ui.SearchPlugin; //import org.eclipse.search.internal.ui.SearchPluginImages; //import org.eclipse.search.internal.ui.SelectAllAction; // //import org.eclipse.search2.internal.ui.MatchFilterSelectionAction; //import org.eclipse.search2.internal.ui.InternalSearchUI; //import org.eclipse.search2.internal.ui.MatchFilterAction; //import org.eclipse.search2.internal.ui.SearchMessages; //import org.eclipse.search2.internal.ui.SearchView; //import org.eclipse.search2.internal.ui.basic.views.CollapseAllAction; //import org.eclipse.search2.internal.ui.basic.views.ExpandAllAction; //import org.eclipse.search2.internal.ui.basic.views.INavigate; //import org.eclipse.search2.internal.ui.basic.views.RemoveAllMatchesAction; //import org.eclipse.search2.internal.ui.basic.views.RemoveMatchAction; //import org.eclipse.search2.internal.ui.basic.views.RemoveSelectedMatchesAction; //import org.eclipse.search2.internal.ui.basic.views.SetLayoutAction; //import org.eclipse.search2.internal.ui.basic.views.ShowNextResultAction; //import org.eclipse.search2.internal.ui.basic.views.ShowPreviousResultAction; //import org.eclipse.search2.internal.ui.basic.views.TableViewerNavigator; //import org.eclipse.search2.internal.ui.basic.views.TreeViewerNavigator; //import org.eclipse.search2.internal.ui.text.AnnotationManagers; //import org.eclipse.search2.internal.ui.text.PositionTracker; // ///** // * An abstract base implementation for classes showing // * <code>AbstractTextSearchResult</code> instances. This class assumes that // * the input element set via {@link AbstractTextSearchViewPage#setInput(ISearchResult,Object)} // * is a subclass of {@link AbstractTextSearchResult}. // * This result page supports a tree and/or a table presentation of search // * results. Subclasses can determine which presentations they want to support at // * construction time by passing the appropriate flags. // * Subclasses must customize the viewers for each presentation with a label // * provider and a content provider. <br> // * Changes in the search result are handled by updating the viewer in the // * <code>elementsChanged()</code> and <code>clear()</code> methods. // * // * @since 3.0 // */ //public abstract class AbstractTextSearchViewPage extends Page implements ISearchResultPage { // private class UpdateUIJob extends UIJob { // // public UpdateUIJob() { // super(SearchMessages.AbstractTextSearchViewPage_update_job_name); // setSystem(true); // } // // public IStatus runInUIThread(IProgressMonitor monitor) { // Control control= getControl(); // if (control == null || control.isDisposed()) { // // disposed the control while the UI was posted. // return Status.OK_STATUS; // } // runBatchedClear(); // runBatchedUpdates(); // if (hasMoreUpdates() || isQueryRunning()) { // schedule(500); // } else { // fIsUIUpdateScheduled= false; // turnOnDecoration(); // updateBusyLabel(); // if (fScheduleEnsureSelection) { // fScheduleEnsureSelection= false; // AbstractTextSearchResult result = getInput(); // if (result != null && fViewer.getSelection().isEmpty()) { // navigateNext(true); // } // } // } // fViewPart.updateLabel(); // return Status.OK_STATUS; // } // // /* // * Undocumented for testing only. Used to find UpdateUIJobs. // */ // public boolean belongsTo(Object family) { // return family == AbstractTextSearchViewPage.this; // } // // } // // private class SelectionProviderAdapter implements ISelectionProvider, ISelectionChangedListener { // private ArrayList fListeners= new ArrayList(5); // // public void addSelectionChangedListener(ISelectionChangedListener listener) { // fListeners.add(listener); // } // // public ISelection getSelection() { // return fViewer.getSelection(); // } // // public void removeSelectionChangedListener(ISelectionChangedListener listener) { // fListeners.remove(listener); // } // // public void setSelection(ISelection selection) { // fViewer.setSelection(selection); // } // // public void selectionChanged(SelectionChangedEvent event) { // // forward to my listeners // SelectionChangedEvent wrappedEvent= new SelectionChangedEvent(this, event.getSelection()); // for (Iterator listeners= fListeners.iterator(); listeners.hasNext();) { // ISelectionChangedListener listener= (ISelectionChangedListener) listeners.next(); // listener.selectionChanged(wrappedEvent); // } // } // // } // // private volatile boolean fIsUIUpdateScheduled= false; // private volatile boolean fScheduleEnsureSelection= false; // private static final String KEY_LAYOUT = "org.eclipse.search.resultpage.layout"; //$NON-NLS-1$ // // /** // * An empty array. // */ // protected static final Match[] EMPTY_MATCH_ARRAY= new Match[0]; // // private StructuredViewer fViewer; // private Composite fViewerContainer; // private Control fBusyLabel; // private PageBook fPagebook; // private boolean fIsBusyShown; // private ISearchResultViewPart fViewPart; // private Set fBatchedUpdates; // private boolean fBatchedClearAll; // // private ISearchResultListener fListener; // private IQueryListener fQueryListener; // private MenuManager fMenu; // private AbstractTextSearchResult fInput; // // Actions // private CopyToClipboardAction fCopyToClipboardAction; // private Action fRemoveSelectedMatches; // private Action fRemoveCurrentMatch; // private Action fRemoveAllResultsAction; // private Action fShowNextAction; // private Action fShowPreviousAction; // private SetLayoutAction fFlatAction; // private SetLayoutAction fHierarchicalAction; // private int fCurrentLayout; // private int fCurrentMatchIndex = 0; // private String fId; // private int fSupportedLayouts; // private SelectionProviderAdapter fViewerAdapter; // private SelectAllAction fSelectAllAction; // // private IAction[] fFilterActions; // private Integer fElementLimit; // // /** // * Flag (<code>value 1</code>) denoting flat list layout. // */ // public static final int FLAG_LAYOUT_FLAT = 1; // /** // * Flag (<code>value 2</code>) denoting tree layout. // */ // public static final int FLAG_LAYOUT_TREE = 2; // // // /** // * This constructor must be passed a combination of layout flags combined // * with bitwise or. At least one flag must be passed in (i.e. 0 is not a // * permitted value). // * // * @param supportedLayouts // * flags determining which layout options this page supports. // * Must not be 0 // * @see #FLAG_LAYOUT_FLAT // * @see #FLAG_LAYOUT_TREE // */ // protected AbstractTextSearchViewPage(int supportedLayouts) { // fSupportedLayouts = supportedLayouts; // initLayout(); // fRemoveAllResultsAction = new RemoveAllMatchesAction(this); // fRemoveSelectedMatches = new RemoveSelectedMatchesAction(this); // fRemoveCurrentMatch = new RemoveMatchAction(this); // fShowNextAction = new ShowNextResultAction(this); // fShowPreviousAction = new ShowPreviousResultAction(this); // fCopyToClipboardAction = new CopyToClipboardAction(); // fSelectAllAction= new SelectAllAction(); // createLayoutActions(); // fBatchedUpdates = new HashSet(); // fBatchedClearAll= false; // // fListener = new ISearchResultListener() { // public void searchResultChanged(SearchResultEvent e) { // handleSearchResultChanged(e); // } // }; // fFilterActions= null; // fElementLimit= null; // } // // private void initLayout() { // if (supportsTreeLayout()) // fCurrentLayout = FLAG_LAYOUT_TREE; // else // fCurrentLayout = FLAG_LAYOUT_FLAT; // } // // /** // * Constructs this page with the default layout flags. // * // * @see AbstractTextSearchViewPage#AbstractTextSearchViewPage(int) // */ // protected AbstractTextSearchViewPage() { // this(FLAG_LAYOUT_FLAT | FLAG_LAYOUT_TREE); // } // // // private void createLayoutActions() { // if (countBits(fSupportedLayouts) > 1) { // fFlatAction = new SetLayoutAction(this, SearchMessages.AbstractTextSearchViewPage_flat_layout_label, SearchMessages.AbstractTextSearchViewPage_flat_layout_tooltip, FLAG_LAYOUT_FLAT); // fHierarchicalAction = new SetLayoutAction(this, SearchMessages.AbstractTextSearchViewPage_hierarchical_layout_label, SearchMessages.AbstractTextSearchViewPage_hierarchical_layout_tooltip, FLAG_LAYOUT_TREE); // SearchPluginImages.setImageDescriptors(fFlatAction, SearchPluginImages.T_LCL, SearchPluginImages.IMG_LCL_SEARCH_FLAT_LAYOUT); // SearchPluginImages.setImageDescriptors(fHierarchicalAction, SearchPluginImages.T_LCL, SearchPluginImages.IMG_LCL_SEARCH_HIERARCHICAL_LAYOUT); // } // } // // private int countBits(int layoutFlags) { // int bitCount = 0; // for (int i = 0; i < 32; i++) { // if (layoutFlags % 2 == 1) // bitCount++; // layoutFlags >>= 1; // } // return bitCount; // } // // private boolean supportsTreeLayout() { // return isLayoutSupported(FLAG_LAYOUT_TREE); // } // // /** // * Returns a dialog settings object for this search result page. There will be // * one dialog settings object per search result page id. // * // * @return the dialog settings for this search result page // * @see AbstractTextSearchViewPage#getID() // */ // protected IDialogSettings getSettings() { // IDialogSettings parent = SearchPlugin.getDefault().getDialogSettings(); // IDialogSettings settings = parent.getSection(getID()); // if (settings == null) // settings = parent.addNewSection(getID()); // return settings; // } // // /** // * {@inheritDoc} // */ // public void setID(String id) { // fId = id; // } // // /** // * {@inheritDoc} // */ // public String getID() { // return fId; // } // // /** // * {@inheritDoc} // */ // public String getLabel() { // AbstractTextSearchResult result= getInput(); // if (result == null) // return ""; //$NON-NLS-1$ // return result.getLabel(); // } // // /** // * Opens an editor on the given element and selects the given range of text. // * If a search results implements a <code>IFileMatchAdapter</code>, match // * locations will be tracked and the current match range will be passed into // * this method. // * // * @param match // * the match to show // * @param currentOffset // * the current start offset of the match // * @param currentLength // * the current length of the selection // * @throws PartInitException // * if an editor can't be opened // * // * @see org.eclipse.core.filebuffers.ITextFileBufferManager // * @see IFileMatchAdapter // * @deprecated // */ // protected void showMatch(Match match, int currentOffset, int currentLength) throws PartInitException { // } // // /** // * Opens an editor on the given element and selects the given range of text. // * If a search results implements a <code>IFileMatchAdapter</code>, match // * locations will be tracked and the current match range will be passed into // * this method. // * If the <code>activate</code> parameter is <code>true</code> the opened editor // * should have be activated. Otherwise the focus should not be changed. // * // * @param match // * the match to show // * @param currentOffset // * the current start offset of the match // * @param currentLength // * the current length of the selection // * @param activate // * whether to activate the editor. // * @throws PartInitException // * if an editor can't be opened // * // * @see org.eclipse.core.filebuffers.ITextFileBufferManager // * @see IFileMatchAdapter // */ // protected void showMatch(Match match, int currentOffset, int currentLength, boolean activate) throws PartInitException { // showMatch(match, currentOffset, currentLength); // } // // /** // * This method is called whenever the set of matches for the given elements // * changes. This method is guaranteed to be called in the UI thread. Note // * that this notification is asynchronous. i.e. further changes may have // * occurred by the time this method is called. They will be described in a // * future call. // * // * @param objects // * array of objects that has to be refreshed // */ // protected abstract void elementsChanged(Object[] objects); // // /** // * This method is called whenever all elements have been removed from the // * shown <code>AbstractSearchResult</code>. This method is guaranteed to // * be called in the UI thread. Note that this notification is asynchronous. // * i.e. further changes may have occurred by the time this method is called. // * They will be described in a future call. // */ // protected abstract void clear(); // // /** // * Configures the given viewer. Implementers have to set at least a content // * provider and a label provider. This method may be called if the page was // * constructed with the flag <code>FLAG_LAYOUT_TREE</code>. // * // * @param viewer the viewer to be configured // */ // protected abstract void configureTreeViewer(TreeViewer viewer); // // /** // * Configures the given viewer. Implementers have to set at least a content // * provider and a label provider. This method may be called if the page was // * constructed with the flag <code>FLAG_LAYOUT_FLAT</code>. // * // * @param viewer the viewer to be configured // */ // protected abstract void configureTableViewer(TableViewer viewer); // // /** // * Fills the context menu for this page. Subclasses may override this // * method. // * // * @param mgr the menu manager representing the context menu // */ // protected void fillContextMenu(IMenuManager mgr) { // mgr.appendToGroup(IContextMenuConstants.GROUP_SHOW, fShowNextAction); // mgr.appendToGroup(IContextMenuConstants.GROUP_SHOW, fShowPreviousAction); // mgr.appendToGroup(IContextMenuConstants.GROUP_EDIT, fCopyToClipboardAction); // if (getCurrentMatch() != null) // mgr.appendToGroup(IContextMenuConstants.GROUP_REMOVE_MATCHES, fRemoveCurrentMatch); // if (canRemoveMatchesWith(getViewer().getSelection())) // mgr.appendToGroup(IContextMenuConstants.GROUP_REMOVE_MATCHES, fRemoveSelectedMatches); // mgr.appendToGroup(IContextMenuConstants.GROUP_REMOVE_MATCHES, fRemoveAllResultsAction); // } // // /** // * Determines whether the provided selection can be used to remove matches from the result. // * @since 3.2 // */ // protected boolean canRemoveMatchesWith(ISelection selection) { // return !selection.isEmpty(); // } // // /** // * {@inheritDoc} // */ // public void createControl(Composite parent) { // fQueryListener = createQueryListener(); // fMenu = new MenuManager("#PopUp"); //$NON-NLS-1$ // fMenu.setRemoveAllWhenShown(true); // fMenu.setParent(getSite().getActionBars().getMenuManager()); // fMenu.addMenuListener(new IMenuListener() { // public void menuAboutToShow(IMenuManager mgr) { // SearchView.createContextMenuGroups(mgr); // fillContextMenu(mgr); // fViewPart.fillContextMenu(mgr); // } // }); // fPagebook = new PageBook(parent, SWT.NULL); // fPagebook.setLayoutData(new GridData(GridData.FILL_BOTH)); // fBusyLabel = createBusyControl(); // fViewerContainer = new Composite(fPagebook, SWT.NULL); // fViewerContainer.setLayoutData(new GridData(GridData.FILL_BOTH)); // fViewerContainer.setSize(100, 100); // fViewerContainer.setLayout(new FillLayout()); // // fViewerAdapter= new SelectionProviderAdapter(); // getSite().setSelectionProvider(fViewerAdapter); // // Register menu // getSite().registerContextMenu(fViewPart.getViewSite().getId(), fMenu, fViewerAdapter); // // // createViewer(fViewerContainer, fCurrentLayout); // showBusyLabel(fIsBusyShown); // NewSearchUI.addQueryListener(fQueryListener); // // } // // private Control createBusyControl() { // Table busyLabel = new Table(fPagebook, SWT.NONE); // TableItem item = new TableItem(busyLabel, SWT.NONE); // item.setText(SearchMessages.AbstractTextSearchViewPage_searching_label); // busyLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); // return busyLabel; // } // // private synchronized void scheduleUIUpdate() { // if (!fIsUIUpdateScheduled) { // fIsUIUpdateScheduled= true; // new UpdateUIJob().schedule(); // } // } // // private IQueryListener createQueryListener() { // return new IQueryListener() { // public void queryAdded(ISearchQuery query) { // // ignore // } // // public void queryRemoved(ISearchQuery query) { // // ignore // } // // public void queryStarting(final ISearchQuery query) { // final Runnable runnable1 = new Runnable() { // public void run() { // updateBusyLabel(); // AbstractTextSearchResult result = getInput(); // // if (result == null || !result.getQuery().equals(query)) { // return; // } // turnOffDecoration(); // scheduleUIUpdate(); // } // // // }; // asyncExec(runnable1); // } // // public void queryFinished(final ISearchQuery query) { // // handle the end of the query in the UIUpdateJob, as ui updates // // may not be finished here. // postEnsureSelection(); // } // }; // } // // /** // * Posts a UI update to make sure an element is selected. // * @since 3.2 // */ // protected void postEnsureSelection() { // fScheduleEnsureSelection= true; // scheduleUIUpdate(); // } // // // private void updateBusyLabel() { // AbstractTextSearchResult result = getInput(); // boolean shouldShowBusy = result != null && NewSearchUI.isQueryRunning(result.getQuery()) && result.getMatchCount() == 0; // if (shouldShowBusy == fIsBusyShown) // return; // fIsBusyShown = shouldShowBusy; // showBusyLabel(fIsBusyShown); // } // // private void showBusyLabel(boolean shouldShowBusy) { // if (shouldShowBusy) // fPagebook.showPage(fBusyLabel); // else // fPagebook.showPage(fViewerContainer); // } // // /** // * Determines whether a certain layout is supported by this search result // * page. // * // * @param layout the layout to test for // * @return whether the given layout is supported or not // * // * @see AbstractTextSearchViewPage#AbstractTextSearchViewPage(int) // */ // public boolean isLayoutSupported(int layout) { // return (layout & fSupportedLayouts) == layout; // } // // /** // * Sets the layout of this search result page. The layout must be on of // * <code>FLAG_LAYOUT_FLAT</code> or <code>FLAG_LAYOUT_TREE</code> and // * it must be one of the values passed during construction of this search // * result page. // * @param layout the new layout // * // * @see AbstractTextSearchViewPage#isLayoutSupported(int) // */ // public void setLayout(int layout) { // Assert.isTrue(countBits(layout) == 1); // Assert.isTrue(isLayoutSupported(layout)); // if (countBits(fSupportedLayouts) < 2) // return; // if (fCurrentLayout == layout) // return; // fCurrentLayout = layout; // ISelection selection = fViewer.getSelection(); // disconnectViewer(); // disposeViewer(); // createViewer(fViewerContainer, layout); // fViewerContainer.layout(true); // connectViewer(fInput); // fViewer.setSelection(selection, true); // getSettings().put(KEY_LAYOUT, layout); // getViewPart().updateLabel(); // } // // private void disposeViewer() { // fViewer.removeSelectionChangedListener(fViewerAdapter); // fViewer.getControl().dispose(); // fViewer = null; // } // // private void updateLayoutActions() { // if (fFlatAction != null) // fFlatAction.setChecked(fCurrentLayout == fFlatAction.getLayout()); // if (fHierarchicalAction != null) // fHierarchicalAction.setChecked(fCurrentLayout == fHierarchicalAction.getLayout()); // } // // /** // * Return the layout this page is currently using. // * // * @return the layout this page is currently using // * // * @see #FLAG_LAYOUT_FLAT // * @see #FLAG_LAYOUT_TREE // */ // public int getLayout() { // return fCurrentLayout; // } // // private void createViewer(Composite parent, int layout) { // if ((layout & FLAG_LAYOUT_FLAT) != 0) { // TableViewer viewer = createTableViewer(parent); // fViewer = viewer; // configureTableViewer(viewer); // } else if ((layout & FLAG_LAYOUT_TREE) != 0) { // TreeViewer viewer = createTreeViewer(parent); // fViewer = viewer; // configureTreeViewer(viewer); // } // // fCopyToClipboardAction.setViewer(fViewer); // fSelectAllAction.setViewer(fViewer); // // IToolBarManager tbm = getSite().getActionBars().getToolBarManager(); // tbm.removeAll(); // SearchView.createToolBarGroups(tbm); // fillToolbar(tbm); // tbm.update(false); // // fViewer.addOpenListener(new IOpenListener() { // public void open(OpenEvent event) { // handleOpen(event); // } // }); // fViewer.addSelectionChangedListener(new ISelectionChangedListener() { // public void selectionChanged(SelectionChangedEvent event) { // fCurrentMatchIndex = -1; // fRemoveSelectedMatches.setEnabled(canRemoveMatchesWith(event.getSelection())); // } // }); // // fViewer.addSelectionChangedListener(fViewerAdapter); // // Menu menu = fMenu.createContextMenu(fViewer.getControl()); // fViewer.getControl().setMenu(menu); // // updateLayoutActions(); // getViewPart().updateLabel(); // } // // /** // * Creates the tree viewer to be shown on this page. Clients may override // * this method. // * // * @param parent the parent widget // * @return returns a newly created <code>TreeViewer</code>. // */ // protected TreeViewer createTreeViewer(Composite parent) { // return new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); // } // // /** // * Creates the table viewer to be shown on this page. Clients may override // * this method. // * // * @param parent the parent widget // * @return returns a newly created <code>TableViewer</code> // */ // protected TableViewer createTableViewer(Composite parent) { // return new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION); // } // // /** // * {@inheritDoc} // */ // public void setFocus() { // Control control = fViewer.getControl(); // if (control != null && !control.isDisposed()) // control.setFocus(); // } // // /** // * {@inheritDoc} // */ // public Control getControl() { // return fPagebook; // } // // /** // * {@inheritDoc} // */ // public void setInput(ISearchResult newSearch, Object viewState) { // if (newSearch != null && !(newSearch instanceof AbstractTextSearchResult)) // return; // ignore // // AbstractTextSearchResult oldSearch= fInput; // if (oldSearch != null) { // disconnectViewer(); // removeFilterActionsFromViewMenu(fFilterActions); // oldSearch.removeListener(fListener); // AnnotationManagers.removeSearchResult(getSite().getWorkbenchWindow(), oldSearch); // } // fInput= (AbstractTextSearchResult) newSearch; // // if (fInput != null) { // AnnotationManagers.addSearchResult(getSite().getWorkbenchWindow(), fInput); // // fInput.addListener(fListener); // connectViewer(fInput); // if (viewState instanceof ISelection) // fViewer.setSelection((ISelection) viewState, true); // else // navigateNext(true); // // updateBusyLabel(); // turnOffDecoration(); // scheduleUIUpdate(); // // fFilterActions= addFilterActionsToViewMenu(); // } // } // // private void removeFilterActionsFromViewMenu(IAction[] filterActions) { // IActionBars bars= getSite().getActionBars(); // IMenuManager menu= bars.getMenuManager(); // // if (filterActions != null) { // for (int i= 0; i < filterActions.length; i++) { // menu.remove(filterActions[i].getId()); // } // } // menu.remove(MatchFilterSelectionAction.ACTION_ID); // } // // private IAction[] addFilterActionsToViewMenu() { // AbstractTextSearchResult input= getInput(); // if (input == null) { // return null; // } // // MatchFilter[] allMatchFilters= input.getAllMatchFilters(); // if (allMatchFilters == null && getElementLimit() == null) { // return null; // } // // IActionBars bars= getSite().getActionBars(); // IMenuManager menu= bars.getMenuManager(); // // menu.prependToGroup(IContextMenuConstants.GROUP_FILTERING, new MatchFilterSelectionAction(this)); // // if (allMatchFilters != null) { // MatchFilterAction[] actions= new MatchFilterAction[allMatchFilters.length]; // for (int i= allMatchFilters.length - 1; i >= 0; i--) { // MatchFilterAction filterAction= new MatchFilterAction(this, allMatchFilters[i]); // actions[i]= filterAction; // menu.prependToGroup(IContextMenuConstants.GROUP_FILTERING, filterAction); // } // return actions; // } // return null; // } // // private void updateFilterActions(IAction[] filterActions) { // if (filterActions != null) { // for (int i= 0; i < filterActions.length; i++) { // IAction curr= filterActions[i]; // if (curr instanceof IUpdate) { // ((IUpdate) curr).update(); // } // } // } // } // // /** // * {@inheritDoc} // */ // public Object getUIState() { // return fViewer.getSelection(); // } // // private void connectViewer(AbstractTextSearchResult search) { // fViewer.setInput(search); // } // // private void disconnectViewer() { // fViewer.setInput(null); // } // // /** // * Returns the viewer currently used in this page. // * // * @return the currently used viewer or <code>null</code> if none has been // * created yet. // */ // protected StructuredViewer getViewer() { // return fViewer; // } // // private void showMatch(final Match match, final boolean activateEditor) { // ISafeRunnable runnable = new ISafeRunnable() { // public void handleException(Throwable exception) { // if (exception instanceof PartInitException) { // PartInitException pie = (PartInitException) exception; // ErrorDialog.openError(getSite().getShell(), SearchMessages.DefaultSearchViewPage_show_match, SearchMessages.DefaultSearchViewPage_error_no_editor, pie.getStatus()); // } // } // // public void run() throws Exception { // IRegion location= getCurrentMatchLocation(match); // showMatch(match, location.getOffset(), location.getLength(), activateEditor); // } // }; // SafeRunner.run(runnable); // } // // /** // * Returns the currently shown result. // * // * @return the previously set result or <code>null</code> // * // * @see AbstractTextSearchViewPage#setInput(ISearchResult, Object) // */ // public AbstractTextSearchResult getInput() { // return fInput; // } // // /** // * Selects the element corresponding to the next match and shows the match // * in an editor. Note that this will cycle back to the first match after the // * last match. // */ // public void gotoNextMatch() { // gotoNextMatch(false); // } // // private void gotoNextMatch(boolean activateEditor) { // fCurrentMatchIndex++; // Match nextMatch = getCurrentMatch(); // if (nextMatch == null) { // navigateNext(true); // fCurrentMatchIndex = 0; // } // showCurrentMatch(activateEditor); // } // // /** // * Selects the element corresponding to the previous match and shows the // * match in an editor. Note that this will cycle back to the last match // * after the first match. // */ // public void gotoPreviousMatch() { // gotoPreviousMatch(false); // } // // private void gotoPreviousMatch(boolean activateEditor) { // fCurrentMatchIndex--; // Match nextMatch = getCurrentMatch(); // if (nextMatch == null) { // navigateNext(false); // fCurrentMatchIndex = getDisplayedMatchCount(getFirstSelectedElement()) - 1; // } // showCurrentMatch(activateEditor); // } // // private void navigateNext(boolean forward) { // INavigate navigator = null; // if (fViewer instanceof TableViewer) { // navigator = new TableViewerNavigator((TableViewer) fViewer); // } else { // navigator = new TreeViewerNavigator(this, (TreeViewer) fViewer); // } // navigator.navigateNext(forward); // } // // private boolean showCurrentMatch(boolean activateEditor) { // Match currentMatch = getCurrentMatch(); // if (currentMatch != null) { // showMatch(currentMatch, activateEditor); // return true; // } // return false; // } // // /** // * Returns the currently selected match. // * // * @return the selected match or <code>null</code> if none are selected // */ // public Match getCurrentMatch() { // Object element = getFirstSelectedElement(); // if (element != null) { // Match[] matches = getDisplayedMatches(element); // if (fCurrentMatchIndex >= 0 && fCurrentMatchIndex < matches.length) // return matches[fCurrentMatchIndex]; // } // return null; // } // // /** // * Returns the matches that are currently displayed for the given element. // * If {@link AbstractTextSearchResult#getActiveMatchFilters()} is not null, only matches are returned // * that are not filtered by the match filters. If {@link AbstractTextSearchResult#getActiveMatchFilters()} is // * null all matches of the given element are returned. // * Any action operating on the visible matches in the search // * result page should use this method to get the matches for a search // * result (instead of asking the search result directly). // * // * @param element // * The element to get the matches for // * @return The matches displayed for the given element. If the current input // * of this page is <code>null</code>, an empty array is returned // * @see AbstractTextSearchResult#getMatches(Object) // */ // public Match[] getDisplayedMatches(Object element) { // AbstractTextSearchResult result= getInput(); // if (result == null) // return EMPTY_MATCH_ARRAY; // Match[] matches= result.getMatches(element); // if (result.getActiveMatchFilters() == null) // default behaviour: filter state not used, all matches shown // return matches; // // int count= 0; // for (int i= 0; i < matches.length; i++) { // if (matches[i].isFiltered()) // matches[i]= null; // else // count++; // } // if (count == matches.length) // return matches; // // Match[] filteredMatches= new Match[count]; // for (int i= 0, k= 0; i < matches.length; i++) { // if (matches[i] != null) // filteredMatches[k++]= matches[i]; // } // return filteredMatches; // } // // /** // * Returns the current location of the match. This takes possible // * modifications of the file into account. Therefore the result may // * differ from the position information that can be obtained directly // * off the match. // * @param match the match to get the position for. // * @return the current position of the match. // * // * @since 3.2 // */ // public IRegion getCurrentMatchLocation(Match match) { // PositionTracker tracker= InternalSearchUI.getInstance().getPositionTracker(); // // int offset, length; // Position pos= tracker.getCurrentPosition(match); // if (pos == null) { // offset= match.getOffset(); // length= match.getLength(); // } else { // offset= pos.getOffset(); // length= pos.getLength(); // } // return new Region(offset, length); // } // // /** // * Returns the number of matches that are currently displayed for the given // * element. If {@link AbstractTextSearchResult#getActiveMatchFilters()} is not null, only matches // * are returned that are not filtered by the match filters. // * Any action operating on the visible matches in the // * search result page should use this method to get the match count for a // * search result (instead of asking the search result directly). // * // * @param element // * The element to get the matches for // * @return The number of matches displayed for the given element. If the // * current input of this page is <code>null</code>, 0 is // * returned // * @see AbstractTextSearchResult#getMatchCount(Object) // */ // public int getDisplayedMatchCount(Object element) { // AbstractTextSearchResult result= getInput(); // if (result == null) // return 0; // if (result.getActiveMatchFilters() == null) // default behaviour: filter state not used, all matches shown // return result.getMatchCount(element); // // int count= 0; // Match[] matches= result.getMatches(element); // for (int i= 0; i < matches.length; i++) { // if (!matches[i].isFiltered()) // count++; // } // return count; // } // // private Object getFirstSelectedElement() { // IStructuredSelection selection = (IStructuredSelection) fViewer.getSelection(); // if (selection.size() > 0) // return selection.getFirstElement(); // return null; // } // // /** // * {@inheritDoc} // */ // public void dispose() { // AbstractTextSearchResult oldSearch = getInput(); // if (oldSearch != null) // AnnotationManagers.removeSearchResult(getSite().getWorkbenchWindow(), oldSearch); // super.dispose(); // NewSearchUI.removeQueryListener(fQueryListener); // } // // /** // * {@inheritDoc} // */ // public void init(IPageSite pageSite) { // super.init(pageSite); // IMenuManager menuManager= pageSite.getActionBars().getMenuManager(); // addLayoutActions(menuManager); // initActionDefinitionIDs(pageSite.getWorkbenchWindow()); // menuManager.updateAll(true); // pageSite.getActionBars().updateActionBars(); // } // // private void initActionDefinitionIDs(IWorkbenchWindow window) { // fCopyToClipboardAction.setActionDefinitionId(IWorkbenchActionDefinitionIds.COPY); // fRemoveSelectedMatches.setActionDefinitionId(IWorkbenchActionDefinitionIds.DELETE); // fShowNextAction.setActionDefinitionId(IWorkbenchActionDefinitionIds.FIND_NEXT); // fShowPreviousAction.setActionDefinitionId(IWorkbenchActionDefinitionIds.FIND_PREVIOUS); // fSelectAllAction.setActionDefinitionId(IWorkbenchActionDefinitionIds.SELECT_ALL); // } // // /** // * Fills the toolbar contribution for this page. Subclasses may override // * this method. // * // * @param tbm the tool bar manager representing the view's toolbar // */ // protected void fillToolbar(IToolBarManager tbm) { // tbm.appendToGroup(IContextMenuConstants.GROUP_SHOW, fShowNextAction); // tbm.appendToGroup(IContextMenuConstants.GROUP_SHOW, fShowPreviousAction); // tbm.appendToGroup(IContextMenuConstants.GROUP_REMOVE_MATCHES, fRemoveSelectedMatches); // tbm.appendToGroup(IContextMenuConstants.GROUP_REMOVE_MATCHES, fRemoveAllResultsAction); // IActionBars actionBars = getSite().getActionBars(); // if (actionBars != null) { // actionBars.setGlobalActionHandler(ActionFactory.NEXT.getId(), fShowNextAction); // actionBars.setGlobalActionHandler(ActionFactory.PREVIOUS.getId(), fShowPreviousAction); // actionBars.setGlobalActionHandler(ActionFactory.DELETE.getId(), fRemoveSelectedMatches); // actionBars.setGlobalActionHandler(ActionFactory.COPY.getId(), fCopyToClipboardAction); // actionBars.setGlobalActionHandler(ActionFactory.SELECT_ALL.getId(), fSelectAllAction); // } // if (getLayout() == FLAG_LAYOUT_TREE) { // addTreeActions(tbm); // } // } // // private void addTreeActions(IToolBarManager tbm) { // // create new actions, new viewer created // tbm.appendToGroup(IContextMenuConstants.GROUP_VIEWER_SETUP, new ExpandAllAction((TreeViewer)getViewer())); // tbm.appendToGroup(IContextMenuConstants.GROUP_VIEWER_SETUP, new CollapseAllAction((TreeViewer)getViewer())); // } // // private void addLayoutActions(IMenuManager menuManager) { // if (fFlatAction != null) // menuManager.appendToGroup(IContextMenuConstants.GROUP_VIEWER_SETUP, fFlatAction); // if (fHierarchicalAction != null) // menuManager.appendToGroup(IContextMenuConstants.GROUP_VIEWER_SETUP, fHierarchicalAction); // } // // /** // * Sets the view part // * @param part View part to set // */ // public void setViewPart(ISearchResultViewPart part) { // fViewPart = part; // } // // /** // * Returns the view part set with // * <code>setViewPart(ISearchResultViewPart)</code>. // * // * @return The view part or <code>null</code> if the view part hasn't been // * set yet (or set to null). // */ // protected ISearchResultViewPart getViewPart() { // return fViewPart; // } // // // multi-threaded update handling. // // /** // * Handles a search result event for the current search result. // * // * @since 3.2 // */ // protected void handleSearchResultChanged(final SearchResultEvent e) { // if (e instanceof MatchEvent) { // postUpdate(((MatchEvent) e).getMatches()); // } else if (e instanceof RemoveAllEvent) { // postClear(); // } else if (e instanceof FilterUpdateEvent) { // postUpdate(((FilterUpdateEvent) e).getUpdatedMatches()); // updateFilterActions(fFilterActions); // } // } // // private synchronized void postUpdate(Match[] matches) { // for (int i = 0; i < matches.length; i++) { // fBatchedUpdates.add(matches[i].getElement()); // } // scheduleUIUpdate(); // } // // private synchronized void runBatchedUpdates() { // if (false /*fBatchedUpdates.size() > 50*/) { // Object[] hundredUpdates= new Object[50]; // Iterator elements= fBatchedUpdates.iterator(); // for (int i= 0; i < hundredUpdates.length; i++) { // hundredUpdates[i]= elements.next(); // elements.remove(); // } // elementsChanged(hundredUpdates); // } else { // elementsChanged(fBatchedUpdates.toArray()); // fBatchedUpdates.clear(); // } // updateBusyLabel(); // } // // private synchronized void postClear() { // fBatchedClearAll= true; // fBatchedUpdates.clear(); // scheduleUIUpdate(); // } // // private synchronized boolean hasMoreUpdates() { // return fBatchedClearAll || fBatchedUpdates.size() > 0; // } // // private boolean isQueryRunning() { // AbstractTextSearchResult result= getInput(); // if (result != null) { // return NewSearchUI.isQueryRunning(result.getQuery()); // } // return false; // } // // private void runBatchedClear() { // synchronized(this) { // if (!fBatchedClearAll) { // return; // } // fBatchedClearAll= false; // updateBusyLabel(); // } // getViewPart().updateLabel(); // clear(); // } // // private void asyncExec(final Runnable runnable) { // final Control control = getControl(); // if (control != null && !control.isDisposed()) { // Display currentDisplay = Display.getCurrent(); // if (currentDisplay == null || !currentDisplay.equals(control.getDisplay())) // // meaning we're not executing on the display thread of the // // control // control.getDisplay().asyncExec(new Runnable() { // public void run() { // if (!control.isDisposed()) // runnable.run(); // } // }); // else // runnable.run(); // } // } // // /** // * {@inheritDoc} // * Subclasses may extend this method. // */ // public void restoreState(IMemento memento) { // if (countBits(fSupportedLayouts) > 1) { // try { // fCurrentLayout = getSettings().getInt(KEY_LAYOUT); // // workaround because the saved value may be 0 // if (fCurrentLayout == 0) // initLayout(); // } catch (NumberFormatException e) { // // ignore, signals no value stored. // } // if (memento != null) { // Integer layout = memento.getInteger(KEY_LAYOUT); // if (layout != null) { // fCurrentLayout = layout.intValue(); // // workaround because the saved value may be 0 // if (fCurrentLayout == 0) // initLayout(); // } // } // } // } // // /* (non-Javadoc) // * @see org.eclipse.search.ui.ISearchResultPage#saveState(org.eclipse.ui.IMemento) // */ // public void saveState(IMemento memento) { // if (countBits(fSupportedLayouts) > 1) { // memento.putInteger(KEY_LAYOUT, fCurrentLayout); // } // } // // /** // * Note: this is internal API and should not be called from clients outside // * of the search plug-in. // * <p> // * Removes the currently selected match. Does nothing if no match is // * selected. // * </p> // */ // public void internalRemoveSelected() { // AbstractTextSearchResult result = getInput(); // if (result == null) // return; // StructuredViewer viewer = getViewer(); // IStructuredSelection selection = (IStructuredSelection) viewer.getSelection(); // HashSet set = new HashSet(); // if (viewer instanceof TreeViewer) { // ITreeContentProvider cp = (ITreeContentProvider) viewer.getContentProvider(); // collectAllMatchesBelow(result, set, cp, selection.toArray()); // } else { // collectAllMatches(set, selection.toArray()); // } // Match[] matches = new Match[set.size()]; // set.toArray(matches); // result.removeMatches(matches); // } // // private void collectAllMatches(HashSet set, Object[] elements) { // for (int j = 0; j < elements.length; j++) { // Match[] matches = getDisplayedMatches(elements[j]); // for (int i = 0; i < matches.length; i++) { // set.add(matches[i]); // } // } // } // // private void collectAllMatchesBelow(AbstractTextSearchResult result, Set set, ITreeContentProvider cp, Object[] elements) { // for (int j = 0; j < elements.length; j++) { // Match[] matches = getDisplayedMatches(elements[j]); // for (int i = 0; i < matches.length; i++) { // set.add(matches[i]); // } // Object[] children = cp.getChildren(elements[j]); // collectAllMatchesBelow(result, set, cp, children); // } // } // // private void turnOffDecoration() { // IBaseLabelProvider lp= fViewer.getLabelProvider(); // if (lp instanceof DecoratingLabelProvider) { // ((DecoratingLabelProvider)lp).setLabelDecorator(null); // } // } // // private void turnOnDecoration() { // IBaseLabelProvider lp= fViewer.getLabelProvider(); // if (lp instanceof DecoratingLabelProvider) { // ((DecoratingLabelProvider)lp).setLabelDecorator(PlatformUI.getWorkbench().getDecoratorManager().getLabelDecorator()); // // } // } // // /** // * <p>This method is called when the search page gets an open even from it's // * underlying viewer (for example on double click). The default // * implementation will open the first match on any element that has matches. // * If the element to be opened is an inner node in the tree layout, the node // * will be expanded if it's collapsed and vice versa. Subclasses are allowed // * to override this method. // * </p> // * @param event // * the event sent for the currently shown viewer // * // * @see IOpenListener // */ // protected void handleOpen(OpenEvent event) { // Viewer viewer= event.getViewer(); // boolean hasCurrentMatch = showCurrentMatch(OpenStrategy.activateOnOpen()); // ISelection sel= event.getSelection(); // if (viewer instanceof TreeViewer && sel instanceof IStructuredSelection) { // IStructuredSelection selection= (IStructuredSelection) sel; // TreeViewer tv = (TreeViewer) getViewer(); // Object element = selection.getFirstElement(); // if (element != null) { // if (!hasCurrentMatch && getDisplayedMatchCount(element) > 0) // gotoNextMatch(OpenStrategy.activateOnOpen()); // else // tv.setExpandedState(element, !tv.getExpandedState(element)); // } // return; // } else if (!hasCurrentMatch) { // gotoNextMatch(OpenStrategy.activateOnOpen()); // } // } // // /** // * Sets the maximal number of top level elements to be shown in a viewer. // * If <code>null</code> is set, the view page does not support to limit the elements and will not provide // * UI to configure it. If a non-null value is set, configuration UI will be provided. The limit value must be a positive // * number or <code>-1</code> to not limit top level element. // * If enabled, the element limit has to be enforced by the content provider that is implemented by the client. The view // * page just manages the value and configuration. // * // * @param limit the element limit. Valid values are: // * <dl> // * <li><code>null</code> to not limit and not provide configuration UI</li> // * <li><code>-1</code> to not limit and provide configuration UI</li> // * <li><code>positive integer</code> to limit by the given value and provide configuration UI</li> // * </dl> // * // * @since 3.3 // */ // public void setElementLimit(Integer limit) { // fElementLimit= limit; // // if (fViewer != null) { // fViewer.refresh(); // } // if (fViewPart != null) { // fViewPart.updateLabel(); // } // } // // /** // * Gets the maximal number of top level elements to be shown in a viewer. // * <code>null</code> means the view page does not limit the elements and will not provide // * UI to configure it. If a non-null value is set, configuration UI will be provided. The limit value must be a positive // * number or <code>-1</code> to not limit top level element. // * // * @return returns the element limit. Valid values are: // * <dl> // * <li><code>null</code> to not limit and not provide configuration UI (default value)</li> // * <li><code>-1</code> to not limit and provide configuration UI</li> // * <li><code>positive integer</code> to limit by the given value and provide configuration UI</li> // * </dl> // * // * @since 3.3 // */ // public Integer getElementLimit() { // return fElementLimit; // } // // //}