| /*=============================================================================# |
| # Copyright (c) 2000, 2021 IBM Corporation 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. |
| # |
| # SPDX-License-Identifier: EPL-2.0 |
| # |
| # Contributors: |
| # IBM Corporation - org.eclipse.jdt: initial API and implementation |
| # Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation |
| #=============================================================================*/ |
| |
| package org.eclipse.statet.ecommons.ui.dialogs; |
| |
| import static org.eclipse.statet.ecommons.ui.actions.UIActions.VIEW_FILTER_GROUP_ID; |
| import static org.eclipse.statet.ecommons.ui.actions.UIActions.VIEW_SORT_GROUP_ID; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IAdaptable; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.jface.action.IMenuManager; |
| import org.eclipse.jface.action.Separator; |
| import org.eclipse.jface.bindings.TriggerSequence; |
| import org.eclipse.jface.bindings.keys.KeySequence; |
| import org.eclipse.jface.bindings.keys.KeyStroke; |
| import org.eclipse.jface.bindings.keys.SWTKeySupport; |
| import org.eclipse.jface.dialogs.Dialog; |
| import org.eclipse.jface.dialogs.PopupDialog; |
| import org.eclipse.jface.text.IInformationControl; |
| import org.eclipse.jface.text.IInformationControlExtension; |
| import org.eclipse.jface.text.IInformationControlExtension2; |
| import org.eclipse.jface.viewers.AbstractTreeViewer; |
| import org.eclipse.jface.viewers.IBaseLabelProvider; |
| import org.eclipse.jface.viewers.ILabelProvider; |
| import org.eclipse.jface.viewers.IStructuredSelection; |
| import org.eclipse.jface.viewers.ITreeContentProvider; |
| import org.eclipse.jface.viewers.StructuredSelection; |
| import org.eclipse.jface.viewers.TreeViewer; |
| import org.eclipse.jface.viewers.Viewer; |
| import org.eclipse.jface.viewers.ViewerFilter; |
| import org.eclipse.osgi.util.NLS; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.events.DisposeEvent; |
| import org.eclipse.swt.events.DisposeListener; |
| import org.eclipse.swt.events.FocusListener; |
| import org.eclipse.swt.events.KeyAdapter; |
| import org.eclipse.swt.events.KeyEvent; |
| import org.eclipse.swt.events.KeyListener; |
| import org.eclipse.swt.events.MouseAdapter; |
| import org.eclipse.swt.events.MouseEvent; |
| import org.eclipse.swt.events.MouseMoveListener; |
| import org.eclipse.swt.events.SelectionEvent; |
| import org.eclipse.swt.events.SelectionListener; |
| import org.eclipse.swt.graphics.Color; |
| import org.eclipse.swt.graphics.Point; |
| import org.eclipse.swt.graphics.Rectangle; |
| import org.eclipse.swt.layout.GridData; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Control; |
| import org.eclipse.swt.widgets.Event; |
| import org.eclipse.swt.widgets.Item; |
| import org.eclipse.swt.widgets.Label; |
| import org.eclipse.swt.widgets.Listener; |
| import org.eclipse.swt.widgets.Shell; |
| import org.eclipse.swt.widgets.Tree; |
| import org.eclipse.swt.widgets.TreeItem; |
| import org.eclipse.ui.IEditorPart; |
| import org.eclipse.ui.IWorkbenchPart; |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.ui.keys.IBindingService; |
| import org.eclipse.ui.statushandlers.StatusManager; |
| |
| import org.eclipse.statet.jcommons.lang.NonNullByDefault; |
| import org.eclipse.statet.jcommons.lang.Nullable; |
| |
| import org.eclipse.statet.ecommons.models.core.util.ElementProxy; |
| import org.eclipse.statet.ecommons.ui.SharedMessages; |
| import org.eclipse.statet.ecommons.ui.components.SearchText; |
| import org.eclipse.statet.ecommons.ui.content.IElementFilter; |
| import org.eclipse.statet.ecommons.ui.content.ITextElementFilter; |
| import org.eclipse.statet.ecommons.ui.content.TextElementFilter; |
| import org.eclipse.statet.ecommons.ui.util.LayoutUtils; |
| import org.eclipse.statet.ecommons.ui.util.UIAccess; |
| import org.eclipse.statet.internal.ecommons.ui.UIMiscellanyPlugin; |
| |
| |
| /** |
| * Abstract class for showing tree in light-weight controls. |
| */ |
| @NonNullByDefault |
| public abstract class QuickTreeInformationControl extends PopupDialog |
| implements IInformationControl, IInformationControlExtension, IInformationControlExtension2, |
| DisposeListener { |
| |
| private static class ElementWithName implements ElementProxy { |
| |
| |
| private IAdaptable element; |
| |
| private String name; |
| |
| |
| public void set(final IAdaptable element, final String name) { |
| this.element= element; |
| this.name= name; |
| } |
| |
| @Override |
| public IAdaptable getElement() { |
| return this.element; |
| } |
| |
| @Override |
| public <T> T getAdapter(final Class<T> adapterType) { |
| return this.element.getAdapter(adapterType); |
| } |
| |
| |
| @Override |
| public String toString() { |
| return this.name; |
| } |
| |
| } |
| |
| /** |
| * The filter selects the elements which match the given string patterns. |
| */ |
| protected class SearchFilter extends ViewerFilter { |
| |
| public SearchFilter() { |
| } |
| |
| @Override |
| public boolean select(final Viewer viewer, final Object parentElement, final Object element) { |
| if (QuickTreeInformationControl.this.select(element)) { |
| return true; |
| } |
| |
| // has unfiltered child? |
| final Object[] children= ((ITreeContentProvider) QuickTreeInformationControl.this.treeViewer.getContentProvider()) |
| .getChildren(element); |
| for (int i= 0; i < children.length; i++) { |
| if (select(viewer, element, children[i])) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| } |
| |
| |
| /** The control's text widget */ |
| private SearchText filterText; |
| |
| /** The control's tree widget */ |
| private TreeViewer treeViewer; |
| |
| /** The current string matcher */ |
| protected ITextElementFilter nameFilter; |
| |
| private IElementFilter.IFinalFilter finalNameFilter; |
| private final ElementWithName nameFilterElement= new ElementWithName(); |
| |
| private final int iterationCount; |
| private int iterationPosition; |
| |
| private final String commandId; |
| |
| private String commandBestKeyStrokeFormatted; |
| private List<KeyStroke> commandActiveKeyStrokes; |
| private KeyListener commandKeyListener; |
| |
| // private IAction fShowViewMenuAction; |
| // private HandlerSubmission fShowViewMenuHandlerSubmission; |
| |
| /** |
| * Creates a tree information control with the given shell as parent. The given |
| * styles are applied to the shell and the tree widget. |
| * |
| * @param parent the parent shell |
| * @param shellStyle the additional styles for the shell |
| * @param treeStyle the additional styles for the tree widget |
| * @param commandId the id of the command that invoked this control or <code>null</code> |
| */ |
| public QuickTreeInformationControl(final Shell parent, final int shellStyle, |
| final boolean showStatusField, final String commandId, final int iterationCount) { |
| super(parent, shellStyle, true, true, false, true, true, null, null); |
| |
| if (iterationCount < 1) { |
| throw new IllegalArgumentException("iterationCount"); //$NON-NLS-1$ |
| } |
| |
| this.commandId= commandId; |
| this.iterationCount= iterationCount; |
| if (this.commandId != null && this.iterationCount > 1) { |
| initIterateKeys(); |
| } |
| |
| // Title and status text must be set to get the title label created, so force empty values here. |
| setInfoText(""); // //$NON-NLS-1$ |
| |
| this.nameFilter= createNameFilter(); |
| |
| create(); |
| } |
| |
| private void initIterateKeys() { |
| if (this.commandId == null || this.iterationCount == 1) { |
| return; |
| } |
| final IBindingService bindingSvc= PlatformUI.getWorkbench().getService(IBindingService.class); |
| if (bindingSvc == null) { |
| return; |
| } |
| { final TriggerSequence sequence= bindingSvc.getBestActiveBindingFor(this.commandId); |
| final KeyStroke keyStroke= getKeyStroke(sequence); |
| if (keyStroke == null) { |
| return; |
| } |
| this.commandBestKeyStrokeFormatted= keyStroke.format(); |
| } |
| { final TriggerSequence[] sequences= bindingSvc.getActiveBindingsFor(this.commandId); |
| this.commandActiveKeyStrokes= new ArrayList<>(sequences.length); |
| for (int i= 0; i < sequences.length; i++) { |
| final KeyStroke keyStroke= getKeyStroke(sequences[i]); |
| if (keyStroke != null) { |
| this.commandActiveKeyStrokes.add(keyStroke); |
| } |
| } |
| } |
| this.commandKeyListener= new KeyAdapter() { |
| @Override |
| public void keyPressed(final KeyEvent event) { |
| final KeyStroke keyStroke= SWTKeySupport.convertAcceleratorToKeyStroke( |
| SWTKeySupport.convertEventToUnmodifiedAccelerator(event) ); |
| for (final KeyStroke activeKeyStroke : QuickTreeInformationControl.this.commandActiveKeyStrokes) { |
| if (activeKeyStroke.equals(keyStroke)) { |
| event.doit= false; |
| iterate(); |
| return; |
| } |
| } |
| } |
| }; |
| } |
| |
| private @Nullable KeyStroke getKeyStroke(final TriggerSequence triggerSequence) { |
| if (triggerSequence instanceof KeySequence) { |
| final KeyStroke[] keyStrokes= ((KeySequence) triggerSequence).getKeyStrokes(); |
| if (keyStrokes.length == 1) { |
| return keyStrokes[0]; |
| } |
| } |
| return null; |
| } |
| |
| |
| protected abstract String getDescription(int iterationPosition); |
| |
| protected void updateInfoText() { |
| final StringBuilder sb= new StringBuilder( |
| getDescription(getIterationPosition()) ); |
| if (this.commandBestKeyStrokeFormatted != null) { |
| sb.append("\u2004\u2004"); //$NON-NLS-1$ |
| sb.append(NLS.bind(SharedMessages.DoToShow_message, |
| this.commandBestKeyStrokeFormatted, |
| getDescription(getNextIterationPosition()) )); |
| } |
| sb.append('\u2006'); |
| setInfoText(sb.toString()); |
| } |
| |
| |
| /** |
| * Create the main content for this information control. |
| * |
| * @param parent The parent composite |
| * @return The control representing the main content. |
| * @since 3.2 |
| */ |
| @Override |
| protected Control createDialogArea(final Composite parent) { |
| final TreeViewer viewer= new TreeViewer(parent, SWT.SINGLE | SWT.V_SCROLL | SWT.H_SCROLL); |
| final Tree tree= viewer.getTree(); |
| { final GridData gd= new GridData(GridData.FILL_BOTH); |
| gd.heightHint= LayoutUtils.hintHeight(tree, 12); |
| tree.setLayoutData(gd); |
| } |
| |
| viewer.setUseHashlookup(true); |
| viewer.setAutoExpandLevel(AbstractTreeViewer.ALL_LEVELS); |
| configureViewer(viewer); |
| |
| viewer.addFilter(new SearchFilter()); |
| |
| // this.fCustomFiltersActionGroup= new CustomFiltersActionGroup(getId(), this.viewer); |
| |
| this.treeViewer= viewer; |
| |
| tree.addSelectionListener(new SelectionListener() { |
| @Override |
| public void widgetSelected(final SelectionEvent e) { |
| // do nothing |
| } |
| @Override |
| public void widgetDefaultSelected(final SelectionEvent e) { |
| gotoSelectedElement(); |
| } |
| }); |
| |
| tree.addMouseMoveListener(new MouseMoveListener() { |
| TreeItem lastItem= null; |
| @Override |
| public void mouseMove(final MouseEvent e) { |
| if (tree.equals(e.getSource())) { |
| final Object o= tree.getItem(new Point(e.x, e.y)); |
| if (this.lastItem == null ^ o == null) { |
| tree.setCursor(o == null ? null : tree.getDisplay().getSystemCursor(SWT.CURSOR_HAND)); |
| } |
| if (o instanceof TreeItem) { |
| final Rectangle clientArea= tree.getClientArea(); |
| if (!o.equals(this.lastItem)) { |
| this.lastItem= (TreeItem)o; |
| tree.setSelection(new TreeItem[] { this.lastItem }); |
| } else if (e.y - clientArea.y < tree.getItemHeight() / 4) { |
| // Scroll up |
| final Point p= tree.toDisplay(e.x, e.y); |
| final Item item= QuickTreeInformationControl.this.treeViewer.scrollUp(p.x, p.y); |
| if (item instanceof TreeItem) { |
| this.lastItem= (TreeItem)item; |
| tree.setSelection(new TreeItem[] { this.lastItem }); |
| } |
| } else if (clientArea.y + clientArea.height - e.y < tree.getItemHeight() / 4) { |
| // Scroll down |
| final Point p= tree.toDisplay(e.x, e.y); |
| final Item item= QuickTreeInformationControl.this.treeViewer.scrollDown(p.x, p.y); |
| if (item instanceof TreeItem) { |
| this.lastItem= (TreeItem)item; |
| tree.setSelection(new TreeItem[] { this.lastItem }); |
| } |
| } |
| } else if (o == null) { |
| this.lastItem= null; |
| } |
| } |
| } |
| }); |
| |
| if (this.commandKeyListener != null) { |
| tree.addKeyListener(this.commandKeyListener); |
| } |
| tree.addMouseListener(new MouseAdapter() { |
| @Override |
| public void mouseUp(final MouseEvent e) { |
| if (tree.getSelectionCount() < 1) { |
| return; |
| } |
| |
| if (e.button != 1) { |
| return; |
| } |
| |
| if (tree.equals(e.getSource())) { |
| final Object o= tree.getItem(new Point(e.x, e.y)); |
| final TreeItem selection= tree.getSelection()[0]; |
| if (selection.equals(o)) { |
| gotoSelectedElement(); |
| } |
| } |
| } |
| }); |
| |
| addDisposeListener(this); |
| return this.treeViewer.getControl(); |
| } |
| |
| protected abstract void configureViewer(TreeViewer viewer); |
| |
| protected TreeViewer getTreeViewer() { |
| return this.treeViewer; |
| } |
| |
| protected SearchText getFilterText() { |
| return this.filterText; |
| } |
| |
| protected SearchText createFilterText(final Composite parent) { |
| this.filterText= new SearchText(parent, "", SWT.NONE); //$NON-NLS-1$ |
| |
| Dialog.applyDialogFont(this.filterText); |
| |
| this.filterText.addListener(new SearchText.Listener() { |
| @Override |
| public void textChanged(final boolean user) { |
| setMatcherString(QuickTreeInformationControl.this.filterText.getText(), true); |
| } |
| @Override |
| public void okPressed() { |
| gotoSelectedElement(); |
| } |
| @Override |
| public void downPressed() { |
| QuickTreeInformationControl.this.treeViewer.getTree().setFocus(); |
| } |
| }); |
| this.filterText.getTextControl().addListener(SWT.KeyDown, new Listener() { |
| @Override |
| public void handleEvent(final Event event) { |
| if (event.character == SWT.ESC) { |
| close(); |
| event.doit= false; |
| } |
| } |
| }); |
| if (this.commandKeyListener != null) { |
| this.filterText.getTextControl().addKeyListener(this.commandKeyListener); |
| } |
| |
| return this.filterText; |
| } |
| |
| protected void createHorizontalSeparator(final Composite parent) { |
| final Label separator= new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL | SWT.LINE_DOT); |
| separator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); |
| } |
| |
| |
| /** |
| * Sets the patterns to filter out for the receiver. |
| * |
| * @param pattern the pattern |
| * @param update <code>true</code> if the viewer should be updated |
| */ |
| protected void setMatcherString(final String pattern, final boolean update) { |
| if (this.nameFilter.setText(pattern) && update) { |
| stringMatcherUpdated(); |
| } |
| } |
| |
| /** |
| * The string matcher has been modified. |
| * |
| * The default implementation refreshes the view and selects the first matched element. |
| */ |
| protected void stringMatcherUpdated() { |
| // refresh viewer to re-filter |
| this.treeViewer.getControl().setRedraw(false); |
| this.finalNameFilter= this.nameFilter.getFinal(false); |
| this.treeViewer.refresh(); |
| this.treeViewer.expandAll(); |
| selectFirstMatch(); |
| this.treeViewer.getControl().setRedraw(true); |
| } |
| |
| /** |
| * Implementers can modify |
| * |
| * @return the selected element |
| */ |
| protected Object getSelectedElement() { |
| if (this.treeViewer == null) { |
| return null; |
| } |
| |
| return ((IStructuredSelection) this.treeViewer.getSelection()).getFirstElement(); |
| } |
| |
| protected void gotoSelectedElement() { |
| final Object selectedElement= getSelectedElement(); |
| if (selectedElement != null) { |
| try { |
| dispose(); |
| |
| openElement(selectedElement); |
| } |
| catch (final CoreException e) { |
| StatusManager.getManager().handle(new Status(IStatus.ERROR, UIMiscellanyPlugin.BUNDLE_ID, |
| "An error occurred when opening the selected element.", e )); |
| } |
| } |
| } |
| |
| protected abstract void openElement(final Object element) throws CoreException; |
| |
| |
| /** |
| * Selects the first element in the tree which matches the current filter pattern. |
| */ |
| protected void selectFirstMatch() { |
| final Tree tree= this.treeViewer.getTree(); |
| final Object element= findFirstMatch(tree.getItems()); |
| if (element != null) { |
| this.treeViewer.setSelection(new StructuredSelection(element), true); |
| } else { |
| this.treeViewer.setSelection(StructuredSelection.EMPTY); |
| } |
| } |
| |
| private @Nullable Object findFirstMatch(final TreeItem[] items) { |
| if (items.length > 0) { |
| // Process each item in the tree |
| for (int i= 0; i < items.length; i++) { |
| final Object element= items[i].getData(); |
| if (element == null) { |
| continue; |
| } |
| if (select(element)) { |
| return element; |
| } |
| } |
| |
| for (int i= 0; i < items.length; i++) { |
| // Recursively check the elements children for a match |
| final Object element= findFirstMatch(items[i].getItems()); |
| // Return the child element match if found |
| if (element != null) { |
| return element; |
| } |
| } |
| } |
| // No match found |
| return null; |
| } |
| |
| |
| @Override |
| public void setInformation(final String information) { |
| // this method is ignored, see IInformationControlExtension2 |
| } |
| |
| @Override |
| public abstract void setInput(Object information); |
| |
| protected void inputChanged(final int iterationPage, final Object newInput, |
| final Object newSelection) { |
| this.filterText.clearText(); |
| resetFilter(); |
| |
| this.iterationPosition= iterationPage; |
| updateInfoText(); |
| |
| this.treeViewer.setInput(newInput); |
| if (newSelection != null) { |
| this.treeViewer.setSelection(new StructuredSelection(newSelection)); |
| } |
| } |
| |
| |
| protected ITextElementFilter createNameFilter() { |
| return new TextElementFilter(); |
| } |
| |
| protected void resetFilter() { |
| this.nameFilter.setText(null); |
| this.finalNameFilter= this.nameFilter.getFinal(true); |
| } |
| |
| protected String getElementName(final IAdaptable element) { |
| final IBaseLabelProvider labelProvider= this.treeViewer.getLabelProvider(); |
| if (labelProvider instanceof ILabelProvider) { |
| return ((ILabelProvider) labelProvider).getText(element); |
| } |
| return element.toString(); |
| } |
| |
| protected boolean select(final Object element) { |
| if (this.finalNameFilter == null) { |
| return true; |
| } |
| if (element instanceof IAdaptable) { |
| final IAdaptable adaptable= (IAdaptable) element; |
| final String name= getElementName(adaptable); |
| if (name != null) { |
| this.nameFilterElement.set(adaptable, name); |
| return this.finalNameFilter.select(this.nameFilterElement); |
| } |
| } |
| return false; |
| } |
| |
| |
| @Override |
| protected void fillDialogMenu(final IMenuManager menu) { |
| super.fillDialogMenu(menu); |
| |
| menu.add(new Separator(VIEW_SORT_GROUP_ID)); |
| menu.add(new Separator(VIEW_FILTER_GROUP_ID)); |
| } |
| |
| @Override |
| public void setVisible(final boolean visible) { |
| if (visible) { |
| open(); |
| } else { |
| disableActions(); |
| saveDialogBounds(getShell()); |
| getShell().setVisible(false); |
| } |
| } |
| |
| @Override |
| public int open() { |
| initActions(); |
| return super.open(); |
| } |
| |
| @Override |
| public final void dispose() { |
| close(); |
| } |
| |
| @Override |
| public void widgetDisposed(final DisposeEvent event) { |
| disableActions(); |
| |
| this.treeViewer= null; |
| this.filterText= null; |
| } |
| |
| /** |
| * Adds handler and key binding support. |
| */ |
| protected void initActions() { |
| // IWorkbenchCommandConstants.WINDOW_SHOW_VIEW_MENU -> showDialogMenu() |
| |
| // // Register action with command support |
| // if (this.fShowViewMenuHandlerSubmission == null) { |
| // this.fShowViewMenuHandlerSubmission= new HandlerSubmission(null, getShell(), null, this.fShowViewMenuAction.getActionDefinitionId(), new ActionHandler(this.fShowViewMenuAction), Priority.MEDIUM); |
| // PlatformUI.getWorkbench().getCommandSupport().addHandlerSubmission(this.fShowViewMenuHandlerSubmission); |
| // } |
| } |
| |
| /** |
| * Removes handler and key binding support. |
| */ |
| protected void disableActions() { |
| // // Remove handler submission |
| // if (this.fShowViewMenuHandlerSubmission != null) { |
| // PlatformUI.getWorkbench().getCommandSupport().removeHandlerSubmission(this.fShowViewMenuHandlerSubmission); |
| // } |
| } |
| |
| @Override |
| public boolean hasContents() { |
| return (this.treeViewer != null && this.treeViewer.getInput() != null); |
| } |
| |
| @Override |
| public void setSizeConstraints(final int maxWidth, final int maxHeight) { |
| // ignore |
| } |
| |
| @Override |
| public Point computeSizeHint() { |
| //Rreturn the shell's size |
| // Note that it already has the persisted size if persisting is enabled. |
| return getShell().getSize(); |
| } |
| |
| @Override |
| public void setLocation(final Point location) { |
| /* |
| * If the location is persisted, it gets managed by PopupDialog - fine. Otherwise, the location is |
| * computed in Window#getInitialLocation, which will center it in the parent shell / main |
| * monitor, which is wrong for two reasons: |
| * - we want to center over the editor / subject control, not the parent shell |
| * - the center is computed via the initalSize, which may be also wrong since the size may |
| * have been updated since via min/max sizing of AbstractInformationControlManager. |
| * In that case, override the location with the one computed by the manager. Note that |
| * the call to constrainShellSize in PopupDialog.open will still ensure that the shell is |
| * entirely visible. |
| */ |
| if (!getPersistLocation() || getDialogSettings() == null) { |
| getShell().setLocation(location); |
| } |
| } |
| |
| @Override |
| public void setSize(final int width, final int height) { |
| getShell().setSize(width, height); |
| } |
| |
| |
| @Override |
| public void addDisposeListener(final DisposeListener listener) { |
| getShell().addDisposeListener(listener); |
| } |
| |
| @Override |
| public void removeDisposeListener(final DisposeListener listener) { |
| getShell().removeDisposeListener(listener); |
| } |
| |
| |
| @Override |
| public void setForegroundColor(final Color foreground) { |
| applyForegroundColor(foreground, getContents()); |
| } |
| |
| @Override |
| public void setBackgroundColor(final Color background) { |
| applyBackgroundColor(background, getContents()); |
| } |
| |
| |
| @Override |
| public boolean isFocusControl() { |
| final Shell shell= getShell(); |
| return (shell != null && shell.getDisplay().getActiveShell() == shell); |
| } |
| |
| @Override |
| public void setFocus() { |
| getShell().forceFocus(); |
| this.filterText.setFocus(); |
| } |
| |
| @Override |
| public void addFocusListener(final FocusListener listener) { |
| getShell().addFocusListener(listener); |
| } |
| |
| @Override |
| public void removeFocusListener(final FocusListener listener) { |
| getShell().removeFocusListener(listener); |
| } |
| |
| |
| protected final String getCommandId() { |
| return this.commandId; |
| } |
| |
| |
| protected final int getIterationPosition() { |
| return this.iterationPosition; |
| } |
| |
| private int getNextIterationPosition() { |
| final int page= this.iterationPosition + 1; |
| return (page < this.iterationCount) ? page : 0; |
| } |
| |
| private void iterate() { |
| this.iterationPosition= getNextIterationPosition(); |
| updateInfoText(); |
| iterated(this.iterationPosition); |
| } |
| |
| protected void iterated(final int iterationPosition) { |
| final Object selectedElement= ((IStructuredSelection) this.treeViewer.getSelection()).getFirstElement(); |
| |
| this.treeViewer.refresh(); |
| |
| if (selectedElement != null && this.treeViewer.getTree().getSelectionCount() == 0) { |
| // if tree path changed, try again |
| this.treeViewer.setSelection(new StructuredSelection(selectedElement), true); |
| } |
| } |
| |
| |
| @Override |
| protected Control createTitleControl(final Composite parent) { |
| this.filterText= createFilterText(parent); |
| this.filterText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); |
| return this.filterText; |
| } |
| |
| protected @Nullable IProgressMonitor getProgressMonitor() { |
| final IWorkbenchPart part= UIAccess.getActiveWorkbenchPart(true); |
| |
| IEditorPart editor; |
| if (part instanceof IEditorPart) { |
| editor= (IEditorPart) part; |
| } |
| else { |
| return null; |
| } |
| |
| return editor.getEditorSite().getActionBars().getStatusLineManager().getProgressMonitor(); |
| } |
| |
| } |