Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[cdt-patch] Open Type dialog

Hello all,

The following patch implements the "Open Type" dialog for C/C++ types (namespaces, classes, structs, unions, enums, typedefs). This mirrors the functionality of the JDT Open Type dialog, so you can select a type from the list and it will open in the editor.

cheers
-Chris

Index: plugin.properties
===================================================================
retrieving revision 1.28
diff -u -r1.28 plugin.properties
--- plugin.properties	1 Oct 2003 13:33:39 -0000	1.28
+++ plugin.properties	28 Jan 2004 20:05:03 -0000
@@ -93,4 +93,11 @@
 
 # Menus
 searchMenu.label= Se&arch
- 
+
+# Open Type
+OpenTypeAction.label= Open &Type...
+OpenTypeAction.tooltip= Open Type
+ActionDefinition.openType.name= Open Type
+ActionDefinition.openType.description= Open a type in a C editor
+
+ 
\ No newline at end of file
Index: plugin.xml
===================================================================
retrieving revision 1.58
diff -u -r1.58 plugin.xml
--- plugin.xml	5 Jan 2004 20:26:01 -0000	1.58
+++ plugin.xml	28 Jan 2004 20:05:04 -0000
@@ -414,6 +414,18 @@
             command="org.eclipse.cdt.ui.edit.opendecl"
             configuration="org.eclipse.ui.defaultAcceleratorConfiguration">
       </keyBinding>
+      <command
+            name="%ActionDefinition.openType.name"
+            description="%ActionDefinition.openType.description"
+            category="org.eclipse.cdt.ui.category.source"
+            id="org.eclipse.cdt.ui.navigate.opentype">
+      </command>
+      <keyBinding
+            string="Ctrl+Shift+T"
+            scope="org.eclipse.cdt.ui.cEditorScope"
+            command="org.eclipse.cdt.ui.navigate.opentype"
+            configuration="org.eclipse.ui.defaultAcceleratorConfiguration">
+      </keyBinding>
    </extension>
    <extension
          id="org.eclipse.cdt.ui.CSearchPage"
@@ -469,6 +481,17 @@
                class="org.eclipse.cdt.internal.ui.search.OpenCSearchPageAction"
                menubarPath="org.eclipse.search.menu/dialogGroup"
                id="org.eclipse.cdt.ui.actions.OpenCSearchPage">
+         </action>
+         <action
+               label="%OpenTypeAction.label"
+               icon="icons/full/opentype16/opentype.gif"
+               class="org.eclipse.cdt.internal.ui.opentype.OpenTypeAction"
+               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="*"
+               tooltip="%OpenTypeAction.tooltip">
          </action>
          <menu
                label="%searchMenu.label"
Index: icons/full/opentype16/opentype.gif
===================================================================
RCS file: icons/full/opentype16/opentype.gif
diff -N icons/full/opentype16/opentype.gif
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ icons/full/opentype16/opentype.gif	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,3 @@
+GIF89ağŸ?ŸŸ_¿_Ÿ  ¤?Ÿ????_?_Ÿ?¿_€€ÿÿŸ__?¿¿ß¿?¿Ÿ?ÿߟŸŸŸ___ÿÿÿ!ù,ià$Ždižè	C¥+ °Á[*Š ³FoØ	d1˜
+‰"qx)†?â1¹DÅbØ «Ä!%0Â0ÖBð¸œñÜ2ø<þ!ÉÚõz|"Ow€{}ƒ‹ŒŒˆ"
+’“”)–"!;
Index: src/org/eclipse/cdt/internal/ui/opentype/OpenTypeAction.java
===================================================================
RCS file: src/org/eclipse/cdt/internal/ui/opentype/OpenTypeAction.java
diff -N src/org/eclipse/cdt/internal/ui/opentype/OpenTypeAction.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/cdt/internal/ui/opentype/OpenTypeAction.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,96 @@
+/*******************************************************************************
+ * 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.search.SearchEngine;
+import org.eclipse.cdt.internal.ui.editor.CEditor;
+import org.eclipse.cdt.internal.ui.opentype.dialogs.*;
+import org.eclipse.cdt.internal.ui.util.EditorUtility;
+import org.eclipse.cdt.ui.CUIPlugin;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.dialogs.IDialogConstants;
+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;
+		
+		ICElement celement= (ICElement)dialog.getFirstResult();
+		if (celement != null) {
+			try {
+				IResource res= celement.getUnderlyingResource();
+				IEditorPart part= EditorUtility.openInEditor(res);
+				if (part instanceof CEditor) {
+					CEditor ed= (CEditor)part;
+					ed.setSelection(celement);
+				}
+			}
+			catch (CModelException ex){
+				ex.printStackTrace();
+			}
+			catch(PartInitException ex) {
+				ex.printStackTrace();
+			}
+		}
+	}
+
+	/* (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
===================================================================
RCS file: src/org/eclipse/cdt/internal/ui/opentype/OpenTypeMessages.java
diff -N src/org/eclipse/cdt/internal/ui/opentype/OpenTypeMessages.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/cdt/internal/ui/opentype/OpenTypeMessages.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * 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= ResourceBundle.getBundle(RESOURCE_BUNDLE);
+
+	private OpenTypeMessages() {
+	}
+
+	public static String getString(String key) {
+		try {
+			return fgResourceBundle.getString(key);
+		} catch (MissingResourceException e) {
+			return '!' + key + '!';
+		}
+	}
+	
+	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
===================================================================
RCS file: src/org/eclipse/cdt/internal/ui/opentype/OpenTypeMessages.properties
diff -N src/org/eclipse/cdt/internal/ui/opentype/OpenTypeMessages.properties
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/cdt/internal/ui/opentype/OpenTypeMessages.properties	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,41 @@
+###############################################################################
+# 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
+###############################################################################
+
+#########
+## 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=\ - 
+TypeInfoLabelProvider.colon=\ : 
Index: src/org/eclipse/cdt/internal/ui/opentype/TypeSearchMatch.java
===================================================================
RCS file: src/org/eclipse/cdt/internal/ui/opentype/TypeSearchMatch.java
diff -N src/org/eclipse/cdt/internal/ui/opentype/TypeSearchMatch.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/cdt/internal/ui/opentype/TypeSearchMatch.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,126 @@
+/*******************************************************************************
+ * 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();
+		return "";
+	}
+
+	public String getFilePath() {
+		if (resource != null)
+			return resource.getFullPath().toString();
+		return "";
+	}
+
+	public String getFileExtension() {
+		if (resource != null)
+			return resource.getFileExtension();
+		return "";
+	}
+
+	public String getQualifiedParentName() {
+		StringBuffer buf= new StringBuffer();
+		if (getFileName().length() > 0)
+			buf.append(getFileName());
+		if (getParentName().length() > 0) {
+			buf.append(OpenTypeMessages.getString("TypeInfoLabelProvider.colon")); //$NON-NLS-1$
+			buf.append(getParentName());
+		}
+		return buf.toString();
+	}
+	
+	public String getFullyQualifiedName() {
+		StringBuffer buf= new StringBuffer();
+		if (getFilePath().length() > 0)
+			buf.append(getFilePath());
+		if (getParentName().length() > 0) {
+			buf.append(OpenTypeMessages.getString("TypeInfoLabelProvider.colon")); //$NON-NLS-1$
+			buf.append(getParentName());
+			buf.append("::");
+		}
+		buf.append(getName());
+		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("::");
+					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
===================================================================
RCS file: src/org/eclipse/cdt/internal/ui/opentype/TypeSearchMatchLabelProvider.java
diff -N src/org/eclipse/cdt/internal/ui/opentype/TypeSearchMatchLabelProvider.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/cdt/internal/ui/opentype/TypeSearchMatchLabelProvider.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,145 @@
+/*******************************************************************************
+ * 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)) {
+			buf.append(typeRef.getName());
+		} else if (isSet(SHOW_TYPE_CONTAINER_ONLY)) {
+			buf.append(typeRef.getQualifiedParentName());
+		} else if (isSet(SHOW_FILENAME_ONLY)) {
+			buf.append(typeRef.getFileName());
+		} else {
+			if (isSet(SHOW_FULLYQUALIFIED))
+				buf.append(typeRef.getFullyQualifiedName());
+			else
+				buf.append(typeRef.getParentName());
+		
+			if (isSet(SHOW_FILENAME_POSTFIX)) {
+				buf.append(OpenTypeMessages.getString("TypeInfoLabelProvider.dash")); //$NON-NLS-1$
+				buf.append(typeRef.getFileName());
+			}
+		}
+
+		if (isSet(SHOW_ROOT_POSTFIX)) {
+			buf.append(OpenTypeMessages.getString("TypeInfoLabelProvider.dash"));//$NON-NLS-1$
+			buf.append(typeRef.getFilePath());
+		}
+		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
===================================================================
RCS file: src/org/eclipse/cdt/internal/ui/opentype/TypeSearchOperation.java
diff -N src/org/eclipse/cdt/internal/ui/opentype/TypeSearchOperation.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/cdt/internal/ui/opentype/TypeSearchOperation.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * 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.SearchEngine;
+import org.eclipse.cdt.internal.core.search.matching.OrPattern;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.runtime.IProgressMonitor;
+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));
+		pattern.addPattern(SearchEngine.createSearchPattern("*", ICSearchConstants.NAMESPACE, ICSearchConstants.DECLARATIONS, false));
+		pattern.addPattern(SearchEngine.createSearchPattern("*", ICSearchConstants.CLASS, ICSearchConstants.DECLARATIONS, false));
+		pattern.addPattern(SearchEngine.createSearchPattern("*", ICSearchConstants.STRUCT, ICSearchConstants.DECLARATIONS, false));
+		pattern.addPattern(SearchEngine.createSearchPattern("*", ICSearchConstants.CLASS_STRUCT, ICSearchConstants.DECLARATIONS, false));
+		pattern.addPattern(SearchEngine.createSearchPattern("*", ICSearchConstants.UNION, ICSearchConstants.DECLARATIONS, false));
+		pattern.addPattern(SearchEngine.createSearchPattern("*", ICSearchConstants.ENUM, ICSearchConstants.DECLARATIONS, false));
+		pattern.addPattern(SearchEngine.createSearchPattern("*", ICSearchConstants.TYPEDEF, ICSearchConstants.DECLARATIONS, false));
+	}
+	
+	public void run(IProgressMonitor monitor) throws InterruptedException {
+		collector.setProgressMonitor(monitor);
+		engine.search(workspace, pattern, scope, collector, true);
+		if (monitor.isCanceled()) {
+			throw new InterruptedException();
+		}
+	}
+
+	public Object[] getResults() {
+		return collector.getSearchResults().toArray();
+	}
+}
Index: src/org/eclipse/cdt/internal/ui/opentype/TypeSearchResultCollector.java
===================================================================
RCS file: src/org/eclipse/cdt/internal/ui/opentype/TypeSearchResultCollector.java
diff -N src/org/eclipse/cdt/internal/ui/opentype/TypeSearchResultCollector.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/cdt/internal/ui/opentype/TypeSearchResultCollector.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * 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 ) throws CoreException 
+	{
+		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
===================================================================
RCS file: src/org/eclipse/cdt/internal/ui/opentype/dialogs/OpenTypeSelectionDialog.java
diff -N src/org/eclipse/cdt/internal/ui/opentype/dialogs/OpenTypeSelectionDialog.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/cdt/internal/ui/opentype/dialogs/OpenTypeSelectionDialog.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,156 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 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
===================================================================
RCS file: src/org/eclipse/cdt/internal/ui/opentype/dialogs/TypeSelectionDialog.java
diff -N src/org/eclipse/cdt/internal/ui/opentype/dialogs/TypeSelectionDialog.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/cdt/internal/ui/opentype/dialogs/TypeSelectionDialog.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,218 @@
+/*******************************************************************************
+ * 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.model.ICElement;
+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.TypeSearchMatchLabelProvider;
+import org.eclipse.cdt.internal.ui.opentype.TypeSearchMatch;
+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;
+
+		// get the corresponding CElement
+		ICElement celement= selection.getCElement();
+		if (celement != null) {
+			List result= new ArrayList(1);
+			result.add(celement);
+			setResult(result);
+		}
+		else {
+			// could not find definition
+			String title= OpenTypeMessages.getString("TypeSelectionDialog.errorTitle"); //$NON-NLS-1$
+			String message= OpenTypeMessages.getFormattedString("TypeSelectionDialog.dialogMessage", selection.getFilePath()); //$NON-NLS-1$
+			MessageDialog.openError(getShell(), title, message);
+			setResult(null);
+		}
+	}
+}

Back to the top