/* * /* Copyright (c) 2012, the Dart project authors. * * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at * * http://www.eclipse.org/legal/epl-v10.html * * Unless required by applicable law or agreed to in writing, software distributed under the License * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing permissions and limitations under * the License. */ package com.google.dart.tools.ui.internal.dialogs; import com.google.common.util.concurrent.Uninterruptibles; import com.google.dart.server.FindTopLevelDeclarationsConsumer; import com.google.dart.tools.core.DartCore; import com.google.dart.tools.core.analysis.model.SearchResultsListener; import com.google.dart.tools.core.model.DartConventions; import com.google.dart.tools.ui.DartElementLabels; import com.google.dart.tools.ui.DartToolsPlugin; import com.google.dart.tools.ui.DartUI; import com.google.dart.tools.ui.DartUIMessages; import com.google.dart.tools.ui.Messages; import com.google.dart.tools.ui.dialogs.ITypeInfoFilterExtension; import com.google.dart.tools.ui.dialogs.ITypeInfoImageProvider; import com.google.dart.tools.ui.dialogs.ITypeSelectionComponent; import com.google.dart.tools.ui.dialogs.TypeSelectionExtension; import com.google.dart.tools.ui.internal.text.DartHelpContextIds; import com.google.dart.tools.ui.internal.util.CamelUtil; import com.google.dart.tools.ui.internal.util.Strings; import com.google.dart.tools.ui.internal.util.TypeNameMatchLabelProvider_NEW; import com.google.dart.tools.ui.internal.viewsupport.ColoredDartElementLabels; import com.google.dart.tools.ui.internal.viewsupport.ColoredString; import com.google.dart.tools.ui.internal.viewsupport.ColoredViewersManager; import com.google.dart.tools.ui.internal.viewsupport.OwnerDrawSupport; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import org.dartlang.analysis.server.protocol.Element; import org.dartlang.analysis.server.protocol.ElementKind; import org.dartlang.analysis.server.protocol.RequestError; import org.dartlang.analysis.server.protocol.SearchResult; import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IAction; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.Separator; import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.operation.IRunnableContext; 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.swt.graphics.Color; 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.Display; import org.eclipse.swt.widgets.Item; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.IMemento; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.WorkbenchException; import org.eclipse.ui.XMLMemento; import org.eclipse.ui.actions.WorkingSetFilterActionGroup; import org.eclipse.ui.dialogs.FilteredItemsSelectionDialog; import org.eclipse.ui.dialogs.ISelectionStatusValidator; import org.eclipse.ui.dialogs.SearchPattern; import java.io.IOException; import java.io.StringReader; import java.io.StringWriter; import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; /** * Shows a list of Dart types to the user with a text entry field for a string pattern used to * filter the list of types. */ public class FilteredTypesSelectionDialog_NEW extends FilteredItemsSelectionDialog implements ITypeSelectionComponent { /** * The <code>ShowContainerForDuplicatesAction</code> provides means to show/hide container * information for duplicate elements. */ private class ShowContainerForDuplicatesAction extends Action { /** * Creates a new instance of the class */ public ShowContainerForDuplicatesAction() { super( DartUIMessages.FilteredTypeSelectionDialog_showContainerForDuplicatesAction, IAction.AS_CHECK_BOX); } @Override public void run() { fTypeInfoLabelProvider.setContainerInfo(isChecked()); } } private class TopLevelElement { private Element element; private SearchResult searchResult; public TopLevelElement(SearchResult result) { this.element = result.getPath().get(0); this.searchResult = result; } public Element getElement() { return element; } public String getInfo() { String info = ""; String file = element.getLocation().getFile(); IFile resource = DartUI.getSourceFile(file); if (resource != null) { info = resource.getFullPath().toString(); } if (info.startsWith("/")) { return info.substring(1); } return info; } public String getLibraryName() { Element e = getLibraryElement(); if (e != null) { return e.getName(); } return ""; } public String getName() { return element.getName(); } public void saveState(IMemento memento) { memento.putString("SEARCHRESULT", searchResult.toJson().toString()); } private Element getLibraryElement() { for (Element element : searchResult.getPath()) { if (element.getKind().equals(ElementKind.LIBRARY)) { return element; } } return null; } } private static class TypeInfoUtil { public TypeInfoUtil(ITypeInfoImageProvider extension) { } public String getFullyQualifiedText(TopLevelElement element) { StringBuffer result = new StringBuffer(); result.append(element.getName()); // String libraryName = element.getLibraryName(); // if (libraryName.length() > 0) { // result.append(DartElementLabels.CONCAT_STRING); // result.append(libraryName); // } // String containerName = element.getInfo(); // if (containerName.length() > 0) { // result.append(DartElementLabels.CONCAT_STRING); // result.append(containerName); // } return result.toString(); } // public ImageDescriptor getImageDescriptor(Object object) { // DartElement element = (DartElement) object; // if (fProviderExtension != null) { // try { // fAdapter.matchFound(new SearchMatch( // MatchQuality.EXACT, // element, // ((SourceReference) element).getSourceRange())); // } catch (DartModelException e) { // DartToolsPlugin.log(e); // } //// ImageDescriptor descriptor = fProviderExtension.getImageDescriptor(fAdapter); // // // TODO(brianwilkerson) This needs to return a different descriptor for function type aliases. // ImageDescriptor descriptor = DartElementImageProvider.getTypeImageDescriptor(false, false); // // if (descriptor != null) { // return descriptor; // } // } // // TODO(brianwilkerson) This needs to return a different descriptor for function type aliases. // return DartElementImageProvider.getTypeImageDescriptor(false, false); // } public String getQualificationText(TopLevelElement element) { StringBuffer result = new StringBuffer(); String libraryName = element.getLibraryName(); if (libraryName.length() > 0) { result.append(element.getLibraryName()); } String path = element.getInfo(); if (path.length() > 0) { if (libraryName.length() > 0) { result.append(DartElementLabels.CONCAT_STRING); } result.append(path); } return result.toString(); } public String getQualifiedText(TopLevelElement element) { StringBuffer result = new StringBuffer(); result.append(element.getName()); String libraryName = element.getLibraryName(); if (libraryName.length() > 0) { result.append(DartElementLabels.CONCAT_STRING); result.append(libraryName); } return result.toString(); } public String getText(Object element) { return ((TopLevelElement) element).getName(); } } /** * A <code>LabelProvider</code> for the label showing type details. */ private static class TypeItemDetailsLabelProvider extends LabelProvider { // private final DartElementLabelProvider imageProvider = new DartElementLabelProvider(); private final TypeInfoUtil fTypeInfoUtil; public TypeItemDetailsLabelProvider(TypeInfoUtil typeInfoUtil) { fTypeInfoUtil = typeInfoUtil; } @Override public Image getImage(Object object) { return super.getImage(object); } @Override public String getText(Object element) { if (element instanceof TopLevelElement) { return fTypeInfoUtil.getQualificationText((TopLevelElement) element); } return super.getText(element); } } /** * A <code>LabelProvider</code> for (the table of) types. */ private class TypeItemLabelProvider extends LabelProvider implements ILabelDecorator { private final TypeNameMatchLabelProvider_NEW fLabelProvider = new TypeNameMatchLabelProvider_NEW( TypeNameMatchLabelProvider_NEW.SHOW_TYPE_CONTAINER_ONLY + TypeNameMatchLabelProvider_NEW.SHOW_ROOT_POSTFIX); private boolean fContainerInfo; /** * Construct a new <code>TypeItemLabelProvider</code>. F */ public TypeItemLabelProvider() { } @Override public Image decorateImage(Image image, Object element) { return null; } @Override public String decorateText(String text, Object element) { if (!(element instanceof TopLevelElement)) { return null; } if (fContainerInfo && isDuplicateElement(element)) { return fTypeInfoUtil.getFullyQualifiedText((TopLevelElement) element); } return fTypeInfoUtil.getQualifiedText((TopLevelElement) element); } @Override public Image getImage(Object element) { if (!(element instanceof TopLevelElement)) { return super.getImage(element); } return fLabelProvider.getImage(((TopLevelElement) element).getElement()); } @Override public String getText(Object element) { if (!(element instanceof TopLevelElement)) { return super.getText(element); } if (fContainerInfo && isDuplicateElement(element)) { return fTypeInfoUtil.getFullyQualifiedText((TopLevelElement) element); } if (!fContainerInfo && isDuplicateElement(element)) { return fTypeInfoUtil.getQualifiedText((TopLevelElement) element); } return fTypeInfoUtil.getText(element); } public void setContainerInfo(boolean containerInfo) { fContainerInfo = containerInfo; fireLabelProviderChanged(new LabelProviderChangedEvent(this)); } } /** * Compares TypeItems is used during sorting */ @SuppressWarnings("rawtypes") private static class TypeItemsComparator implements Comparator { // private final Map fLib2Name = new HashMap(); // private final String[] fInstallLocations; // // private final String[] fVMNames; /** * Creates new instance of TypeItemsComparator */ public TypeItemsComparator() { // List locations = new ArrayList(); // List labels = new ArrayList(); // IVMInstallType[] installs = JavaRuntime.getVMInstallTypes(); // for (int i = 0; i < installs.length; i++) { // processVMInstallType(installs[i], locations, labels); // } // fInstallLocations = (String[]) locations.toArray(new String[locations.size()]); // fVMNames = (String[]) labels.toArray(new String[labels.size()]); } @Override public int compare(Object left, Object right) { TopLevelElement leftInfo = (TopLevelElement) left; TopLevelElement rightInfo = (TopLevelElement) right; return compareName(leftInfo.getName(), rightInfo.getName()); } 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); } } } /** * Filters types using pattern, scope, element kind and filter extension. */ @SuppressWarnings("unused") private class TypeItemsFilter extends ItemsFilter { 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(int elementKind, ITypeInfoFilterExtension extension) { super(new TypeSearchPattern()); fIsWorkspaceScope = true; fElemKind = elementKind; fFilterExt = extension; String stringPackage = ((TypeSearchPattern) patternMatcher).getPackagePattern(); if (stringPackage != null) { fPackageMatcher = new SearchPattern(); fPackageMatcher.setPattern(stringPackage); } else { fPackageMatcher = null; } } @Override public boolean equalsFilter(ItemsFilter iFilter) { if (!super.equalsFilter(iFilter)) { return false; } if (!(iFilter instanceof TypeItemsFilter)) { return false; } TypeItemsFilter typeItemsFilter = (TypeItemsFilter) iFilter; if (fMyTypeFilterVersion != typeItemsFilter.getMyTypeFilterVersion()) { return false; } return true; } public int getElementKind() { return fElemKind; } public ITypeInfoFilterExtension getFilterExtension() { return fFilterExt; } public int getMyTypeFilterVersion() { return fMyTypeFilterVersion; } public int getPackageFlags() { if (fPackageMatcher == null) { return SearchPattern.RULE_PREFIX_MATCH; } return fPackageMatcher.getMatchRule(); } public String getPackagePattern() { if (fPackageMatcher == null) { return null; } return fPackageMatcher.getPattern(); } @Override public boolean isConsistentItem(Object item) { return true; } @Override public boolean isSubFilter(ItemsFilter filter) { if (!super.isSubFilter(filter)) { return false; } TypeItemsFilter typeItemsFilter = (TypeItemsFilter) filter; if (fMyTypeFilterVersion != typeItemsFilter.getMyTypeFilterVersion()) { return false; } //TODO(pquitslund): this forces a full refresh which works-around filter application refresh issues return true; } public boolean matchesCachedResult(SearchResult result) { if (!(matchesFilterExtension(result))) { return false; } return matchesName(result); } public boolean matchesFilterExtension(Object result) { return true; } public boolean matchesHistoryElement(SearchResult result) { if (!(matchesScope(result) && matchesFilterExtension(result))) { return false; } return matchesName(result); } @Override public boolean matchesRawNamePattern(Object item) { Element element = (Element) item; return !element.getName().endsWith(".dart"); } public boolean matchesRawNamePattern(SearchResult result) { List<Element> elements = result.getPath(); if (!result.getPath().isEmpty()) { return Strings.startsWithIgnoreCase(result.getPath().get(0).getName(), getPattern()); } return false; } @Override public boolean matchItem(Object item) { if (fMatchEverything) { return true; } TopLevelElement element = (TopLevelElement) item; if (!(matchesScope(element) && matchesFilterExtension(element))) { return false; } return matchesName(element); } /** * 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; } private boolean matchesName(SearchResult result) { return matches(result.getPath().get(0).getName()); } private boolean matchesName(TopLevelElement element) { return matches(element.getName()); } private boolean matchesScope(Object element) { return true; } } /** * Extends functionality of SearchPatterns */ private static class TypeSearchPattern extends SearchPattern { private String packagePattern; /** * @return the packagePattern */ public String getPackagePattern() { return 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; } @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); } /* * 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(); } } /** * 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 implements SearchResultsListener { private final AbstractContentProvider fContentProvider; private final TypeItemsFilter fTypeItemsFilter; public TypeSearchRequestor(AbstractContentProvider contentProvider, TypeItemsFilter typeItemsFilter) { super(); fContentProvider = contentProvider; fTypeItemsFilter = typeItemsFilter; } @Override public void computedSearchResults(List<SearchResult> searchResults, boolean last) { int length = searchResults.size(); int index; if (length > 25) { index = 25; } else { index = length; } for (int i = 0; i < index; i++) { SearchResult searchResult = searchResults.get(i); addToResults(searchResult); } scheduleRefresh(); if (index < length) { for (int i = index; i < length; i++) { SearchResult searchResult = searchResults.get(i); addToResults(searchResult); } } } private void addToResults(SearchResult searchResult) { TopLevelElement result = new TopLevelElement(searchResult); results.add(result); fContentProvider.add(result, fTypeItemsFilter); } } private class TypeSelectionHistory extends SelectionHistory { @Override protected Object restoreItemFromMemento(IMemento memento) { SearchResult result = SearchResult.fromJson((JsonObject) new JsonParser().parse(memento.getString("SEARCHRESULT"))); return new TopLevelElement(result); } @Override protected void storeItemToMemento(Object item, IMemento memento) { TopLevelElement element = (TopLevelElement) item; element.saveState(memento); } } /** * Disabled "Show Container for Duplicates because of * https://bugs.eclipse.org/bugs/show_bug.cgi?id=184693 . */ private static final boolean BUG_184693 = true; private static final String DIALOG_SETTINGS = "com.google.dart.tools.ui.dialogs.FilteredTypesSelectionDialog"; //$NON-NLS-1$ private static final String SHOW_CONTAINER_FOR_DUPLICATES = "ShowContainerForDuplicates"; //$NON-NLS-1$ private static final String WORKINGS_SET_SETTINGS = "WorkingSet"; //$NON-NLS-1$ private static String getIdentifierCharacters(String str) { int length = str.length(); StringBuilder buf = new StringBuilder(length); for (int i = 0; i < length; i++) { char c = str.charAt(i); if (Character.isJavaIdentifierPart(c)) { buf.append(c); } } return buf.toString(); } private WorkingSetFilterActionGroup fFilterActionGroup; private final TypeItemLabelProvider fTypeInfoLabelProvider; private String fTitle; private ShowContainerForDuplicatesAction fShowContainerForDuplicatesAction; private boolean fAllowScopeSwitching; private final int fElementKinds; private final ITypeInfoFilterExtension fFilterExtension; private final TypeSelectionExtension fExtension; private ISelectionStatusValidator fValidator; private final TypeInfoUtil fTypeInfoUtil; @SuppressWarnings("unused") private static boolean fgFirstTime = true; private final TypeItemsComparator fTypeItemsComparator; private int fTypeFilterVersion = 0; private List<TopLevelElement> results = new ArrayList<TopLevelElement>(); // /** // * 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>IJavaScriptSearchConstants.TYPE</code> // * <code>IJavaScriptSearchConstants.ANNOTATION_TYPE</code> // * <code>IJavaScriptSearchConstants.INTERFACE</code> // * <code>IJavaScriptSearchConstants.ENUM</code> // * <code>IJavaScriptSearchConstants.CLASS_AND_INTERFACE</code> // * <code>IJavaScriptSearchConstants.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, // SearchScope scope, int elementKinds) { // this(parent, multi, context, scope, elementKinds, null); // } /** * 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 (<em>currently ignored</em>). * @param extension an extension of the standard type selection dialog; See * {@link TypeSelectionExtension} */ public FilteredTypesSelectionDialog_NEW(Shell shell, boolean multi, IRunnableContext context, int elementKinds, TypeSelectionExtension extension) { super(shell, multi); setSelectionHistory(new TypeSelectionHistory()); PlatformUI.getWorkbench().getHelpSystem().setHelp( shell, DartHelpContextIds.TYPE_SELECTION_DIALOG2); fElementKinds = elementKinds; fExtension = extension; fFilterExtension = (extension == null) ? null : extension.getFilterExtension(); 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 create() { super.create(); Control patternControl = getPatternControl(); if (patternControl instanceof Text) { TextFieldNavigationHandler.install((Text) patternControl); } } @Override public String getElementName(Object item) { return fTypeInfoUtil.getText(item); } @Override public int open() { if (getInitialPattern() == null) { IWorkbenchWindow window = DartToolsPlugin.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 && DartConventions.validateTypeName(text).isOK()) { setInitialPattern(text, FULL_SELECTION); } } } } } return super.open(); } @Override public void reloadCache(boolean checkDuplicates, IProgressMonitor monitor) { IProgressMonitor remainingMonitor = monitor; //TODO: enable history consistency runnable // if (ConsistencyRunnable.needsExecution()) { // monitor.beginTask( // DartUIMessages.TypeSelectionDialog_progress_consistency, 10); // try { // ConsistencyRunnable runnable = new ConsistencyRunnable(); // runnable.run(new SubProgressMonitor(monitor, 1)); // } catch (InvocationTargetException e) { // ExceptionHandler.handle(e, // DartUIMessages.TypeSelectionDialog_error3Title, // DartUIMessages.TypeSelectionDialog_error3Message); // close(); // return; // } catch (InterruptedException e) { // // cancelled by user // close(); // return; // } // remainingMonitor = new SubProgressMonitor(monitor, 9); // } else { // remainingMonitor = monitor; // } super.reloadCache(checkDuplicates, remainingMonitor); monitor.done(); } @Override public void setTitle(String title) { super.setTitle(title); fTitle = title; } /** * Sets a new validator. * * @param validator the new validator */ public void setValidator(ISelectionStatusValidator validator) { fValidator = validator; } @Override public void triggerSearch() { fTypeFilterVersion++; applyFilter(); } @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 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 ItemsFilter createFilter() { return new TypeItemsFilter(fElementKinds, fFilterExtension); } @Override protected void fillContentProvider(final AbstractContentProvider provider, ItemsFilter itemsFilter, IProgressMonitor progressMonitor) throws CoreException { TypeItemsFilter typeSearchFilter = (TypeItemsFilter) itemsFilter; final SearchResultsListener requestor = new TypeSearchRequestor(provider, typeSearchFilter); //SearchEngine engine = SearchEngineFactory.createSearchEngine((WorkingCopyOwner) null); progressMonitor.setTaskName(DartUIMessages.FilteredTypesSelectionDialog_searchJob_taskName); /* * 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. */ String typePattern = itemsFilter.getPattern(); // 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); // } typePattern = getIdentifierCharacters(typePattern); final String pattern = "^" + CamelUtil.getCamelCaseRegExp(typePattern) + ".*"; try { // boolean searchComplete = false; results.clear(); final CountDownLatch latch = new CountDownLatch(1); DartCore.getAnalysisServer().search_findTopLevelDeclarations( pattern, new FindTopLevelDeclarationsConsumer() { @Override public void computedSearchId(String searchId) { DartCore.getAnalysisServerData().addSearchResultsListener(searchId, requestor); } @Override public void onError(RequestError requestError) { } }); Uninterruptibles.awaitUninterruptibly(latch, 5, TimeUnit.SECONDS); // searchComplete = true; } finally { // typeSearchFilter.setMatchEverythingMode(false); } } @Override protected void fillViewMenu(IMenuManager menuManager) { super.fillViewMenu(menuManager); if (!BUG_184693) { fShowContainerForDuplicatesAction = new ShowContainerForDuplicatesAction(); menuManager.add(fShowContainerForDuplicatesAction); } menuManager.add(new Separator()); //TODO: add/remove type filter preferences // menuManager.add(new TypeFiltersPreferencesAction()); } @Override protected IDialogSettings getDialogSettings() { IDialogSettings settings = DartToolsPlugin.getDefault().getDialogSettings().getSection( DIALOG_SETTINGS); if (settings == null) { settings = DartToolsPlugin.getDefault().getDialogSettings().addNewSection(DIALOG_SETTINGS); } return settings; } @SuppressWarnings("rawtypes") @Override protected Comparator getItemsComparator() { return fTypeItemsComparator; } @Override protected void restoreDialog(IDialogSettings settings) { super.restoreDialog(settings); if (!BUG_184693) { boolean showContainer = settings.getBoolean(SHOW_CONTAINER_FOR_DUPLICATES); fShowContainerForDuplicatesAction.setChecked(showContainer); fTypeInfoLabelProvider.setContainerInfo(showContainer); } else { 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 DartToolsPlugin.log(e); } } Object[] items = getSelectionHistory().getHistoryItems(); for (Object o : items) { accessedHistoryItem(o); } //TODO: adding workingset scope support // IWorkingSet ws = fFilterActionGroup.getWorkingSet(); // if (ws == null || (ws.isAggregateWorkingSet() && ws.isEmpty())) { // setSearchScope(SearchScopeFactory.createUniverseScope()); setSubtitle(null); // } else { // setSearchScope(JavaSearchScopeFactory.getInstance().createJavaSearchScope( // ws, true)); // 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 setResult(@SuppressWarnings("rawtypes") List newResult) { List<Element> resultToReturn = new ArrayList<Element>(); for (Object result : newResult) { if (result instanceof TopLevelElement) { Element element = ((TopLevelElement) result).getElement(); // items are added to history in the // org.eclipse.ui.dialogs.FilteredItemsSelectionDialog#computeResult() // method resultToReturn.add(element); } } super.setResult(resultToReturn); } @Override protected void storeDialog(IDialogSettings settings) { super.storeDialog(settings); if (!BUG_184693) { settings.put(SHOW_CONTAINER_FOR_DUPLICATES, fShowContainerForDuplicatesAction.isChecked()); } 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 DartToolsPlugin.log(e); } } } @Override protected IStatus validateItem(Object item) { if (item == null) { return new Status(IStatus.ERROR, DartToolsPlugin.getPluginId(), IStatus.ERROR, "", null); //$NON-NLS-1$ } if (fValidator != null) { Object[] elements = {item}; return fValidator.validate(elements); } else { return new Status(IStatus.OK, DartToolsPlugin.getPluginId(), IStatus.OK, "", null); //$NON-NLS-1$ } } private Table findTableControl(Composite composite) { Control[] children = composite.getChildren(); for (int i = 0; i < children.length; i++) { Control curr = children[i]; if (curr instanceof Table) { return (Table) curr; } else if (curr instanceof Composite) { Table res = findTableControl((Composite) curr); if (res != null) { return res; } } } return null; } private void installOwnerDraw(Table tableControl) { new OwnerDrawSupport(tableControl) { // installs the owner draw listeners @Override public Color getColor(String foregroundColorName, Display display) { return PlatformUI.getWorkbench().getThemeManager().getCurrentTheme().getColorRegistry().get( foregroundColorName); } @Override public ColoredString getColoredLabel(Item item) { String text = item.getText(); ColoredString str = new ColoredString(text); int index = text.indexOf('-'); if (index != -1) { str.colorize(index, str.length() - index, ColoredDartElementLabels.QUALIFIER_STYLE); } return str; } }; } /** * 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(DartUIMessages.FilteredTypeSelectionDialog_titleFormat, new String[] { fTitle, text})); } } }