Java tutorial
/*=============================================================================# # Copyright (c) 2005-2015 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.nico.ui.views; import java.util.Date; import java.util.EnumSet; import java.util.List; import com.ibm.icu.text.DateFormat; import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; import org.eclipse.core.commands.IHandler2; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.jface.action.Action; 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.action.Separator; import org.eclipse.jface.resource.ImageRegistry; import org.eclipse.jface.window.DefaultToolTip; import org.eclipse.swt.SWT; import org.eclipse.swt.dnd.Clipboard; import org.eclipse.swt.dnd.DND; import org.eclipse.swt.dnd.DragSource; import org.eclipse.swt.dnd.TextTransfer; import org.eclipse.swt.dnd.Transfer; import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.events.KeyListener; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.TableItem; import org.eclipse.ui.IActionBars; import org.eclipse.ui.IMemento; import org.eclipse.ui.IViewSite; import org.eclipse.ui.IWorkbenchActionConstants; import org.eclipse.ui.IWorkbenchCommandConstants; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.actions.ActionFactory; import org.eclipse.ui.dialogs.SearchPattern; import org.eclipse.ui.handlers.IHandlerService; import org.eclipse.ui.menus.CommandContributionItemParameter; import org.eclipse.ui.part.ViewPart; import org.eclipse.ui.progress.IWorkbenchSiteProgressService; import de.walware.ecommons.FastArrayBufferList; import de.walware.ecommons.FastList; import de.walware.ecommons.collections.ConstArrayList; import de.walware.ecommons.preferences.Preference.EnumSetPref; import de.walware.ecommons.ui.SharedMessages; import de.walware.ecommons.ui.SharedUIResources; import de.walware.ecommons.ui.actions.HandlerContributionItem; import de.walware.ecommons.ui.actions.SearchContributionItem; import de.walware.ecommons.ui.actions.SimpleContributionItem; import de.walware.ecommons.ui.util.LayoutUtil; import de.walware.ecommons.ui.util.UIAccess; import de.walware.statet.nico.core.runtime.History; import de.walware.statet.nico.core.runtime.History.Entry; import de.walware.statet.nico.core.runtime.IHistoryListener; import de.walware.statet.nico.core.runtime.SubmitType; import de.walware.statet.nico.core.runtime.ToolProcess; import de.walware.statet.nico.core.util.IToolProvider; import de.walware.statet.nico.core.util.IToolRetargetable; import de.walware.statet.nico.internal.ui.Messages; import de.walware.statet.nico.internal.ui.NicoUIPlugin; import de.walware.statet.nico.internal.ui.actions.HistoryCopyAction; import de.walware.statet.nico.internal.ui.actions.HistoryDragAdapter; import de.walware.statet.nico.internal.ui.actions.HistorySubmitAction; import de.walware.statet.nico.ui.IToolRegistry; import de.walware.statet.nico.ui.IToolRegistryListener; import de.walware.statet.nico.ui.NicoUI; import de.walware.statet.nico.ui.ToolSessionUIData; import de.walware.statet.nico.ui.actions.LoadHistoryAction; import de.walware.statet.nico.ui.actions.SaveHistoryAction; import de.walware.statet.nico.ui.console.ScrollLockAction; import de.walware.statet.nico.ui.console.ScrollLockAction.Receiver; /** * A view for the history of a tool process. * * Usage: This class is not intend to be subclassed. */ public class HistoryView extends ViewPart implements IToolProvider { public static interface EntryFilter { public boolean select(Entry e); } /** * Converts the selection of this view/viewer into a commmand text block. * * @param selection a selection with history entries. * @return command block. */ public static String createTextBlock(final Entry[] selection) { final StringBuilder text = new StringBuilder(selection.length * 8); for (int i = 0; i < selection.length; i++) { text.append(selection[i].getCommand()); text.append('\n'); } return text.toString(); } public static List<String> createCommandList(final Entry[] selection) { final String[] array = new String[selection.length]; for (int i = 0; i < selection.length; i++) { array[i] = selection[i].getCommand(); } return new ConstArrayList<String>(array); } private static final EntryFilter EMPTY_FILTER = new EntryFilter() { @Override public boolean select(final Entry e) { return (e.getCommandMarker() >= 0); } }; private static final class SubmitTypeFilter implements EntryFilter { private final EnumSet<SubmitType> fSubmitTypes; public SubmitTypeFilter(final EnumSet<SubmitType> types) { fSubmitTypes = types; } @Override public boolean select(final Entry e) { final SubmitType type = e.getSubmitType(); return (type == null || fSubmitTypes.contains(type)); } } private static final EnumSetPref<SubmitType> SOURCE_ENCODER = new EnumSetPref<SubmitType>(null, null, SubmitType.class); private class ViewReloadJob extends Job { ViewReloadJob() { super("Update History View"); //$NON-NLS-1$ setPriority(SHORT); setUser(false); } @Override protected IStatus run(final IProgressMonitor monitor) { final ToolProcess process = fProcess; if (monitor.isCanceled()) { return Status.CANCEL_STATUS; } if (process == null) { fContentProvider.setNewSource(null, new Entry[0]); return Status.OK_STATUS; } final History history = process.getHistory(); history.getReadLock().lock(); final Entry[] entries; try { entries = history.toArray(); } finally { history.getReadLock().unlock(); } if (monitor.isCanceled()) { return Status.CANCEL_STATUS; } fContentProvider.setNewSource(history, entries); return Status.OK_STATUS; } } private class ViewContentProvider implements IHistoryListener, Runnable { private static final int REMOVE_THRESHOLD = 25; private History fCurrentSource; private boolean fIsScheduled; private final FastArrayBufferList<Entry> fToAdd = new FastArrayBufferList<Entry>(Entry.class, 16); private final FastArrayBufferList<Entry> fToRemove = new FastArrayBufferList<Entry>(Entry.class, 16); private Entry[] fNewEntrys; public synchronized void setNewSource(final History source, final Entry[] es) { fCurrentSource = source; fNewEntrys = es; fToAdd.clear(); fToRemove.clear(); if (!fIsScheduled) { fIsScheduled = true; UIAccess.getDisplay().asyncExec(this); } } @Override public synchronized void completeChange(final History source, final Entry[] es) { if (fCurrentSource != source) { return; } fNewEntrys = es; fToAdd.clear(); fToRemove.clear(); if (!fIsScheduled) { fIsScheduled = true; UIAccess.getDisplay().asyncExec(this); } } @Override public synchronized void entryAdded(final History source, final Entry e) { if (fCurrentSource != source) { return; } fToAdd.add(e); if (!fIsScheduled) { fIsScheduled = true; UIAccess.getDisplay().asyncExec(this); } } @Override public synchronized void entryRemoved(final History source, final Entry e) { if (fCurrentSource != source) { return; } fToRemove.add(e); if (!fIsScheduled) { fIsScheduled = true; UIAccess.getDisplay().asyncExec(this); } } @Override public void run() { final Entry[] newEntries; final int toAdd; final Entry[] toAddEntries; final int toRemove; final Entry[] toRemoveEntries; final EntryFilter[] filter; synchronized (this) { fIsScheduled = false; if (!UIAccess.isOkToUse(fTable)) { return; } if ((fProcess != null && fCurrentSource != fProcess.getHistory()) || (fProcess == null && fCurrentSource != null)) { return; } newEntries = fNewEntrys; fNewEntrys = null; toAdd = fToAdd.size(); toAddEntries = (toAdd > 0) ? fToAdd.removeAll() : null; toRemove = fToRemove.size(); toRemoveEntries = (toRemove > REMOVE_THRESHOLD) ? fToRemove.removeAll() : null; filter = fFilter.toArray(); } fTable.setRedraw(false); TableItem addedItem = null; if (newEntries != null) { fTable.deselectAll(); final int reusableItemCount = fTable.getItemCount(); int reuseItemIdx = 0; final int n = newEntries.length; ITER_ENTRY: for (int i = 0; i < n; i++) { final Entry e = newEntries[i]; for (int f = 0; f < filter.length; f++) { if (!filter[f].select(e)) { continue ITER_ENTRY; } } if (reuseItemIdx < reusableItemCount) { addedItem = fTable.getItem(reuseItemIdx++); } else { addedItem = new TableItem(fTable, SWT.NONE); } addedItem.setData(e); updateItem(addedItem); } if (reuseItemIdx < reusableItemCount) { fTable.remove(reuseItemIdx, reusableItemCount - 1); } if (addedItem != null) { fTable.showItem(addedItem); } } if (toAdd > 0) { ITER_ENTRY: for (int i = 0; i < toAdd; i++) { final Entry e = toAddEntries[i]; for (int f = 0; f < filter.length; f++) { if (!filter[f].select(e)) { continue ITER_ENTRY; } } addedItem = new TableItem(fTable, SWT.NONE); addedItem.setData(e); updateItem(addedItem); } } if (toRemove > REMOVE_THRESHOLD) { final int itemCount = fTable.getItemCount(); int[] removeIdxs = new int[toRemove]; int count = 0; for (int i = 0; i < toRemove; i++) { for (int j = 0; j < itemCount; j++) { final TableItem removedItem = fTable.getItem(j); if (removedItem.getData() == toRemoveEntries[i]) { removedItem.setData(null); removeIdxs[count++] = j; } } } if (count > 0) { if (count < removeIdxs.length) { System.arraycopy(removeIdxs, 0, removeIdxs = new int[count], 0, count); } fTable.remove(removeIdxs); } } if (fDoAutoscroll && addedItem != null) { fTable.showItem(addedItem); } fTable.setRedraw(true); } } private class FilterEmptyAction extends Action { FilterEmptyAction() { setText(Messages.FilterEmptyAction_name); setToolTipText(Messages.FilterEmptyAction_tooltip); setImageDescriptor( SharedUIResources.getImages().getDescriptor(SharedUIResources.LOCTOOL_FILTER_IMAGE_ID)); setChecked(fDoFilterEmpty); } @Override public void run() { final boolean switchOn = isChecked(); fDoFilterEmpty = switchOn; if (switchOn) { addFilter(EMPTY_FILTER); } else { removeFilter(EMPTY_FILTER); } } } private class FilterBySourceAction extends SimpleContributionItem { private final SubmitType fType; public FilterBySourceAction(final SubmitType type) { super(type.getLabel(), null, SimpleContributionItem.STYLE_CHECK); fType = type; setChecked(fFilterBySource.fSubmitTypes.contains(type)); } @Override protected void execute() throws ExecutionException { final SubmitTypeFilter currentFilter = fFilterBySource; final EnumSet<SubmitType> types = EnumSet.copyOf(currentFilter.fSubmitTypes); if (types.contains(fType)) { types.remove(fType); setChecked(false); } else { types.add(fType); setChecked(true); } final SubmitTypeFilter newFilter = new SubmitTypeFilter(types); fFilterBySource = newFilter; replaceFilter(currentFilter, newFilter); } } private volatile ToolProcess fProcess; // note: we write only in ui thread private IToolRegistryListener fToolRegistryListener; private final ViewContentProvider fContentProvider; private Table fTable; private Clipboard fClipboard; private static final String M_FILTER_EMPTY = "FilterEmpty.enabled"; //$NON-NLS-1$ private boolean fDoFilterEmpty; private Action fFilterEmptyAction; private final FastList<EntryFilter> fFilter = new FastList<EntryFilter>(EntryFilter.class, FastList.IDENTITY); private static final String M_AUTOSCROLL = "Autoscroll.enabled"; //$NON-NLS-1$ private boolean fDoAutoscroll; private Action fScrollLockAction; private static final String M_FILTER_BY_SOURCE = "FilterBySource.include"; //$NON-NLS-1$ private SubmitTypeFilter fFilterBySource; private final FastList<IToolRetargetable> fToolListenerList = new FastList<IToolRetargetable>( IToolRetargetable.class); private Action fSelectAllAction; private Action fCopyAction; private Action fSubmitAction; private IHandler2 fSearchStartHandler; private IHandler2 fSearchNextHandler; private IHandler2 fSearchPrevHandler; private SearchContributionItem fSearchTextItem; private final SearchPattern fSearchPattern = new SearchPattern( SearchPattern.RULE_EXACT_MATCH | SearchPattern.RULE_PREFIX_MATCH | SearchPattern.RULE_CAMELCASE_MATCH | SearchPattern.RULE_PATTERN_MATCH | SearchPattern.RULE_BLANK_MATCH); private LoadHistoryAction fLoadHistoryAction; private SaveHistoryAction fSaveHistoryAction; private final ViewReloadJob fReloadJob; /** * The constructor. */ public HistoryView() { fReloadJob = new ViewReloadJob(); fContentProvider = new ViewContentProvider(); } @Override public void init(final IViewSite site, final IMemento memento) throws PartInitException { super.init(site, memento); final String autoscroll = (memento != null) ? memento.getString(M_AUTOSCROLL) : null; if (autoscroll == null || autoscroll.equals("on")) { // default //$NON-NLS-1$ fDoAutoscroll = true; } else { fDoAutoscroll = false; } final String filterBySource = (memento != null) ? memento.getString(M_FILTER_BY_SOURCE) : null; if (filterBySource == null) { fFilterBySource = new SubmitTypeFilter(EnumSet.range(SubmitType.CONSOLE, SubmitType.TOOLS)); } else { fFilterBySource = new SubmitTypeFilter(SOURCE_ENCODER.store2Usage(filterBySource)); } fFilter.add(fFilterBySource); final String filterEmpty = (memento != null) ? memento.getString(M_FILTER_EMPTY) : null; if (filterEmpty == null || filterEmpty.equals("off")) { // default //$NON-NLS-1$ fDoFilterEmpty = false; } else { fDoFilterEmpty = true; fFilter.add(EMPTY_FILTER); } } @Override public void saveState(final IMemento memento) { super.saveState(memento); memento.putString(M_AUTOSCROLL, (fDoAutoscroll) ? "on" : "off"); //$NON-NLS-1$ //$NON-NLS-2$ memento.putString(M_FILTER_BY_SOURCE, SOURCE_ENCODER.usage2Store(fFilterBySource.fSubmitTypes)); memento.putString(M_FILTER_EMPTY, (fDoFilterEmpty) ? "on" : "off"); //$NON-NLS-1$ //$NON-NLS-2$ } @Override public void createPartControl(final Composite parent) { parent.setLayout(LayoutUtil.applySashDefaults(new GridLayout(), 1)); fTable = new Table(parent, SWT.MULTI | SWT.V_SCROLL | SWT.FULL_SELECTION); fTable.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); fTable.setLinesVisible(false); fTable.setHeaderVisible(false); new DefaultToolTip(fTable) { private final DateFormat fFormat = DateFormat.getDateTimeInstance(); @Override protected String getText(final Event event) { final TableItem item = fTable.getItem(new Point(event.x, event.y)); if (item != null) { final Entry e = (Entry) item.getData(); if (e.getTimeStamp() < 0) { return "[-]\n" + e.getCommand(); //$NON-NLS-1$ } else { return "[" + fFormat.format(new Date(e.getTimeStamp())) + "]\n" + e.getCommand(); //$NON-NLS-1$ //$NON-NLS-2$ } } return null; } }; final TableColumn column = new TableColumn(fTable, SWT.DEFAULT); fTable.addListener(SWT.Resize, new Listener() { @Override public void handleEvent(final Event event) { // adapt the column width to the width of the table final int tableWidth = fTable.getClientArea().width; if (tableWidth == 0) { return; } column.setWidth(tableWidth); } }); fTable.addKeyListener(new KeyListener() { @Override public void keyPressed(final KeyEvent e) { if (e.keyCode == SWT.ARROW_UP && fTable.getSelectionCount() == 1 && fTable.getSelectionIndex() == 0) { fSearchTextItem.show(); fTable.deselectAll(); e.doit = false; } } @Override public void keyReleased(final KeyEvent e) { } }); createActions(); hookContextMenu(); contributeToActionBars(); final DragSource dragSource = new DragSource(fTable, DND.DROP_COPY); dragSource.setTransfer(new Transfer[] { TextTransfer.getInstance() }); dragSource.addDragListener(new HistoryDragAdapter(this)); // listen on console changes final IToolRegistry toolRegistry = NicoUI.getToolRegistry(); fToolRegistryListener = new IToolRegistryListener() { @Override public void toolSessionActivated(final ToolSessionUIData sessionData) { final ToolProcess process = sessionData.getProcess(); UIAccess.getDisplay().syncExec(new Runnable() { @Override public void run() { connect(process); } }); } @Override public void toolTerminated(final ToolSessionUIData sessionData) { final ToolProcess process = sessionData.getProcess(); UIAccess.getDisplay().syncExec(new Runnable() { @Override public void run() { if (fProcess != null && fProcess == process) { connect(null); } } }); } }; toolRegistry.addListener(fToolRegistryListener, getViewSite().getPage()); connect(toolRegistry.getActiveToolSession(getViewSite().getPage()).getProcess()); PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, "de.walware.statet.nico.ui.cmd_history_view"); //$NON-NLS-1$ } private void updateItem(final TableItem item) { final Entry e = (Entry) item.getData(); item.setImage(NicoUIPlugin.getDefault().getImageRegistry().get(NicoUI.OBJ_CONSOLECOMMAND_IMAGE_ID)); item.setText(e.getCommand()); } private void createActions() { final IHandlerService handlerService = (IHandlerService) getSite().getService(IHandlerService.class); fFilterEmptyAction = new FilterEmptyAction(); fScrollLockAction = new ScrollLockAction(new Receiver() { @Override public void setAutoScroll(final boolean enabled) { fDoAutoscroll = enabled; } }, !fDoAutoscroll); fSelectAllAction = new Action() { @Override public void run() { fTable.selectAll(); } }; fCopyAction = new HistoryCopyAction(this); fSubmitAction = new HistorySubmitAction(this); enabledSelectionActions(false); fTable.addSelectionListener(new SelectionListener() { @Override public void widgetSelected(final SelectionEvent e) { if (fTable.getSelectionCount() > 0) { enabledSelectionActions(true); } else { enabledSelectionActions(false); } }; @Override public void widgetDefaultSelected(final SelectionEvent e) { fSubmitAction.run(); } }); fLoadHistoryAction = new LoadHistoryAction(this); fSaveHistoryAction = new SaveHistoryAction(this); fSearchStartHandler = new AbstractHandler() { @Override public Object execute(final ExecutionEvent arg0) { fSearchTextItem.show(); return null; } }; handlerService.activateHandler(IWorkbenchCommandConstants.EDIT_FIND_AND_REPLACE, fSearchStartHandler); fSearchNextHandler = new AbstractHandler() { @Override public Object execute(final ExecutionEvent arg0) { search(true, -1); return null; } }; handlerService.activateHandler(SharedUIResources.FIND_NEXT_COMMAND_ID, fSearchNextHandler); handlerService.activateHandler("org.eclipse.ui.navigate.next", fSearchNextHandler); //$NON-NLS-1$ fSearchPrevHandler = new AbstractHandler() { @Override public Object execute(final ExecutionEvent arg0) { search(false, -1); return null; } }; handlerService.activateHandler(SharedUIResources.FIND_PREVIOUS_COMMAND_ID, fSearchPrevHandler); handlerService.activateHandler("org.eclipse.ui.navigate.previous", fSearchPrevHandler); //$NON-NLS-1$ } protected void enabledSelectionActions(final boolean enable) { fCopyAction.setEnabled(enable); fSubmitAction.setEnabled(enable); } private void hookContextMenu() { final MenuManager menuMgr = new MenuManager("ContextMenu"); //$NON-NLS-1$ menuMgr.setRemoveAllWhenShown(true); menuMgr.addMenuListener(new IMenuListener() { @Override public void menuAboutToShow(final IMenuManager manager) { HistoryView.this.fillContextMenu(manager); } }); final Menu menu = menuMgr.createContextMenu(fTable); fTable.setMenu(menu); // getSite().registerContextMenu(menuMgr, fTableViewer); } private void contributeToActionBars() { final IActionBars bars = getViewSite().getActionBars(); bars.setGlobalActionHandler(ActionFactory.SELECT_ALL.getId(), fSelectAllAction); bars.setGlobalActionHandler(ActionFactory.COPY.getId(), fCopyAction); fillLocalPullDown(bars.getMenuManager()); fillLocalToolBar(bars.getToolBarManager()); } private void fillLocalPullDown(final IMenuManager manager) { manager.add(fLoadHistoryAction); manager.add(fSaveHistoryAction); manager.add(new Separator()); final IMenuManager filterBySourceMenu = new MenuManager("Include Commands &From", SharedUIResources.getImages().getDescriptor(SharedUIResources.LOCTOOL_FILTER_IMAGE_ID), null); // final IMenuManager filterBySourceMenu = new MenuManager("Hide Commands &From", StatetImages.getDescriptor(StatetImages.LOCTOOL_FILTER), null); final EnumSet<SubmitType> types = SubmitType.getDefaultSet(); for (final SubmitType submitType : types) { filterBySourceMenu.add(new FilterBySourceAction(submitType)); } manager.add(filterBySourceMenu); manager.add(fFilterEmptyAction); manager.add(new Separator()); manager.add(fScrollLockAction); manager.add(new Separator()); } private void fillContextMenu(final IMenuManager manager) { manager.add(fCopyAction); manager.add(fSubmitAction); // Other plug-ins can contribute there actions here manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); } private void fillLocalToolBar(final IToolBarManager manager) { fSearchTextItem = new SearchContributionItem("search.text", //$NON-NLS-1$ SearchContributionItem.VIEW_TOOLBAR) { @Override protected void search() { HistoryView.this.search(true, -1); } }; fSearchTextItem.setToolTip(Messages.HistorySearch_Pattern_tooltip); fSearchTextItem.setSizeControl(fTable.getParent()); fSearchTextItem.setResultControl(fTable); manager.add(fSearchTextItem); final ImageRegistry ecommonsImages = SharedUIResources.getImages(); manager.add(new HandlerContributionItem(new CommandContributionItemParameter(getSite(), "search.next", //$NON-NLS-1$ SharedUIResources.FIND_NEXT_COMMAND_ID, null, ecommonsImages.getDescriptor(SharedUIResources.LOCTOOL_DOWN_IMAGE_ID), null, ecommonsImages.getDescriptor(SharedUIResources.LOCTOOL_DOWN_H_IMAGE_ID), SharedMessages.FindNext_tooltip, null, null, SWT.PUSH, null, false), fSearchNextHandler)); manager.add(new HandlerContributionItem( new CommandContributionItemParameter(getSite(), "search.previous", //$NON-NLS-1$ SharedUIResources.FIND_PREVIOUS_COMMAND_ID, null, ecommonsImages.getDescriptor(SharedUIResources.LOCTOOL_UP_IMAGE_ID), null, ecommonsImages.getDescriptor(SharedUIResources.LOCTOOL_UP_H_IMAGE_ID), SharedMessages.FindPrevious_tooltip, null, null, SWT.PUSH, null, false), fSearchPrevHandler)); manager.add(new Separator()); manager.add(fScrollLockAction); } /** May only be called in UI thread */ public void connect(final ToolProcess process) { if (fProcess == process) { return; } if (fProcess != null) { fProcess.getHistory().removeListener(fContentProvider); } fProcess = process; if (fProcess != null) { fProcess.getHistory().addListener(fContentProvider); } scheduleRefresh(true); for (final IToolRetargetable action : fToolListenerList.toArray()) { action.setTool(fProcess); } } private void scheduleRefresh(final boolean change) { final IWorkbenchSiteProgressService context = (IWorkbenchSiteProgressService) getSite() .getAdapter(IWorkbenchSiteProgressService.class); if (change) { fReloadJob.cancel(); context.schedule(fReloadJob, 200); } else { context.schedule(fReloadJob, 0); } } @Override public void addToolRetargetable(final IToolRetargetable action) { fToolListenerList.add(action); } @Override public void removeToolRetargetable(final IToolRetargetable action) { fToolListenerList.remove(action); } public void addFilter(final EntryFilter filter) { fFilter.add(filter); scheduleRefresh(false); } public void removeFilter(final EntryFilter filter) { fFilter.remove(filter); scheduleRefresh(false); } public void replaceFilter(final EntryFilter oldFilter, final EntryFilter newFilter) { fFilter.replace(oldFilter, newFilter); scheduleRefresh(false); } public void search(final String pattern, final boolean forward) { fSearchTextItem.getSearchText().setText(pattern); search(forward, forward ? 0 : fTable.getItemCount() - 1); } /** * Returns the tool process, which this view is connected to. * * @return a tool process or <code>null</code>, if no process is connected. */ @Override public ToolProcess getTool() { return fProcess; } /** * Returns a shared clipboard resource, which can be used by actions of this view. * * @return a clipboard object. */ public Clipboard getClipboard() { if (fClipboard == null) { fClipboard = new Clipboard(Display.getCurrent()); } return fClipboard; } public Entry[] getSelection() { final TableItem[] items = fTable.getSelection(); final int n = items.length; final Entry[] selection = new Entry[n]; for (int i = 0; i < n; i++) { selection[i] = (Entry) items[i].getData(); } return selection; } @Override public void setFocus() { // Passing the focus request to the viewer's control. fTable.setFocus(); } private void search(final boolean forward, final int startIdx) { if (!UIAccess.isOkToUse(fTable)) { return; } final int itemCount = fTable.getItemCount(); final String text = fSearchTextItem.getText(); if (itemCount == 0 || text.isEmpty()) { return; } int start = 0; do { final char c = text.charAt(start); if (c == ' ' || c == '\t') { start++; } else { break; } } while (start < text.length()); fSearchPattern.setPattern(text.substring(start)); int idx; if (startIdx < 0) { idx = fTable.getSelectionIndex(); } else { idx = (forward) ? startIdx - 1 : startIdx + 1; } if (forward) { idx++; while (idx < itemCount) { final Entry e = (Entry) fTable.getItem(idx).getData(); final int offset = e.getCommandMarker(); if (fSearchPattern.matches(e.getCommand().substring(offset >= 0 ? offset : -1 - offset))) { fTable.setSelection(idx); return; } idx++; } } else { idx--; while (idx >= 0) { final Entry e = (Entry) fTable.getItem(idx).getData(); final int offset = e.getCommandMarker(); if (fSearchPattern.matches(e.getCommand().substring(offset >= 0 ? offset : -1 - offset))) { fTable.setSelection(idx); return; } idx--; } } Display.getCurrent().beep(); } @Override public void dispose() { if (fToolRegistryListener != null) { NicoUI.getToolRegistry().removeListener(fToolRegistryListener); fToolRegistryListener = null; } fReloadJob.cancel(); final ToolProcess process = fProcess; if (process != null) { process.getHistory().removeListener(fContentProvider); } fToolListenerList.clear(); fProcess = null; fCopyAction = null; fSubmitAction = null; fLoadHistoryAction = null; fSaveHistoryAction = null; if (fSearchStartHandler != null) { fSearchStartHandler.dispose(); fSearchStartHandler = null; } if (fSearchPrevHandler != null) { fSearchPrevHandler.dispose(); fSearchPrevHandler = null; } if (fSearchNextHandler != null) { fSearchNextHandler.dispose(); fSearchNextHandler = null; } super.dispose(); if (fClipboard != null) { fClipboard.dispose(); fClipboard = null; } fTable = null; } }