| /******************************************************************************* |
| * Copyright (c) 2000, 2018 IBM Corporation and others. |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License v. 2.0 which is available at |
| * http://www.eclipse.org/legal/epl-2.0. |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.dltk.ui.dialogs; |
| |
| import java.io.IOException; |
| import java.io.StringReader; |
| import java.io.StringWriter; |
| import java.lang.reflect.InvocationTargetException; |
| import java.util.ArrayList; |
| import java.util.Comparator; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Platform; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.core.runtime.SubMonitor; |
| import org.eclipse.core.runtime.jobs.IJobManager; |
| import org.eclipse.core.runtime.jobs.Job; |
| import org.eclipse.dltk.ast.Modifiers; |
| import org.eclipse.dltk.core.Flags; |
| import org.eclipse.dltk.core.IDLTKLanguageToolkit; |
| import org.eclipse.dltk.core.IModelElement; |
| import org.eclipse.dltk.core.IProjectFragment; |
| import org.eclipse.dltk.core.IType; |
| import org.eclipse.dltk.core.ModelException; |
| import org.eclipse.dltk.core.WorkingCopyOwner; |
| import org.eclipse.dltk.core.index2.search.ModelAccess; |
| import org.eclipse.dltk.core.search.IDLTKSearchConstants; |
| import org.eclipse.dltk.core.search.IDLTKSearchScope; |
| import org.eclipse.dltk.core.search.NopTypeNameRequestor; |
| import org.eclipse.dltk.core.search.SearchEngine; |
| import org.eclipse.dltk.core.search.TypeNameMatch; |
| import org.eclipse.dltk.core.search.TypeNameMatchRequestor; |
| import org.eclipse.dltk.internal.core.search.DLTKSearchTypeNameMatch; |
| import org.eclipse.dltk.internal.corext.util.Messages; |
| import org.eclipse.dltk.internal.corext.util.OpenTypeHistory; |
| import org.eclipse.dltk.internal.corext.util.Strings; |
| import org.eclipse.dltk.internal.corext.util.TypeFilter; |
| import org.eclipse.dltk.internal.corext.util.TypeInfoRequestorAdapter; |
| import org.eclipse.dltk.internal.ui.DLTKUIMessages; |
| import org.eclipse.dltk.internal.ui.dialogs.TextFieldNavigationHandler; |
| import org.eclipse.dltk.internal.ui.search.DLTKSearchScopeFactory; |
| import org.eclipse.dltk.internal.ui.util.TypeNameMatchLabelProvider; |
| import org.eclipse.dltk.internal.ui.workingsets.WorkingSetFilterActionGroup; |
| import org.eclipse.dltk.launching.IInterpreterInstall; |
| import org.eclipse.dltk.launching.IInterpreterInstallType; |
| import org.eclipse.dltk.launching.LibraryLocation; |
| import org.eclipse.dltk.launching.ScriptRuntime; |
| import org.eclipse.dltk.ui.DLTKUILanguageManager; |
| import org.eclipse.dltk.ui.DLTKUIPlugin; |
| import org.eclipse.dltk.ui.IDLTKUILanguageToolkit; |
| import org.eclipse.dltk.ui.ScriptElementImageProvider; |
| import org.eclipse.dltk.ui.ScriptElementLabels; |
| import org.eclipse.dltk.ui.util.ExceptionHandler; |
| import org.eclipse.jface.action.IMenuManager; |
| import org.eclipse.jface.dialogs.IDialogSettings; |
| import org.eclipse.jface.dialogs.MessageDialog; |
| import org.eclipse.jface.operation.IRunnableContext; |
| import org.eclipse.jface.operation.IRunnableWithProgress; |
| import org.eclipse.jface.resource.ImageDescriptor; |
| import org.eclipse.jface.text.ITextSelection; |
| import org.eclipse.jface.viewers.ILabelDecorator; |
| import org.eclipse.jface.viewers.ISelection; |
| import org.eclipse.jface.viewers.LabelProvider; |
| import org.eclipse.jface.viewers.LabelProviderChangedEvent; |
| import org.eclipse.osgi.util.NLS; |
| import org.eclipse.swt.graphics.Image; |
| import org.eclipse.swt.layout.GridData; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Control; |
| import org.eclipse.swt.widgets.Shell; |
| import org.eclipse.swt.widgets.Text; |
| import org.eclipse.ui.IMemento; |
| import org.eclipse.ui.IWorkbenchWindow; |
| import org.eclipse.ui.IWorkingSet; |
| import org.eclipse.ui.WorkbenchException; |
| import org.eclipse.ui.XMLMemento; |
| import org.eclipse.ui.dialogs.FilteredItemsSelectionDialog; |
| import org.eclipse.ui.dialogs.ISelectionStatusValidator; |
| import org.eclipse.ui.dialogs.SearchPattern; |
| |
| /** |
| * Shows a list of Java types to the user with a text entry field for a string |
| * pattern used to filter the list of types. |
| * |
| * @since 3.3 |
| */ |
| public class FilteredTypesSelectionDialog extends FilteredItemsSelectionDialog implements ITypeSelectionComponent { |
| |
| private static final String DIALOG_SETTINGS = "org.eclipse.jdt.internal.ui.dialogs.FilteredTypesSelectionDialog"; //$NON-NLS-1$ |
| |
| private static final String WORKINGS_SET_SETTINGS = "WorkingSet"; //$NON-NLS-1$ |
| |
| private WorkingSetFilterActionGroup fFilterActionGroup; |
| |
| private final TypeItemLabelProvider fTypeInfoLabelProvider; |
| |
| private String fTitle; |
| |
| private IDLTKSearchScope fSearchScope; |
| |
| private boolean fAllowScopeSwitching; |
| |
| private final int fElementKinds; |
| |
| private final ITypeInfoFilterExtension fFilterExtension; |
| |
| private final TypeSelectionExtension fExtension; |
| |
| private ISelectionStatusValidator fValidator; |
| |
| private final TypeInfoUtil fTypeInfoUtil; |
| |
| private static boolean fgFirstTime = true; |
| |
| private final TypeItemsComparator fTypeItemsComparator; |
| |
| private int fTypeFilterVersion = 0; |
| |
| private IDLTKLanguageToolkit fToolkit; |
| |
| /** |
| * Creates new FilteredTypesSelectionDialog instance |
| * |
| * @param parent shell to parent the dialog on |
| * @param multi <code>true</code> if multiple selection is allowed |
| * @param context context used to execute long-running operations |
| * associated with this dialog |
| * @param scope scope used when searching for types |
| * @param elementKinds flags defining nature of searched elements; the only |
| * valid values are: <code>IJavaSearchConstants.TYPE</code> |
| * <code>IJavaSearchConstants.ANNOTATION_TYPE</code> |
| * <code>IJavaSearchConstants.INTERFACE</code> |
| * <code>IJavaSearchConstants.ENUM</code> |
| * <code>IJavaSearchConstants.CLASS_AND_INTERFACE</code> |
| * <code>IJavaSearchConstants.CLASS_AND_ENUM</code>. Please |
| * note that the bitwise OR combination of the elementary |
| * constants is not supported. |
| */ |
| public FilteredTypesSelectionDialog(Shell parent, boolean multi, IRunnableContext context, IDLTKSearchScope scope, |
| int elementKinds, IDLTKLanguageToolkit toolkit) { |
| this(parent, multi, context, scope, elementKinds, null, toolkit); |
| } |
| |
| /** |
| * Creates new FilteredTypesSelectionDialog instance. |
| * |
| * @param shell shell to parent the dialog on |
| * @param multi <code>true</code> if multiple selection is allowed |
| * @param context context used to execute long-running operations |
| * associated with this dialog |
| * @param scope scope used when searching for types. If the scope is |
| * <code>null</code>, then workspace is scope is used as |
| * default, and the user can choose a working set as scope. |
| * @param elementKinds flags defining nature of searched elements; the only |
| * valid values are: <code>IJavaSearchConstants.TYPE</code> |
| * <code>IJavaSearchConstants.ANNOTATION_TYPE</code> |
| * <code>IJavaSearchConstants.INTERFACE</code> |
| * <code>IJavaSearchConstants.ENUM</code> |
| * <code>IJavaSearchConstants.CLASS_AND_INTERFACE</code> |
| * <code>IJavaSearchConstants.CLASS_AND_ENUM</code>. Please |
| * note that the bitwise OR combination of the elementary |
| * constants is not supported. |
| * @param extension an extension of the standard type selection dialog; See |
| * {@link TypeSelectionExtension} |
| */ |
| public FilteredTypesSelectionDialog(Shell shell, boolean multi, IRunnableContext context, IDLTKSearchScope scope, |
| int elementKinds, TypeSelectionExtension extension, IDLTKLanguageToolkit toolkit) { |
| super(shell, multi); |
| |
| this.fToolkit = toolkit; |
| |
| setSelectionHistory(new TypeSelectionHistory()); |
| |
| if (scope == null) { |
| fAllowScopeSwitching = true; |
| scope = SearchEngine.createWorkspaceScope(toolkit); |
| } |
| // PlatformUI.getWorkbench().getHelpSystem().setHelp(shell, |
| // IJavaHelpContextIds.TYPE_SELECTION_DIALOG2); |
| |
| fElementKinds = elementKinds; |
| fExtension = extension; |
| fFilterExtension = (extension == null) ? null : extension.getFilterExtension(); |
| fSearchScope = scope; |
| |
| if (extension != null) { |
| fValidator = extension.getSelectionValidator(); |
| } |
| |
| fTypeInfoUtil = new TypeInfoUtil(extension != null ? extension.getImageProvider() : null); |
| |
| fTypeInfoLabelProvider = new TypeItemLabelProvider(); |
| |
| setListLabelProvider(fTypeInfoLabelProvider); |
| setListSelectionLabelDecorator(fTypeInfoLabelProvider); |
| setDetailsLabelProvider(new TypeItemDetailsLabelProvider(fTypeInfoUtil)); |
| |
| fTypeItemsComparator = new TypeItemsComparator(); |
| } |
| |
| @Override |
| public void setTitle(String title) { |
| super.setTitle(title); |
| fTitle = title; |
| } |
| |
| /** |
| * Adds or replaces subtitle of the dialog |
| * |
| * @param text the new subtitle for this dialog |
| */ |
| private void setSubtitle(String text) { |
| if (text == null || text.length() == 0) { |
| getShell().setText(fTitle); |
| } else { |
| getShell().setText(Messages.format(DLTKUIMessages.FilteredTypeSelectionDialog_titleFormat, fTitle, text)); |
| } |
| } |
| |
| @Override |
| protected IDialogSettings getDialogSettings() { |
| IDialogSettings settings = DLTKUIPlugin.getDefault().getDialogSettings().getSection(DIALOG_SETTINGS); |
| |
| if (settings == null) { |
| settings = DLTKUIPlugin.getDefault().getDialogSettings().addNewSection(DIALOG_SETTINGS); |
| } |
| |
| return settings; |
| } |
| |
| @Override |
| protected void storeDialog(IDialogSettings settings) { |
| super.storeDialog(settings); |
| |
| if (fFilterActionGroup != null) { |
| XMLMemento memento = XMLMemento.createWriteRoot("workingSet"); //$NON-NLS-1$ |
| fFilterActionGroup.saveState(memento); |
| fFilterActionGroup.dispose(); |
| StringWriter writer = new StringWriter(); |
| try { |
| memento.save(writer); |
| settings.put(WORKINGS_SET_SETTINGS, writer.getBuffer().toString()); |
| } catch (IOException e) { |
| // don't do anything. Simply don't store the settings |
| DLTKUIPlugin.log(e); |
| } |
| } |
| } |
| |
| @Override |
| protected void restoreDialog(IDialogSettings settings) { |
| super.restoreDialog(settings); |
| |
| fTypeInfoLabelProvider.setContainerInfo(true); |
| |
| if (fAllowScopeSwitching) { |
| String setting = settings.get(WORKINGS_SET_SETTINGS); |
| if (setting != null) { |
| try { |
| IMemento memento = XMLMemento.createReadRoot(new StringReader(setting)); |
| fFilterActionGroup.restoreState(memento); |
| } catch (WorkbenchException e) { |
| // don't do anything. Simply don't restore the settings |
| DLTKUIPlugin.log(e); |
| } |
| } |
| IWorkingSet ws = fFilterActionGroup.getWorkingSet(); |
| if (ws == null || (ws.isAggregateWorkingSet() && ws.isEmpty())) { |
| setSearchScope(SearchEngine.createWorkspaceScope(fToolkit)); |
| setSubtitle(null); |
| } else { |
| setSearchScope(DLTKSearchScopeFactory.getInstance().createSearchScope(ws, true, fToolkit)); |
| setSubtitle(ws.getLabel()); |
| } |
| } |
| |
| // TypeNameMatch[] types = OpenTypeHistory.getInstance().getTypeInfos(); |
| // |
| // for (int i = 0; i < types.length; i++) { |
| // TypeNameMatch type = types[i]; |
| // accessedHistoryItem(type); |
| // } |
| } |
| |
| @Override |
| protected void fillViewMenu(IMenuManager menuManager) { |
| super.fillViewMenu(menuManager); |
| |
| if (fAllowScopeSwitching) { |
| fFilterActionGroup = new WorkingSetFilterActionGroup(getShell(), DLTKUIPlugin.getActivePage(), event -> { |
| IWorkingSet ws = (IWorkingSet) event.getNewValue(); |
| if (ws == null || (ws.isAggregateWorkingSet() && ws.isEmpty())) { |
| setSearchScope(SearchEngine.createWorkspaceScope(fToolkit)); |
| setSubtitle(null); |
| } else { |
| setSearchScope(DLTKSearchScopeFactory.getInstance().createSearchScope(ws, true, fToolkit)); |
| setSubtitle(ws.getLabel()); |
| } |
| |
| applyFilter(); |
| }); |
| fFilterActionGroup.fillViewMenu(menuManager); |
| } |
| |
| // menuManager.add(new Separator()); |
| // menuManager.add(new TypeFiltersPreferencesAction()); |
| } |
| |
| @Override |
| protected Control createExtendedContentArea(Composite parent) { |
| Control addition = null; |
| |
| if (fExtension != null) { |
| |
| addition = fExtension.createContentArea(parent); |
| if (addition != null) { |
| GridData gd = new GridData(GridData.FILL_HORIZONTAL); |
| gd.horizontalSpan = 2; |
| addition.setLayoutData(gd); |
| |
| } |
| |
| fExtension.initialize(this); |
| } |
| |
| return addition; |
| } |
| |
| @Override |
| protected void setResult(List newResult) { |
| |
| List<IType> resultToReturn = new ArrayList<>(); |
| |
| for (int i = 0; i < newResult.size(); i++) { |
| if (newResult.get(i) instanceof TypeNameMatch) { |
| IType type = ((TypeNameMatch) newResult.get(i)).getType(); |
| if (type.exists()) { |
| // items are added to history in the |
| // org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#computeResult() |
| // method |
| resultToReturn.add(type); |
| } else { |
| TypeNameMatch typeInfo = (TypeNameMatch) newResult.get(i); |
| IProjectFragment root = typeInfo.getProjectFragment(); |
| IDLTKUILanguageToolkit uiToolkit = DLTKUILanguageManager.getLanguageToolkit(fToolkit.getNatureId()); |
| ScriptElementLabels labels = uiToolkit.getScriptElementLabels(); |
| String containerName = labels.getElementLabel(root, ScriptElementLabels.ALL_FULLY_QUALIFIED); |
| String message = Messages.format(DLTKUIMessages.FilteredTypesSelectionDialog_dialogMessage, |
| typeInfo.getFullyQualifiedName(), containerName); |
| MessageDialog.openError(getShell(), fTitle, message); |
| getSelectionHistory().remove(typeInfo); |
| } |
| } |
| } |
| |
| super.setResult(resultToReturn); |
| } |
| |
| @Override |
| public void create() { |
| super.create(); |
| Control patternControl = getPatternControl(); |
| if (patternControl instanceof Text) { |
| TextFieldNavigationHandler.install((Text) patternControl); |
| } |
| } |
| |
| @Override |
| public int open() { |
| if (getInitialPattern() == null) { |
| IWorkbenchWindow window = DLTKUIPlugin.getActiveWorkbenchWindow(); |
| if (window != null) { |
| ISelection selection = window.getSelectionService().getSelection(); |
| if (selection instanceof ITextSelection) { |
| String text = ((ITextSelection) selection).getText(); |
| if (text != null) { |
| text = text.trim(); |
| if (text.length() > 0) { |
| setInitialPattern(text, FULL_SELECTION); |
| } |
| } |
| } |
| } |
| } |
| return super.open(); |
| } |
| |
| /** |
| * Sets a new validator. |
| * |
| * @param validator the new validator |
| */ |
| public void setValidator(ISelectionStatusValidator validator) { |
| fValidator = validator; |
| } |
| |
| @Override |
| protected ItemsFilter createFilter() { |
| return new TypeItemsFilter(fSearchScope, fElementKinds, fFilterExtension); |
| } |
| |
| @Override |
| protected Control createContents(Composite parent) { |
| Control contents = super.createContents(parent); |
| // if (ColoredViewersManager.showColoredLabels()) { |
| // if (contents instanceof Composite) { |
| // Table listControl = findTableControl((Composite) contents); |
| // if (listControl != null) { |
| // installOwnerDraw(listControl); |
| // } |
| // } |
| // } |
| return contents; |
| } |
| |
| @Override |
| protected void fillContentProvider(AbstractContentProvider provider, ItemsFilter itemsFilter, |
| IProgressMonitor progressMonitor) throws CoreException { |
| TypeItemsFilter typeSearchFilter = (TypeItemsFilter) itemsFilter; |
| TypeSearchRequestor requestor = new TypeSearchRequestor(provider, typeSearchFilter); |
| String typePattern = itemsFilter.getPattern(); |
| |
| progressMonitor.setTaskName(DLTKUIMessages.FilteredTypesSelectionDialog_searchJob_taskName); |
| |
| IType[] types = new ModelAccess().findTypes(typePattern, |
| ModelAccess.convertSearchRule(itemsFilter.getMatchRule()), 0, Modifiers.AccNameSpace, |
| typeSearchFilter.getSearchScope(), progressMonitor); |
| if (types != null) { |
| for (IType type : types) { |
| requestor.acceptTypeNameMatch(new DLTKSearchTypeNameMatch(type, type.getFlags())); |
| } |
| } else { |
| |
| SearchEngine engine = new SearchEngine((WorkingCopyOwner) null); |
| String packPattern = typeSearchFilter.getPackagePattern(); |
| |
| /* |
| * Setting the filter into match everything mode avoids filtering twice by the |
| * same pattern (the search engine only provides filtered matches). For the case |
| * when the pattern is a camel case pattern with a terminator, the filter is not |
| * set to match everything mode because jdt.core's SearchPattern does not |
| * support that case. |
| */ |
| int matchRule = typeSearchFilter.getMatchRule(); |
| if (matchRule == SearchPattern.RULE_CAMELCASE_MATCH) { |
| // If the pattern is empty, the RULE_BLANK_MATCH will be chosen, |
| // so |
| // we don't have to check the pattern length |
| char lastChar = typePattern.charAt(typePattern.length() - 1); |
| |
| if (lastChar == '<' || lastChar == ' ') { |
| typePattern = typePattern.substring(0, typePattern.length() - 1); |
| } else { |
| typeSearchFilter.setMatchEverythingMode(true); |
| } |
| } else { |
| typeSearchFilter.setMatchEverythingMode(true); |
| } |
| |
| try { |
| engine.searchAllTypeNames(packPattern == null ? null : packPattern.toCharArray(), |
| typeSearchFilter.getPackageFlags(), typePattern.toCharArray(), matchRule, |
| typeSearchFilter.getElementKind(), typeSearchFilter.getSearchScope(), requestor, |
| IDLTKSearchConstants.WAIT_UNTIL_READY_TO_SEARCH, progressMonitor); |
| } finally { |
| typeSearchFilter.setMatchEverythingMode(false); |
| } |
| } |
| } |
| |
| @Override |
| protected Comparator getItemsComparator() { |
| return fTypeItemsComparator; |
| } |
| |
| @Override |
| public String getElementName(Object item) { |
| TypeNameMatch type = (TypeNameMatch) item; |
| return fTypeInfoUtil.getText(type); |
| } |
| |
| @Override |
| protected IStatus validateItem(Object item) { |
| |
| if (item == null) |
| return new Status(IStatus.ERROR, DLTKUIPlugin.getPluginId(), IStatus.ERROR, "", null); //$NON-NLS-1$ |
| |
| if (fValidator != null) { |
| IType type = ((TypeNameMatch) item).getType(); |
| if (!type.exists()) |
| return new Status(IStatus.ERROR, DLTKUIPlugin.getPluginId(), IStatus.ERROR, |
| Messages.format(DLTKUIMessages.FilteredTypesSelectionDialog_error_type_doesnot_exist, |
| ((TypeNameMatch) item).getFullyQualifiedName()), |
| null); |
| Object[] elements = { type }; |
| return fValidator.validate(elements); |
| } |
| return new Status(IStatus.OK, DLTKUIPlugin.getPluginId(), IStatus.OK, "", null); //$NON-NLS-1$ |
| } |
| |
| /** |
| * Sets search scope used when searching for types. |
| * |
| * @param scope the new scope |
| */ |
| private void setSearchScope(IDLTKSearchScope scope) { |
| fSearchScope = scope; |
| } |
| |
| /* |
| * We only have to ensure history consistency here since the search engine takes |
| * care of working copies. |
| */ |
| private static class ConsistencyRunnable implements IRunnableWithProgress { |
| private IDLTKUILanguageToolkit tookit; |
| |
| ConsistencyRunnable(IDLTKLanguageToolkit toolkit) { |
| this.tookit = DLTKUILanguageManager.getLanguageToolkit(toolkit.getNatureId()); |
| } |
| |
| @Override |
| public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { |
| if (fgFirstTime) { |
| // Join the initialize after load job. |
| IJobManager manager = Job.getJobManager(); |
| manager.join(DLTKUIPlugin.PLUGIN_ID, monitor); |
| } |
| OpenTypeHistory history = OpenTypeHistory.getInstance(tookit); |
| if (fgFirstTime || history.isEmpty()) { |
| if (history.needConsistencyCheck()) { |
| SubMonitor subMonitor = SubMonitor.convert(monitor, |
| DLTKUIMessages.TypeSelectionDialog_progress_consistency, 100); |
| refreshSearchIndices(subMonitor.split(90)); |
| history.checkConsistency(subMonitor.split(10)); |
| } else { |
| refreshSearchIndices(monitor); |
| } |
| fgFirstTime = false; |
| } else { |
| history.checkConsistency(monitor); |
| } |
| } |
| |
| public static boolean needsExecution(IDLTKLanguageToolkit toolkit) { |
| OpenTypeHistory history = OpenTypeHistory |
| .getInstance(DLTKUILanguageManager.getLanguageToolkit(toolkit.getNatureId())); |
| return fgFirstTime || history.isEmpty() || history.needConsistencyCheck(); |
| } |
| |
| private void refreshSearchIndices(IProgressMonitor monitor) throws InvocationTargetException { |
| try { |
| new SearchEngine().searchAllTypeNames(null, 0, |
| // make sure we search a concrete name. This is faster |
| // according to Kent |
| "_______________".toCharArray(), //$NON-NLS-1$ |
| SearchPattern.RULE_EXACT_MATCH | SearchPattern.RULE_CASE_SENSITIVE, IDLTKSearchConstants.TYPE, |
| SearchEngine.createWorkspaceScope(tookit.getCoreToolkit()), new NopTypeNameRequestor(), |
| IDLTKSearchConstants.WAIT_UNTIL_READY_TO_SEARCH, monitor); |
| } catch (ModelException e) { |
| throw new InvocationTargetException(e); |
| } |
| } |
| } |
| |
| @Override |
| public void reloadCache(boolean checkDuplicates, IProgressMonitor monitor) { |
| IProgressMonitor remainingMonitor; |
| SubMonitor subMonitor = SubMonitor.convert(monitor, DLTKUIMessages.TypeSelectionDialog_progress_consistency, |
| 10); |
| if (ConsistencyRunnable.needsExecution(fToolkit)) { |
| try { |
| ConsistencyRunnable runnable = new ConsistencyRunnable(fToolkit); |
| runnable.run(subMonitor.split(1)); |
| } catch (InvocationTargetException e) { |
| ExceptionHandler.handle(e, DLTKUIMessages.TypeSelectionDialog_error3Title, |
| DLTKUIMessages.TypeSelectionDialog_error3Message); |
| close(); |
| return; |
| } catch (InterruptedException e) { |
| // cancelled by user |
| close(); |
| return; |
| } |
| remainingMonitor = subMonitor.split(9); |
| } else { |
| remainingMonitor = subMonitor; |
| } |
| super.reloadCache(checkDuplicates, remainingMonitor); |
| } |
| |
| @Override |
| public void triggerSearch() { |
| fTypeFilterVersion++; |
| applyFilter(); |
| } |
| |
| /** |
| * A <code>LabelProvider</code> for (the table of) types. |
| */ |
| private class TypeItemLabelProvider extends LabelProvider implements ILabelDecorator { |
| |
| private boolean fContainerInfo; |
| |
| /** |
| * Construct a new <code>TypeItemLabelProvider</code>. F |
| */ |
| public TypeItemLabelProvider() { |
| |
| } |
| |
| public void setContainerInfo(boolean containerInfo) { |
| fContainerInfo = containerInfo; |
| fireLabelProviderChanged(new LabelProviderChangedEvent(this)); |
| } |
| |
| @Override |
| public Image getImage(Object element) { |
| if (!(element instanceof TypeNameMatch)) { |
| return super.getImage(element); |
| } |
| |
| TypeNameMatch type = (TypeNameMatch) element; |
| |
| ImageDescriptor iD = ScriptElementImageProvider.getTypeImageDescriptor(type.getModifiers(), false); |
| |
| return DLTKUIPlugin.getImageDescriptorRegistry().get(iD); |
| } |
| |
| @Override |
| public String getText(Object element) { |
| if (!(element instanceof TypeNameMatch)) { |
| return super.getText(element); |
| } |
| |
| if (fContainerInfo && isDuplicateElement(element)) { |
| return fTypeInfoUtil.getFullyQualifiedText((TypeNameMatch) element); |
| } |
| |
| if (!fContainerInfo && isDuplicateElement(element)) { |
| return fTypeInfoUtil.getQualifiedText((TypeNameMatch) element); |
| } |
| |
| return fTypeInfoUtil.getText(element); |
| } |
| |
| @Override |
| public Image decorateImage(Image image, Object element) { |
| return null; |
| } |
| |
| @Override |
| public String decorateText(String text, Object element) { |
| if (!(element instanceof TypeNameMatch)) { |
| return null; |
| } |
| |
| if (fContainerInfo && isDuplicateElement(element)) { |
| return fTypeInfoUtil.getFullyQualifiedText((TypeNameMatch) element); |
| } |
| |
| return fTypeInfoUtil.getQualifiedText((TypeNameMatch) element); |
| } |
| |
| } |
| |
| /** |
| * A <code>LabelProvider</code> for the label showing type details. |
| */ |
| private class TypeItemDetailsLabelProvider extends LabelProvider { |
| |
| private TypeNameMatchLabelProvider fLabelProvider; |
| |
| private final TypeInfoUtil fTypeInfoUtil; |
| |
| public TypeItemDetailsLabelProvider(TypeInfoUtil typeInfoUtil) { |
| fTypeInfoUtil = typeInfoUtil; |
| |
| fLabelProvider = new TypeNameMatchLabelProvider( |
| TypeNameMatchLabelProvider.SHOW_TYPE_ONLY + TypeNameMatchLabelProvider.SHOW_FULLYQUALIFIED, |
| DLTKUILanguageManager.getLanguageToolkit(fToolkit.getNatureId())); |
| } |
| |
| @Override |
| public Image getImage(Object element) { |
| if (element instanceof TypeNameMatch) { |
| return fLabelProvider.getImage((element)); |
| } |
| |
| return super.getImage(element); |
| } |
| |
| @Override |
| public String getText(Object element) { |
| if (element instanceof TypeNameMatch) { |
| return fTypeInfoUtil.getQualificationText((TypeNameMatch) element); |
| } |
| |
| return super.getText(element); |
| } |
| } |
| |
| private class TypeInfoUtil { |
| |
| private final ITypeInfoImageProvider fProviderExtension; |
| |
| private final TypeInfoRequestorAdapter fAdapter = new TypeInfoRequestorAdapter(); |
| |
| private final Map<String, String> fLib2Name = new HashMap<>(); |
| |
| private final String[] fInstallLocations; |
| |
| private final String[] fVMNames; |
| |
| public TypeInfoUtil(ITypeInfoImageProvider extension) { |
| fProviderExtension = extension; |
| List<String> locations = new ArrayList<>(); |
| List<String> labels = new ArrayList<>(); |
| IInterpreterInstallType[] installs = ScriptRuntime.getInterpreterInstallTypes(fToolkit.getNatureId()); |
| for (int i = 0; i < installs.length; i++) { |
| processInterpreterInstallType(installs[i], locations, labels); |
| } |
| fInstallLocations = locations.toArray(new String[locations.size()]); |
| fVMNames = labels.toArray(new String[labels.size()]); |
| |
| } |
| |
| private void processInterpreterInstallType(IInterpreterInstallType installType, List<String> locations, |
| List<String> labels) { |
| if (installType != null) { |
| IInterpreterInstall[] installs = installType.getInterpreterInstalls(); |
| boolean isMac = Platform.OS_MACOSX.equals(Platform.getOS()); |
| final String HOME_SUFFIX = "/Home"; //$NON-NLS-1$ |
| for (int i = 0; i < installs.length; i++) { |
| String label = getFormattedLabel(installs[i].getName()); |
| LibraryLocation[] libLocations = installs[i].getLibraryLocations(); |
| if (libLocations != null) { |
| processLibraryLocation(libLocations, label); |
| } else { |
| String filePath = installs[i].getInstallLocation().toOSString(); |
| if (filePath != null) { |
| // on MacOS X install locations end in an additional |
| // "/Home" segment; remove it |
| if (isMac && filePath.endsWith(HOME_SUFFIX)) |
| filePath = filePath.substring(0, filePath.length() - HOME_SUFFIX.length() + 1); |
| locations.add(filePath); |
| labels.add(label); |
| } |
| } |
| } |
| } |
| } |
| |
| private void processLibraryLocation(LibraryLocation[] libLocations, String label) { |
| for (int l = 0; l < libLocations.length; l++) { |
| LibraryLocation location = libLocations[l]; |
| fLib2Name.put(location.getLibraryPath().toOSString(), label); |
| } |
| } |
| |
| private String getFormattedLabel(String name) { |
| return Messages.format(DLTKUIMessages.FilteredTypesSelectionDialog_library_name_format, name); |
| } |
| |
| public String getText(Object element) { |
| return ((TypeNameMatch) element).getSimpleTypeName(); |
| } |
| |
| public String getQualifiedText(TypeNameMatch type) { |
| StringBuffer result = new StringBuffer(); |
| result.append(type.getSimpleTypeName()); |
| // String containerName = type.getTypeContainerName(); |
| // result.append(ScriptElementLabels.CONCAT_STRING); |
| // if (containerName.length() > 0) { |
| // result.append(containerName); |
| // } else { |
| // result.append(""); |
| // } |
| return result.toString(); |
| } |
| |
| public String getFullyQualifiedText(TypeNameMatch type) { |
| StringBuffer result = new StringBuffer(); |
| result.append(type.getSimpleTypeName()); |
| IType stype = type.getType(); |
| if (stype.getParent().getElementType() == IModelElement.TYPE) { |
| result.append(ScriptElementLabels.CONCAT_STRING); |
| IType parent = (IType) stype.getParent(); |
| result.append(parent.getTypeQualifiedName(".")); //$NON-NLS-1$ |
| } |
| // String containerName = type.getTypeContainerName(); |
| // if (containerName.length() > 0) { |
| // result.append(ScriptElementLabels.CONCAT_STRING); |
| // result.append(containerName); |
| // } |
| // result.append(ScriptElementLabels.CONCAT_STRING); |
| // result.append(getContainerName(type)); |
| return result.toString(); |
| } |
| |
| public String getQualificationText(TypeNameMatch type) { |
| StringBuffer result = new StringBuffer(); |
| result.append(type.getType().getTypeQualifiedName(".")); //$NON-NLS-1$ |
| result.append(ScriptElementLabels.CONCAT_STRING); |
| result.append(getContainerName(type)); |
| return result.toString(); |
| } |
| |
| private String getContainerName(TypeNameMatch type) { |
| IProjectFragment root = type.getProjectFragment(); |
| if (root.isExternal()) { |
| String name = root.getPath().toOSString(); |
| for (int i = 0; i < fInstallLocations.length; i++) { |
| if (name.startsWith(fInstallLocations[i])) { |
| return fVMNames[i]; |
| } |
| } |
| String lib = fLib2Name.get(name); |
| if (lib != null) |
| return lib; |
| } |
| StringBuffer buf = new StringBuffer(); |
| ScriptElementLabels labels = DLTKUILanguageManager.getLanguageToolkit(fToolkit.getNatureId()) |
| .getScriptElementLabels(); |
| labels.getProjectFragmentLabel(root, ScriptElementLabels.ROOT_QUALIFIED | ScriptElementLabels.ROOT_VARIABLE, |
| buf); |
| return buf.toString(); |
| } |
| |
| } |
| |
| /** |
| * Filters types using pattern, scope, element kind and filter extension. |
| */ |
| private class TypeItemsFilter extends ItemsFilter { |
| |
| private static final int TYPE_MODIFIERS = Flags.AccAnnotation | Flags.AccInterface; |
| |
| private final IDLTKSearchScope fScope; |
| |
| private final boolean fIsWorkspaceScope; |
| |
| private final int fElemKind; |
| |
| private final ITypeInfoFilterExtension fFilterExt; |
| |
| private final TypeInfoRequestorAdapter fAdapter = new TypeInfoRequestorAdapter(); |
| |
| private SearchPattern fPackageMatcher; |
| |
| private boolean fMatchEverything = false; |
| |
| private final int fMyTypeFilterVersion = fTypeFilterVersion; |
| |
| /** |
| * Creates instance of TypeItemsFilter |
| * |
| * @param scope |
| * @param elementKind |
| * @param extension |
| */ |
| public TypeItemsFilter(IDLTKSearchScope scope, int elementKind, ITypeInfoFilterExtension extension) { |
| super(new TypeSearchPattern()); |
| fScope = scope; |
| fIsWorkspaceScope = scope == null ? false : scope.equals(SearchEngine.createWorkspaceScope(fToolkit)); |
| fElemKind = elementKind; |
| fFilterExt = extension; |
| String stringPackage = ((TypeSearchPattern) patternMatcher).getPackagePattern(); |
| if (stringPackage != null) { |
| fPackageMatcher = new SearchPattern(); |
| fPackageMatcher.setPattern(stringPackage); |
| } else { |
| fPackageMatcher = null; |
| } |
| } |
| |
| @Override |
| public boolean isSubFilter(ItemsFilter filter) { |
| if (!super.isSubFilter(filter)) |
| return false; |
| TypeItemsFilter typeItemsFilter = (TypeItemsFilter) filter; |
| if (fScope != typeItemsFilter.getSearchScope()) |
| return false; |
| if (fMyTypeFilterVersion != typeItemsFilter.getMyTypeFilterVersion()) |
| return false; |
| return getPattern().indexOf('.', filter.getPattern().length()) == -1; |
| } |
| |
| @Override |
| public boolean equalsFilter(ItemsFilter iFilter) { |
| if (!super.equalsFilter(iFilter)) |
| return false; |
| if (!(iFilter instanceof TypeItemsFilter)) |
| return false; |
| TypeItemsFilter typeItemsFilter = (TypeItemsFilter) iFilter; |
| if (fScope != typeItemsFilter.getSearchScope()) |
| return false; |
| if (fMyTypeFilterVersion != typeItemsFilter.getMyTypeFilterVersion()) |
| return false; |
| return true; |
| } |
| |
| public int getElementKind() { |
| return fElemKind; |
| } |
| |
| public IDLTKSearchScope getSearchScope() { |
| return fScope; |
| } |
| |
| public int getMyTypeFilterVersion() { |
| return fMyTypeFilterVersion; |
| } |
| |
| public String getPackagePattern() { |
| if (fPackageMatcher == null) |
| return null; |
| return fPackageMatcher.getPattern(); |
| } |
| |
| public int getPackageFlags() { |
| if (fPackageMatcher == null) |
| return SearchPattern.RULE_EXACT_MATCH; |
| |
| return fPackageMatcher.getMatchRule(); |
| } |
| |
| public boolean matchesRawNamePattern(TypeNameMatch type) { |
| return Strings.startsWithIgnoreCase(type.getSimpleTypeName(), getPattern()); |
| } |
| |
| public boolean matchesFilterExtension(TypeNameMatch type) { |
| if (fFilterExt == null) |
| return true; |
| fAdapter.setMatch(type); |
| return fFilterExt.select(fAdapter); |
| } |
| |
| private boolean matchesName(TypeNameMatch type) { |
| return matches(type.getSimpleTypeName()); |
| } |
| |
| private boolean matchesPackage(TypeNameMatch type) { |
| if (fPackageMatcher == null) |
| return true; |
| return fPackageMatcher.matches(type.getPackageName()); |
| } |
| |
| private boolean matchesScope(TypeNameMatch type) { |
| if (fIsWorkspaceScope) |
| return true; |
| return fScope.encloses(type.getType()); |
| |
| } |
| |
| private boolean matchesModifiers(TypeNameMatch type) { |
| if (fElemKind == IDLTKSearchConstants.TYPE) |
| return true; |
| int modifiers = type.getModifiers() & TYPE_MODIFIERS; |
| switch (fElemKind) { |
| case IDLTKSearchConstants.TYPE: |
| return modifiers == 0; |
| case IDLTKSearchConstants.ANNOTATION_TYPE: |
| // return Flags.isAnnotation(modifiers); |
| return false; |
| } |
| return false; |
| } |
| |
| /** |
| * Set filter to "match everything" mode. |
| * |
| * @param matchEverything if <code>true</code>, {@link #matchItem(Object)} |
| * always returns true. If <code>false</code>, the filter |
| * is enabled. |
| */ |
| public void setMatchEverythingMode(boolean matchEverything) { |
| this.fMatchEverything = matchEverything; |
| } |
| |
| @Override |
| public boolean isConsistentItem(Object item) { |
| return true; |
| } |
| |
| @Override |
| public boolean matchItem(Object item) { |
| |
| if (fMatchEverything) |
| return true; |
| |
| TypeNameMatch type = (TypeNameMatch) item; |
| if (!(matchesPackage(type) && matchesModifiers(type) && matchesScope(type) && matchesFilterExtension(type))) |
| return false; |
| return matchesName(type); |
| } |
| |
| @Override |
| public boolean matchesRawNamePattern(Object item) { |
| TypeNameMatch type = (TypeNameMatch) item; |
| return matchesRawNamePattern(type); |
| } |
| |
| } |
| |
| /** |
| * Extends functionality of SearchPatterns |
| */ |
| private static class TypeSearchPattern extends SearchPattern { |
| |
| private String packagePattern; |
| |
| @Override |
| public void setPattern(String stringPattern) { |
| String pattern = stringPattern; |
| String packPattern = null; |
| int index = stringPattern.lastIndexOf("."); //$NON-NLS-1$ |
| if (index != -1) { |
| packPattern = evaluatePackagePattern(stringPattern.substring(0, index)); |
| pattern = stringPattern.substring(index + 1); |
| if (pattern.length() == 0) |
| pattern = "**"; //$NON-NLS-1$ |
| } |
| super.setPattern(pattern); |
| packagePattern = packPattern; |
| } |
| |
| /* |
| * Transforms o.e.j to o.e.j |
| */ |
| private String evaluatePackagePattern(String s) { |
| StringBuffer buf = new StringBuffer(); |
| boolean hasWildCard = false; |
| for (int i = 0; i < s.length(); i++) { |
| char ch = s.charAt(i); |
| if (ch == '.') { |
| if (!hasWildCard) { |
| buf.append('*'); |
| } |
| hasWildCard = false; |
| } else if (ch == '*' || ch == '?') { |
| hasWildCard = true; |
| } |
| buf.append(ch); |
| } |
| if (!hasWildCard) { |
| buf.append('*'); |
| } |
| return buf.toString(); |
| } |
| |
| @Override |
| protected boolean isNameCharAllowed(char nameChar) { |
| return super.isNameCharAllowed(nameChar); |
| } |
| |
| @Override |
| protected boolean isPatternCharAllowed(char patternChar) { |
| return super.isPatternCharAllowed(patternChar); |
| } |
| |
| @Override |
| protected boolean isValidCamelCaseChar(char ch) { |
| return super.isValidCamelCaseChar(ch); |
| } |
| |
| /** |
| * @return the packagePattern |
| */ |
| public String getPackagePattern() { |
| return packagePattern; |
| } |
| |
| } |
| |
| /** |
| * A <code>TypeSearchRequestor</code> collects matches filtered using |
| * <code>TypeItemsFilter</code>. The attached content provider is filled on the |
| * basis of the collected entries (instances of <code>TypeNameMatch</code>). |
| */ |
| private class TypeSearchRequestor extends TypeNameMatchRequestor { |
| private volatile boolean fStop; |
| |
| private final AbstractContentProvider fContentProvider; |
| |
| private final TypeItemsFilter fTypeItemsFilter; |
| Set<String> addedNames = new HashSet<>(); |
| |
| public TypeSearchRequestor(AbstractContentProvider contentProvider, TypeItemsFilter typeItemsFilter) { |
| super(); |
| fContentProvider = contentProvider; |
| fTypeItemsFilter = typeItemsFilter; |
| } |
| |
| @Override |
| public void acceptTypeNameMatch(TypeNameMatch match) { |
| if (fStop) |
| return; |
| if (new TypeFilter(DLTKUILanguageManager.getLanguageToolkit(fToolkit.getNatureId())).isFiltered(match)) |
| return; |
| if (!addedNames.contains(match.getTypeQualifiedName())) { |
| addedNames.add(match.getTypeQualifiedName()); |
| if (fTypeItemsFilter.matchesFilterExtension(match)) |
| fContentProvider.add(match, fTypeItemsFilter); |
| } |
| } |
| } |
| |
| /** |
| * Compares TypeItems is used during sorting |
| */ |
| private class TypeItemsComparator implements Comparator<TypeNameMatch> { |
| |
| private final Map<String, String> fLib2Name = new HashMap<>(); |
| |
| private final String[] fInstallLocations; |
| |
| private final String[] fVMNames; |
| |
| /** |
| * Creates new instance of TypeItemsComparator |
| */ |
| public TypeItemsComparator() { |
| List<String> locations = new ArrayList<>(); |
| List<String> labels = new ArrayList<>(); |
| IInterpreterInstallType[] installs = ScriptRuntime.getInterpreterInstallTypes(); |
| for (int i = 0; i < installs.length; i++) { |
| processVMInstallType(installs[i], locations, labels); |
| } |
| fInstallLocations = locations.toArray(new String[locations.size()]); |
| fVMNames = labels.toArray(new String[labels.size()]); |
| } |
| |
| private void processVMInstallType(IInterpreterInstallType installType, List<String> locations, |
| List<String> labels) { |
| if (installType != null) { |
| IInterpreterInstall[] installs = installType.getInterpreterInstalls(); |
| boolean isMac = Platform.OS_MACOSX.equals(Platform.getOS()); |
| final String HOME_SUFFIX = "/Home"; //$NON-NLS-1$ |
| for (int i = 0; i < installs.length; i++) { |
| String label = getFormattedLabel(installs[i].getName()); |
| LibraryLocation[] libLocations = installs[i].getLibraryLocations(); |
| if (libLocations != null) { |
| processLibraryLocation(libLocations, label); |
| } else { |
| String filePath = installs[i].getInstallLocation().toOSString(); |
| // on MacOS X install locations end in an additional |
| // "/Home" segment; remove it |
| if (isMac && filePath.endsWith(HOME_SUFFIX)) |
| filePath = filePath.substring(0, filePath.length() - HOME_SUFFIX.length() + 1); |
| locations.add(filePath); |
| labels.add(label); |
| } |
| } |
| } |
| } |
| |
| private void processLibraryLocation(LibraryLocation[] libLocations, String label) { |
| for (int l = 0; l < libLocations.length; l++) { |
| LibraryLocation location = libLocations[l]; |
| fLib2Name.put(location.getLibraryPath().toString(), label); |
| } |
| } |
| |
| private String getFormattedLabel(String name) { |
| return NLS.bind(DLTKUIMessages.FilteredTypesSelectionDialog_library_name_format, name); |
| } |
| |
| @Override |
| public int compare(TypeNameMatch leftInfo, TypeNameMatch rightInfo) { |
| |
| int result = compareName(leftInfo.getSimpleTypeName(), rightInfo.getSimpleTypeName()); |
| if (result != 0) |
| return result; |
| result = compareTypeContainerName(leftInfo.getTypeContainerName(), rightInfo.getTypeContainerName()); |
| if (result != 0) |
| return result; |
| |
| int leftCategory = getElementTypeCategory(leftInfo); |
| int rightCategory = getElementTypeCategory(rightInfo); |
| if (leftCategory < rightCategory) |
| return -1; |
| if (leftCategory > rightCategory) |
| return +1; |
| return compareContainerName(leftInfo, rightInfo); |
| } |
| |
| private int compareName(String leftString, String rightString) { |
| int result = leftString.compareToIgnoreCase(rightString); |
| if (result != 0 || rightString.length() == 0) { |
| return result; |
| } else if (Strings.isLowerCase(leftString.charAt(0)) && !Strings.isLowerCase(rightString.charAt(0))) { |
| return +1; |
| } else if (Strings.isLowerCase(rightString.charAt(0)) && !Strings.isLowerCase(leftString.charAt(0))) { |
| return -1; |
| } else { |
| return leftString.compareTo(rightString); |
| } |
| } |
| |
| private int compareTypeContainerName(String leftString, String rightString) { |
| int leftLength = leftString.length(); |
| int rightLength = rightString.length(); |
| if (leftLength == 0 && rightLength > 0) |
| return -1; |
| if (leftLength == 0 && rightLength == 0) |
| return 0; |
| if (leftLength > 0 && rightLength == 0) |
| return +1; |
| return compareName(leftString, rightString); |
| } |
| |
| private int compareContainerName(TypeNameMatch leftType, TypeNameMatch rightType) { |
| return getContainerName(leftType).compareTo(getContainerName(rightType)); |
| } |
| |
| private String getContainerName(TypeNameMatch type) { |
| IProjectFragment root = type.getProjectFragment(); |
| if (root.isExternal()) { |
| String name = root.getPath().toOSString(); |
| for (int i = 0; i < fInstallLocations.length; i++) { |
| if (name.startsWith(fInstallLocations[i])) { |
| return fVMNames[i]; |
| } |
| } |
| String lib = fLib2Name.get(name); |
| if (lib != null) |
| return lib; |
| } |
| StringBuffer buf = new StringBuffer(); |
| ScriptElementLabels labels = getUIToolkit().getScriptElementLabels(); |
| labels.getProjectFragmentLabel(root, ScriptElementLabels.ROOT_QUALIFIED | ScriptElementLabels.ROOT_VARIABLE, |
| buf); |
| return buf.toString(); |
| } |
| |
| private int getElementTypeCategory(TypeNameMatch type) { |
| try { |
| if (type.getProjectFragment().getKind() == IProjectFragment.K_SOURCE) |
| return 0; |
| } catch (ModelException e) { |
| DLTKUIPlugin.log(e); |
| } |
| return 1; |
| } |
| } |
| |
| private IDLTKUILanguageToolkit getUIToolkit() { |
| return DLTKUILanguageManager.getLanguageToolkit(fToolkit.getNatureId()); |
| } |
| |
| /** |
| * Extends the <code>SelectionHistory</code>, providing support for |
| * <code>OpenTypeHistory</code>. |
| */ |
| protected class TypeSelectionHistory extends SelectionHistory { |
| |
| /** |
| * Creates new instance of TypeSelectionHistory |
| */ |
| |
| public TypeSelectionHistory() { |
| super(); |
| } |
| |
| @Override |
| public synchronized void accessed(Object object) { |
| super.accessed(object); |
| } |
| |
| @Override |
| public synchronized boolean remove(Object element) { |
| OpenTypeHistory.getInstance(getUIToolkit()).remove((TypeNameMatch) element); |
| return super.remove(element); |
| } |
| |
| @Override |
| public void load(IMemento memento) { |
| TypeNameMatch[] types = OpenTypeHistory.getInstance(getUIToolkit()).getTypeInfos(); |
| |
| for (int i = 0; i < types.length; i++) { |
| TypeNameMatch type = types[i]; |
| accessed(type); |
| } |
| } |
| |
| @Override |
| public void save(IMemento memento) { |
| persistHistory(); |
| } |
| |
| /** |
| * Stores contents of the local history into persistent history container. |
| */ |
| private synchronized void persistHistory() { |
| if (getReturnCode() == OK) { |
| Object[] items = getHistoryItems(); |
| for (int i = 0; i < items.length; i++) { |
| OpenTypeHistory.getInstance(getUIToolkit()).accessed((TypeNameMatch) items[i]); |
| } |
| } |
| } |
| |
| @Override |
| protected Object restoreItemFromMemento(IMemento element) { |
| return null; |
| } |
| |
| @Override |
| protected void storeItemToMemento(Object item, IMemento element) { |
| |
| } |
| |
| } |
| |
| } |