Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[cdt-patch] type cache for open type actions

This patch implements a background type cache (using new Jobs API) for the open type action. It also fixes the scope qualifier on the open type dialog so you can filter by parent scope (eg. "std::" shows all types inside namespace std).

-Chris
Index: .classpath
===================================================================
retrieving revision 1.10
diff -u -r1.10 .classpath
--- .classpath	5 Jan 2004 21:15:51 -0000	1.10
+++ .classpath	8 Mar 2004 18:04:32 -0000
@@ -4,5 +4,6 @@
 	<classpathentry kind="src" path="utils.ui"/>
 	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry kind="src" path="browser"/>
 	<classpathentry kind="output" path="bin"/>
 </classpath>
Index: plugin.xml
===================================================================
retrieving revision 1.62
diff -u -r1.62 plugin.xml
--- plugin.xml	20 Feb 2004 15:31:33 -0000	1.62
+++ plugin.xml	8 Mar 2004 18:04:32 -0000
@@ -490,14 +490,14 @@
                id="org.eclipse.cdt.ui.actions.OpenCSearchPage">
          </action>
          <action
+               id="org.eclipse.cdt.ui.actions.OpenType"
                label="%OpenTypeAction.label"
                icon="icons/full/opentype16/opentype.gif"
-               class="org.eclipse.cdt.internal.ui.opentype.OpenTypeAction"
+               class="org.eclipse.cdt.internal.ui.browser.opentype.OpenTypeAction"
+               definitionId="org.eclipse.cdt.ui.navigate.opentype"
                menubarPath="navigate/open.ext2"
                toolbarPath="org.eclipse.search.searchActionSet/Search"
-               id="org.eclipse.cdt.ui.actions.OpenType"
-               definitionId="org.eclipse.cdt.ui.navigate.opentype"
-               enablesFor="*"
+               helpContextId="org.eclipse.cdt.ui.open_type_action"
                tooltip="%OpenTypeAction.tooltip">
          </action>
          <menu
Index: src/org/eclipse/cdt/internal/ui/opentype/OpenTypeAction.java
===================================================================
diff -N src/org/eclipse/cdt/internal/ui/opentype/OpenTypeAction.java
--- src/org/eclipse/cdt/internal/ui/opentype/OpenTypeAction.java	26 Feb 2004 19:30:35 -0000	1.3
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,138 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 QNX Software Systems and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
- * Contributors:
- *     QNX Software Systems - initial API and implementation
- *******************************************************************************/
-package org.eclipse.cdt.internal.ui.opentype;
-
-import org.eclipse.cdt.core.model.CModelException;
-import org.eclipse.cdt.core.model.ICElement;
-import org.eclipse.cdt.core.resources.FileStorage;
-import org.eclipse.cdt.core.search.SearchEngine;
-import org.eclipse.cdt.internal.ui.editor.CEditor;
-import org.eclipse.cdt.internal.ui.opentype.dialogs.OpenTypeSelectionDialog;
-import org.eclipse.cdt.internal.ui.util.EditorUtility;
-import org.eclipse.cdt.ui.CUIPlugin;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IStorage;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.jface.action.IAction;
-import org.eclipse.jface.dialogs.IDialogConstants;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.dialogs.ProgressMonitorDialog;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.ui.IEditorPart;
-import org.eclipse.ui.IWorkbenchWindow;
-import org.eclipse.ui.IWorkbenchWindowActionDelegate;
-import org.eclipse.ui.PartInitException;
-
-/**
- * To change the template for this generated type comment go to
- * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
- */
-public class OpenTypeAction implements IWorkbenchWindowActionDelegate {
-
-	IWorkbenchWindow window;
-
-	public OpenTypeAction() {
-		super();
-	}
-
-	/* (non-Javadoc)
-	 * @see org.eclipse.ui.IWorkbenchWindowActionDelegate#dispose()
-	 */
-	public void dispose() {
-	}
-
-	/* (non-Javadoc)
-	 * @see org.eclipse.ui.IWorkbenchWindowActionDelegate#init(org.eclipse.ui.IWorkbenchWindow)
-	 */
-	public void init(IWorkbenchWindow window) {
-		this.window= window;
-	}
-
-	/* (non-Javadoc)
-	 * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
-	 */
-	public void run(IAction action) {
-
-		Shell parent= CUIPlugin.getDefault().getActiveWorkbenchShell();
-		OpenTypeSelectionDialog dialog= new OpenTypeSelectionDialog(parent, new ProgressMonitorDialog(parent), 
-			SearchEngine.createWorkspaceScope());
-		dialog.setTitle(OpenTypeMessages.getString("OpenTypeAction.dialogTitle")); //$NON-NLS-1$
-		dialog.setMessage(OpenTypeMessages.getString("OpenTypeAction.dialogMessage")); //$NON-NLS-1$
-		dialog.setMatchEmptyString(true);
-
-		int result= dialog.open();
-		if (result != IDialogConstants.OK_ID)
-			return;
-		
-		TypeSearchMatch selection= (TypeSearchMatch)dialog.getFirstResult();
-		if (selection == null)
-			return;
-
-		boolean revealed = false;
-
-		// get the corresponding CElement
-		ICElement celement= selection.getCElement();
-		if (celement != null) {
-			try {
-				IResource res= celement.getUnderlyingResource();
-				IEditorPart part= EditorUtility.openInEditor(res);
-				if (part instanceof CEditor) {
-					CEditor ed= (CEditor)part;
-					ed.setSelection(celement);
-					revealed = true;
-				}
-			}
-			catch (CModelException ex){
-				ex.printStackTrace();
-			}
-			catch(PartInitException ex) {
-				ex.printStackTrace();
-			}
-		}
-		
-		if (!revealed) {
-			try {
-				IPath path = selection.getLocation();
-				IStorage storage = new FileStorage(path);
-				IEditorPart part= EditorUtility.openInEditor(storage);
-				if (part instanceof CEditor) {
-					CEditor ed= (CEditor)part;
-					ed.selectAndReveal(selection.getStartOffset(), selection.getName().length());
-					revealed = true;
-				}
-			}
-			catch (CModelException ex){
-				ex.printStackTrace();
-			}
-			catch(PartInitException ex) {
-				ex.printStackTrace();
-			}
-		}
-		
-		if (!revealed)
-		{
-			// could not find definition
-			String path= selection.getFilePath();
-			if (path == null || path.length() == 0)
-				path= OpenTypeMessages.getString("TypeSelectionDialog.unknown"); //$NON-NLS-1$
-			String title= OpenTypeMessages.getString("TypeSelectionDialog.errorTitle"); //$NON-NLS-1$
-			String message= OpenTypeMessages.getFormattedString("TypeSelectionDialog.dialogMessage", path); //$NON-NLS-1$
-			MessageDialog.openError(parent, title, message);
-		}
-	}
-
-	/* (non-Javadoc)
-	 * @see org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action.IAction, org.eclipse.jface.viewers.ISelection)
-	 */
-	public void selectionChanged(IAction action, ISelection selection) {
-	}
-}
Index: src/org/eclipse/cdt/internal/ui/opentype/OpenTypeMessages.java
===================================================================
diff -N src/org/eclipse/cdt/internal/ui/opentype/OpenTypeMessages.java
--- src/org/eclipse/cdt/internal/ui/opentype/OpenTypeMessages.java	3 Mar 2004 15:10:01 -0000	1.2
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,51 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 QNX Software Systems and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
- * Contributors:
- *     QNX Software Systems - initial API and implementation
- *******************************************************************************/
-package org.eclipse.cdt.internal.ui.opentype;
-
-import java.text.MessageFormat;
-import java.util.MissingResourceException;
-import java.util.ResourceBundle;
-
-public class OpenTypeMessages {
-
-	private static final String RESOURCE_BUNDLE= "org.eclipse.cdt.internal.ui.opentype.OpenTypeMessages";//$NON-NLS-1$
-
-	private static ResourceBundle fgResourceBundle;
-	static {
-		try {
-			fgResourceBundle = ResourceBundle.getBundle(RESOURCE_BUNDLE);
-		} catch (MissingResourceException x) {
-			fgResourceBundle = null;
-		}
-	}
-
-	private OpenTypeMessages() {
-	}
-
-	public static String getString(String key) {
-		try {
-			return fgResourceBundle.getString(key);
-		} catch (MissingResourceException e) {
-			return '!' + key + '!';
-		} catch (NullPointerException e) {
-			return "#" + key + "#"; //$NON-NLS-1$ //$NON-NLS-2$
-		}
-	}
-	
-	public static String getFormattedString(String key, String arg) {
-		return getFormattedString(key, new String[] { arg });
-	}
-	
-	public static String getFormattedString(String key, String[] args) {
-		return MessageFormat.format(getString(key), args);	
-	}	
-	
-}
Index: src/org/eclipse/cdt/internal/ui/opentype/OpenTypeMessages.properties
===================================================================
diff -N src/org/eclipse/cdt/internal/ui/opentype/OpenTypeMessages.properties
--- src/org/eclipse/cdt/internal/ui/opentype/OpenTypeMessages.properties	26 Feb 2004 19:30:35 -0000	1.2
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,42 +0,0 @@
-###############################################################################
-# Copyright (c) 2004 QNX Software Systems Ltd. and others.
-# All rights reserved.   This program and the accompanying materials
-# are made available under the terms of the Common Public License v0.5
-# which accompanies this distribution, and is available at
-# http://www.eclipse.org/legal/cpl-v05.html
-# 
-# QNX Software Systems - Initial API and implementation
-###############################################################################
-
-#########
-## actions
-#########
-
-OpenTypeAction.description=Open a type in the editor
-OpenTypeAction.tooltip=Open a Type
-OpenTypeAction.dialogMessage=&Choose a type (? = any character, * = any string):
-OpenTypeAction.dialogTitle=Open Type
-OpenTypeAction.errorMessage=An exception occurred while opening the type.
-OpenTypeAction.errorTitle=Open Type
-OpenTypeAction.label=Open Type...
-
-#######
-## dialogs
-#######
-TypeSelectionDialog.errorMessage=Could not uniquely map the type name to a type.
-TypeSelectionDialog.dialogMessage=Could not uniquely map the type name to a type. Path is {0}
-TypeSelectionDialog.errorTitle=Select Type
-TypeSelectionDialog.lowerLabel=&Qualifier:
-TypeSelectionDialog.upperLabel=&Matching types:
-TypeSelectionDialog.notypes.title=Type Selection
-TypeSelectionDialog.notypes.message=No types available.
-TypeSelectionDialog.error2Message=Unexpected exception. See log for details.
-TypeSelectionDialog.error2Title=Exception
-TypeSelectionDialog.error3Message=Unexpected exception. See log for details.
-TypeSelectionDialog.error3Title=Exception
-
-TypeInfoLabelProvider.default_filename=default
-TypeInfoLabelProvider.dash=\ - 
-TypeSelectionDialog.unknown=Unknown
Index: src/org/eclipse/cdt/internal/ui/opentype/TypeSearchMatch.java
===================================================================
diff -N src/org/eclipse/cdt/internal/ui/opentype/TypeSearchMatch.java
--- src/org/eclipse/cdt/internal/ui/opentype/TypeSearchMatch.java	26 Feb 2004 19:30:35 -0000	1.3
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,142 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 QNX Software Systems and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
- * Contributors:
- *     QNX Software Systems - initial API and implementation
- *******************************************************************************/
-package org.eclipse.cdt.internal.ui.opentype;
-
-import org.eclipse.cdt.core.model.CoreModel;
-import org.eclipse.cdt.core.model.ICElement;
-import org.eclipse.cdt.core.model.IParent;
-import org.eclipse.cdt.core.search.BasicSearchMatch;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IResource;
-
-
-/**
- * To change the template for this generated type comment go to
- * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
- */
-public class TypeSearchMatch extends BasicSearchMatch
-{
-	public TypeSearchMatch() {
-		super();
-	}
-
-	public String getFileName() {
-		if (resource != null)
-			return resource.getName();
-		else if (path != null)
-			return path.lastSegment();
-		else
-			return null;
-	}
-
-	public String getFilePath() {
-		if (resource != null)
-			return resource.getFullPath().toString();
-		else if (path != null)
-			return path.toString();
-		else
-			return null;
-	}
-
-	public String getFileExtension() {
-		if (resource != null)
-			return resource.getFileExtension();
-		else if (path != null)
-			return path.getFileExtension();
-		else
-			return null;
-	}
-
-	public String getQualifiedParentName() {
-		StringBuffer buf= new StringBuffer();
-		String fileName = getFileName();
-		if (fileName != null && fileName.length() > 0)
-			buf.append(fileName);
-		String parentName = getParentName();
-		if (parentName != null && parentName.length() > 0) {
-			buf.append(OpenTypeMessages.getString("TypeInfoLabelProvider.colon")); //$NON-NLS-1$
-			buf.append(parentName);
-		}
-		return buf.toString();
-	}
-	
-	public String getFullyQualifiedName() {
-		StringBuffer buf= new StringBuffer();
-		String filePath = getFilePath();
-		if (filePath != null && filePath.length() > 0)
-			buf.append(filePath);
-		String parentName = getParentName();
-		if (parentName != null && parentName.length() > 0) {
-			buf.append(OpenTypeMessages.getString("TypeInfoLabelProvider.colon")); //$NON-NLS-1$
-			buf.append(parentName);
-			buf.append("::"); //$NON-NLS-1$
-		}
-		String name = getName();
-		if (name != null && name.length() > 0)
-			buf.append(name);
-		return buf.toString();
-	}
-	
-	private boolean matchesCType(ICElement celement, String name) {
-		switch (celement.getElementType())
-		{
-		case ICElement.C_NAMESPACE:
-		case ICElement.C_TEMPLATE_CLASS:
-		case ICElement.C_CLASS:
-		case ICElement.C_STRUCT:
-		case ICElement.C_UNION:
-		case ICElement.C_ENUMERATION:
-		case ICElement.C_TYPEDEF:
-			return celement.getElementName().equals(name);
-
-		default:
-			return false;
-		}
-	}
-	
-	private ICElement findCElement(ICElement celement, String name) {
-		if (matchesCType(celement, name))
-			return celement;
-		else if (celement instanceof IParent) {
-			ICElement[] children = ((IParent)celement).getChildren();
-			for (int i = 0; i < children.length; i++) {
-				if (matchesCType(children[i], name))
-					return children[i];
-			}
-		}
-		return null;
-	}
-	
-	public ICElement getCElement() {
-		if (resource != null && resource.getType() == IResource.FILE) {
-			ICElement parentElement = CoreModel.getDefault().create((IFile)resource);
-			if (parentElement instanceof IParent) {
-				String parentName = getParentName();
-				while (parentElement != null && parentName != null && parentName.length() > 0)
-				{
-					int pos = parentName.indexOf("::"); //$NON-NLS-1$
-					if (pos >= 0) {
-						parentElement = findCElement(parentElement, parentName.substring(0, pos));
-						parentName = parentName.substring(pos + 2);
-					}
-					else {
-						parentElement = findCElement(parentElement, parentName);
-						parentName = null;
-					}
-				}
-				
-				if (parentElement != null)
-					return findCElement(parentElement, getName());
-			}
-		}
-		return null;
-	}
-}
Index: src/org/eclipse/cdt/internal/ui/opentype/TypeSearchMatchLabelProvider.java
===================================================================
diff -N src/org/eclipse/cdt/internal/ui/opentype/TypeSearchMatchLabelProvider.java
--- src/org/eclipse/cdt/internal/ui/opentype/TypeSearchMatchLabelProvider.java	5 Feb 2004 16:21:45 -0000	1.2
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,164 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2000,2003,2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
- * Contributors:
- *     IBM Corporation - initial API and implementation
- *     QNX Software Systems - adapted for use in CDT
- *******************************************************************************/
-package org.eclipse.cdt.internal.ui.opentype;
-
-import org.eclipse.cdt.core.model.CoreModel;
-import org.eclipse.cdt.core.model.ICElement;
-import org.eclipse.cdt.internal.ui.CPluginImages;
-import org.eclipse.jface.viewers.LabelProvider;
-import org.eclipse.swt.graphics.Image;
-
-
-
-public class TypeSearchMatchLabelProvider extends LabelProvider {
-
-	public static final int SHOW_FULLYQUALIFIED=	0x01;
-	public static final int SHOW_FILENAME_POSTFIX=	0x02;
-	public static final int SHOW_FILENAME_ONLY=		0x04;
-	public static final int SHOW_ROOT_POSTFIX=		0x08;
-	public static final int SHOW_TYPE_ONLY=			0x10;
-	public static final int SHOW_TYPE_CONTAINER_ONLY=	0x20;
-
-	private static final Image HEADER_ICON= CPluginImages.get(CPluginImages.IMG_OBJS_TUNIT_HEADER);
-	private static final Image SOURCE_ICON= CPluginImages.get(CPluginImages.IMG_OBJS_TUNIT);
-	private static final Image NAMESPACE_ICON= CPluginImages.get(CPluginImages.IMG_OBJS_CONTAINER);
-	private static final Image TEMPLATE_ICON= CPluginImages.get(CPluginImages.IMG_OBJS_TEMPLATE);
-	private static final Image CLASS_ICON= CPluginImages.get(CPluginImages.IMG_OBJS_CLASS);
-	private static final Image STRUCT_ICON= CPluginImages.get(CPluginImages.IMG_OBJS_STRUCT);
-	private static final Image TYPEDEF_ICON= CPluginImages.get(CPluginImages.IMG_OBJS_TYPEDEF);
-	private static final Image UNION_ICON= CPluginImages.get(CPluginImages.IMG_OBJS_UNION);
-	private static final Image ENUM_ICON= CPluginImages.get(CPluginImages.IMG_OBJS_ENUMERATION);
-
-	private int fFlags;
-	
-	public TypeSearchMatchLabelProvider(int flags) {
-		fFlags= flags;
-	}	
-	
-	private boolean isSet(int flag) {
-		return (fFlags & flag) != 0;
-	}
-
-	/* non java-doc
-	 * @see ILabelProvider#getText
-	 */
-	public String getText(Object element) {
-		if (! (element instanceof TypeSearchMatch)) 
-			return super.getText(element);
-		
-		TypeSearchMatch typeRef= (TypeSearchMatch) element;
-		
-		StringBuffer buf= new StringBuffer();
-		if (isSet(SHOW_TYPE_ONLY)) {
-			String name= typeRef.getName();
-			if (name != null && name.length() > 0)
-				buf.append(name);
-		} else if (isSet(SHOW_TYPE_CONTAINER_ONLY)) {
-			String name= typeRef.getQualifiedParentName();
-			if (name != null && name.length() > 0)
-				buf.append(name);
-		} else if (isSet(SHOW_FILENAME_ONLY)) {
-			String name= typeRef.getFileName();
-			if (name != null && name.length() > 0)
-				buf.append(name);
-		} else {
-			if (isSet(SHOW_FULLYQUALIFIED)) {
-				String name= typeRef.getFullyQualifiedName();
-				if (name != null && name.length() > 0)
-					buf.append(name);
-			}
-			else {
-				String name= typeRef.getParentName();
-				if (name != null && name.length() > 0)
-					buf.append(name);
-			}
-		
-			if (isSet(SHOW_FILENAME_POSTFIX)) {
-				String name= typeRef.getFileName();
-				if (name != null && name.length() > 0) {
-					buf.append(OpenTypeMessages.getString("TypeInfoLabelProvider.dash")); //$NON-NLS-1$
-					buf.append(name);
-				}
-			}
-		}
-
-		if (isSet(SHOW_ROOT_POSTFIX)) {
-			String path= typeRef.getFilePath();
-			if (path != null && path.length() > 0) {
-				buf.append(OpenTypeMessages.getString("TypeInfoLabelProvider.dash"));//$NON-NLS-1$
-				buf.append(path);
-			}
-		}
-		return buf.toString();				
-	}
-	
-	private Image getFileIcon(TypeSearchMatch typeRef)
-	{
-		String ext = typeRef.getFileExtension();
-		if (ext != null) {	
-			String[] exts = CoreModel.getDefault().getHeaderExtensions();
-			for (int i = 0; i < exts.length; i++) {
-				if (exts[i].equalsIgnoreCase(ext)) {
-					return HEADER_ICON;
-				}
-			}
-		}
-		return SOURCE_ICON;
-	}
-	
-	private Image getIcon(TypeSearchMatch typeRef)
-	{
-		switch (typeRef.getType())
-		{
-		case ICElement.C_NAMESPACE:
-			return NAMESPACE_ICON;
-			
-		case ICElement.C_TEMPLATE_CLASS:
-			return TEMPLATE_ICON;
-
-		case ICElement.C_CLASS:
-			return CLASS_ICON;
-
-		case ICElement.C_STRUCT:
-			return STRUCT_ICON;
-
-		case ICElement.C_UNION:
-			return UNION_ICON;
-
-		case ICElement.C_ENUMERATION:
-			return ENUM_ICON;
-
-		case ICElement.C_TYPEDEF:
-			return TYPEDEF_ICON;
-
-		default:
-			return CLASS_ICON;
-		}
-	}
-
-	/* non java-doc
-	 * @see ILabelProvider#getImage
-	 */	
-	public Image getImage(Object element) {
-		if (!(element instanceof TypeSearchMatch)) 
-			return super.getImage(element);	
-
-		TypeSearchMatch typeRef= (TypeSearchMatch) element;
-		if (isSet(SHOW_TYPE_CONTAINER_ONLY)) {
-			return getFileIcon(typeRef);
-		} else if (isSet(SHOW_FILENAME_ONLY)) {
-			return getFileIcon(typeRef);
-		} else {
-			return getIcon(typeRef);
-		}
-	}
-}
Index: src/org/eclipse/cdt/internal/ui/opentype/TypeSearchOperation.java
===================================================================
diff -N src/org/eclipse/cdt/internal/ui/opentype/TypeSearchOperation.java
--- src/org/eclipse/cdt/internal/ui/opentype/TypeSearchOperation.java	26 Feb 2004 19:30:35 -0000	1.4
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,65 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 QNX Software Systems and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
- * Contributors:
- *     QNX Software Systems - initial API and implementation
- *******************************************************************************/
-package org.eclipse.cdt.internal.ui.opentype;
-
-import org.eclipse.cdt.core.search.ICSearchConstants;
-import org.eclipse.cdt.core.search.ICSearchScope;
-import org.eclipse.cdt.core.search.OrPattern;
-import org.eclipse.cdt.core.search.SearchEngine;
-import org.eclipse.core.resources.IWorkspace;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.OperationCanceledException;
-import org.eclipse.jface.operation.IRunnableWithProgress;
-
-public class TypeSearchOperation implements IRunnableWithProgress {
-
-	private final TypeSearchResultCollector collector = new TypeSearchResultCollector();
-
-	private ICSearchScope scope;
-	private IWorkspace workspace;
-	private OrPattern pattern;
-	private SearchEngine engine;
-
-	public TypeSearchOperation(IWorkspace workspace, ICSearchScope scope, SearchEngine engine) {
-		this.workspace = workspace;
-		this.scope = scope;
-		this.engine = engine;
-
-		// search for namespaces, classes, structs, unions, enums and typedefs
-		pattern = new OrPattern();
-		pattern.addPattern(SearchEngine.createSearchPattern("*", ICSearchConstants.TYPE, ICSearchConstants.DECLARATIONS, false)); //$NON-NLS-1$
-		pattern.addPattern(
-			SearchEngine.createSearchPattern("*", ICSearchConstants.NAMESPACE, ICSearchConstants.DECLARATIONS, false)); //$NON-NLS-1$
-		pattern.addPattern(SearchEngine.createSearchPattern("*", ICSearchConstants.CLASS, ICSearchConstants.DECLARATIONS, false)); //$NON-NLS-1$
-		pattern.addPattern(SearchEngine.createSearchPattern("*", ICSearchConstants.STRUCT, ICSearchConstants.DECLARATIONS, false)); //$NON-NLS-1$
-		pattern.addPattern(
-			SearchEngine.createSearchPattern("*", ICSearchConstants.CLASS_STRUCT, ICSearchConstants.DECLARATIONS, false)); //$NON-NLS-1$
-		pattern.addPattern(SearchEngine.createSearchPattern("*", ICSearchConstants.UNION, ICSearchConstants.DECLARATIONS, false)); //$NON-NLS-1$
-		pattern.addPattern(SearchEngine.createSearchPattern("*", ICSearchConstants.ENUM, ICSearchConstants.DECLARATIONS, false)); //$NON-NLS-1$
-		pattern.addPattern(SearchEngine.createSearchPattern("*", ICSearchConstants.TYPEDEF, ICSearchConstants.DECLARATIONS, false)); //$NON-NLS-1$
-	}
-
-	public void run(IProgressMonitor monitor) throws InterruptedException {
-		collector.setProgressMonitor(monitor);
-		try {
-			engine.search(workspace, pattern, scope, collector, true);
-		} catch (OperationCanceledException e) {
-			throw new InterruptedException();
-		}
-		if (monitor.isCanceled()) {
-			throw new InterruptedException();
-		}
-	}
-
-	public Object[] getResults() {
-		return collector.getSearchResults().toArray();
-	}
-}
Index: src/org/eclipse/cdt/internal/ui/opentype/TypeSearchResultCollector.java
===================================================================
diff -N src/org/eclipse/cdt/internal/ui/opentype/TypeSearchResultCollector.java
--- src/org/eclipse/cdt/internal/ui/opentype/TypeSearchResultCollector.java	8 Mar 2004 15:30:13 -0000	1.2
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,49 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2004 QNX Software Systems and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
- * Contributors:
- *     QNX Software Systems - initial API and implementation
- *******************************************************************************/
-package org.eclipse.cdt.internal.ui.opentype;
-
-import org.eclipse.cdt.core.parser.ISourceElementCallbackDelegate;
-import org.eclipse.cdt.core.search.BasicSearchResultCollector;
-import org.eclipse.cdt.core.search.IMatch;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-
-public class TypeSearchResultCollector extends BasicSearchResultCollector {
-
-	private IProgressMonitor monitor;
-	
-	public TypeSearchResultCollector() {
-		super();
-	}
-	
-	public IProgressMonitor getProgressMonitor() {
-		return monitor;
-	}
-
-	public void setProgressMonitor(IProgressMonitor monitor) {
-		this.monitor = monitor;
-	}
-	
-	public IMatch createMatch(Object fileResource, int start, int end, ISourceElementCallbackDelegate node )
-	{
-		TypeSearchMatch result = new TypeSearchMatch();
-		return super.createMatch( result, fileResource, start, end, node );
-	}
-
-	public boolean acceptMatch(IMatch match) throws CoreException {
-		// filter out unnamed structs
-		TypeSearchMatch result = (TypeSearchMatch) match;
-		if (result.getName().length() == 0)
-			return false;
-		else
-			return super.acceptMatch(match);
-	}
-}
Index: src/org/eclipse/cdt/internal/ui/opentype/dialogs/OpenTypeSelectionDialog.java
===================================================================
diff -N src/org/eclipse/cdt/internal/ui/opentype/dialogs/OpenTypeSelectionDialog.java
--- src/org/eclipse/cdt/internal/ui/opentype/dialogs/OpenTypeSelectionDialog.java	5 Feb 2004 16:21:45 -0000	1.2
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,156 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2000,2003,2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
- * Contributors:
- *     IBM Corporation - initial API and implementation
- *     QNX Software Systems - adapted for use in CDT
- *******************************************************************************/
-package org.eclipse.cdt.internal.ui.opentype.dialogs;
-
-import org.eclipse.cdt.core.search.ICSearchScope;
-import org.eclipse.cdt.ui.CUIPlugin;
-import org.eclipse.jface.dialogs.IDialogConstants;
-import org.eclipse.jface.dialogs.IDialogSettings;
-import org.eclipse.jface.operation.IRunnableContext;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Shell;
-
-/**
- * A dialog to select a type from a list of types. The selected type will be
- * opened in the editor.
- */
-public class OpenTypeSelectionDialog extends TypeSelectionDialog {
-
-	public static final int IN_HIERARCHY= IDialogConstants.CLIENT_ID + 1;
-	/** The dialog location. */
-	private Point fLocation;
-	/** The dialog size. */
-	private Point fSize;
-
-	/**
-	 * Constructs an instance of <code>OpenTypeSelectionDialog</code>.
-	 * @param parent  the parent shell.
-	 * @param context the context.
-	 * @param scope   the C search scope.
-	 */
-	public OpenTypeSelectionDialog(Shell parent, IRunnableContext context, ICSearchScope scope) {
-		super(parent, context, scope);
-	}
-	
-	/*
-	 * @see org.eclipse.jface.window.Window#configureShell(Shell)
-	 */
-	protected void configureShell(Shell newShell) {
-		super.configureShell(newShell);
-	}
-
-	/*
-	 * @see Window#close()
-	 */
-	public boolean close() {
-		writeSettings();
-		return super.close();
-	}
-
-	/*
-	 * @see org.eclipse.jface.window.Window#createContents(org.eclipse.swt.widgets.Composite)
-	 */
-	protected Control createContents(Composite parent) {
-		Control control= super.createContents(parent);
-		readSettings();
-		return control;
-	}
-	
-	/* (non-Javadoc)
-	 * @see org.eclipse.jface.window.Window#getInitialSize()
-	 */
-	protected Point getInitialSize() {
-		Point result= super.getInitialSize();
-		if (fSize != null) {
-			result.x= Math.max(result.x, fSize.x);
-			result.y= Math.max(result.y, fSize.y);
-			Rectangle display= getShell().getDisplay().getClientArea();
-			result.x= Math.min(result.x, display.width);
-			result.y= Math.min(result.y, display.height);
-		}
-		return result;
-	}
-	
-	/* (non-Javadoc)
-	 * @see org.eclipse.jface.window.Window#getInitialLocation(org.eclipse.swt.graphics.Point)
-	 */
-	protected Point getInitialLocation(Point initialSize) {
-		Point result= super.getInitialLocation(initialSize);
-		if (fLocation != null) {
-			result.x= fLocation.x;
-			result.y= fLocation.y;
-			Rectangle display= getShell().getDisplay().getClientArea();
-			int xe= result.x + initialSize.x;
-			if (xe > display.width) {
-				result.x-= xe - display.width; 
-			}
-			int ye= result.y + initialSize.y;
-			if (ye > display.height) {
-				result.y-= ye - display.height; 
-			}
-		}
-		return result;
-	}
-
-	/**
-	 * Initializes itself from the dialog settings with the same state
-	 * as at the previous invocation.
-	 */
-	private void readSettings() {
-		IDialogSettings s= getDialogSettings();
-		try {
-			int x= s.getInt("x"); //$NON-NLS-1$
-			int y= s.getInt("y"); //$NON-NLS-1$
-			fLocation= new Point(x, y);
-			int width= s.getInt("width"); //$NON-NLS-1$
-			int height= s.getInt("height"); //$NON-NLS-1$
-			fSize= new Point(width, height);
-
-		} catch (NumberFormatException e) {
-			fLocation= null;
-			fSize= null;
-		}
-	}
-
-	/**
-	 * Stores it current configuration in the dialog store.
-	 */
-	private void writeSettings() {
-		IDialogSettings s= getDialogSettings();
-
-		Point location= getShell().getLocation();
-		s.put("x", location.x); //$NON-NLS-1$
-		s.put("y", location.y); //$NON-NLS-1$
-
-		Point size= getShell().getSize();
-		s.put("width", size.x); //$NON-NLS-1$
-		s.put("height", size.y); //$NON-NLS-1$
-	}
-
-	/**
-	 * Returns the dialog settings object used to share state
-	 * between several find/replace dialogs.
-	 *
-	 * @return the dialog settings to be used
-	 */
-	private IDialogSettings getDialogSettings() {
-		IDialogSettings settings= CUIPlugin.getDefault().getDialogSettings();
-		String sectionName= getClass().getName();
-		IDialogSettings subSettings= settings.getSection(sectionName);
-		if (subSettings == null)
-			subSettings= settings.addNewSection(sectionName);
-		return subSettings;
-	}
-}
Index: src/org/eclipse/cdt/internal/ui/opentype/dialogs/TypeSelectionDialog.java
===================================================================
diff -N src/org/eclipse/cdt/internal/ui/opentype/dialogs/TypeSelectionDialog.java
--- src/org/eclipse/cdt/internal/ui/opentype/dialogs/TypeSelectionDialog.java	5 Feb 2004 16:21:45 -0000	1.2
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,207 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2000,2003,2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- * 
- * Contributors:
- *     IBM Corporation - initial API and implementation
- *     QNX Software Systems - adapted for use in CDT
- *******************************************************************************/
-package org.eclipse.cdt.internal.ui.opentype.dialogs;
-
-import java.lang.reflect.InvocationTargetException;
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.List;
-
-import org.eclipse.cdt.core.search.ICSearchScope;
-import org.eclipse.cdt.core.search.SearchEngine;
-import org.eclipse.cdt.internal.ui.opentype.OpenTypeMessages;
-import org.eclipse.cdt.internal.ui.opentype.TypeSearchMatch;
-import org.eclipse.cdt.internal.ui.opentype.TypeSearchMatchLabelProvider;
-import org.eclipse.cdt.internal.ui.opentype.TypeSearchOperation;
-import org.eclipse.cdt.internal.ui.util.StringMatcher;
-import org.eclipse.cdt.internal.ui.util.ExceptionHandler;
-import org.eclipse.cdt.internal.ui.util.Strings;
-import org.eclipse.cdt.ui.CUIPlugin;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.operation.IRunnableContext;
-import org.eclipse.jface.util.Assert;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.ui.dialogs.FilteredList;
-import org.eclipse.ui.dialogs.TwoPaneElementSelector;
-
-
-/**
- * A dialog to select a type from a list of types.
- */
-public class TypeSelectionDialog extends TwoPaneElementSelector {
-
-	private static class TypeFilterMatcher implements FilteredList.FilterMatcher {
-
-		private static final char END_SYMBOL= '<';
-		private static final char ANY_STRING= '*';
-
-		private StringMatcher fMatcher;
-		private StringMatcher fQualifierMatcher;
-		
-		/*
-		 * @see FilteredList.FilterMatcher#setFilter(String, boolean)
-		 */
-		public void setFilter(String pattern, boolean ignoreCase, boolean igoreWildCards) {
-			int qualifierIndex= pattern.lastIndexOf("::"); //$NON-NLS-1$
-
-			// type			
-			if (qualifierIndex == -1) {
-				fQualifierMatcher= null;
-				fMatcher= new StringMatcher(adjustPattern(pattern), ignoreCase, igoreWildCards);
-				
-			// qualified type
-			} else {
-				fQualifierMatcher= new StringMatcher(pattern.substring(0, qualifierIndex), ignoreCase, igoreWildCards);
-				fMatcher= new StringMatcher(adjustPattern(pattern.substring(qualifierIndex + 2)), ignoreCase, igoreWildCards);
-			}
-		}
-
-		/*
-		 * @see FilteredList.FilterMatcher#match(Object)
-		 */
-		public boolean match(Object element) {
-			if (!(element instanceof TypeSearchMatch))
-				return false;
-
-			TypeSearchMatch type= (TypeSearchMatch) element;
-
-			if (!fMatcher.match(type.getName()))
-				return false;
-
-			if (fQualifierMatcher == null)
-				return true;
-
-			return fQualifierMatcher.match(type.getFullyQualifiedName());
-		}
-		
-		private String adjustPattern(String pattern) {
-			int length= pattern.length();
-			if (length > 0) {
-				switch (pattern.charAt(length - 1)) {
-					case END_SYMBOL:
-						pattern= pattern.substring(0, length - 1);
-						break;
-					case ANY_STRING:
-						break;
-					default:
-						pattern= pattern + ANY_STRING;
-				}
-			}
-			return pattern;
-		}
-	}
-	
-	/*
-	 * A string comparator which is aware of obfuscated code
-	 * (type names starting with lower case characters).
-	 */
-	private static class StringComparator implements Comparator {
-	    public int compare(Object left, Object right) {
-	     	String leftString= (String) left;
-	     	String rightString= (String) right;
-	     	
-	     	if (leftString.length() != 0 && rightString.length() != 0)
-	     	{
-		     	if (Strings.isLowerCase(leftString.charAt(0)) &&
-		     		!Strings.isLowerCase(rightString.charAt(0)))
-		     		return +1;
-	
-		     	if (Strings.isLowerCase(rightString.charAt(0)) &&
-		     		!Strings.isLowerCase(leftString.charAt(0)))
-		     		return -1;
-			}
-	     	
-			int result= leftString.compareToIgnoreCase(rightString);			
-			if (result == 0)
-				result= leftString.compareTo(rightString);
-
-			return result;
-	    }
-	}
-	
-	private IRunnableContext fRunnableContext;
-	private ICSearchScope fScope;
-	
-	/**
-	 * Constructs a type selection dialog.
-	 * @param parent  the parent shell.
-	 * @param context the runnable context.
-	 * @param scope   the C search scope.
-	 */
-	public TypeSelectionDialog(Shell parent, IRunnableContext context, ICSearchScope scope) {
-		super(parent, new TypeSearchMatchLabelProvider(TypeSearchMatchLabelProvider.SHOW_TYPE_ONLY),
-			new TypeSearchMatchLabelProvider(TypeSearchMatchLabelProvider.SHOW_TYPE_CONTAINER_ONLY + TypeSearchMatchLabelProvider.SHOW_ROOT_POSTFIX));
-
-		Assert.isNotNull(context);
-		Assert.isNotNull(scope);
-
-		fRunnableContext= context;
-		fScope= scope;
-		
-		setUpperListLabel(OpenTypeMessages.getString("TypeSelectionDialog.upperLabel")); //$NON-NLS-1$
-		setLowerListLabel(OpenTypeMessages.getString("TypeSelectionDialog.lowerLabel")); //$NON-NLS-1$
-	}
-
-	/*
-	 * @see AbstractElementListSelectionDialog#createFilteredList(Composite)
-	 */
- 	protected FilteredList createFilteredList(Composite parent) {
- 		FilteredList list= super.createFilteredList(parent);
- 		
-		fFilteredList.setFilterMatcher(new TypeFilterMatcher());
-		fFilteredList.setComparator(new StringComparator());
-		
-		return list;
-	}
- 
- 	/*
-	 * @see org.eclipse.jface.window.Window#open()
-	 */
-	public int open() {
-		TypeSearchOperation search = new TypeSearchOperation(CUIPlugin.getWorkspace(), fScope, new SearchEngine());
-		
-		try {
-			fRunnableContext.run(true, true, search);
-		} catch (InvocationTargetException e) {
-			ExceptionHandler.handle(e, OpenTypeMessages.getString("TypeSelectionDialog.error3Title"), OpenTypeMessages.getString("TypeSelectionDialog.error3Message")); //$NON-NLS-1$ //$NON-NLS-2$
-			return CANCEL;
-		} catch (InterruptedException e) {
-			// cancelled by user
-			return CANCEL;
-		}
-		
-		Object[] results = search.getResults();
-		if (results.length == 0) {
-			String title = OpenTypeMessages.getString("TypeSelectionDialog.notypes.title"); //$NON-NLS-1$
-			String message = OpenTypeMessages.getString("TypeSelectionDialog.notypes.message"); //$NON-NLS-1$
-			MessageDialog.openInformation(getShell(), title, message);
-			return CANCEL;
-		}
-
-		setElements(results);
-		return super.open();
-	}
-	
-	/*
-	 * @see org.eclipse.ui.dialogs.SelectionStatusDialog#computeResult()
-	 */
-	protected void computeResult() {
-		TypeSearchMatch selection= (TypeSearchMatch) getLowerSelectedElement();
-		if (selection == null)
-			return;
-			
-		List result= new ArrayList(1);
-		result.add(selection);
-		setResult(result);
-	}
-}
Index: src/org/eclipse/cdt/ui/CUIPlugin.java
===================================================================
retrieving revision 1.25
diff -u -r1.25 CUIPlugin.java
--- src/org/eclipse/cdt/ui/CUIPlugin.java	3 Mar 2004 19:19:36 -0000	1.25
+++ src/org/eclipse/cdt/ui/CUIPlugin.java	8 Mar 2004 18:04:39 -0000
@@ -34,6 +34,7 @@
 import org.eclipse.cdt.internal.ui.editor.SharedTextColors;
 import org.eclipse.cdt.internal.ui.editor.WorkingCopyManager;
 import org.eclipse.cdt.internal.ui.editor.asm.AsmTextTools;
+import org.eclipse.cdt.ui.browser.typeinfo.AllTypesCache;
 import org.eclipse.cdt.internal.ui.preferences.BuildConsolePreferencePage;
 import org.eclipse.cdt.internal.ui.preferences.CEditorPreferencePage;
 import org.eclipse.cdt.internal.ui.preferences.CPluginPreferencePage;
@@ -277,6 +278,9 @@
 	 * @see Plugin#shutdown
 	 */
 	public void shutdown() throws CoreException {
+
+		AllTypesCache.terminate();
+		
 		if (fTextTools != null) {
 			fTextTools.dispose();
 		}
@@ -326,6 +330,7 @@
 			public void run() {
 				registerAdapters();
 				CPluginImages.initialize();
+				AllTypesCache.initialize();
 			}
 		});
 	}
Index: browser/org/eclipse/cdt/internal/ui/browser/opentype/OpenTypeAction.java
===================================================================
RCS file: browser/org/eclipse/cdt/internal/ui/browser/opentype/OpenTypeAction.java
diff -N browser/org/eclipse/cdt/internal/ui/browser/opentype/OpenTypeAction.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ browser/org/eclipse/cdt/internal/ui/browser/opentype/OpenTypeAction.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,198 @@
+/*******************************************************************************
+ * Copyright (c) 2004 QNX Software Systems and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     QNX Software Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.internal.ui.browser.opentype;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+
+import org.eclipse.cdt.core.model.CModelException;
+import org.eclipse.cdt.core.model.ICElement;
+import org.eclipse.cdt.core.resources.FileStorage;
+import org.eclipse.cdt.core.search.ICSearchScope;
+import org.eclipse.cdt.core.search.SearchEngine;
+import org.eclipse.cdt.internal.ui.editor.CEditor;
+import org.eclipse.cdt.ui.browser.typeinfo.AllTypesCache;
+import org.eclipse.cdt.ui.browser.typeinfo.ITypeInfo;
+import org.eclipse.cdt.ui.browser.typeinfo.TypeInfoFilter;
+import org.eclipse.cdt.internal.ui.util.EditorUtility;
+import org.eclipse.cdt.internal.ui.util.ExceptionHandler;
+import org.eclipse.cdt.ui.CUIPlugin;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IStorage;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.dialogs.ProgressMonitorDialog;
+import org.eclipse.jface.operation.IRunnableContext;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.IWorkbenchWindowActionDelegate;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+/**
+ * To change the template for this generated type comment go to
+ * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
+ */
+public class OpenTypeAction implements IWorkbenchWindowActionDelegate {
+
+	public OpenTypeAction() {
+		super();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
+	 */
+	public void run(IAction action) {		
+		final ICSearchScope scope= SearchEngine.createWorkspaceScope();
+		Shell shell= CUIPlugin.getDefault().getActiveWorkbenchShell();
+
+		final ArrayList typeList= new ArrayList();
+		final TypeInfoFilter filter= new TypeInfoFilter();
+
+		if (AllTypesCache.isCacheUpToDate(filter)) {
+			// run without progress monitor
+			AllTypesCache.getTypes(scope, filter, null, typeList);
+		} else {
+			IRunnableContext runnableContext= new ProgressMonitorDialog(shell);
+			IRunnableWithProgress runnable= new IRunnableWithProgress() {
+				public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
+					AllTypesCache.getTypes(scope, filter, monitor, typeList);
+					if (monitor.isCanceled()) {
+						throw new InterruptedException();
+					}
+				}
+			};
+
+			try {
+				runnableContext.run(true, true, runnable);
+			} catch (InvocationTargetException e) {
+				String title= OpenTypeMessages.getString("OpenTypeAction.exception.title"); //$NON-NLS-1$
+				String message= OpenTypeMessages.getString("OpenTypeAction.exception.message"); //$NON-NLS-1$
+				ExceptionHandler.handle(e, title, message);
+				return;
+			} catch (InterruptedException e) {
+				// cancelled by user
+				return;
+			}
+		}
+		
+		if (typeList.isEmpty()) {
+			String title= OpenTypeMessages.getString("OpenTypeAction.notypes.title"); //$NON-NLS-1$
+			String message= OpenTypeMessages.getString("OpenTypeAction.notypes.message"); //$NON-NLS-1$
+			MessageDialog.openInformation(shell, title, message);
+			return;
+		}
+		ITypeInfo[] typeRefs= (ITypeInfo[])typeList.toArray(new ITypeInfo[typeList.size()]);
+			
+		OpenTypeDialog dialog= new OpenTypeDialog(shell);
+		dialog.setElements(typeRefs);
+
+		int result= dialog.open();
+		if (result != IDialogConstants.OK_ID)
+			return;
+		
+		ITypeInfo info= (ITypeInfo)dialog.getFirstResult();
+		if (info == null)
+			return;
+
+		if (!openTypeInEditor(shell, info))
+		{
+			// could not find definition
+			String path= info.getFilePath();
+			if (path == null || path.length() == 0)
+				path= OpenTypeMessages.getString("OpenTypeAction.errorNoPath"); //$NON-NLS-1$
+			String title= OpenTypeMessages.getString("OpenTypeAction.errorTitle"); //$NON-NLS-1$
+			String message= OpenTypeMessages.getFormattedString("OpenTypeAction.errorMessage", path); //$NON-NLS-1$
+			MessageDialog.openError(shell, title, message);
+		}
+	}
+	
+	/**
+	 * Opens an editor and displays the selected type.
+	 * @param shell Workbench shell.
+	 * @param info Type to display.
+	 * @return true if succesfully displayed.
+	 */
+	private boolean openTypeInEditor(Shell shell, ITypeInfo info) {
+		IResource res= null;
+		IEditorPart editorPart= null;
+		IPath path= info.getLocation();
+		ICElement celement= info.getCElement();
+
+		// attempt to locate the resource
+		if (celement != null)
+			res= celement.getUnderlyingResource();
+		if (res == null)
+			res= info.getResource();
+		if (res == null && path != null) {
+			IWorkspaceRoot wsRoot= CUIPlugin.getWorkspace().getRoot();
+			res= wsRoot.getFileForLocation(path);
+		}
+
+		try {
+			// open resource in editor
+			if (res != null)
+				editorPart= EditorUtility.openInEditor(res);
+			if (editorPart == null) {
+				// open as external file
+				IStorage storage = new FileStorage(path);
+				editorPart= EditorUtility.openInEditor(storage);
+			}
+			if (editorPart == null)
+				return false;
+		} catch (CModelException ex){
+			ex.printStackTrace();
+			return false;
+		}
+		catch(PartInitException ex) {
+			ex.printStackTrace();
+			return false;
+		}
+
+		// highlight the type in the editor
+		if (celement != null && editorPart instanceof CEditor) {
+			CEditor editor= (CEditor)editorPart;
+			editor.setSelection(celement);
+			return true;
+		} else if (editorPart instanceof ITextEditor) {
+			ITextEditor editor= (ITextEditor)editorPart;
+			editor.selectAndReveal(info.getStartOffset(), info.getName().length());
+			return true;
+		}
+		
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ui.IWorkbenchWindowActionDelegate#dispose()
+	 */
+	public void dispose() {
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ui.IWorkbenchWindowActionDelegate#init(org.eclipse.ui.IWorkbenchWindow)
+	 */
+	public void init(IWorkbenchWindow window) {
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action.IAction, org.eclipse.jface.viewers.ISelection)
+	 */
+	public void selectionChanged(IAction action, ISelection selection) {
+	}
+}
Index: browser/org/eclipse/cdt/internal/ui/browser/opentype/OpenTypeDialog.java
===================================================================
RCS file: browser/org/eclipse/cdt/internal/ui/browser/opentype/OpenTypeDialog.java
diff -N browser/org/eclipse/cdt/internal/ui/browser/opentype/OpenTypeDialog.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ browser/org/eclipse/cdt/internal/ui/browser/opentype/OpenTypeDialog.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,153 @@
+/*******************************************************************************
+ * Copyright (c) 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     QNX Software Systems - adapted for use in CDT
+ *******************************************************************************/
+package org.eclipse.cdt.internal.ui.browser.opentype;
+
+import org.eclipse.cdt.ui.browser.typeinfo.TypeSelectionDialog;
+import org.eclipse.cdt.ui.CUIPlugin;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * A dialog to select a type from a list of types. The selected type will be
+ * opened in the editor.
+ */
+public class OpenTypeDialog extends TypeSelectionDialog {
+
+	/** The dialog location. */
+	private Point fLocation;
+	/** The dialog size. */
+	private Point fSize;
+
+	/**
+	 * Constructs an instance of <code>OpenTypeDialog</code>.
+	 * @param parent  the parent shell.
+	 * @param context the context.
+	 */
+	public OpenTypeDialog(Shell parent) {
+		super(parent);
+		setTitle(OpenTypeMessages.getString("OpenTypeDialog.title")); //$NON-NLS-1$
+		setMessage(OpenTypeMessages.getString("OpenTypeDialog.message")); //$NON-NLS-1$
+		//setFilter(OpenTypeMessages.getString("OpenTypeDialog.filter")); //$NON-NLS-1$
+		setMatchEmptyString(true);
+	}
+	
+	/*
+	 * @see org.eclipse.jface.window.Window#configureShell(Shell)
+	 */
+	protected void configureShell(Shell newShell) {
+		super.configureShell(newShell);
+	}
+
+	/*
+	 * @see Window#close()
+	 */
+	public boolean close() {
+		writeSettings();
+		return super.close();
+	}
+
+	/*
+	 * @see org.eclipse.jface.window.Window#createContents(org.eclipse.swt.widgets.Composite)
+	 */
+	protected Control createContents(Composite parent) {
+		Control control= super.createContents(parent);
+		readSettings();
+		return control;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.window.Window#getInitialSize()
+	 */
+	protected Point getInitialSize() {
+		Point result= super.getInitialSize();
+		if (fSize != null) {
+			result.x= Math.max(result.x, fSize.x);
+			result.y= Math.max(result.y, fSize.y);
+			Rectangle display= getShell().getDisplay().getClientArea();
+			result.x= Math.min(result.x, display.width);
+			result.y= Math.min(result.y, display.height);
+		}
+		return result;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.window.Window#getInitialLocation(org.eclipse.swt.graphics.Point)
+	 */
+	protected Point getInitialLocation(Point initialSize) {
+		Point result= super.getInitialLocation(initialSize);
+		if (fLocation != null) {
+			result.x= fLocation.x;
+			result.y= fLocation.y;
+			Rectangle display= getShell().getDisplay().getClientArea();
+			int xe= result.x + initialSize.x;
+			if (xe > display.width) {
+				result.x-= xe - display.width; 
+			}
+			int ye= result.y + initialSize.y;
+			if (ye > display.height) {
+				result.y-= ye - display.height; 
+			}
+		}
+		return result;
+	}
+
+	/**
+	 * Initializes itself from the dialog settings with the same state
+	 * as at the previous invocation.
+	 */
+	private void readSettings() {
+		IDialogSettings s= getDialogSettings();
+		try {
+			int x= s.getInt("x"); //$NON-NLS-1$
+			int y= s.getInt("y"); //$NON-NLS-1$
+			fLocation= new Point(x, y);
+			int width= s.getInt("width"); //$NON-NLS-1$
+			int height= s.getInt("height"); //$NON-NLS-1$
+			fSize= new Point(width, height);
+		} catch (NumberFormatException e) {
+			fLocation= null;
+			fSize= null;
+		}
+	}
+
+	/**
+	 * Stores it current configuration in the dialog store.
+	 */
+	private void writeSettings() {
+		IDialogSettings s= getDialogSettings();
+		Point location= getShell().getLocation();
+		s.put("x", location.x); //$NON-NLS-1$
+		s.put("y", location.y); //$NON-NLS-1$
+		Point size= getShell().getSize();
+		s.put("width", size.x); //$NON-NLS-1$
+		s.put("height", size.y); //$NON-NLS-1$
+	}
+
+	/**
+	 * Returns the dialog settings object used to share state
+	 * between several find/replace dialogs.
+	 *
+	 * @return the dialog settings to be used
+	 */
+	private IDialogSettings getDialogSettings() {
+		IDialogSettings settings= CUIPlugin.getDefault().getDialogSettings();
+		String sectionName= getClass().getName();
+		IDialogSettings subSettings= settings.getSection(sectionName);
+		if (subSettings == null)
+			subSettings= settings.addNewSection(sectionName);
+		return subSettings;
+	}
+}
Index: browser/org/eclipse/cdt/internal/ui/browser/opentype/OpenTypeMessages.java
===================================================================
RCS file: browser/org/eclipse/cdt/internal/ui/browser/opentype/OpenTypeMessages.java
diff -N browser/org/eclipse/cdt/internal/ui/browser/opentype/OpenTypeMessages.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ browser/org/eclipse/cdt/internal/ui/browser/opentype/OpenTypeMessages.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 2004 QNX Software Systems and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     QNX Software Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.internal.ui.browser.opentype;
+
+import java.text.MessageFormat;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * OpenTypeMessages
+ */
+public class OpenTypeMessages {
+
+	private static final String RESOURCE_BUNDLE= OpenTypeMessages.class.getName();
+
+	private static ResourceBundle fgResourceBundle;
+	static {
+		try {
+			fgResourceBundle = ResourceBundle.getBundle(RESOURCE_BUNDLE);
+		} catch (MissingResourceException x) {
+			fgResourceBundle = null;
+		}
+	}
+
+	private OpenTypeMessages() {
+	}
+
+	public static String getString(String key) {
+		try {
+			return fgResourceBundle.getString(key);
+		} catch (MissingResourceException e) {
+			return '!' + key + '!';
+		} catch (NullPointerException e) {
+			return "#" + key + "#"; //$NON-NLS-1$ //$NON-NLS-2$
+		}
+	}
+	
+	public static String getFormattedString(String key, String arg) {
+		return getFormattedString(key, new String[] { arg });
+	}
+	
+	public static String getFormattedString(String key, String[] args) {
+		return MessageFormat.format(getString(key), args);	
+	}	
+
+}
Index: browser/org/eclipse/cdt/internal/ui/browser/opentype/OpenTypeMessages.properties
===================================================================
RCS file: browser/org/eclipse/cdt/internal/ui/browser/opentype/OpenTypeMessages.properties
diff -N browser/org/eclipse/cdt/internal/ui/browser/opentype/OpenTypeMessages.properties
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ browser/org/eclipse/cdt/internal/ui/browser/opentype/OpenTypeMessages.properties	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,26 @@
+###############################################################################
+# Copyright (c) 2004 QNX Software Systems Ltd. and others.
+# All rights reserved.   This program and the accompanying materials
+# are made available under the terms of the Common Public License v0.5
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/cpl-v05.html
+# 
+# Contributors: 
+# QNX Software Systems - Initial API and implementation
+###############################################################################
+
+OpenTypeAction.exception.title=Exception
+OpenTypeAction.exception.message=Unexpected exception. See log for details.
+OpenTypeAction.notypes.title=Type Selection
+OpenTypeAction.notypes.message=No types available.
+
+OpenTypeAction.description=Open a type in the editor
+OpenTypeAction.tooltip=Open a Type
+OpenTypeAction.label=Open Type...
+OpenTypeAction.errorTitle=Open Type
+OpenTypeAction.errorMessage=Could not uniquely map the type name to a type. Path is {0}
+OpenTypeAction.errorNoPath=Unknown
+
+OpenTypeDialog.title=Open Type
+OpenTypeDialog.message=&Choose a type (? = any character, * = any string):
+OpenTypeDialog.filter=
Index: browser/org/eclipse/cdt/internal/ui/browser/util/ArrayUtil.java
===================================================================
RCS file: browser/org/eclipse/cdt/internal/ui/browser/util/ArrayUtil.java
diff -N browser/org/eclipse/cdt/internal/ui/browser/util/ArrayUtil.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ browser/org/eclipse/cdt/internal/ui/browser/util/ArrayUtil.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2004 QNX Software Systems and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     QNX Software Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.internal.ui.browser.util;
+
+/**
+ * A helper class which allows you to perform some
+ * simple set operations on int arrays.
+ */
+public class ArrayUtil {
+	private ArrayUtil() {
+	}
+
+	// returns true if set contains elem
+	public static boolean contains(int[] set, int elem) {
+		for (int i= 0; i < set.length; ++i) {
+			if (set[i] == elem)
+				return true;
+		}
+		return false;
+	}
+	
+	// returns true if set contains all of subset
+	public static boolean containsAll(int[] set, int[] subset) {
+		for (int i= 0; i < subset.length; ++i) {
+			if (!contains(set, subset[i]))
+				return false;
+		}
+		return true;
+	}
+	
+	// return a copy of fromSet
+	public static int[] clone(int[] fromSet) {
+		int[] newSet= new int[fromSet.length];
+		for (int i= 0; i < fromSet.length; ++i) {
+			newSet[i]= newSet[i];
+		}
+		return newSet;
+	}
+}
Index: browser/org/eclipse/cdt/internal/ui/browser/util/ProgressMonitorMultiWrapper.java
===================================================================
RCS file: browser/org/eclipse/cdt/internal/ui/browser/util/ProgressMonitorMultiWrapper.java
diff -N browser/org/eclipse/cdt/internal/ui/browser/util/ProgressMonitorMultiWrapper.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ browser/org/eclipse/cdt/internal/ui/browser/util/ProgressMonitorMultiWrapper.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,233 @@
+/*******************************************************************************
+ * Copyright (c) 2004 QNX Software Systems and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     QNX Software Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.internal.ui.browser.util;
+
+import java.util.ArrayList;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IProgressMonitorWithBlocking;
+import org.eclipse.core.runtime.IStatus;
+
+/**
+ * A wrapper around multiple progress monitors which forwards
+ * <code>IProgressMonitor</code> and <code>IProgressMonitorWithBlocking</code>
+ * methods to the wrapped progress monitors.
+ */
+public class ProgressMonitorMultiWrapper implements IProgressMonitor, IProgressMonitorWithBlocking {
+
+	private double internalWork;
+	private int totalWork;
+	private int work;
+	private String taskName;
+	private String subtaskName;
+	private boolean isCanceled= false;
+	private boolean blocked= false;
+
+	/** The wrapped progress monitors. */
+	private final ArrayList fProgressMonitors= new ArrayList(2);
+
+	/**
+	 * Creates a new monitor wrapper.
+	 */
+	public ProgressMonitorMultiWrapper() {
+	}
+	
+	/**
+	 * Creates a new monitor wrapper around the given monitor.
+	 */
+	public ProgressMonitorMultiWrapper(IProgressMonitor monitor) {
+		addProgressMonitor(monitor);
+	}
+
+	/* 
+	 * @see IProgressMonitor#beginTask
+	 */
+	public void beginTask(String name, int totalWork) {
+		taskName= name;
+		this.totalWork= totalWork;
+
+		// Clone the monitors since they could remove themselves when called 
+		ArrayList monitors= (ArrayList) fProgressMonitors.clone();
+		for (int i= 0; i < monitors.size(); i++) {
+			IProgressMonitor monitor= (IProgressMonitor) monitors.get(i);
+			monitor.beginTask(name, totalWork);
+		}
+	}
+	
+	/*
+	 * @see IProgressMonitor#setTaskName
+	 */
+	public void setTaskName(String name) {
+		taskName= name;
+
+		// Clone the monitors since they could remove themselves when called 
+		ArrayList monitors= (ArrayList) fProgressMonitors.clone();
+		for (int i= 0; i < monitors.size(); i++) {
+			IProgressMonitor monitor= (IProgressMonitor) monitors.get(i);
+			monitor.setTaskName(name);
+		}
+	}
+	
+	/*
+	 * @see IProgressMonitor#subTask
+	 */
+	public void subTask(String name) {
+		subtaskName= name;
+
+		// Clone the monitors since they could remove themselves when called 
+		ArrayList monitors= (ArrayList) fProgressMonitors.clone();
+		for (int i= 0; i < monitors.size(); i++) {
+			IProgressMonitor monitor= (IProgressMonitor) monitors.get(i);
+			monitor.subTask(name);
+		}
+	}
+	
+	/*
+	 * @see IProgressMonitor#worked
+	 */
+	public void worked(int work) {
+		this.work= work;
+
+		// Clone the monitors since they could remove themselves when called 
+		ArrayList monitors= (ArrayList) fProgressMonitors.clone();
+		for (int i= 0; i < monitors.size(); i++) {
+			IProgressMonitor monitor= (IProgressMonitor) monitors.get(i);
+			monitor.worked(work);
+		}
+	}
+	
+	/*
+	 * @see IProgressMonitor#internalWorked
+	 */
+	public void internalWorked(double work) {
+		internalWork= work;
+
+		// Clone the monitors since they could remove themselves when called 
+		ArrayList monitors= (ArrayList) fProgressMonitors.clone();
+		for (int i= 0; i < monitors.size(); i++) {
+			IProgressMonitor monitor= (IProgressMonitor) monitors.get(i);
+			monitor.internalWorked(work);
+		}
+	}
+	
+	/*
+	 * @see IProgressMonitor#done
+	 */
+	public void done() {
+		// Clone the monitors since they could remove themselves when called 
+		ArrayList monitors= (ArrayList) fProgressMonitors.clone();
+		for (int i= 0; i < monitors.size(); i++) {
+			IProgressMonitor monitor= (IProgressMonitor) monitors.get(i);
+			monitor.done();
+		}
+	}
+	
+	/*
+	 * @see IProgressMonitor#setCanceled
+	 */
+	public void setCanceled(boolean canceled) {
+		isCanceled= canceled;
+
+		// Clone the monitors since they could remove themselves when called 
+		ArrayList monitors= (ArrayList) fProgressMonitors.clone();
+		for (int i= 0; i < monitors.size(); i++) {
+			IProgressMonitor monitor= (IProgressMonitor) monitors.get(i);
+			monitor.setCanceled(canceled);
+		}
+	}
+
+	/*
+	 * @see IProgressMonitor#isCanceled
+	 */
+	public boolean isCanceled() {
+		// Clone the monitors since they could remove themselves when called 
+		ArrayList monitors= (ArrayList) fProgressMonitors.clone();
+		for (int i= 0; i < monitors.size(); i++) {
+			IProgressMonitor monitor= (IProgressMonitor) monitors.get(i);
+			isCanceled |= monitor.isCanceled();
+		}
+		return isCanceled;
+	}
+	
+	/*
+	 * @see IProgressMonitor#setBlocked
+	 */
+	public void setBlocked(IStatus reason) {
+		blocked= true;
+
+		// Clone the monitors since they could remove themselves when called 
+		ArrayList monitors= (ArrayList) fProgressMonitors.clone();
+		for (int i= 0; i < monitors.size(); i++) {
+			IProgressMonitor monitor= (IProgressMonitor) monitors.get(i);
+			if (monitor instanceof IProgressMonitorWithBlocking)
+				 ((IProgressMonitorWithBlocking) monitor).setBlocked(reason);
+		}
+	}
+	
+	/*
+	 * @see IProgressMonitor#clearBlocked
+	 */
+	public void clearBlocked() {
+		blocked= false;
+
+		// Clone the monitors since they could remove themselves when called 
+		ArrayList monitors= (ArrayList) fProgressMonitors.clone();
+		for (int i= 0; i < monitors.size(); i++) {
+			IProgressMonitor monitor= (IProgressMonitor) monitors.get(i);
+			if (monitor instanceof IProgressMonitorWithBlocking)
+				 ((IProgressMonitorWithBlocking) monitor).clearBlocked();
+		}
+	}
+	
+	/*
+	 * brings monitor up to date
+	 */
+	private void syncUpMonitor(IProgressMonitor monitor) {
+		if (totalWork > 0) {
+			monitor.beginTask(taskName, totalWork);
+			monitor.worked(work);
+			monitor.internalWorked(internalWork);
+			if (subtaskName != null && subtaskName.length() > 0)
+				monitor.subTask(subtaskName);
+			if (blocked && monitor instanceof IProgressMonitorWithBlocking)
+				 ((IProgressMonitorWithBlocking) monitor).setBlocked(null);
+		}
+	}
+	
+	/**
+	 * Adds a monitor to the list of wrapped monitors.
+	 */
+	public synchronized void addProgressMonitor(IProgressMonitor monitor) {
+		if (fProgressMonitors.indexOf(monitor) == -1) {
+			syncUpMonitor(monitor);
+			fProgressMonitors.add(monitor);
+		}
+	}
+	
+	/**
+	 * Removes a monitor from the list of wrapped monitors.
+	 */
+	public synchronized void removeProgressMonitor(IProgressMonitor monitor) {
+		int index = fProgressMonitors.indexOf(monitor);
+		if (index != -1) {
+			fProgressMonitors.remove(index);
+		}
+	}
+
+	/**
+	 * Returns the wrapped progress monitors.
+	 *
+	 * @return the wrapped progress monitors
+	 */
+	public IProgressMonitor[] getWrappedProgressMonitors() {
+		return (IProgressMonitor[]) fProgressMonitors.toArray();
+	}
+}
Index: browser/org/eclipse/cdt/ui/browser/typeinfo/AllTypesCache.java
===================================================================
RCS file: browser/org/eclipse/cdt/ui/browser/typeinfo/AllTypesCache.java
diff -N browser/org/eclipse/cdt/ui/browser/typeinfo/AllTypesCache.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ browser/org/eclipse/cdt/ui/browser/typeinfo/AllTypesCache.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,476 @@
+/*******************************************************************************
+ * Copyright (c) 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     QNX Software Systems - adapted for use in CDT
+ *******************************************************************************/
+package org.eclipse.cdt.ui.browser.typeinfo;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.Set;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.model.CoreModel;
+import org.eclipse.cdt.core.model.ElementChangedEvent;
+import org.eclipse.cdt.core.model.ICElement;
+import org.eclipse.cdt.core.model.ICElementDelta;
+import org.eclipse.cdt.core.model.IElementChangedListener;
+import org.eclipse.cdt.core.parser.ISourceElementCallbackDelegate;
+import org.eclipse.cdt.core.search.BasicSearchResultCollector;
+import org.eclipse.cdt.core.search.ICSearchConstants;
+import org.eclipse.cdt.core.search.ICSearchPattern;
+import org.eclipse.cdt.core.search.ICSearchScope;
+import org.eclipse.cdt.core.search.IMatch;
+import org.eclipse.cdt.core.search.OrPattern;
+import org.eclipse.cdt.core.search.SearchEngine;
+import org.eclipse.cdt.internal.ui.browser.util.ArrayUtil;
+import org.eclipse.cdt.internal.ui.browser.util.ProgressMonitorMultiWrapper;
+import org.eclipse.core.resources.IWorkspace;
+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.core.runtime.SubProgressMonitor;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.core.runtime.jobs.Job;
+
+/**
+ * Manages a search cache for types in the workspace. Instead of returning objects of type <code>ICElement</code>
+ * the methods of this class returns a list of the lightweight objects <code>TypeInfo</code>.
+ * <P>
+ * AllTypesCache runs asynchronously using a background job to rebuild the cache as needed.
+ * If the cache becomes dirty again while the background job is running, the job is restarted.
+ * <P>
+ * If <code>getAllTypes</code> is called in response to a user action, a progress dialog is shown.
+ * If called before the background job has finished, getAllTypes waits
+ * for the completion of the background job.
+ */
+public class AllTypesCache {
+	
+	/**
+	 * Background job for filling the type cache.
+	 * @see org.eclipse.core.runtime.jobs.Job
+	 * @since 3.0
+	 */
+	private static class TypeCacherJob extends Job {
+
+		/**
+		 * An "identity rule" that forces jobs to be queued.
+		 * @see org.eclipse.core.runtime.jobs.ISchedulingRule
+		 * @since 3.0
+		 */
+		final static ISchedulingRule MUTEX_RULE= new ISchedulingRule() {
+			public boolean contains(ISchedulingRule rule) {
+				return rule == this;
+			}
+			public boolean isConflicting(ISchedulingRule rule) {
+				return rule == this;
+			}			
+		};
+
+		/**
+		 * A comparator for simple type names
+		 */
+		private static class TypeNameComparator implements Comparator {
+			public int compare(Object o1, Object o2) {
+				return ((TypeInfo)o1).getName().compareTo(((TypeInfo)o2).getName());
+			}
+		}
+		
+		/**
+		 * A search result collector for type info.
+		 * @see org.eclipse.cdt.core.search.ICSearchResultCollector
+		 */
+		private static class TypeSearchResultCollector extends BasicSearchResultCollector {
+
+			public TypeSearchResultCollector() {
+				super();
+			}
+			
+			public TypeSearchResultCollector(IProgressMonitor monitor) {
+				super(monitor);
+			}
+			
+			public IMatch createMatch(Object fileResource, int start, int end, ISourceElementCallbackDelegate node )
+			{
+				TypeInfo result= new TypeInfo();
+				return super.createMatch( result, fileResource, start, end, node );
+			}
+
+			public boolean acceptMatch(IMatch match) throws CoreException {
+				// filter out unnamed structs
+				TypeInfo result= (TypeInfo) match;
+				String name= result.getName();
+				if (name == null || name.length() == 0)
+					return false;
+
+				// make sure we've got a valid type
+				if (!TypeInfo.isValidCElementType(result.getElementType()))
+					return false;
+
+				return super.acceptMatch(match);
+			}
+		}		
+
+		/**
+		 * Constant identifying the job family identifier for the background job.
+		 * @see IJobManager#join(Object, IProgressMonitor)
+		 * @since 3.0
+		 */
+		public static final Object FAMILY= new Object();
+
+		final static Comparator TYPE_COMPARATOR= new TypeNameComparator();
+
+		private ProgressMonitorMultiWrapper progressMonitor;
+		
+		public TypeCacherJob() {
+			super(TypeInfoMessages.getString("TypeCacherJob.jobName")); //$NON-NLS-1$
+			setPriority(BUILD);
+			setSystem(true);
+			//setRule(MUTEX_RULE);
+		}
+
+		/* (non-Javadoc)
+		 * @see org.eclipse.core.internal.jobs.InternalJob#belongsTo(java.lang.Object)
+		 */
+		public boolean belongsTo(Object family) {
+			return family == FAMILY;
+		}
+
+		/* (non-Javadoc)
+		 * @see org.eclipse.core.runtime.jobs.Job#shouldRun()
+		 */
+		public boolean shouldRun() {
+			return isCacheDirty();
+		}
+
+		/* (non-Javadoc)
+		 * @see org.eclipse.core.runtime.jobs.Job#run(IProgressMonitor)
+		 */
+		public IStatus run(IProgressMonitor monitor) {
+			progressMonitor= new ProgressMonitorMultiWrapper(monitor);
+			progressMonitor.beginTask(TypeInfoMessages.getString("TypeCacherJob.taskName"), 100); //$NON-NLS-1$
+
+			SubProgressMonitor subMonitor= new SubProgressMonitor(progressMonitor, 100);
+			TypeSearchResultCollector collector= new TypeSearchResultCollector(subMonitor);
+
+			IWorkspace workspace= CCorePlugin.getWorkspace();
+			ICSearchScope scope= SearchEngine.createWorkspaceScope();
+			SearchEngine engine= new SearchEngine();
+			
+			ICSearchPattern pattern= createSearchPattern();
+			try {
+				flushCache();
+				// start the search engine
+				engine.search(workspace, pattern, scope, collector, true);
+				if (progressMonitor.isCanceled())
+					throw new InterruptedException();
+				progressMonitor.done();
+			} catch(InterruptedException ex) {
+				return Status.CANCEL_STATUS;
+			} finally {
+				progressMonitor= null;
+			}
+
+			Set searchResults= collector.getSearchResults();
+
+			if (searchResults != null) {
+				TypeInfo[] result= (TypeInfo[]) searchResults.toArray(new TypeInfo[searchResults.size()]);
+				Arrays.sort(result, TYPE_COMPARATOR);
+				setCache(result);
+			}
+			else {
+				TypeInfo[] result= new TypeInfo[0];
+				setCache(result);
+			}
+			return Status.OK_STATUS;
+		}
+
+		/*
+		 * creates a search pattern based on the cache types
+		 */
+		private ICSearchPattern createSearchPattern() {
+			OrPattern pattern= new OrPattern();
+			int[] types= getCacheTypes();
+			for (int i= 0; i < types.length; ++i) {
+				switch (types[i]) {
+					case ICElement.C_NAMESPACE:
+						pattern.addPattern(SearchEngine.createSearchPattern("*", ICSearchConstants.NAMESPACE, ICSearchConstants.DECLARATIONS, false));
+					break;
+
+					case ICElement.C_CLASS: // fall through
+					case ICElement.C_TEMPLATE_CLASS:
+						pattern.addPattern(SearchEngine.createSearchPattern("*", ICSearchConstants.CLASS, ICSearchConstants.DECLARATIONS, false));
+					break;
+					
+					case ICElement.C_STRUCT: // fall through
+					case ICElement.C_TEMPLATE_STRUCT:
+						pattern.addPattern(SearchEngine.createSearchPattern("*", ICSearchConstants.STRUCT, ICSearchConstants.DECLARATIONS, false));
+					break;
+
+					case ICElement.C_UNION: // fall through
+					case ICElement.C_TEMPLATE_UNION:
+						pattern.addPattern(SearchEngine.createSearchPattern("*", ICSearchConstants.UNION, ICSearchConstants.DECLARATIONS, false));
+					break;
+
+					case ICElement.C_ENUMERATION:
+						pattern.addPattern(SearchEngine.createSearchPattern("*", ICSearchConstants.ENUM, ICSearchConstants.DECLARATIONS, false));
+					break;
+
+					case ICElement.C_TYPEDEF:
+						pattern.addPattern(SearchEngine.createSearchPattern("*", ICSearchConstants.TYPEDEF, ICSearchConstants.DECLARATIONS, false));
+					break;
+					
+					default:
+					break;
+				}
+			}
+			return pattern;
+		}
+		
+		/**
+		 * Forwards progress info to the progress monitor and
+		 * blocks until the job is finished.
+		 * 
+		 * @param monitor Optional progress monitor.
+		 * @throws InterruptedException
+		 * 
+		 * @see Job#join
+		 */
+		public void join(IProgressMonitor monitor) throws InterruptedException {
+			if (progressMonitor != null)
+				progressMonitor.addProgressMonitor(monitor);
+			super.join();
+		}
+	}
+
+	/**
+	 * Listener for changes to CModel.
+	 * @see org.eclipse.cdt.core.model.IElementChangedListener
+	 * @since 3.0
+	 */
+	private static class TypeCacheDeltaListener implements IElementChangedListener {
+		/*
+		 * @see IElementChangedListener#elementChanged
+		 */
+		public void elementChanged(ElementChangedEvent event) {
+			//TODO optimization: calculate deltas per file and
+			// update the cache selectively
+			boolean needsFlushing= processDelta(event.getDelta());
+			if (needsFlushing) {
+				// mark cache as dirty and reschedule the
+				// background job
+				setCacheDirty();
+				if (fgJob.getState() == Job.RUNNING)
+					fgJob.cancel();
+				fgJob.setPriority(Job.BUILD);
+				fgJob.schedule();
+			}
+		}
+		
+		/*
+		 * returns true if the cache needs to be flushed
+		 */
+		private boolean processDelta(ICElementDelta delta) {
+			ICElement elem= delta.getElement();
+			int pathEntryChanged= ICElementDelta.F_ADDED_PATHENTRY_SOURCE | ICElementDelta.F_REMOVED_PATHENTRY_SOURCE |
+									ICElementDelta.F_CHANGED_PATHENTRY_INCLUDE | ICElementDelta.F_CHANGED_PATHENTRY_MACRO;
+			boolean isAddedOrRemoved= (delta.getKind() != ICElementDelta.CHANGED)
+			 || ((delta.getFlags() & pathEntryChanged) != 0);
+			
+			switch (elem.getElementType()) {
+				case ICElement.C_MODEL:
+				case ICElement.C_PROJECT:
+				case ICElement.C_CCONTAINER:
+				case ICElement.C_NAMESPACE:
+				case ICElement.C_TEMPLATE_CLASS:
+				case ICElement.C_CLASS:
+				case ICElement.C_STRUCT:
+				case ICElement.C_UNION:
+				case ICElement.C_ENUMERATION:
+				case ICElement.C_TYPEDEF:
+				case ICElement.C_INCLUDE:
+				case ICElement.C_UNIT:
+					if (isAddedOrRemoved) {
+						return true;
+					}				
+					return processChildrenDelta(delta);
+				default:
+					// fields, methods, imports ect
+					return false;
+			}	
+		}
+		
+		private boolean isPossibleStructuralChange(int flags) {
+			return (flags & (ICElementDelta.F_CONTENT | ICElementDelta.F_FINE_GRAINED)) == ICElementDelta.F_CONTENT;
+		}		
+		
+		private boolean processChildrenDelta(ICElementDelta delta) {
+			ICElementDelta[] children= delta.getAffectedChildren();
+			for (int i= 0; i < children.length; i++) {
+				if (processDelta(children[i])) {
+					return true;
+				}
+			}
+			return false;
+		}
+	}
+	
+	private static final int INITIAL_DELAY= 5000;
+	private static final TypeCacherJob fgJob= new TypeCacherJob();
+	private static final TypeCacheDeltaListener fgDeltaListener= new TypeCacheDeltaListener();
+	private static int[] fgCacheTypes= TypeInfo.getAllCElementTypes();
+	private static TypeInfo[] fgCacheData;
+	private static int fgNumberOfCacheFlushes;
+	private static boolean cacheIsDirty= true;
+	
+	/**
+	 * Initializes the AllTypesCache service.
+	 */
+	public static void initialize() {
+		// add delta listener
+		CoreModel.getDefault().addElementChangedListener(fgDeltaListener);
+
+		// schedule job to run after INITIAL_DELAY
+		if (fgJob.getState() != Job.RUNNING) {
+			fgJob.setPriority(Job.BUILD);
+			fgJob.schedule(INITIAL_DELAY);
+		}
+	}
+	
+	/**
+	 * Terminates the service provided by AllTypesCache.
+	 */
+	public static void terminate() {
+		// remove delta listener
+		CoreModel.getDefault().removeElementChangedListener(fgDeltaListener);
+		
+		// terminate background job
+		fgJob.cancel();
+	}
+
+	/*
+	 * Sets the cache contents.
+	 */
+	private static synchronized void setCache(TypeInfo[] cache) {
+		fgCacheData= cache;
+		cacheIsDirty= false;
+	}
+	
+	/*
+	 * Gets the cache contents.
+	 */
+	private static synchronized TypeInfo[] getCache() {
+		return fgCacheData;
+	}
+	
+	/*
+	 * Clears the cache.
+	 */
+	private static synchronized void flushCache() {
+		fgCacheData= null;
+		++fgNumberOfCacheFlushes;
+		cacheIsDirty= true;
+	}
+	
+	/*
+	 * Marks cache as dirty.
+	 */
+	private static synchronized void setCacheDirty() {
+		cacheIsDirty= true;
+	}
+
+	/*
+	 * Tests if cache is dirty.
+	 */
+	private static synchronized boolean isCacheDirty() {
+		return cacheIsDirty;
+	}
+
+	/*
+	 * Sets which types are stored in the cache.
+	 */
+	private static synchronized void setCacheTypes(int[] cElementTypes) {
+		fgCacheTypes= ArrayUtil.clone(cElementTypes);
+	}
+	
+	/*
+	 * Gets types stored in the cache.
+	 */
+	private static synchronized int[] getCacheTypes() {
+		return fgCacheTypes;
+	}
+
+	/**
+	 * Returns all types in the given scope, matching the given filter.
+	 * @param filter Filter for the type info.
+	 * @param monitor Progress monitor.
+	 * @param typesFound The resulting <code>TypeInfo</code> elements are added to this collection
+	 */		
+	public static void getTypes(ICSearchScope scope, ITypeInfoFilter filter, IProgressMonitor monitor, Collection typesFound) {
+		TypeInfo[] allTypes= getAllTypes(filter, monitor);
+		if (allTypes != null) {
+			boolean isWorkspaceScope= scope.equals(SearchEngine.createWorkspaceScope());
+			for (int i= 0; i < allTypes.length; i++) {
+				TypeInfo info= allTypes[i];
+				if (isWorkspaceScope || info.isEnclosed(scope)) {
+					if (filter.match(info))
+						typesFound.add(info);
+				}
+			}
+		}
+	}
+
+	/**
+	 * Returns all types in the workspace. The returned array must not be
+	 * modified. The elements in the array are sorted by simple type name.
+	 */
+	public static TypeInfo[] getAllTypes(ITypeInfoFilter filter, IProgressMonitor monitor) {
+
+		// check if requested types are in cache
+		if (!ArrayUtil.containsAll(getCacheTypes(), filter.getCElementTypes()))
+		{
+			// mark cache dirty and cancel the running job
+			setCacheDirty();
+			if (fgJob.getState() == Job.RUNNING)
+				fgJob.cancel();
+			setCacheTypes(filter.getCElementTypes());
+		}
+		
+		if (isCacheDirty()) {
+			// start job if not already running
+			if (fgJob.getState() != Job.RUNNING) {
+				// boost priority since action was user-initiated
+				fgJob.setPriority(Job.SHORT);
+				fgJob.schedule();
+			}
+
+			// wait for job to finish
+			try {
+				fgJob.join(monitor);
+				if (monitor != null)
+					monitor.done();
+			} catch (InterruptedException ex) {
+				return null;
+			}
+		}
+		return getCache();
+	}
+		
+	/**
+	 * Returns true if the type cache is up to date.
+	 */
+	public static boolean isCacheUpToDate(ITypeInfoFilter filter) {
+		// check if requested types are in cache
+		if (!ArrayUtil.containsAll(getCacheTypes(), filter.getCElementTypes()))
+			return false;
+		return !isCacheDirty();
+	}
+}
Index: browser/org/eclipse/cdt/ui/browser/typeinfo/ITypeInfo.java
===================================================================
RCS file: browser/org/eclipse/cdt/ui/browser/typeinfo/ITypeInfo.java
diff -N browser/org/eclipse/cdt/ui/browser/typeinfo/ITypeInfo.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ browser/org/eclipse/cdt/ui/browser/typeinfo/ITypeInfo.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (c) 2004 QNX Software Systems and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     QNX Software Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.ui.browser.typeinfo;
+
+import org.eclipse.cdt.core.model.ICElement;
+import org.eclipse.cdt.core.search.ICSearchScope;
+import org.eclipse.cdt.core.search.IMatch;
+
+/**
+ * Type information.
+ */
+public interface ITypeInfo extends IMatch {
+	
+	/**
+	 * Returns true if type is enclosed in the given scope
+	 */
+	public boolean isEnclosed(ICSearchScope scope);
+
+	/**
+	 * Returns true if the type is a low-level system type.
+	 * e.g. __FILE
+	 */
+	public boolean isSystemType();
+
+	/**
+	 * Gets the enclosing type names.
+	 */
+	public String[] getEnclosingNames();
+
+	/**
+	 * Gets the filename where this type is located.
+	 */
+	public String getFileName();
+	
+	/**
+	 * Gets the file path where this type is located.
+	 */
+	public String getFilePath();
+	
+	/**
+	 * Gets the extension of the file where this type is located.
+	 */
+	public String getFileExtension();
+	
+	/**
+	 * Gets the type qualified name: Includes enclosing type names, but
+	 * not filename. Identifiers are separated by colons.
+	 */
+	public String getQualifiedName();
+
+	/**
+	 * Gets the fully qualified type container name: Filename or
+	 * enclosing type name with filename.
+	 * All identifiers are separated by colons.
+	 */
+	public String getQualifiedParentName();
+	
+	/**
+	 * Gets the fully qualified type name: Includes enclosing type names and
+	 * filename. All identifiers are separated by colons.
+	 */
+	public String getFullyQualifiedName();
+	
+	/**
+	 * Gets the CElement which corresponds to this type.
+	 */
+	public ICElement getCElement();
+}
Index: browser/org/eclipse/cdt/ui/browser/typeinfo/ITypeInfoFilter.java
===================================================================
RCS file: browser/org/eclipse/cdt/ui/browser/typeinfo/ITypeInfoFilter.java
diff -N browser/org/eclipse/cdt/ui/browser/typeinfo/ITypeInfoFilter.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ browser/org/eclipse/cdt/ui/browser/typeinfo/ITypeInfoFilter.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2004 QNX Software Systems and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     QNX Software Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.ui.browser.typeinfo;
+
+/**
+ * Filter for type info.
+ */
+public interface ITypeInfoFilter {
+	
+	/**
+	 * Gets the C types handled by this filter.
+	 * 
+	 * @return An array of ICElement types.
+	 * 
+	 */
+	public int[] getCElementTypes();
+
+	/**
+	 * Matches type info against filter.
+	 * 
+	 * @param info The object to filter.
+	 * @return <code>true</code> if successful match.
+	 */
+	public boolean match(ITypeInfo info);
+	/**
+	 * Returns <code>true</code> if <code>info</code> matches the filter.
+	 */
+}
Index: browser/org/eclipse/cdt/ui/browser/typeinfo/TypeInfo.java
===================================================================
RCS file: browser/org/eclipse/cdt/ui/browser/typeinfo/TypeInfo.java
diff -N browser/org/eclipse/cdt/ui/browser/typeinfo/TypeInfo.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ browser/org/eclipse/cdt/ui/browser/typeinfo/TypeInfo.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,210 @@
+/*******************************************************************************
+ * Copyright (c) 2004 QNX Software Systems and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     QNX Software Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.ui.browser.typeinfo;
+
+import java.util.ArrayList;
+
+import org.eclipse.cdt.core.model.CoreModel;
+import org.eclipse.cdt.core.model.ICElement;
+import org.eclipse.cdt.core.model.IParent;
+import org.eclipse.cdt.core.search.BasicSearchMatch;
+import org.eclipse.cdt.core.search.ICSearchScope;
+import org.eclipse.cdt.internal.core.index.StringMatcher;
+import org.eclipse.cdt.internal.ui.browser.util.ArrayUtil;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+
+
+/**
+ * To change the template for this generated type comment go to
+ * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
+ */
+public class TypeInfo extends BasicSearchMatch implements ITypeInfo
+{
+	private final static int[] cElementTypes= {
+		ICElement.C_NAMESPACE,
+		ICElement.C_CLASS,
+		ICElement.C_TEMPLATE_CLASS,
+		ICElement.C_STRUCT,
+		ICElement.C_TEMPLATE_STRUCT,
+		ICElement.C_UNION,
+		ICElement.C_TEMPLATE_UNION,
+		ICElement.C_ENUMERATION,
+		ICElement.C_TYPEDEF
+	};
+
+	public static int[] getAllCElementTypes() {
+		return cElementTypes;
+	}
+
+	public static boolean isValidCElementType(int type) {
+		return ArrayUtil.contains(cElementTypes, type);
+	}
+
+	private final static String scopeResolutionOperator= "::"; //$NON-NLS-1$
+	private final static String fileScopeSeparator= " : "; //$NON-NLS-1$
+	private static final StringMatcher fSystemTypeMatcher= new StringMatcher("_*", true, false); //$NON-NLS-1$
+	
+	public TypeInfo() {
+		super();
+	}
+	
+	public boolean isEnclosed(ICSearchScope scope) {
+		return scope.encloses(getFilePath());
+	}
+	
+	public boolean isSystemType() {
+		// recognized low-level system types eg __FILE
+		String[] names= getEnclosingNames();
+		if (names != null) {
+			for (int i= 0; i < names.length; ++i) {
+				if (fSystemTypeMatcher.match(names[i]))
+					return true;
+			}
+		}
+		return fSystemTypeMatcher.match(getName());
+	}
+
+	public String getFileName() {
+		if (resource != null)
+			return resource.getName();
+		else if (path != null)
+			return path.lastSegment();
+		else
+			return null;
+	}
+
+	public String getFilePath() {
+		if (resource != null)
+			return resource.getFullPath().toString();
+		else if (path != null)
+			return path.toString();
+		else
+			return null;
+	}
+
+	public String getFileExtension() {
+		if (resource != null)
+			return resource.getFileExtension();
+		else if (path != null)
+			return path.getFileExtension();
+		else
+			return null;
+	}
+
+	public String getQualifiedParentName() {
+		StringBuffer buf= new StringBuffer();
+		String fileName = getFileName();
+		if (fileName != null && fileName.length() > 0)
+			buf.append(fileName);
+		String parentName = getParentName();
+		if (parentName != null && parentName.length() > 0) {
+			buf.append(fileScopeSeparator); //$NON-NLS-1$
+			buf.append(parentName);
+		}
+		return buf.toString();
+	}
+	
+	public String getFullyQualifiedName() {
+		StringBuffer buf= new StringBuffer();
+		String fileName = getFileName();
+		if (fileName != null && fileName.length() > 0)
+			buf.append(fileName);
+		String parentName = getParentName();
+		if (parentName != null && parentName.length() > 0) {
+			buf.append(fileScopeSeparator); //$NON-NLS-1$
+			buf.append(parentName);
+			buf.append(scopeResolutionOperator); //$NON-NLS-1$
+		}
+		String name = getName();
+		if (name != null && name.length() > 0)
+			buf.append(name);
+		return buf.toString();
+	}
+	
+	public String getQualifiedName() {
+		StringBuffer buf= new StringBuffer();
+		String parentName = getParentName();
+		if (parentName != null && parentName.length() > 0) {
+			buf.append(parentName);
+			buf.append(scopeResolutionOperator); //$NON-NLS-1$
+		}
+		String name = getName();
+		if (name != null && name.length() > 0)
+			buf.append(name);
+		return buf.toString();
+	}
+	
+	public String[] getEnclosingNames() {
+		//TODO pull up this method into BasicSearchMatch
+		//since it already has access to this info
+		String parentName= getParentName();
+		if (parentName == null)
+			return null;
+
+		ArrayList names= new ArrayList(5);
+		int lastIndex= 0;
+		String nextName;
+		int qualifierIndex= parentName.indexOf(scopeResolutionOperator, 0);
+		while (qualifierIndex >= 0) {
+			nextName= parentName.substring(lastIndex, qualifierIndex);
+			lastIndex= qualifierIndex + scopeResolutionOperator.length();
+			names.add(nextName);
+			qualifierIndex= parentName.indexOf(scopeResolutionOperator, lastIndex);
+		}
+		nextName= parentName.substring(lastIndex);
+		names.add(nextName);
+
+		return (String[]) names.toArray(new String[names.size()]);
+	}	
+
+	public String toString() {
+		return getFullyQualifiedName();
+	}
+	
+	private boolean matchesCType(ICElement celement, String name) {
+		if (isValidCElementType(celement.getElementType()))
+			return celement.getElementName().equals(name);
+		return false;
+	}
+	
+	private ICElement findCElement(ICElement celement, String name) {
+		if (matchesCType(celement, name))
+			return celement;
+		else if (celement instanceof IParent) {
+			ICElement[] children = ((IParent)celement).getChildren();
+			for (int i = 0; i < children.length; i++) {
+				if (matchesCType(children[i], name))
+					return children[i];
+			}
+		}
+		return null;
+	}
+	
+	public ICElement getCElement() {
+		if (resource != null && resource.getType() == IResource.FILE) {
+			ICElement parentElement= CoreModel.getDefault().create((IFile)resource);
+			if (parentElement instanceof IParent) {
+				String[] names= getEnclosingNames();
+				if (names != null) {
+					for (int i= 0; i < names.length; ++i) {
+						parentElement= findCElement(parentElement, names[i]);
+						if (parentElement == null)
+							break;
+					}
+				}
+				if (parentElement != null)
+					return findCElement(parentElement, getName());
+			}
+		}
+		return null;
+	}
+}
Index: browser/org/eclipse/cdt/ui/browser/typeinfo/TypeInfoFilter.java
===================================================================
RCS file: browser/org/eclipse/cdt/ui/browser/typeinfo/TypeInfoFilter.java
diff -N browser/org/eclipse/cdt/ui/browser/typeinfo/TypeInfoFilter.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ browser/org/eclipse/cdt/ui/browser/typeinfo/TypeInfoFilter.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2004 QNX Software Systems and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     QNX Software Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.ui.browser.typeinfo;
+
+import org.eclipse.cdt.internal.ui.browser.util.ArrayUtil;
+
+/**
+ * The default type filter.
+ */
+public class TypeInfoFilter implements ITypeInfoFilter {
+
+	public int[] getCElementTypes() {
+		return TypeInfo.getAllCElementTypes();
+	}
+	
+	public TypeInfoFilter() {
+	}
+
+	protected boolean hideSystemTypes() {
+		return true;
+	}
+
+	public boolean match(ITypeInfo info) {
+		// check if type is handled
+		if (!ArrayUtil.contains(getCElementTypes(), info.getElementType()))
+			return false;
+
+		// filter out low-level system types eg __FILE
+		//TODO make this a preferences option
+		if (hideSystemTypes() && info.isSystemType())
+			return false;
+
+		return true;
+	}
+}
Index: browser/org/eclipse/cdt/ui/browser/typeinfo/TypeInfoLabelProvider.java
===================================================================
RCS file: browser/org/eclipse/cdt/ui/browser/typeinfo/TypeInfoLabelProvider.java
diff -N browser/org/eclipse/cdt/ui/browser/typeinfo/TypeInfoLabelProvider.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ browser/org/eclipse/cdt/ui/browser/typeinfo/TypeInfoLabelProvider.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,162 @@
+/*******************************************************************************
+ * Copyright (c) 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     QNX Software Systems - adapted for use in CDT
+ *******************************************************************************/
+package org.eclipse.cdt.ui.browser.typeinfo;
+
+import org.eclipse.cdt.core.model.CoreModel;
+import org.eclipse.cdt.core.model.ICElement;
+import org.eclipse.cdt.internal.ui.CPluginImages;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.swt.graphics.Image;
+
+public class TypeInfoLabelProvider extends LabelProvider {
+
+	public static final int SHOW_FULLYQUALIFIED=	0x01;
+	public static final int SHOW_FILENAME_POSTFIX=	0x02;
+	public static final int SHOW_FILENAME_ONLY=		0x04;
+	public static final int SHOW_ROOT_POSTFIX=		0x08;
+	public static final int SHOW_TYPE_ONLY=			0x10;
+	public static final int SHOW_TYPE_CONTAINER_ONLY=	0x20;
+
+	private static final Image HEADER_ICON= CPluginImages.get(CPluginImages.IMG_OBJS_TUNIT_HEADER);
+	private static final Image SOURCE_ICON= CPluginImages.get(CPluginImages.IMG_OBJS_TUNIT);
+	private static final Image NAMESPACE_ICON= CPluginImages.get(CPluginImages.IMG_OBJS_CONTAINER);
+	private static final Image TEMPLATE_ICON= CPluginImages.get(CPluginImages.IMG_OBJS_TEMPLATE);
+	private static final Image CLASS_ICON= CPluginImages.get(CPluginImages.IMG_OBJS_CLASS);
+	private static final Image STRUCT_ICON= CPluginImages.get(CPluginImages.IMG_OBJS_STRUCT);
+	private static final Image TYPEDEF_ICON= CPluginImages.get(CPluginImages.IMG_OBJS_TYPEDEF);
+	private static final Image UNION_ICON= CPluginImages.get(CPluginImages.IMG_OBJS_UNION);
+	private static final Image ENUM_ICON= CPluginImages.get(CPluginImages.IMG_OBJS_ENUMERATION);
+
+	private int fFlags;
+	
+	public TypeInfoLabelProvider(int flags) {
+		fFlags= flags;
+	}	
+	
+	private boolean isSet(int flag) {
+		return (fFlags & flag) != 0;
+	}
+
+	/* non java-doc
+	 * @see ILabelProvider#getText
+	 */
+	public String getText(Object element) {
+		if (! (element instanceof ITypeInfo)) 
+			return super.getText(element);
+		
+		ITypeInfo typeRef= (ITypeInfo) element;
+		
+		StringBuffer buf= new StringBuffer();
+		if (isSet(SHOW_TYPE_ONLY)) {
+			String name= typeRef.getName();
+			if (name != null && name.length() > 0)
+				buf.append(name);
+		} else if (isSet(SHOW_TYPE_CONTAINER_ONLY)) {
+			String name= typeRef.getQualifiedParentName();
+			if (name != null && name.length() > 0)
+				buf.append(name);
+		} else if (isSet(SHOW_FILENAME_ONLY)) {
+			String name= typeRef.getFileName();
+			if (name != null && name.length() > 0)
+				buf.append(name);
+		} else {
+			if (isSet(SHOW_FULLYQUALIFIED)) {
+				String name= typeRef.getFullyQualifiedName();
+				if (name != null && name.length() > 0)
+					buf.append(name);
+			}
+			else {
+				String name= typeRef.getParentName();
+				if (name != null && name.length() > 0)
+					buf.append(name);
+			}
+		
+			if (isSet(SHOW_FILENAME_POSTFIX)) {
+				String name= typeRef.getFileName();
+				if (name != null && name.length() > 0) {
+					buf.append(TypeInfoMessages.getString("TypeInfoLabelProvider.dash")); //$NON-NLS-1$
+					buf.append(name);
+				}
+			}
+		}
+
+		if (isSet(SHOW_ROOT_POSTFIX)) {
+			String path= typeRef.getFilePath();
+			if (path != null && path.length() > 0) {
+				buf.append(TypeInfoMessages.getString("TypeInfoLabelProvider.dash"));//$NON-NLS-1$
+				buf.append(path);
+			}
+		}
+		return buf.toString();				
+	}
+	
+	private Image getFileIcon(ITypeInfo typeRef)
+	{
+		String ext = typeRef.getFileExtension();
+		if (ext != null) {	
+			String[] exts = CoreModel.getDefault().getHeaderExtensions();
+			for (int i = 0; i < exts.length; i++) {
+				if (exts[i].equalsIgnoreCase(ext)) {
+					return HEADER_ICON;
+				}
+			}
+		}
+		return SOURCE_ICON;
+	}
+	
+	private Image getIcon(ITypeInfo typeRef)
+	{
+		switch (typeRef.getElementType())
+		{
+		case ICElement.C_NAMESPACE:
+			return NAMESPACE_ICON;
+			
+		case ICElement.C_TEMPLATE_CLASS:
+			return TEMPLATE_ICON;
+
+		case ICElement.C_CLASS:
+			return CLASS_ICON;
+
+		case ICElement.C_STRUCT:
+			return STRUCT_ICON;
+
+		case ICElement.C_UNION:
+			return UNION_ICON;
+
+		case ICElement.C_ENUMERATION:
+			return ENUM_ICON;
+
+		case ICElement.C_TYPEDEF:
+			return TYPEDEF_ICON;
+
+		default:
+			return CLASS_ICON;
+		}
+	}
+
+	/* non java-doc
+	 * @see ILabelProvider#getImage
+	 */	
+	public Image getImage(Object element) {
+		if (!(element instanceof ITypeInfo)) 
+			return super.getImage(element);	
+
+		ITypeInfo typeRef= (ITypeInfo) element;
+		if (isSet(SHOW_TYPE_CONTAINER_ONLY)) {
+			return getFileIcon(typeRef);
+		} else if (isSet(SHOW_FILENAME_ONLY)) {
+			return getFileIcon(typeRef);
+		} else {
+			return getIcon(typeRef);
+		}
+	}
+}
Index: browser/org/eclipse/cdt/ui/browser/typeinfo/TypeInfoMessages.java
===================================================================
RCS file: browser/org/eclipse/cdt/ui/browser/typeinfo/TypeInfoMessages.java
diff -N browser/org/eclipse/cdt/ui/browser/typeinfo/TypeInfoMessages.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ browser/org/eclipse/cdt/ui/browser/typeinfo/TypeInfoMessages.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2004 QNX Software Systems and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     QNX Software Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.ui.browser.typeinfo;
+
+import java.text.MessageFormat;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class TypeInfoMessages {
+
+	private static final String RESOURCE_BUNDLE= TypeInfoMessages.class.getName();
+
+	private static ResourceBundle fgResourceBundle;
+	static {
+		try {
+			fgResourceBundle = ResourceBundle.getBundle(RESOURCE_BUNDLE);
+		} catch (MissingResourceException x) {
+			fgResourceBundle = null;
+		}
+	}
+
+	private TypeInfoMessages() {
+	}
+
+	public static String getString(String key) {
+		try {
+			return fgResourceBundle.getString(key);
+		} catch (MissingResourceException e) {
+			return '!' + key + '!';
+		} catch (NullPointerException e) {
+			return "#" + key + "#"; //$NON-NLS-1$ //$NON-NLS-2$
+		}
+	}
+	
+	public static String getFormattedString(String key, String arg) {
+		return getFormattedString(key, new String[] { arg });
+	}
+	
+	public static String getFormattedString(String key, String[] args) {
+		return MessageFormat.format(getString(key), args);	
+	}	
+}
Index: browser/org/eclipse/cdt/ui/browser/typeinfo/TypeInfoMessages.properties
===================================================================
RCS file: browser/org/eclipse/cdt/ui/browser/typeinfo/TypeInfoMessages.properties
diff -N browser/org/eclipse/cdt/ui/browser/typeinfo/TypeInfoMessages.properties
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ browser/org/eclipse/cdt/ui/browser/typeinfo/TypeInfoMessages.properties	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,19 @@
+###############################################################################
+# Copyright (c) 2004 QNX Software Systems Ltd. and others.
+# All rights reserved.   This program and the accompanying materials
+# are made available under the terms of the Common Public License v0.5
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/cpl-v05.html
+# 
+# Contributors: 
+# QNX Software Systems - Initial API and implementation
+###############################################################################
+
+TypeCacherJob.jobName=TypeCache
+TypeCacherJob.taskName=Updating Type Info...
+
+TypeSelectionDialog.lowerLabel=&Qualifier:
+TypeSelectionDialog.upperLabel=&Matching types:
+
+TypeInfoLabelProvider.default_filename=default
+TypeInfoLabelProvider.dash=\ - 
Index: browser/org/eclipse/cdt/ui/browser/typeinfo/TypeSelectionDialog.java
===================================================================
RCS file: browser/org/eclipse/cdt/ui/browser/typeinfo/TypeSelectionDialog.java
diff -N browser/org/eclipse/cdt/ui/browser/typeinfo/TypeSelectionDialog.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ browser/org/eclipse/cdt/ui/browser/typeinfo/TypeSelectionDialog.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,155 @@
+/*******************************************************************************
+ * Copyright (c) 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     QNX Software Systems - adapted for use in CDT
+ *******************************************************************************/
+package org.eclipse.cdt.ui.browser.typeinfo;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+
+import org.eclipse.cdt.internal.ui.util.StringMatcher;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.dialogs.FilteredList;
+import org.eclipse.ui.dialogs.TwoPaneElementSelector;
+
+
+/**
+ * A dialog to select a type from a list of types.
+ */
+public class TypeSelectionDialog extends TwoPaneElementSelector {
+
+	private static class TypeFilterMatcher implements FilteredList.FilterMatcher {
+
+		private static final char END_SYMBOL= '<';
+		private static final char ANY_STRING= '*';
+		private final static String scopeResolutionOperator= "::";
+
+		private StringMatcher fMatcher;
+		private StringMatcher fQualifierMatcher;
+		private StringMatcher fScopedQualifierMatcher;
+		
+		/*
+		 * @see FilteredList.FilterMatcher#setFilter(String, boolean)
+		 */
+		public void setFilter(String pattern, boolean ignoreCase, boolean ignoreWildCards) {
+			int qualifierIndex= pattern.lastIndexOf(scopeResolutionOperator); //$NON-NLS-1$
+
+			// type			
+			if (qualifierIndex == -1) {
+				fQualifierMatcher= null;
+				fScopedQualifierMatcher= null;
+				fMatcher= new StringMatcher(adjustPattern(pattern), ignoreCase, ignoreWildCards);
+				
+			// qualified type
+			} else {
+				String pattern1 = pattern.substring(0, qualifierIndex + scopeResolutionOperator.length());
+				fQualifierMatcher= new StringMatcher(adjustPattern(pattern1), ignoreCase, ignoreWildCards);
+				StringBuffer buf = new StringBuffer();
+				buf.append(ANY_STRING);
+				buf.append(scopeResolutionOperator);
+				buf.append(pattern1);
+				String pattern2= buf.toString();
+				fScopedQualifierMatcher= new StringMatcher(adjustPattern(pattern2), ignoreCase, ignoreWildCards);
+				String pattern3 = pattern.substring(qualifierIndex + scopeResolutionOperator.length());
+				fMatcher= new StringMatcher(adjustPattern(pattern3), ignoreCase, ignoreWildCards);
+			}
+		}
+
+		/*
+		 * @see FilteredList.FilterMatcher#match(Object)
+		 */
+		public boolean match(Object element) {
+			if (!(element instanceof ITypeInfo))
+				return false;
+
+			TypeInfo type= (TypeInfo) element;
+
+			if (!fMatcher.match(type.getName()))
+				return false;
+
+			if (fQualifierMatcher == null)
+				return true;
+			
+			if (fQualifierMatcher.match(type.getQualifiedName()))
+				return true;
+			else
+				return fScopedQualifierMatcher.match(type.getQualifiedName());
+		}
+		
+		private String adjustPattern(String pattern) {
+			int length= pattern.length();
+			if (length > 0) {
+				switch (pattern.charAt(length - 1)) {
+					case END_SYMBOL:
+						pattern= pattern.substring(0, length - 1);
+						break;
+					case ANY_STRING:
+						break;
+					default:
+						pattern= pattern + ANY_STRING;
+				}
+			}
+			return pattern;
+		}
+	}
+	
+	private static class StringComparator implements Comparator {
+	    public int compare(Object left, Object right) {
+	     	String leftString= (String) left;
+	     	String rightString= (String) right;
+	     	
+			int result= leftString.compareToIgnoreCase(rightString);			
+			if (result == 0)
+				result= leftString.compareTo(rightString);
+
+			return result;
+	    }
+	}
+	
+	/**
+	 * Constructs a type selection dialog.
+	 * @param parent  the parent shell.
+	 * @param context the runnable context.
+	 * @param scope   the C search scope.
+	 */
+	public TypeSelectionDialog(Shell parent) {
+		super(parent, new TypeInfoLabelProvider(TypeInfoLabelProvider.SHOW_TYPE_ONLY),
+			new TypeInfoLabelProvider(TypeInfoLabelProvider.SHOW_TYPE_CONTAINER_ONLY + TypeInfoLabelProvider.SHOW_ROOT_POSTFIX));
+		setUpperListLabel(TypeInfoMessages.getString("TypeSelectionDialog.upperLabel")); //$NON-NLS-1$
+		setLowerListLabel(TypeInfoMessages.getString("TypeSelectionDialog.lowerLabel")); //$NON-NLS-1$
+	}
+
+	/*
+	 * @see AbstractElementListSelectionDialog#createFilteredList(Composite)
+	 */
+ 	protected FilteredList createFilteredList(Composite parent) {
+ 		FilteredList list= super.createFilteredList(parent);
+ 		
+		fFilteredList.setFilterMatcher(new TypeFilterMatcher());
+		fFilteredList.setComparator(new StringComparator());
+		
+		return list;
+	}
+	
+	/*
+	 * @see org.eclipse.ui.dialogs.SelectionStatusDialog#computeResult()
+	 */
+	protected void computeResult() {
+		ITypeInfo selection= (ITypeInfo) getLowerSelectedElement();
+		if (selection == null)
+			return;
+			
+		List result= new ArrayList(1);
+		result.add(selection);
+		setResult(result);
+	}
+}

Back to the top