From ccfe7d8f5fb16ffce595bc26621d085f534ba238 Mon Sep 17 00:00:00 2001 From: Alain Magloire Date: Wed, 26 May 2004 14:49:48 +0000 Subject: [PATCH] 2004-05-26 Alain Magloire Jumbo Patch from Chris Wiebe. Putting a starting skeleton for C Browsing. --- core/org.eclipse.cdt.core/ChangeLog | 5 + .../cdt/core/browser/AllTypesCache.java | 52 +- .../eclipse/cdt/core/browser/ITypeInfo.java | 114 +- .../cdt/core/browser/ITypeInfoVisitor.java | 5 +- .../eclipse/cdt/core/browser/TypeInfo.java | 150 +- .../cdt/core/browser/UnknownTypeInfo.java | 32 + .../core/browser/cache/ITypeCache.java | 35 + .../core/browser/cache/IndexerTypesJob.java | 10 +- .../core/browser/cache/TypeCache.java | 321 +++- .../cache/TypeCacheMessages.properties | 2 + .../core/browser/cache/TypeParser.java | 20 +- core/org.eclipse.cdt.ui/ChangeLog | 5 + .../AppearanceAwareLabelProvider.java | 99 + .../cbrowsing/CBrowsingContentProvider.java | 103 + .../browser/cbrowsing/CBrowsingMessages.java | 47 + .../cbrowsing/CBrowsingMessages.properties | 3 + .../ui/browser/cbrowsing/CBrowsingPart.java | 1685 +++++++++++++++++ .../CBrowsingPerspectiveFactory.java | 212 +++ .../browser/cbrowsing/CUILabelProvider.java | 247 +++ .../cbrowsing/DecoratingCLabelProvider.java | 59 + .../ui/browser/cbrowsing/FilterUpdater.java | 57 + .../cbrowsing/LexicalSortingAction.java | 61 + .../ui/browser/cbrowsing/MembersView.java | 239 +++ .../cbrowsing/MembersViewContentProvider.java | 193 ++ .../ui/browser/cbrowsing/NamespacesView.java | 156 ++ .../NamespacesViewContentProvider.java | 187 ++ .../browser/cbrowsing/OpenProjectAction.java | 218 +++ .../cbrowsing/ProblemsLabelDecorator.java | 371 ++++ .../browser/cbrowsing/ProjectActionGroup.java | 109 ++ .../ui/browser/cbrowsing/ProjectsView.java | 194 ++ .../ProjectsViewContentProvider.java | 175 ++ .../browser/cbrowsing/StatusBarUpdater.java | 92 + .../cbrowsing/StorageLabelProvider.java | 129 ++ .../browser/cbrowsing/TypeInfoComparator.java | 86 + .../ui/browser/cbrowsing/TypeInfoSorter.java | 61 + .../ui/browser/cbrowsing/TypesView.java | 166 ++ .../cbrowsing/TypesViewContentProvider.java | 129 ++ .../typeinfo/TypeInfoLabelProvider.java | 5 +- .../browser/typeinfo/TypeSelectionDialog.java | 81 +- .../icons/full/cview16/cbrowsing_pers.gif | Bin 0 -> 200 bytes .../icons/full/eview16/cbrowsing_pers.gif | Bin 0 -> 200 bytes .../icons/full/eview16/cprojects.gif | Bin 0 -> 366 bytes .../icons/full/eview16/members.gif | Bin 0 -> 345 bytes .../icons/full/eview16/namespaces.gif | Bin 0 -> 361 bytes .../icons/full/eview16/types.gif | Bin 0 -> 365 bytes core/org.eclipse.cdt.ui/plugin.properties | 10 + core/org.eclipse.cdt.ui/plugin.xml | 61 +- .../cdt/internal/corext/util/CModelUtil.java | 37 + .../cdt/internal/ui/ICHelpContextIds.java | 21 +- .../internal/ui/search/CElementLabels.java | 140 +- .../internal/ui/util/ProblemTableViewer.java | 136 ++ .../ui/util/ResourceToItemsMapper.java | 205 ++ .../viewsupport/IViewPartInputProvider.java | 25 + .../ui/viewsupport/ImageImageDescriptor.java | 53 + .../ui/workingsets/ClearWorkingSetAction.java | 44 + .../ui/workingsets/EditWorkingSetAction.java | 73 + .../workingsets/SelectWorkingSetAction.java | 67 + .../ui/workingsets/WorkingSetComparator.java | 37 + .../ui/workingsets/WorkingSetFilter.java | 207 ++ .../WorkingSetFilterActionGroup.java | 256 +++ .../WorkingSetMenuContributionItem.java | 96 + .../src/org/eclipse/cdt/ui/CUIPlugin.java | 61 + .../eclipse/cdt/ui/PreferenceConstants.java | 68 + .../cdt/ui/wizards/NewClassWizardPage.java | 6 +- 64 files changed, 7308 insertions(+), 210 deletions(-) create mode 100644 core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/UnknownTypeInfo.java create mode 100644 core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/AppearanceAwareLabelProvider.java create mode 100644 core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/CBrowsingContentProvider.java create mode 100644 core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/CBrowsingMessages.java create mode 100644 core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/CBrowsingPart.java create mode 100644 core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/CBrowsingPerspectiveFactory.java create mode 100644 core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/CUILabelProvider.java create mode 100644 core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/DecoratingCLabelProvider.java create mode 100644 core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/FilterUpdater.java create mode 100644 core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/LexicalSortingAction.java create mode 100644 core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/MembersView.java create mode 100644 core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/MembersViewContentProvider.java create mode 100644 core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/NamespacesView.java create mode 100644 core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/NamespacesViewContentProvider.java create mode 100644 core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/OpenProjectAction.java create mode 100644 core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/ProblemsLabelDecorator.java create mode 100644 core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/ProjectActionGroup.java create mode 100644 core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/ProjectsView.java create mode 100644 core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/ProjectsViewContentProvider.java create mode 100644 core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/StatusBarUpdater.java create mode 100644 core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/StorageLabelProvider.java create mode 100644 core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/TypeInfoComparator.java create mode 100644 core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/TypeInfoSorter.java create mode 100644 core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/TypesView.java create mode 100644 core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/TypesViewContentProvider.java create mode 100644 core/org.eclipse.cdt.ui/icons/full/cview16/cbrowsing_pers.gif create mode 100644 core/org.eclipse.cdt.ui/icons/full/eview16/cbrowsing_pers.gif create mode 100644 core/org.eclipse.cdt.ui/icons/full/eview16/cprojects.gif create mode 100644 core/org.eclipse.cdt.ui/icons/full/eview16/members.gif create mode 100644 core/org.eclipse.cdt.ui/icons/full/eview16/namespaces.gif create mode 100644 core/org.eclipse.cdt.ui/icons/full/eview16/types.gif create mode 100644 core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/ProblemTableViewer.java create mode 100644 core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/ResourceToItemsMapper.java create mode 100644 core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/IViewPartInputProvider.java create mode 100644 core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/ImageImageDescriptor.java create mode 100644 core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/workingsets/ClearWorkingSetAction.java create mode 100644 core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/workingsets/EditWorkingSetAction.java create mode 100644 core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/workingsets/SelectWorkingSetAction.java create mode 100644 core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/workingsets/WorkingSetComparator.java create mode 100644 core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/workingsets/WorkingSetFilter.java create mode 100644 core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/workingsets/WorkingSetFilterActionGroup.java create mode 100644 core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/workingsets/WorkingSetMenuContributionItem.java diff --git a/core/org.eclipse.cdt.core/ChangeLog b/core/org.eclipse.cdt.core/ChangeLog index 0d095c1caa2..276eb59703e 100644 --- a/core/org.eclipse.cdt.core/ChangeLog +++ b/core/org.eclipse.cdt.core/ChangeLog @@ -1,3 +1,8 @@ +2004-05-26 Alain Magloire + + Jumbo Patch from Chris Wiebe. + Putting a starting skeleton for C Browsing. + 2004-05-25 Alain Magloire Update the necessary classes to use the new ResolverModel. diff --git a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/AllTypesCache.java b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/AllTypesCache.java index d46d8a025e3..2ba97fc17ff 100644 --- a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/AllTypesCache.java +++ b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/AllTypesCache.java @@ -17,8 +17,10 @@ import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.model.CModelException; 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.IElementChangedListener; import org.eclipse.cdt.core.model.IWorkingCopy; +import org.eclipse.cdt.internal.core.browser.cache.ITypeCache; import org.eclipse.cdt.internal.core.browser.cache.TypeCacheMessages; import org.eclipse.cdt.internal.core.browser.cache.TypeCacheManager; import org.eclipse.cdt.internal.core.browser.util.ArrayUtil; @@ -130,9 +132,11 @@ public class AllTypesCache { TypeSearchScope workspaceScope = new TypeSearchScope(true); IProject[] projects = workspaceScope.getEnclosingProjects(); ITypeInfoVisitor visitor = new ITypeInfoVisitor() { - public void visit(ITypeInfo info) { + public boolean visit(ITypeInfo info) { fAllTypes.add(info); + return true; } + public boolean shouldContinue() { return true; } }; for (int i = 0; i < projects.length; ++i) { fgTypeCacheManager.getCache(projects[i]).accept(visitor); @@ -153,11 +157,14 @@ public class AllTypesCache { final int[] fKinds = kinds; IProject[] projects = scope.getEnclosingProjects(); ITypeInfoVisitor visitor = new ITypeInfoVisitor() { - public void visit(ITypeInfo info) { - if (info.isEnclosed(fScope) && ArrayUtil.contains(fKinds, info.getCElementType())) { + public boolean visit(ITypeInfo info) { + if (ArrayUtil.contains(fKinds, info.getCElementType()) + && (fScope != null && info.isEnclosed(fScope))) { fTypesFound.add(info); } + return true; } + public boolean shouldContinue() { return true; } }; for (int i = 0; i < projects.length; ++i) { fgTypeCacheManager.getCache(projects[i]).accept(visitor); @@ -180,18 +187,51 @@ public class AllTypesCache { final IQualifiedTypeName fQualifiedName = qualifiedName; IProject[] projects = scope.getEnclosingProjects(); ITypeInfoVisitor visitor = new ITypeInfoVisitor() { - public void visit(ITypeInfo info) { - if ((fScope != null && info.isEnclosed(fScope)) && fQualifiedName.equals(info.getQualifiedTypeName()) - && ArrayUtil.contains(fKinds, info.getCElementType())) { + public boolean visit(ITypeInfo info) { + if (ArrayUtil.contains(fKinds, info.getCElementType()) + && fQualifiedName.equals(info.getQualifiedTypeName()) + && (fScope != null && info.isEnclosed(fScope))) { fTypesFound.add(info); } + return true; } + public boolean shouldContinue() { return true; } }; for (int i = 0; i < projects.length; ++i) { fgTypeCacheManager.getCache(projects[i]).accept(visitor); } return (ITypeInfo[]) fTypesFound.toArray(new ITypeInfo[fTypesFound.size()]); } + + /** + * Returns all namespaces in the given scope. + * + * @param scope The search scope + * @param includeGlobalNamespace true if the global (default) namespace should be returned + */ + public static ITypeInfo[] getNamespaces(ITypeSearchScope scope, boolean includeGlobalNamespace) { + final Collection fTypesFound = new ArrayList(); + final ITypeSearchScope fScope = scope; + IProject[] projects = scope.getEnclosingProjects(); + ITypeInfoVisitor visitor = new ITypeInfoVisitor() { + public boolean visit(ITypeInfo info) { + if (info.getCElementType() == ICElement.C_NAMESPACE + && (fScope != null && info.isEnclosed(fScope))) { + fTypesFound.add(info); + } + return true; + } + public boolean shouldContinue() { return true; } + }; + for (int i = 0; i < projects.length; ++i) { + ITypeCache cache = fgTypeCacheManager.getCache(projects[i]); + cache.accept(visitor); + if (includeGlobalNamespace) { + fTypesFound.add(cache.getGlobalNamespace()); + } + } + return (ITypeInfo[]) fTypesFound.toArray(new ITypeInfo[fTypesFound.size()]); + } /** * Returns true if the type cache is up to date. diff --git a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/ITypeInfo.java b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/ITypeInfo.java index 84519f65cc9..6943508b7ce 100644 --- a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/ITypeInfo.java +++ b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/ITypeInfo.java @@ -10,34 +10,31 @@ *******************************************************************************/ package org.eclipse.cdt.core.browser; +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.internal.core.browser.cache.ITypeCache; import org.eclipse.core.resources.IProject; /** * Type information. */ -public interface ITypeInfo { +public interface ITypeInfo extends Comparable { + public static final int KNOWN_TYPES[] = { + ICElement.C_NAMESPACE, + ICElement.C_CLASS, + ICElement.C_STRUCT, + ICElement.C_UNION, + ICElement.C_ENUMERATION, + ICElement.C_TYPEDEF + }; + /** * Gets the CElement type. + * @return ICElement.C_NAMESPACE, C_CLASS, C_STRUCT, C_UNION, C_ENUMERATION, or C_TYPEDEF, + * or zero if unknown type. */ public int getCElementType(); - /** - * Sets the CElement type. - */ - public void setCElementType(int type); - - /** - * Returns true if the element type is unknown. - */ - public boolean isUndefinedType(); - - /** - * Returns true if this type can enclose other types, - * i.e. it is a namespace, class, or struct. - */ - public boolean isQualifierType(); - /** * Gets the type name. */ @@ -49,10 +46,73 @@ public interface ITypeInfo { public IQualifiedTypeName getQualifiedTypeName(); /** - * Gets the enclosing type. + * Returns true if the type exists. + */ + public boolean exists(); + + /** + * Returns true if the element type is unknown. + */ + public boolean isUndefinedType(); + + /** + * Returns true if this type is enclosed by other types, + * i.e. declared an inside another namespace or class. + */ + public boolean isEnclosedType(); + + /** Gets the enclosing type, i.e. the outer class or namespace which contains this type. + * @return the enclosing type, or null if not found. */ public ITypeInfo getEnclosingType(); + + /** Gets the first enclosing type which matches one of the given kinds. + * @param kinds Array containing CElement types: C_NAMESPACE, C_CLASS, C_STRUCT + * @return the enclosing type, or null if not found. + */ + public ITypeInfo getEnclosingType(int[] kinds); + + /** Gets the root namespace, i.e. the outermost namespace + * which contains this type. + * @param includeGlobalNamespace true if the global (default) namespace should be returned + * @return the namespace, or null if not found. + */ + public ITypeInfo getRootNamespace(boolean includeGlobalNamespace); + /** + * Returns true if this type is capable of enclosing other types, + * i.e. it is a namespace, class, or struct. + */ + public boolean isEnclosingType(); + + /** + * Returns true if this type encloses other types, i.e. contains + * inner classes or namespaces. + */ + public boolean hasEnclosedTypes(); + + /** + * Returns true if this type encloses the given type. + */ + public boolean encloses(ITypeInfo info); + + /** + * Returns true if this type is enclosed by the given type. + */ + public boolean isEnclosed(ITypeInfo info); + + /** Gets the enclosed types, i.e. inner classes or classes inside this namespace. + * @return array of inner types, or empty array if not found. + */ + public ITypeInfo[] getEnclosedTypes(); + + /** Gets the enclosed types, i.e. inner classes or classes inside this namespace. + * @param kinds Array containing CElement types: C_NAMESPACE, C_CLASS, C_STRUCT, + * C_UNION, C_ENUMERATION, C_TYPEDEF + * @return array of inner types, or empty array if not found. + */ + public ITypeInfo[] getEnclosedTypes(int kinds[]); + /** * Gets the enclosing project. */ @@ -68,13 +128,23 @@ public interface ITypeInfo { */ public void addReference(ITypeReference location); - /** - * Returns all known source references. + /** Gets the originating locations where this type was declared. + * @return all known source references, or an empty + * array if none found. */ public ITypeReference[] getReferences(); - /** - * Returns parsed source location with offset and length. + /** Gets the real location where type was declared. + * @return the parsed source reference (with offset and length), + * or null if not found. */ public ITypeReference getResolvedReference(); + + /** + * Returns true if the type can be substituted. + */ + public boolean canSubstituteFor(ITypeInfo info); + + public ITypeCache getCache(); + public void setCache(ITypeCache typeCache); } diff --git a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/ITypeInfoVisitor.java b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/ITypeInfoVisitor.java index 39769d2dff8..87dfaa9a3fd 100644 --- a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/ITypeInfoVisitor.java +++ b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/ITypeInfoVisitor.java @@ -11,5 +11,8 @@ package org.eclipse.cdt.core.browser; public interface ITypeInfoVisitor { - public void visit(ITypeInfo info); + + public boolean visit(ITypeInfo info); + + public boolean shouldContinue(); } diff --git a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/TypeInfo.java b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/TypeInfo.java index 47581b047ea..0c0783fc1c9 100644 --- a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/TypeInfo.java +++ b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/TypeInfo.java @@ -16,19 +16,20 @@ import java.util.Set; import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.internal.core.browser.cache.ITypeCache; +import org.eclipse.cdt.internal.core.browser.util.ArrayUtil; import org.eclipse.core.resources.IProject; -public class TypeInfo implements ITypeInfo, Comparable +public class TypeInfo implements ITypeInfo { - private ITypeCache fTypeCache; - private int fElementType; - private QualifiedTypeName fQualifiedName; - private Set fSourceRefs = new HashSet(); + protected ITypeCache fTypeCache; + protected int fElementType; + protected QualifiedTypeName fQualifiedName; + protected Set fSourceRefs = new HashSet(); + protected final static ITypeInfo[] EMPTY_TYPES = new ITypeInfo[0]; - public TypeInfo(int elementType, IQualifiedTypeName typeName, ITypeCache typeCache) { + public TypeInfo(int elementType, IQualifiedTypeName typeName) { fElementType = elementType; fQualifiedName = new QualifiedTypeName(typeName); - fTypeCache = typeCache; } public void addReference(ITypeReference location) { @@ -57,10 +58,28 @@ public class TypeInfo implements ITypeInfo, Comparable return fElementType == 0; } - public boolean isQualifierType() { - return (fElementType == ICElement.C_NAMESPACE - || fElementType == ICElement.C_CLASS - || fElementType == ICElement.C_STRUCT); + public boolean canSubstituteFor(ITypeInfo info) { + return isExactMatch(info); + } + + protected boolean isExactMatch(ITypeInfo info) { + if (hashCode() != info.hashCode()) + return false; + if (fElementType == info.getCElementType() + && fQualifiedName.equals(info.getQualifiedTypeName())) { + IProject project1 = getEnclosingProject(); + IProject project2 = info.getEnclosingProject(); + if (project1 == null && project2 == null) + return true; + if (project1 == null || project2 == null) + return false; + return project1.equals(project2); + } + return false; + } + + public boolean exists() { + return fTypeCache != null; } public int getCElementType() { @@ -79,33 +98,68 @@ public class TypeInfo implements ITypeInfo, Comparable return fQualifiedName.getName(); } - public ITypeInfo getEnclosingType() { - ITypeInfo enclosingType = null; + public boolean isEnclosedType() { + return (fQualifiedName.getEnclosingNames() != null); + } + + public ITypeInfo getEnclosingType(int kinds[]) { if (fTypeCache != null) { - IQualifiedTypeName parentName = fQualifiedName.getEnclosingTypeName(); - if (parentName != null) { - ITypeInfo[] types = fTypeCache.getTypes(parentName); - for (int i = 0; i < types.length; ++i) { - ITypeInfo info = types[i]; - if (info.isQualifierType()) { - enclosingType = info; - break; - } else if (info.isUndefinedType()) { - enclosingType = info; - // don't break, in case we can still find a defined type - } - } - } + return fTypeCache.getEnclosingType(this, kinds); } - return enclosingType; + return null; + } + + public ITypeInfo getEnclosingType() { + return getEnclosingType(KNOWN_TYPES); } + public ITypeInfo getRootNamespace(boolean includeGlobalNamespace) { + if (fTypeCache != null) { + return fTypeCache.getRootNamespace(this, true); + } + return null; + } + + public boolean isEnclosingType() { + return (fElementType == ICElement.C_NAMESPACE + || fElementType == ICElement.C_CLASS + || fElementType == ICElement.C_STRUCT); + } + + public boolean encloses(ITypeInfo info) { + if (isEnclosingType() && fTypeCache == info.getCache()) { + return fQualifiedName.isPrefixOf(info.getQualifiedTypeName()); + } + return false; + } + + public boolean isEnclosed(ITypeInfo info) { + return info.encloses(this); + } + + public boolean hasEnclosedTypes() { + if (isEnclosingType() && fTypeCache != null) { + return fTypeCache.hasEnclosedTypes(this); + } + return false; + } + + public ITypeInfo[] getEnclosedTypes() { + return getEnclosedTypes(KNOWN_TYPES); + } + + public ITypeInfo[] getEnclosedTypes(int kinds[]) { + if (fTypeCache != null) { + return fTypeCache.getEnclosedTypes(this, kinds); + } + return EMPTY_TYPES; + } + public IProject getEnclosingProject() { if (fTypeCache != null) { return fTypeCache.getProject(); - } else { - return null; } + return null; } public String toString() { @@ -141,20 +195,7 @@ public class TypeInfo implements ITypeInfo, Comparable if (!(obj instanceof TypeInfo)) { return false; } - ITypeInfo info= (TypeInfo)obj; - if (hashCode() != info.hashCode()) - return false; - if (fElementType == info.getCElementType() - && fQualifiedName.equals(info.getQualifiedTypeName())) { - IProject project1 = getEnclosingProject(); - IProject project2 = info.getEnclosingProject(); - if (project1 == null && project2 == null) - return true; - if (project1 == null || project2 == null) - return false; - return project1.equals(project2); - } - return false; + return isExactMatch((TypeInfo)obj); } public int compareTo(Object obj) { @@ -171,17 +212,14 @@ public class TypeInfo implements ITypeInfo, Comparable } public static boolean isValidType(int type) { - switch (type) { - case ICElement.C_NAMESPACE: - case ICElement.C_CLASS: - case ICElement.C_STRUCT: - case ICElement.C_UNION: - case ICElement.C_ENUMERATION: - case ICElement.C_TYPEDEF: - return true; - - default: - return false; - } + return ArrayUtil.contains(KNOWN_TYPES, type); + } + + public ITypeCache getCache() { + return fTypeCache; + } + + public void setCache(ITypeCache typeCache) { + fTypeCache = typeCache; } } diff --git a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/UnknownTypeInfo.java b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/UnknownTypeInfo.java new file mode 100644 index 00000000000..71e6fd68005 --- /dev/null +++ b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/core/browser/UnknownTypeInfo.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * 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.core.browser; + +public class UnknownTypeInfo extends TypeInfo { + + public UnknownTypeInfo(IQualifiedTypeName typeName) { + super(0, typeName); + } + + public boolean isUndefinedType() { + return true; + } + + public boolean canSubstituteFor(ITypeInfo info) { + if (fTypeCache == info.getCache()) { + int compareType = info.getCElementType(); + if (fElementType == 0 || compareType == 0 || fElementType == compareType) { + return fQualifiedName.equals(info.getQualifiedTypeName()); + } + } + return false; + } +} diff --git a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/ITypeCache.java b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/ITypeCache.java index 2a5a6f631f1..2f632033c6a 100644 --- a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/ITypeCache.java +++ b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/ITypeCache.java @@ -100,6 +100,40 @@ public interface ITypeCache extends ISchedulingRule { */ public ITypeInfo getType(int type, IQualifiedTypeName qualifiedName); + /** Gets the first enclosing type which matches one of the given kinds. + * + * @param info the given type + * @param kinds Array containing CElement types: C_NAMESPACE, C_CLASS, C_STRUCT + * + * @return the enclosing type, or null if not found. + */ + public ITypeInfo getEnclosingType(ITypeInfo info, int[] kinds); + + + /** Gets the root namespace of which encloses the given type. + * + * @param info the given type + * @param includeGlobalNamespace true if the global (default) namespace should be returned + * @return the enclosing namespace, or null if not found. + */ + public ITypeInfo getRootNamespace(ITypeInfo info, boolean includeGlobalNamespace); + + /** Returns whether any types are enclosed by the given type. + * + * @param info the given type + * @return true if the given type encloses other types. + */ + public boolean hasEnclosedTypes(ITypeInfo info); + + /** Gets the types which are enclosed by the given type. + * + * @param info the given type + * @param kinds Array containing CElement types: C_NAMESPACE, C_CLASS, + * C_UNION, C_ENUMERATION, C_TYPEDEF + * @return the enclosed types, or an empty array if not found. + */ + public ITypeInfo[] getEnclosedTypes(ITypeInfo info, int kinds[]); + /** Returns the project associated with this cache. * * @return the project @@ -120,4 +154,5 @@ public interface ITypeCache extends ISchedulingRule { public void locateType(ITypeInfo info, int priority, int delay); public ITypeReference locateTypeAndWait(ITypeInfo info, int priority, IProgressMonitor monitor); + public ITypeInfo getGlobalNamespace(); } diff --git a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/IndexerTypesJob.java b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/IndexerTypesJob.java index 33bdc1bc1b4..03002c1eb9f 100644 --- a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/IndexerTypesJob.java +++ b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/IndexerTypesJob.java @@ -148,12 +148,10 @@ public class IndexerTypesJob extends IndexerJob { if (info == null || info.isUndefinedType()) { int[] references = entry.getFileReferences(); if (references != null && references.length > 0) { - if (info == null) { - info = new TypeInfo(type, qualifiedName, fTypeCache); - fTypeCache.insert(info); - } else { - info.setCElementType(type); - } + // add new type to cache + info = new TypeInfo(type, qualifiedName); + fTypeCache.insert(info); + for (int i = 0; i < references.length; ++i) { if (monitor.isCanceled()) throw new InterruptedException(); diff --git a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/TypeCache.java b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/TypeCache.java index d36fd10e347..546fb504685 100644 --- a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/TypeCache.java +++ b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/TypeCache.java @@ -24,8 +24,11 @@ import org.eclipse.cdt.core.browser.ITypeInfoVisitor; import org.eclipse.cdt.core.browser.ITypeReference; import org.eclipse.cdt.core.browser.ITypeSearchScope; import org.eclipse.cdt.core.browser.IWorkingCopyProvider; +import org.eclipse.cdt.core.browser.QualifiedTypeName; import org.eclipse.cdt.core.browser.TypeInfo; import org.eclipse.cdt.core.browser.TypeSearchScope; +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.internal.core.browser.util.ArrayUtil; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; @@ -45,7 +48,8 @@ public class TypeCache implements ITypeCache { private final IProject fProject; private final IWorkingCopyProvider fWorkingCopyProvider; private final Collection fDeltas = new ArrayList(); - + private final ITypeInfo fGlobalNamespace; + private IJobChangeListener fJobChangeListener = new IJobChangeListener() { public void aboutToRun(IJobChangeEvent event) { } @@ -87,10 +91,128 @@ public class TypeCache implements ITypeCache { } }; + private static class GlobalNamespace implements IQualifiedTypeName { + + private static final String GLOBAL_NAMESPACE = TypeCacheMessages.getString("TypeCache.globalNamespace"); //$NON-NLS-1$ + + public GlobalNamespace() { + } + + public String getName() { + return GLOBAL_NAMESPACE; + } + + public String[] getEnclosingNames() { + return null; + } + + public String getFullyQualifiedName() { + return GLOBAL_NAMESPACE; + } + + public IQualifiedTypeName getEnclosingTypeName() { + return null; + } + + public boolean isEmpty() { + return false; + } + + public boolean isGlobal() { + return true; + } + + public int segmentCount() { + return 1; + } + + public String[] segments() { + return new String[] { GLOBAL_NAMESPACE }; + } + + public String segment(int index) { + if (index > 0) + return null; + return GLOBAL_NAMESPACE; + } + + public String lastSegment() { + return GLOBAL_NAMESPACE; + } + + public int matchingFirstSegments(IQualifiedTypeName typeName) { + return 1; + } + + public boolean isPrefixOf(IQualifiedTypeName typeName) { + return true; + } + + public IQualifiedTypeName append(String[] names) { + return new QualifiedTypeName(names); + } + + public IQualifiedTypeName append(IQualifiedTypeName typeName) { + return new QualifiedTypeName(typeName); + } + + public IQualifiedTypeName append(String qualifiedName) { + return new QualifiedTypeName(qualifiedName); + } + + public IQualifiedTypeName removeFirstSegments(int count) { + return new QualifiedTypeName(this); + } + + public IQualifiedTypeName removeLastSegments(int count) { + return new QualifiedTypeName(this); + } + + public boolean isLowLevel() { + return false; + } + + public boolean validate() { + return true; + } + + public int hashCode() { + return GLOBAL_NAMESPACE.hashCode(); + } + + public String toString() { + return getFullyQualifiedName(); + } + + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof IQualifiedTypeName)) { + return false; + } + IQualifiedTypeName typeName = (IQualifiedTypeName) obj; + return (typeName instanceof GlobalNamespace); + } + + public int compareTo(Object obj) { + if (obj == this) { + return 0; + } + if (!(obj instanceof IQualifiedTypeName)) { + throw new ClassCastException(); + } + IQualifiedTypeName typeName = (IQualifiedTypeName) obj; + return getFullyQualifiedName().compareTo(typeName.getFullyQualifiedName()); + } + } + public TypeCache(IProject project, IWorkingCopyProvider workingCopyProvider) { fProject = project; fWorkingCopyProvider = workingCopyProvider; fDeltas.add(new TypeCacheDelta(fProject)); + fGlobalNamespace = new TypeInfo(ICElement.C_NAMESPACE, new GlobalNamespace()); + fGlobalNamespace.setCache(this); } public boolean contains(ISchedulingRule rule) { @@ -121,20 +243,38 @@ public class TypeCache implements ITypeCache { return fTypeNameMap.isEmpty(); } - public synchronized void insert(ITypeInfo info) { + public synchronized void insert(ITypeInfo newType) { + // check if type already exists + Collection typeCollection = (Collection) fTypeNameMap.get(newType.getName()); + if (typeCollection != null) { + for (Iterator typeIter = typeCollection.iterator(); typeIter.hasNext(); ) { + ITypeInfo currType = (ITypeInfo) typeIter.next(); + if (currType.canSubstituteFor(newType)) { + // merge references into new type + ITypeReference[] refs = currType.getReferences(); + for (int i = 0; i < refs.length; ++i) { + newType.addReference(refs[i]); + } + // remove the old type + currType.setCache(null); + typeIter.remove(); + } + } + } + // check if enclosing types are already in cache - IQualifiedTypeName typeName = info.getQualifiedTypeName().getEnclosingTypeName(); - if (typeName != null) { - while (!typeName.isEmpty()) { + IQualifiedTypeName enclosingName = newType.getQualifiedTypeName().getEnclosingTypeName(); + if (enclosingName != null) { + while (!enclosingName.isEmpty()) { boolean foundType = false; - Collection typeCollection = (Collection) fTypeNameMap.get(typeName.getName()); - if (typeCollection == null) { - typeCollection = new HashSet(); - fTypeNameMap.put(typeName.getName(), typeCollection); + Collection enclosingCollection = (Collection) fTypeNameMap.get(enclosingName.getName()); + if (enclosingCollection == null) { + enclosingCollection = new HashSet(); + fTypeNameMap.put(enclosingName.getName(), enclosingCollection); } else { - for (Iterator typeIter = typeCollection.iterator(); typeIter.hasNext(); ) { + for (Iterator typeIter = enclosingCollection.iterator(); typeIter.hasNext(); ) { ITypeInfo curr = (ITypeInfo) typeIter.next(); - if (curr.getQualifiedTypeName().equals(typeName)) { + if (curr.getQualifiedTypeName().equals(enclosingName)) { foundType = true; break; } @@ -142,24 +282,27 @@ public class TypeCache implements ITypeCache { } if (!foundType) { // create a dummy type to take this place (type 0 == unknown) - ITypeInfo dummyType = new TypeInfo(0, typeName, this); - typeCollection.add(dummyType); + ITypeInfo dummyType = new TypeInfo(0, enclosingName); + enclosingCollection.add(dummyType); + dummyType.setCache(this); } - typeName = typeName.removeLastSegments(1); + enclosingName = enclosingName.removeLastSegments(1); } } - Collection typeCollection = (Collection) fTypeNameMap.get(info.getName()); + typeCollection = (Collection) fTypeNameMap.get(newType.getName()); if (typeCollection == null) { typeCollection = new HashSet(); - fTypeNameMap.put(info.getName(), typeCollection); + fTypeNameMap.put(newType.getName(), typeCollection); } - typeCollection.add(info); + typeCollection.add(newType); + newType.setCache(this); } public synchronized void remove(ITypeInfo info) { Collection typeCollection = (Collection) fTypeNameMap.get(info.getName()); if (typeCollection != null) { + info.setCache(null); typeCollection.remove(info); } } @@ -174,6 +317,7 @@ public class TypeCache implements ITypeCache { for (Iterator typeIter = typeCollection.iterator(); typeIter.hasNext(); ) { ITypeInfo info = (ITypeInfo) typeIter.next(); if (info.isEnclosed(scope)) { + info.setCache(null); typeIter.remove(); } } @@ -191,6 +335,13 @@ public class TypeCache implements ITypeCache { public synchronized void flushAll() { // flush the entire cache + accept(new ITypeInfoVisitor() { + public boolean visit(ITypeInfo info) { + info.setCache(null); + return true; + } + public boolean shouldContinue() { return true; } + }); fTypeNameMap.clear(); } @@ -200,40 +351,44 @@ public class TypeCache implements ITypeCache { Collection typeCollection = (Collection) entry.getValue(); for (Iterator typeIter = typeCollection.iterator(); typeIter.hasNext(); ) { ITypeInfo info = (ITypeInfo) typeIter.next(); + if (!visitor.shouldContinue()) + return; // stop visiting visitor.visit(info); } } } - public synchronized IPath[] getPaths(ITypeSearchScope scope) { - final Set fPathSet = new HashSet(); - final ITypeSearchScope fScope = scope; + public synchronized IPath[] getPaths(final ITypeSearchScope scope) { + final Set pathSet = new HashSet(); accept(new ITypeInfoVisitor() { - public void visit(ITypeInfo info) { - if (fScope == null || info.isEnclosed(fScope)) { + public boolean visit(ITypeInfo info) { + if (scope == null || info.isEnclosed(scope)) { ITypeReference[] refs = info.getReferences(); for (int i = 0; i < refs.length; ++i) { IPath path = refs[i].getPath(); - if (fScope == null || fScope.encloses(path)) - fPathSet.add(path); + if (scope == null || scope.encloses(path)) + pathSet.add(path); } } + return true; } + public boolean shouldContinue() { return true; } }); - return (IPath[]) fPathSet.toArray(new IPath[fPathSet.size()]); + return (IPath[]) pathSet.toArray(new IPath[pathSet.size()]); } - public synchronized ITypeInfo[] getTypes(ITypeSearchScope scope) { - final Collection fTypesFound = new ArrayList(); - final ITypeSearchScope fScope = scope; + public synchronized ITypeInfo[] getTypes(final ITypeSearchScope scope) { + final Collection results = new ArrayList(); accept(new ITypeInfoVisitor() { - public void visit(ITypeInfo info) { - if (fScope == null || info.isEnclosed(fScope)) { - fTypesFound.add(info); + public boolean visit(ITypeInfo info) { + if (scope == null || info.isEnclosed(scope)) { + results.add(info); } + return true; } + public boolean shouldContinue() { return true; } }); - return (ITypeInfo[]) fTypesFound.toArray(new ITypeInfo[fTypesFound.size()]); + return (ITypeInfo[]) results.toArray(new ITypeInfo[results.size()]); } public synchronized ITypeInfo[] getTypes(IQualifiedTypeName qualifiedName) { @@ -255,8 +410,8 @@ public class TypeCache implements ITypeCache { if (typeCollection != null) { for (Iterator typeIter = typeCollection.iterator(); typeIter.hasNext(); ) { ITypeInfo info = (ITypeInfo) typeIter.next(); - if (info.getQualifiedTypeName().equals(qualifiedName) - && (info.getCElementType() == type || info.getCElementType() == 0)) { + if ((info.getCElementType() == type || info.getCElementType() == 0) + && info.getQualifiedTypeName().equals(qualifiedName)) { return info; } } @@ -264,6 +419,104 @@ public class TypeCache implements ITypeCache { return null; } + public synchronized ITypeInfo getEnclosingType(ITypeInfo info, final int[] kinds) { + IQualifiedTypeName enclosingName = info.getQualifiedTypeName().getEnclosingTypeName(); + if (enclosingName != null) { + Collection typeCollection = (Collection) fTypeNameMap.get(enclosingName.getName()); + if (typeCollection != null) { + // try namespace, class, struct, then undefined + final int[] validKinds = {ICElement.C_NAMESPACE, ICElement.C_CLASS, ICElement.C_STRUCT, 0}; + for (int i = 0; i < validKinds.length; ++i) { + if (ArrayUtil.contains(kinds, validKinds[i])) { + for (Iterator typeIter = typeCollection.iterator(); typeIter.hasNext(); ) { + ITypeInfo type = (ITypeInfo) typeIter.next(); + if (type.getCElementType() == validKinds[i] + && type.getQualifiedTypeName().equals(enclosingName)) { + return type; + } + } + } + } + } + } + return null; + } + + public synchronized ITypeInfo getRootNamespace(ITypeInfo info, boolean includeGlobalNamespace) { + IQualifiedTypeName qualifiedName = info.getQualifiedTypeName(); + if (qualifiedName.isGlobal()) { + if (info.getCElementType() == ICElement.C_NAMESPACE) + return info; + if (includeGlobalNamespace) + return fGlobalNamespace; + return null; + } + String[] segments = qualifiedName.segments(); + String namespace = segments[0]; + Collection typeCollection = (Collection) fTypeNameMap.get(namespace); + if (typeCollection != null) { + // try namespace, then undefined + final int[] kinds = {ICElement.C_NAMESPACE, 0}; + for (int i = 0; i < kinds.length; ++i) { + for (Iterator typeIter = typeCollection.iterator(); typeIter.hasNext(); ) { + ITypeInfo type = (ITypeInfo) typeIter.next(); + if (type.getCElementType() == kinds[i] + && type.getQualifiedTypeName().isGlobal()) { + return type; + } + } + } + } + return null; + } + + public synchronized boolean hasEnclosedTypes(final ITypeInfo info) { + final IQualifiedTypeName parentName = info.getQualifiedTypeName(); + final boolean[] foundTypes = { false }; + accept(new ITypeInfoVisitor() { + public boolean visit(ITypeInfo type) { + if (type != info && parentName.isPrefixOf(type.getQualifiedTypeName())) { + foundTypes[0] = true; + } + return true; + } + public boolean shouldContinue() { + return !foundTypes[0]; + } + }); + return foundTypes[0]; + } + + public synchronized ITypeInfo[] getEnclosedTypes(final ITypeInfo enclosedBy, final int kinds[]) { + final IQualifiedTypeName parentName = enclosedBy.getQualifiedTypeName(); + final Collection results = new ArrayList(); + accept(new ITypeInfoVisitor() { + public boolean visit(ITypeInfo type) { + if (ArrayUtil.contains(kinds, type.getCElementType())) { + IQualifiedTypeName enclosingName = type.getQualifiedTypeName().getEnclosingTypeName(); + if (enclosedBy == fGlobalNamespace) { + if (enclosingName == null) { + results.add(type); + } else { +// // check if enclosing parent is namespace +// getRootNamespace(type); + } + } else if (parentName.equals(enclosingName)) { + results.add(type); + } + } + return true; + } + public boolean shouldContinue() { return true; } + }); + + return (ITypeInfo[]) results.toArray(new ITypeInfo[results.size()]); + } + + public ITypeInfo getGlobalNamespace() { + return fGlobalNamespace; + } + public boolean isUpToDate() { synchronized(fDeltas) { return fDeltas.isEmpty(); diff --git a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/TypeCacheMessages.properties b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/TypeCacheMessages.properties index bfdf6461efa..059511df834 100644 --- a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/TypeCacheMessages.properties +++ b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/TypeCacheMessages.properties @@ -17,3 +17,5 @@ TypeCacherJob.taskName=Updating Type Cache... TypeLocatorJob.jobName=Type Locator TypeLocatorJob.taskName=Searching for Type Declaration... + +TypeCache.globalNamespace=(global) diff --git a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/TypeParser.java b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/TypeParser.java index a2e50588490..a6e31a798a2 100644 --- a/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/TypeParser.java +++ b/core/org.eclipse.cdt.core/browser/org/eclipse/cdt/internal/core/browser/cache/TypeParser.java @@ -186,6 +186,9 @@ public class TypeParser implements ISourceElementRequestor { fScope = new TypeSearchScope(); ITypeReference[] refs = info.getReferences(); + if (refs == null || refs.length == 0) + return false; // no source references + fScope.add(refs[0].getPath(), false, null); // for (int i = 0; i < refs.length; ++i) { // ITypeReference location = refs[i]; @@ -420,15 +423,13 @@ public class TypeParser implements ISourceElementRequestor { IParser parser = ParserFactory.createParser(scanner, this, ParserMode.STRUCTURAL_PARSE, language, ParserUtil.getParserLogService()); parser.parse(); } catch (ParserFactoryError e) { - e.printStackTrace(); + CCorePlugin.log(e); } catch (ParseError e) { - e.printStackTrace(); + CCorePlugin.log(e); } catch (OperationCanceledException e) { throw new InterruptedException(); } catch (Exception e) { - e.printStackTrace(); - } catch (VirtualMachineError e) { - e.printStackTrace(); + CCorePlugin.log(e); } finally { fProgressMonitor = null; } @@ -671,12 +672,9 @@ public class TypeParser implements ISourceElementRequestor { QualifiedTypeName qualifiedName = new QualifiedTypeName(name, enclosingNames); ITypeInfo info = fTypeCache.getType(type, qualifiedName); if (info == null || info.isUndefinedType()) { - if (info == null) { - info = new TypeInfo(type, qualifiedName, fTypeCache); - fTypeCache.insert(info); - } else { - info.setCElementType(type); - } + // add new type to cache + info = new TypeInfo(type, qualifiedName); + fTypeCache.insert(info); TypeReference location; if (originalRef instanceof IWorkingCopy) { diff --git a/core/org.eclipse.cdt.ui/ChangeLog b/core/org.eclipse.cdt.ui/ChangeLog index bed54b1b9ec..1cc91783c42 100644 --- a/core/org.eclipse.cdt.ui/ChangeLog +++ b/core/org.eclipse.cdt.ui/ChangeLog @@ -1,3 +1,8 @@ +2004-05-26 Alain Magloire + + Jumbo Patch from Chris Wiebe. + Putting a starting skeleton for C Browsing. + 2004-05-26 Alain Magloire PR 61965 diff --git a/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/AppearanceAwareLabelProvider.java b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/AppearanceAwareLabelProvider.java new file mode 100644 index 00000000000..da124b7a2ef --- /dev/null +++ b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/AppearanceAwareLabelProvider.java @@ -0,0 +1,99 @@ +/******************************************************************************* + * 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 + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.browser.cbrowsing; + +import org.eclipse.cdt.internal.ui.CElementImageProvider; +import org.eclipse.cdt.internal.ui.search.CElementLabels; +import org.eclipse.cdt.ui.PreferenceConstants; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.jface.viewers.LabelProviderChangedEvent; + +/** + * JavaUILabelProvider that respects settings from the Appearance preference page. + * Triggers a viewer update when a preference changes. + */ +public class AppearanceAwareLabelProvider extends CUILabelProvider implements IPropertyChangeListener { + + public final static int DEFAULT_TEXTFLAGS= CElementLabels.ROOT_VARIABLE | CElementLabels.M_PARAMETER_TYPES | + CElementLabels.M_APP_RETURNTYPE | CElementLabels.REFERENCED_ROOT_POST_QUALIFIED; + public final static int DEFAULT_IMAGEFLAGS= CElementImageProvider.OVERLAY_ICONS; + + private int fTextFlagMask; + private int fImageFlagMask; + + /** + * Constructor for AppearanceAwareLabelProvider. + */ + public AppearanceAwareLabelProvider(int textFlags, int imageFlags) { + super(textFlags, imageFlags); + initMasks(); + PreferenceConstants.getPreferenceStore().addPropertyChangeListener(this); + } + + /** + * Creates a labelProvider with DEFAULT_TEXTFLAGS and DEFAULT_IMAGEFLAGS + */ + public AppearanceAwareLabelProvider() { + this(DEFAULT_TEXTFLAGS, DEFAULT_IMAGEFLAGS); + } + + private void initMasks() { + IPreferenceStore store= PreferenceConstants.getPreferenceStore(); + fTextFlagMask= -1; +// if (!store.getBoolean(PreferenceConstants.APPEARANCE_METHOD_RETURNTYPE)) { +// fTextFlagMask ^= CElementLabels.M_APP_RETURNTYPE; +// } +// if (!store.getBoolean(PreferenceConstants.APPEARANCE_COMPRESS_PACKAGE_NAMES)) { +// fTextFlagMask ^= CElementLabels.P_COMPRESSED; +// } + + fImageFlagMask= -1; + } + + /* + * @see IPropertyChangeListener#propertyChange(PropertyChangeEvent) + */ + public void propertyChange(PropertyChangeEvent event) { + String property= event.getProperty(); +// if (property.equals(PreferenceConstants.APPEARANCE_METHOD_RETURNTYPE) +// || property.equals(PreferenceConstants.APPEARANCE_PKG_NAME_PATTERN_FOR_PKG_VIEW) +// || property.equals(PreferenceConstants.APPEARANCE_COMPRESS_PACKAGE_NAMES)) { +// initMasks(); +// LabelProviderChangedEvent lpEvent= new LabelProviderChangedEvent(this, null); // refresh all +// fireLabelProviderChanged(lpEvent); +// } + } + + /* + * @see IBaseLabelProvider#dispose() + */ + public void dispose() { + PreferenceConstants.getPreferenceStore().removePropertyChangeListener(this); + super.dispose(); + } + + /* + * @see JavaUILabelProvider#evaluateImageFlags() + */ + protected int evaluateImageFlags(Object element) { + return getImageFlags() & fImageFlagMask; + } + + /* + * @see JavaUILabelProvider#evaluateTextFlags() + */ + protected int evaluateTextFlags(Object element) { + return getTextFlags() & fTextFlagMask; + } + +} diff --git a/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/CBrowsingContentProvider.java b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/CBrowsingContentProvider.java new file mode 100644 index 00000000000..2f97bd9f5a3 --- /dev/null +++ b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/CBrowsingContentProvider.java @@ -0,0 +1,103 @@ +/******************************************************************************* + * 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 + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.browser.cbrowsing; + +import java.util.Collection; + +import org.eclipse.cdt.core.model.CoreModel; +import org.eclipse.cdt.core.model.ElementChangedEvent; +import org.eclipse.cdt.core.model.IElementChangedListener; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.StructuredViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; + +public abstract class CBrowsingContentProvider implements ITreeContentProvider, IElementChangedListener { + + protected StructuredViewer fViewer; + protected Object fInput; + protected CBrowsingPart fBrowsingPart; + protected int fReadsInDisplayThread; + protected static final Object[] NO_CHILDREN = new Object[0]; + + public CBrowsingContentProvider(CBrowsingPart browsingPart) { + fBrowsingPart= browsingPart; + fViewer= fBrowsingPart.getViewer(); + CoreModel.getDefault().addElementChangedListener(this); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object) + */ + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + if (newInput instanceof Collection) { + // Get a template object from the collection + Collection col = (Collection) newInput; + if (!col.isEmpty()) + newInput = col.iterator().next(); + else + newInput = null; + } + fInput = newInput; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.IContentProvider#dispose() + */ + public void dispose() { + CoreModel.getDefault().removeElementChangedListener(this); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.model.IElementChangedListener#elementChanged(org.eclipse.cdt.core.model.ElementChangedEvent) + */ + public void elementChanged(ElementChangedEvent event) { +// TODO listen for cache updates +// try { +// processDelta(event.getDelta()); +// } catch(CModelException e) { +// CUIPlugin.getDefault().log(e.getStatus()); +// } + } + + + protected void startReadInDisplayThread() { + if (isDisplayThread()) + fReadsInDisplayThread++; + } + + protected void finishedReadInDisplayThread() { + if (isDisplayThread()) + fReadsInDisplayThread--; + } + + private boolean isDisplayThread() { + Control ctrl= fViewer.getControl(); + if (ctrl == null) + return false; + + Display currentDisplay= Display.getCurrent(); + return currentDisplay != null && currentDisplay.equals(ctrl.getDisplay()); + } + + /** + * Note: This method is for internal use only. Clients should not call this method. + */ + protected static Object[] concatenate(Object[] a1, Object[] a2) { + int a1Len = a1.length; + int a2Len = a2.length; + Object[] res = new Object[a1Len + a2Len]; + System.arraycopy(a1, 0, res, 0, a1Len); + System.arraycopy(a2, 0, res, a1Len, a2Len); + return res; + } +} diff --git a/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/CBrowsingMessages.java b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/CBrowsingMessages.java new file mode 100644 index 00000000000..1a71e67ddd3 --- /dev/null +++ b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/CBrowsingMessages.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * 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 + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.browser.cbrowsing; + +import java.text.MessageFormat; +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +public class CBrowsingMessages { + + private static final String RESOURCE_BUNDLE= CBrowsingMessages.class.getName(); + + private static ResourceBundle fgResourceBundle= ResourceBundle.getBundle(RESOURCE_BUNDLE); + + private CBrowsingMessages() { + } + + public static String getString(String key) { + try { + return fgResourceBundle.getString(key); + } catch (MissingResourceException e) { + return "!" + key + "!";//$NON-NLS-2$ //$NON-NLS-1$ + } + } + /** + * Gets a string from the resource bundle and formats it with the argument + * + * @param key the string used to get the bundle value, must not be null + */ + public static String getFormattedString(String key, Object[] args) { + String format= null; + try { + format= fgResourceBundle.getString(key); + } catch (MissingResourceException e) { + return "!" + key + "!";//$NON-NLS-2$ //$NON-NLS-1$ + } + return MessageFormat.format(format, args); + } +} diff --git a/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/CBrowsingMessages.properties b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/CBrowsingMessages.properties index fb3e25c0d9c..e9fe8baee02 100644 --- a/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/CBrowsingMessages.properties +++ b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/CBrowsingMessages.properties @@ -23,3 +23,6 @@ ClassesView.LayoutActionGroup.layout.label= &Layout # the first argument is the string to which the second one is appended StatusBar.concat= {0}, {1} + +ClassPathContainer.unbound_label={0} (unbound) +ClassPathContainer.unknown_label={0} (unknown) diff --git a/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/CBrowsingPart.java b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/CBrowsingPart.java new file mode 100644 index 00000000000..7686d25971e --- /dev/null +++ b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/CBrowsingPart.java @@ -0,0 +1,1685 @@ +/******************************************************************************* + * 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 + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.browser.cbrowsing; + +import java.lang.reflect.InvocationTargetException; +import java.util.Collection; +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.cdt.core.browser.AllTypesCache; +import org.eclipse.cdt.core.browser.ITypeInfo; +import org.eclipse.cdt.core.browser.ITypeReference; +import org.eclipse.cdt.core.browser.TypeSearchScope; +import org.eclipse.cdt.core.model.CModelException; +import org.eclipse.cdt.core.model.CoreModel; +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.core.model.ICModel; +import org.eclipse.cdt.core.model.ICProject; +import org.eclipse.cdt.core.model.ISourceRoot; +import org.eclipse.cdt.core.model.ITranslationUnit; +import org.eclipse.cdt.core.resources.FileStorage; +import org.eclipse.cdt.internal.ui.browser.opentype.OpenTypeMessages; +import org.eclipse.cdt.internal.ui.editor.CEditor; +import org.eclipse.cdt.internal.ui.search.CElementLabels; +import org.eclipse.cdt.internal.ui.util.EditorUtility; +import org.eclipse.cdt.internal.ui.util.ExceptionHandler; +import org.eclipse.cdt.internal.ui.util.ProblemTableViewer; +import org.eclipse.cdt.internal.ui.viewsupport.IViewPartInputProvider; +import org.eclipse.cdt.internal.ui.workingsets.WorkingSetFilterActionGroup; +import org.eclipse.cdt.ui.CElementLabelProvider; +import org.eclipse.cdt.ui.CUIPlugin; +import org.eclipse.cdt.ui.IWorkingCopyManager; +import org.eclipse.cdt.ui.PreferenceConstants; +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IStorage; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jface.action.IMenuListener; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.IStatusLineManager; +import org.eclipse.jface.action.IToolBarManager; +import org.eclipse.jface.action.MenuManager; +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.text.ITextSelection; +import org.eclipse.jface.util.Assert; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.jface.viewers.IContentProvider; +import org.eclipse.jface.viewers.ILabelProvider; +import org.eclipse.jface.viewers.IOpenListener; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.OpenEvent; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.StructuredViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.KeyAdapter; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IActionBars; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IFileEditorInput; +import org.eclipse.ui.IMemento; +import org.eclipse.ui.IPartListener2; +import org.eclipse.ui.ISelectionListener; +import org.eclipse.ui.IViewSite; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchPartReference; +import org.eclipse.ui.IWorkbenchPartSite; +import org.eclipse.ui.IWorkingSet; +import org.eclipse.ui.IWorkingSetManager; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.part.IShowInSource; +import org.eclipse.ui.part.ShowInContext; +import org.eclipse.ui.part.ViewPart; +import org.eclipse.ui.texteditor.ITextEditor; + +public abstract class CBrowsingPart extends ViewPart implements IMenuListener, ISelectionListener, IViewPartInputProvider { + + private static final String TAG_SELECTED_ELEMENTS= "selectedElements"; //$NON-NLS-1$ + private static final String TAG_SELECTED_ELEMENT= "selectedElement"; //$NON-NLS-1$ + private static final String TAG_LOGICAL_PACKAGE= "logicalPackage"; //$NON-NLS-1$ + private static final String TAG_SELECTED_ELEMENT_PATH= "selectedElementPath"; //$NON-NLS-1$ + + private LabelProvider fLabelProvider; + private ILabelProvider fTitleProvider; + private StructuredViewer fViewer; + private IMemento fMemento; + private TypeInfoComparator fTypeComparator; + + // Actions + private WorkingSetFilterActionGroup fWorkingSetFilterActionGroup; + private boolean fHasWorkingSetFilter= true; + private boolean fHasCustomFilter= true; +// private OpenEditorActionGroup fOpenEditorGroup; +// private CCPActionGroup fCCPActionGroup; +// private BuildActionGroup fBuildActionGroup; +// private ToggleLinkingAction fToggleLinkingAction; +// protected CompositeActionGroup fActionGroups; + + +// // Filters +// private CustomFiltersActionGroup fCustomFiltersActionGroup; + + protected IWorkbenchPart fPreviousSelectionProvider; + protected Object fPreviousSelectedElement; + + // Linking + private boolean fLinkingEnabled; + + /* + * Ensure selection changed events being processed only if + * initiated by user interaction with this part. + */ + private boolean fProcessSelectionEvents= true; + + private IPartListener2 fPartListener= new IPartListener2() { + public void partActivated(IWorkbenchPartReference ref) { + setSelectionFromEditor(ref); + } + public void partBroughtToTop(IWorkbenchPartReference ref) { + setSelectionFromEditor(ref); + } + public void partInputChanged(IWorkbenchPartReference ref) { + setSelectionFromEditor(ref); + } + public void partClosed(IWorkbenchPartReference ref) { + } + public void partDeactivated(IWorkbenchPartReference ref) { + } + public void partOpened(IWorkbenchPartReference ref) { + } + public void partVisible(IWorkbenchPartReference ref) { + if (ref != null && ref.getId() == getSite().getId()){ + fProcessSelectionEvents= true; + IWorkbenchPage page= getSite().getWorkbenchWindow().getActivePage(); + if (page != null) + selectionChanged(page.getActivePart(), page.getSelection()); + } + } + public void partHidden(IWorkbenchPartReference ref) { + if (ref != null && ref.getId() == getSite().getId()) + fProcessSelectionEvents= false; + } + }; + + public CBrowsingPart() { + super(); + initLinkingEnabled(); + } + + /* + * Implements method from IViewPart. + */ + public void init(IViewSite site, IMemento memento) throws PartInitException { + super.init(site, memento); + fMemento= memento; + } + + /* + * Implements method from IViewPart. + */ + public void saveState(IMemento memento) { + if (fViewer == null) { + // part has not been created + if (fMemento != null) //Keep the old state; + memento.putMemento(fMemento); + return; + } + if (fHasWorkingSetFilter) + fWorkingSetFilterActionGroup.saveState(memento); +// if (fHasCustomFilter) +// fCustomFiltersActionGroup.saveState(memento); + saveSelectionState(memento); + saveLinkingEnabled(memento); + } + + private void saveLinkingEnabled(IMemento memento) { + memento.putInteger(getLinkToEditorKey(), fLinkingEnabled ? 1 : 0); + } + + private void saveSelectionState(IMemento memento) { +/* Object elements[]= ((IStructuredSelection) fViewer.getSelection()).toArray(); + if (elements.length > 0) { + IMemento selectionMem= memento.createChild(TAG_SELECTED_ELEMENTS); + for (int i= 0; i < elements.length; i++) { + IMemento elementMem= selectionMem.createChild(TAG_SELECTED_ELEMENT); + Object o= elements[i]; + if (o instanceof ICElement) + elementMem.putString(TAG_SELECTED_ELEMENT_PATH, ((ICElement) elements[i]).getHandleIdentifier()); + else if (o instanceof LogicalPackage) { + IPackageFragment[] packages=((LogicalPackage)o).getFragments(); + for (int j= 0; j < packages.length; j++) { + IMemento packageMem= elementMem.createChild(TAG_LOGICAL_PACKAGE); + packageMem.putString(TAG_SELECTED_ELEMENT_PATH, packages[j].getHandleIdentifier()); + } + } + } + } +*/ + } + + protected void restoreState(IMemento memento) { + if (fHasWorkingSetFilter) + fWorkingSetFilterActionGroup.restoreState(memento); +// if (fHasCustomFilter) +// fCustomFiltersActionGroup.restoreState(memento); + + if (fHasCustomFilter || fHasWorkingSetFilter) { + fViewer.getControl().setRedraw(false); + fViewer.refresh(); + fViewer.getControl().setRedraw(true); + } + } + + private ISelection restoreSelectionState(IMemento memento) { +/* + if (memento == null) + return null; + + IMemento childMem; + childMem= memento.getChild(TAG_SELECTED_ELEMENTS); + if (childMem != null) { + ArrayList list= new ArrayList(); + IMemento[] elementMem= childMem.getChildren(TAG_SELECTED_ELEMENT); + for (int i= 0; i < elementMem.length; i++) { + String javaElementHandle= elementMem[i].getString(TAG_SELECTED_ELEMENT_PATH); + if (javaElementHandle == null) { + // logical package + IMemento[] packagesMem= elementMem[i].getChildren(TAG_LOGICAL_PACKAGE); + LogicalPackage lp= null; + for (int j= 0; j < packagesMem.length; j++) { + javaElementHandle= packagesMem[j].getString(TAG_SELECTED_ELEMENT_PATH); + Object pack= (IPackageFragment)JavaCore.create(javaElementHandle); + if (pack instanceof IPackageFragment && ((IPackageFragment)pack).exists()) { + if (lp == null) + lp= new LogicalPackage((IPackageFragment)pack); + else + lp.add((IPackageFragment)pack); + } + } + if (lp != null) + list.add(lp); + } else { + ICElement element= JavaCore.create(javaElementHandle); + if (element != null && element.exists()) + list.add(element); + } + } + return new StructuredSelection(list); + } +*/ + return null; + } + + private void restoreLinkingEnabled(IMemento memento) { + Integer val= memento.getInteger(getLinkToEditorKey()); + if (val != null) { + fLinkingEnabled= val.intValue() != 0; + } + } + + /** + * Creates the search list inner viewer. + */ + public void createPartControl(Composite parent) { + Assert.isTrue(fViewer == null); + + + fTypeComparator= new TypeInfoComparator(); + + // Setup viewer + fViewer= createViewer(parent); + + initDragAndDrop(); + + fLabelProvider= createLabelProvider(); + fViewer.setLabelProvider(fLabelProvider); + + fViewer.setSorter(createTypeInfoSorter()); + fViewer.setUseHashlookup(true); + fTitleProvider= createTitleProvider(); + + createContextMenu(); + getSite().setSelectionProvider(fViewer); + + if (fMemento != null) { // initialize linking state before creating the actions + restoreLinkingEnabled(fMemento); + } + + createActions(); // call before registering for selection changes + addKeyListener(); + + if (fMemento != null) + restoreState(fMemento); + + getSite().setSelectionProvider(fViewer); + + // Status line + IStatusLineManager slManager= getViewSite().getActionBars().getStatusLineManager(); + fViewer.addSelectionChangedListener(createStatusBarUpdater(slManager)); + + + hookViewerListeners(); + + // Filters + addFilters(); + + // Initialize viewer input + fViewer.setContentProvider(createContentProvider()); + setInitialInput(); + + // Initialize selecton + setInitialSelection(); + fMemento= null; + + // Listen to page changes + getViewSite().getPage().addPostSelectionListener(this); + getViewSite().getPage().addPartListener(fPartListener); + + fillActionBars(getViewSite().getActionBars()); + + setHelp(); + } + + /** + * Answer the property defined by key. + */ + public Object getAdapter(Class key) { + if (key == IShowInSource.class) { + return getShowInSource(); + } + return super.getAdapter(key); + } + + /** + * Returns the IShowInSource for this view. + */ + protected IShowInSource getShowInSource() { + return new IShowInSource() { + public ShowInContext getShowInContext() { + return new ShowInContext( + null, + getSite().getSelectionProvider().getSelection()); + } + }; + } + +// protected DecoratingLabelProvider createDecoratingLabelProvider(CUILabelProvider provider) { +//// XXX: Work in progress for problem decorator being a workbench decorator// +//// return new ExcludingDecoratingLabelProvider(provider, decorationMgr, "org.eclipse.jdt.ui.problem.decorator"); //$NON-NLS-1$ +// return new DecoratingCLabelProvider(provider); +// } + + protected TypeInfoSorter createTypeInfoSorter() { + return new TypeInfoSorter(); + } + + protected StatusBarUpdater createStatusBarUpdater(IStatusLineManager slManager) { + return new StatusBarUpdater(slManager); + } + + protected void createContextMenu() { + MenuManager menuManager= new MenuManager("#PopupMenu"); //$NON-NLS-1$ + menuManager.setRemoveAllWhenShown(true); + menuManager.addMenuListener(this); + Menu contextMenu= menuManager.createContextMenu(fViewer.getControl()); + fViewer.getControl().setMenu(contextMenu); + getSite().registerContextMenu(menuManager, fViewer); + } + + protected void initDragAndDrop() { +/* int ops= DND.DROP_COPY | DND.DROP_MOVE | DND.DROP_LINK; + // drop + Transfer[] dropTransfers= new Transfer[] { + LocalSelectionTransfer.getInstance() + }; + TransferDropTargetListener[] dropListeners= new TransferDropTargetListener[] { + new SelectionTransferDropAdapter(fViewer) + }; + fViewer.addDropSupport(ops | DND.DROP_DEFAULT, dropTransfers, new DelegatingDropAdapter(dropListeners)); + + // Drag + Transfer[] dragTransfers= new Transfer[] { + LocalSelectionTransfer.getInstance(), + ResourceTransfer.getInstance()}; + TransferDragSourceListener[] dragListeners= new TransferDragSourceListener[] { + new SelectionTransferDragAdapter(fViewer), + new ResourceTransferDragAdapter(fViewer) + }; + fViewer.addDragSupport(ops, dragTransfers, new JdtViewerDragAdapter(fViewer, dragListeners)); +*/ } + + protected void fillActionBars(IActionBars actionBars) { + IToolBarManager toolBar= actionBars.getToolBarManager(); + fillToolBar(toolBar); + + + if (fHasWorkingSetFilter) + fWorkingSetFilterActionGroup.fillActionBars(getViewSite().getActionBars()); + + actionBars.updateActionBars(); + +// fActionGroups.fillActionBars(actionBars); +// +// if (fHasCustomFilter) +// fCustomFiltersActionGroup.fillActionBars(actionBars); +// +// IMenuManager menu= actionBars.getMenuManager(); +// menu.add(fToggleLinkingAction); + } + + //---- IWorkbenchPart ------------------------------------------------------ + + + public void setFocus() { + fViewer.getControl().setFocus(); + } + + public void dispose() { + if (fViewer != null) { + getViewSite().getPage().removePostSelectionListener(this); + getViewSite().getPage().removePartListener(fPartListener); + fViewer= null; + } +// if (fActionGroups != null) +// fActionGroups.dispose(); + + if (fWorkingSetFilterActionGroup != null) { + fWorkingSetFilterActionGroup.dispose(); + } + + super.dispose(); + } + + /** + * Adds the KeyListener + */ + protected void addKeyListener() { + fViewer.getControl().addKeyListener(new KeyAdapter() { + public void keyReleased(KeyEvent event) { + handleKeyReleased(event); + } + }); + } + + protected void handleKeyReleased(KeyEvent event) { + if (event.stateMask != 0) + return; + + int key= event.keyCode; + if (key == SWT.F5) { +// IAction action= fBuildActionGroup.getRefreshAction(); +// if (action.isEnabled()) +// action.run(); + } + } + + //---- Adding Action to Toolbar ------------------------------------------- + + protected void fillToolBar(IToolBarManager tbm) { + } + + /** + * Called when the context menu is about to open. + * Override to add your own context dependent menu contributions. + */ + public void menuAboutToShow(IMenuManager menu) { + CUIPlugin.createStandardGroups(menu); + + IStructuredSelection selection= (IStructuredSelection) fViewer.getSelection(); + int size= selection.size(); + Object element= selection.getFirstElement(); + + if (size == 1) + addOpenNewWindowAction(menu, element); +// fActionGroups.setContext(new ActionContext(selection)); +// fActionGroups.fillContextMenu(menu); +// fActionGroups.setContext(null); + } + + private void addOpenNewWindowAction(IMenuManager menu, Object element) { + if (element instanceof ICElement) { + element= ((ICElement)element).getResource(); + } + if (!(element instanceof IContainer)) + return; +// menu.appendToGroup( +// IContextMenuConstants.GROUP_OPEN, +// new PatchedOpenInNewWindowAction(getSite().getWorkbenchWindow(), (IContainer)element)); + } + + protected void createActions() { +// fActionGroups= new CompositeActionGroup(new ActionGroup[] { +// new NewWizardsActionGroup(this.getSite()), +// fOpenEditorGroup= new OpenEditorActionGroup(this), +// new OpenViewActionGroup(this), +// fCCPActionGroup= new CCPActionGroup(this), +// new GenerateActionGroup(this), +// new RefactorActionGroup(this), +// new ImportActionGroup(this), +// fBuildActionGroup= new BuildActionGroup(this), +// new JavaSearchActionGroup(this)}); + + + if (fHasWorkingSetFilter) { + String viewId= getConfigurationElement().getAttribute("id"); //$NON-NLS-1$ + Assert.isNotNull(viewId); + IPropertyChangeListener workingSetListener= new IPropertyChangeListener() { + public void propertyChange(PropertyChangeEvent event) { + doWorkingSetChanged(event); + } + }; + fWorkingSetFilterActionGroup= new WorkingSetFilterActionGroup(viewId, getShell(), workingSetListener); + fViewer.addFilter(fWorkingSetFilterActionGroup.getWorkingSetFilter()); + } + +// // Custom filter group +// if (fHasCustomFilter) +// fCustomFiltersActionGroup= new CustomFiltersActionGroup(this, fViewer); +// +// fToggleLinkingAction= new ToggleLinkingAction(this); + } + + private void doWorkingSetChanged(PropertyChangeEvent event) { + String property= event.getProperty(); + if (IWorkingSetManager.CHANGE_WORKING_SET_NAME_CHANGE.equals(property)) + updateTitle(); + else if (IWorkingSetManager.CHANGE_WORKING_SET_CONTENT_CHANGE.equals(property)) { + updateTitle(); + fViewer.getControl().setRedraw(false); + fViewer.refresh(); + fViewer.getControl().setRedraw(true); + } + + } + + + /** + * Returns the shell to use for opening dialogs. + * Used in this class, and in the actions. + */ + Shell getShell() { + return fViewer.getControl().getShell(); + } + + protected final Display getDisplay() { + return fViewer.getControl().getDisplay(); + } + + /** + * Returns the selection provider. + */ + ISelectionProvider getSelectionProvider() { + return fViewer; + } + + /** + * Answers if the given element is a valid + * input for this part. + * + * @param element the object to test + * @return if the given element is a valid input + */ + abstract protected boolean isValidInput(Object element); + + protected boolean exists(Object element) { + if (element == null) + return false; + if (element instanceof ICElement) + return ((ICElement)element).exists(); + if (element instanceof ITypeInfo) + return ((ITypeInfo)element).exists(); + return false; + } + + protected ICProject findCProject(ICElement element) { + return element.getCProject(); + } + + protected ICProject findCProject(ITypeInfo info) { + IProject project = info.getEnclosingProject(); + if (project != null) { + try { + ICProject[] cProjects = CoreModel.getDefault().getCModel().getCProjects(); + if (cProjects != null) { + for (int i = 0; i < cProjects.length; ++i) { + ICProject cProject = cProjects[i]; + if (cProject.getProject().equals(project)) + return cProject; + } + } + } catch (CModelException e) { + } + } + return null; + } + + protected ISourceRoot findSourceRoot(ICElement element) { + while (element != null) { + if (element instanceof ISourceRoot) + return (ISourceRoot)element; + if (element instanceof ICProject) + return null; + element = element.getParent(); + } + return null; + } + + protected ISourceRoot findSourceRoot(ITypeInfo info) { + ICProject cProject = findCProject(info); + if (cProject != null) { + try { + ISourceRoot[] roots = cProject.getAllSourceRoots(); + if (roots != null) { + for (int i = 0; i < roots.length; ++i) { + ISourceRoot root = roots[i]; + if (!isProjectSourceRoot(root)) { + TypeSearchScope scope = new TypeSearchScope(); + scope.add(root); + if (info.isEnclosed(scope)) + return root; + } + } + } + } catch (CModelException e) { + } + } + return null; + } + + protected boolean isProjectSourceRoot(ISourceRoot root) { + IResource resource= root.getResource(); + return (resource instanceof IProject); + } + + protected boolean isValidNamespace(Object element) { + if (element instanceof ITypeInfo) { + ITypeInfo info = (ITypeInfo)element; + if (info.exists() && info.getCElementType() == ICElement.C_NAMESPACE) { + // make sure it has types other than namespaces + ITypeInfo[] types = info.getEnclosedTypes(); + if (types != null) { + for (int i = 0; i < types.length; ++i) { + if (types[i].getCElementType() != ICElement.C_NAMESPACE) { + return true; + } + } + } + } + } + return false; + } + + protected Object getNamespaceInput(Object element) { + if (element instanceof ICModel) { + return null; + } + + if (element instanceof ICProject || element instanceof ISourceRoot) { + if (exists(element)) + return element; + } + + if (element instanceof ITypeInfo) { + ITypeInfo info = (ITypeInfo)element; + ISourceRoot root = findSourceRoot(info); + if (exists(root)) + return root; + ICProject cProject = findCProject(info); + if (exists(cProject)) + return cProject; + } + + if (element instanceof ICElement) { + ICElement cElem = (ICElement)element; + ISourceRoot root = findSourceRoot(cElem); + if (exists(root)) + return root; + ICProject cProject = findCProject(cElem); + if (exists(cProject)) + return cProject; + } + + return null; + } + + protected Object getTypesInput(Object element) { + if (element instanceof ICModel || element instanceof ICProject || element instanceof ISourceRoot) { + return null; + } + + if (element instanceof ICElement) { + //TODO optimization needed here - how do we get back parent ITypeInfo + TypeSearchScope scope = new TypeSearchScope(); + ICElement cElem = ((ICElement)element).getParent(); + ISourceRoot root = findSourceRoot(cElem); + if (root != null) { + scope.add(root); + } else { + ICProject cProject = findCProject(cElem); + if (cProject != null) { + scope.add(cProject); + } + } + ITypeInfo[] namespaces = AllTypesCache.getNamespaces(scope, true); + if (namespaces != null) { + for (int i = 0; i < namespaces.length; ++i) { + ITypeInfo[] enclosedTypes = namespaces[i].getEnclosedTypes(); + for (int j = 0; j < enclosedTypes.length; ++j) { + ITypeInfo enclosedType = enclosedTypes[j]; + if (enclosedType.getResolvedReference() != null) { + ICElement typeElem = enclosedType.getResolvedReference().getCElement(); + if (typeElem != null && typeElem.equals(cElem)) { + return namespaces[i]; + } + } + } + } + } + return null; + } + + if (element instanceof ITypeInfo) { + ITypeInfo info = (ITypeInfo) element; + if (info.getCElementType() == ICElement.C_NAMESPACE) { + if (exists(info)) + return info; + } + ITypeInfo namespace = info.getEnclosingType(new int[]{ICElement.C_NAMESPACE}); + if (namespace == null) { + namespace = info.getRootNamespace(true); + } + if (exists(namespace)) + return namespace; + } + + return null; + } + + protected Object getMembersInput(Object element) { + if (element instanceof ICModel || element instanceof ICProject || element instanceof ISourceRoot) { + return null; + } + + if (element instanceof ITypeInfo) { + ITypeInfo info = (ITypeInfo) element; + if (info.getCElementType() != ICElement.C_NAMESPACE) { + if (exists(info)) + return info; + } + } + + if (element instanceof ICElement) { + //TODO optimization needed here - how do we get back parent ITypeInfo + TypeSearchScope scope = new TypeSearchScope(); + ICElement cElem = ((ICElement)element).getParent(); + ISourceRoot root = findSourceRoot(cElem); + if (root != null) { + scope.add(root); + } else { + ICProject cProject = findCProject(cElem); + if (cProject != null) { + scope.add(cProject); + } + } + ITypeInfo[] namespaces = AllTypesCache.getNamespaces(scope, true); + if (namespaces != null) { + for (int i = 0; i < namespaces.length; ++i) { + ITypeInfo[] enclosedTypes = namespaces[i].getEnclosedTypes(); + for (int j = 0; j < enclosedTypes.length; ++j) { + ITypeInfo enclosedType = enclosedTypes[j]; + if (enclosedType.getResolvedReference() != null) { + ICElement typeElem = enclosedType.getResolvedReference().getCElement(); + if (typeElem != null && typeElem.equals(cElem)) { + return enclosedType; + } + } + } + } + } + return null; + } + + return null; + } + + /** + * Answers if the given element is a valid + * element for this part. + * + * @param element the object to test + * @return if the given element is a valid element + */ + abstract protected boolean isValidElement(Object element); +// if (element == null) +// return false; +//// element= getSuitableCElement(element); +//// if (element == null) +//// return false; +// Object input= getViewer().getInput(); +// if (input == null) +// return false; +// if (input instanceof Collection) +// return ((Collection)input).contains(element); +// else +// return input.equals(element); +// +// } + + private boolean isInputResetBy(Object newInput, Object input, IWorkbenchPart part) { + if (newInput == null) + return part == fPreviousSelectionProvider; + + if (input instanceof ICElement && newInput instanceof ICElement) + return getTypeComparator().compare(newInput, input) > 0; + + if((newInput instanceof List) && (part instanceof NamespacesView)) + return true; + else + return false; + } + + private boolean isInputResetBy(IWorkbenchPart part) { + if (!(part instanceof CBrowsingPart)) + return true; + Object thisInput= getViewer().getInput(); + Object partInput= ((CBrowsingPart)part).getViewer().getInput(); + + if(thisInput instanceof Collection) + thisInput= ((Collection)thisInput).iterator().next(); + + if(partInput instanceof Collection) + partInput= ((Collection)partInput).iterator().next(); + + if ((thisInput instanceof ICElement || thisInput instanceof ITypeInfo) + && (partInput instanceof ICElement || partInput instanceof ITypeInfo)) + return getTypeComparator().compare(partInput, thisInput) > 0; + else + return true; + } + + protected boolean isAncestorOf(Object ancestor, Object element) { + if (element instanceof ICElement && ancestor instanceof ICElement) + return !element.equals(ancestor) && internalIsAncestorOf((ICElement)ancestor, (ICElement)element); + if (element instanceof ITypeInfo) { + if (ancestor instanceof ISourceRoot || ancestor instanceof ICProject || ancestor instanceof ICModel) { + ICProject cProject = ((ICElement)ancestor).getCProject(); + if (cProject != null) { + IProject proj = (((ITypeInfo)element).getEnclosingProject()); + return (proj != null && proj.equals(cProject.getProject())); + } + } + if (ancestor instanceof ITypeInfo) { + return ((ITypeInfo)ancestor).encloses(((ITypeInfo)element)); + } + } + return false; + } + + private boolean internalIsAncestorOf(ICElement ancestor, ICElement element) { + if (element != null) + return element.equals(ancestor) || internalIsAncestorOf(ancestor, element.getParent()); + else + return false; + } + + private boolean isSearchResultView(IWorkbenchPart part) { +// return SearchUtil.isSearchPlugInActivated() && (part instanceof ISearchResultView); + return false; + } + + protected boolean needsToProcessSelectionChanged(IWorkbenchPart part, ISelection selection) { + if (!fProcessSelectionEvents || part == this || isSearchResultView(part)){ + if (part == this) + fPreviousSelectionProvider= part; + return false; + } + return true; + } + + public void selectionChanged(IWorkbenchPart part, ISelection selection) { + if (!needsToProcessSelectionChanged(part, selection)) + return; + +// if (fToggleLinkingAction.isChecked() && (part instanceof ITextEditor)) { +// setSelectionFromEditor(part, selection); +// return; +// } + + if (!(selection instanceof IStructuredSelection)) + return; + + // Set selection + Object selectedElement= getSingleElementFromSelection(selection); + + if (selectedElement != null && (part == null || part.equals(fPreviousSelectionProvider)) && selectedElement.equals(fPreviousSelectedElement)) + return; + + fPreviousSelectedElement= selectedElement; + + Object currentInput= getViewer().getInput(); + if (selectedElement != null && selectedElement.equals(currentInput)) { + Object elementToSelect= findElementToSelect(selectedElement); + if (elementToSelect != null && getTypeComparator().compare(selectedElement, elementToSelect) < 0) + setSelection(new StructuredSelection(elementToSelect), true); + else if (elementToSelect == null && (this instanceof MembersView)) { + setSelection(StructuredSelection.EMPTY, true); + fPreviousSelectedElement= StructuredSelection.EMPTY; + } + fPreviousSelectionProvider= part; + return; + } + + // Clear input if needed + if (part != fPreviousSelectionProvider && selectedElement != null && !selectedElement.equals(currentInput) && isInputResetBy(selectedElement, currentInput, part)) { + if (!isAncestorOf(selectedElement, currentInput)) + setInput(null); + fPreviousSelectionProvider= part; + return; + } else if (selection.isEmpty() && !isInputResetBy(part)) { + fPreviousSelectionProvider= part; + return; + } else if (selectedElement == null && part == fPreviousSelectionProvider) { + setInput(null); + fPreviousSelectionProvider= part; + return; + } + fPreviousSelectionProvider= part; + + // Adjust input and set selection and + adjustInputAndSetSelection(selectedElement); + } + + + void setHasWorkingSetFilter(boolean state) { + fHasWorkingSetFilter= state; + } + + void setHasCustomSetFilter(boolean state) { + fHasCustomFilter= state; + } + + protected Object getInput() { + return fViewer.getInput(); + } + + protected void setInput(Object input) { + setViewerInput(input); + updateTitle(); + } + + boolean isLinkingEnabled() { + return fLinkingEnabled; + } + + private void initLinkingEnabled() { + fLinkingEnabled= PreferenceConstants.getPreferenceStore().getBoolean(getLinkToEditorKey()); + } + + private void setViewerInput(Object input) { + fProcessSelectionEvents= false; + fViewer.setInput(input); + fProcessSelectionEvents= true; + } + + protected void updateTitle() { + setTitleToolTip(getToolTipText(fViewer.getInput())); + } + + /** + * Returns the tool tip text for the given element. + */ + String getToolTipText(Object element) { + String result; + if (!(element instanceof IResource)) { + result= CElementLabels.getTextLabel(element, AppearanceAwareLabelProvider.DEFAULT_TEXTFLAGS); + } else { + IPath path= ((IResource) element).getFullPath(); + if (path.isRoot()) { + result= getConfigurationElement().getAttribute("name"); //$NON-NLS-1$ + } else { + result= path.makeRelative().toString(); + } + } + + if (fWorkingSetFilterActionGroup == null || fWorkingSetFilterActionGroup.getWorkingSet() == null) + return result; + + IWorkingSet ws= fWorkingSetFilterActionGroup.getWorkingSet(); + String wsstr= CBrowsingMessages.getFormattedString("CBrowsingPart.toolTip", new String[] { ws.getName() }); //$NON-NLS-1$ + if (result.length() == 0) + return wsstr; + return CBrowsingMessages.getFormattedString("CBrowsingPart.toolTip2", new String[] { result, ws.getName() }); //$NON-NLS-1$ + } + + public String getTitleToolTip() { + if (fViewer == null) + return super.getTitleToolTip(); + return getToolTipText(fViewer.getInput()); + } + + protected final StructuredViewer getViewer() { + return fViewer; + } + + protected final void setViewer(StructuredViewer viewer){ + fViewer= viewer; + } + + protected abstract LabelProvider createLabelProvider(); + + protected ILabelProvider createTitleProvider() { + return new CElementLabelProvider(CElementLabelProvider.SHOW_BASICS | CElementLabelProvider.SHOW_SMALL_ICONS); + } + + protected final ILabelProvider getLabelProvider() { + return fLabelProvider; + } + + protected final ILabelProvider getTitleProvider() { + return fTitleProvider; + } + + /** + * Creates the the viewer of this part. + * + * @param parent the parent for the viewer + */ + protected StructuredViewer createViewer(Composite parent) { + return new ProblemTableViewer(parent, SWT.MULTI); + } + + protected int getLabelProviderFlags() { + return CElementLabelProvider.SHOW_BASICS | CElementLabelProvider.SHOW_OVERLAY_ICONS | + CElementLabelProvider.SHOW_SMALL_ICONS | /*CElementLabelProvider.SHOW_VARIABLE |*/ CElementLabelProvider.SHOW_PARAMETERS; + } + + /** + * Adds filters the viewer of this part. + */ + protected void addFilters() { + // default is to have no filters + } + +// /** +// * Creates the the content provider of this part. +// */ + protected abstract IContentProvider createContentProvider(); + + protected void setInitialInput() { + // Use the selection, if any + ISelection selection= getSite().getPage().getSelection(); + Object input= getSingleElementFromSelection(selection); + if (!(input instanceof ICElement) && !(input instanceof ITypeInfo)) { + // Use the input of the page + input= getSite().getPage().getInput(); + if (!(input instanceof ICElement) && input instanceof IAdaptable) + input= ((IAdaptable)input).getAdapter(ICElement.class); + } + setInput(findInputForElement(input)); + } + + protected void setInitialSelection() { + // Use the selection, if any + Object input; + IWorkbenchPage page= getSite().getPage(); + ISelection selection= null; + if (page != null) + selection= page.getSelection(); + if (selection instanceof ITextSelection) { + Object part= PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActivePart(); + if (part instanceof IEditorPart) { + setSelectionFromEditor((IEditorPart)part); + if (fViewer.getSelection() != null) + return; + } + } + + // Use saved selection from memento + if (selection == null || selection.isEmpty()) + selection= restoreSelectionState(fMemento); + + if (selection == null || selection.isEmpty()) { + // Use the input of the page + input= getSite().getPage().getInput(); + if (!(input instanceof ICElement)) { + if (input instanceof IAdaptable) + input= ((IAdaptable)input).getAdapter(ICElement.class); + else + return; + } + selection= new StructuredSelection(input); + } + selectionChanged(null, selection); + } + + protected final void setHelp() { +// CUIHelp.setHelp(fViewer, getHelpContextId()); + } + + /** + * Returns the context ID for the Help system + * + * @return the string used as ID for the Help context + */ + abstract protected String getHelpContextId(); + + /** + * Returns the preference key for the link to editor setting. + * + * @return the string used as key into the preference store + */ + abstract protected String getLinkToEditorKey(); + + /** + * Adds additional listeners to this view. + * This method can be overridden but should + * call super. + */ + protected void hookViewerListeners() { + fViewer.addPostSelectionChangedListener(new ISelectionChangedListener() { + public void selectionChanged(SelectionChangedEvent event) { + if (!fProcessSelectionEvents) + return; + + fPreviousSelectedElement= getSingleElementFromSelection(event.getSelection()); + + IWorkbenchPage page= getSite().getPage(); + if (page == null) + return; + + if (page.equals(CUIPlugin.getActivePage()) && CBrowsingPart.this.equals(page.getActivePart())) { + linkToEditor((IStructuredSelection)event.getSelection()); + } + } + }); + + fViewer.addOpenListener(new IOpenListener() { + public void open(OpenEvent event) { + ISelection selection = event.getSelection(); + if (selection != null) { + Object element = getSingleElementFromSelection(selection); + ICElement cElem = null; + if (element instanceof ICElement) { + openInEditor((ICElement)element); + } else if (element instanceof ITypeInfo) { + openTypeInEditor((ITypeInfo)element); + } + } +// IAction open= fOpenEditorGroup.getOpenAction(); +// if (open.isEnabled()) { +// open.run(); +// restoreSelection(); +// } + } + }); + } + + protected void openTypeInEditor(ITypeInfo info) { + ITypeReference location = info.getResolvedReference(); + if (location == null) { + final ITypeInfo[] typesToResolve = new ITypeInfo[] { info }; + IRunnableWithProgress runnable = new IRunnableWithProgress() { + public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { + AllTypesCache.resolveTypeLocation(typesToResolve[0], monitor); + if (monitor.isCanceled()) { + throw new InterruptedException(); + } + } + }; + + IRunnableContext runnableContext = new ProgressMonitorDialog(getShell()); + 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; + } + + location = info.getResolvedReference(); + } + + if (location == null) { + // could not resolve location + String title = OpenTypeMessages.getString("OpenTypeAction.errorTitle"); //$NON-NLS-1$ + String message = OpenTypeMessages.getFormattedString("OpenTypeAction.errorTypeNotFound", info.getQualifiedTypeName().toString()); //$NON-NLS-1$ + MessageDialog.openError(getShell(), title, message); + } else if (!openInEditor(location)) { + // error opening editor + String title = OpenTypeMessages.getString("OpenTypeAction.errorTitle"); //$NON-NLS-1$ + String message = OpenTypeMessages.getFormattedString("OpenTypeAction.errorOpenEditor", location.getPath().toString()); //$NON-NLS-1$ + MessageDialog.openError(getShell(), title, message); + } + } + + protected boolean openInEditor(ITypeReference location) { + ICElement cElement = location.getCElement(); + IEditorPart editorPart = null; + + try { + if (cElement != null) + editorPart = EditorUtility.openInEditor(cElement); + if (editorPart == null) { + // open as external file + IPath path = location.getLocation(); + if (path != null) { + 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(location.getOffset(), location.getLength()); + return true; + } + return false; + } + + protected boolean openInEditor(ICElement cElement) { + IEditorPart editorPart = null; + + try { + if (cElement != null) + editorPart = EditorUtility.openInEditor(cElement); + 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; + } + return false; + } + + void restoreSelection() { + // Default is to do nothing + } + + void adjustInputAndSetSelection(Object o) { + if (!(o instanceof ICElement) && !(o instanceof ITypeInfo)) { + setSelection(StructuredSelection.EMPTY, true); + return; + } + + Object elementToSelect= getSuitableElement(findElementToSelect(o)); + Object newInput= findInputForElement(o); + Object oldInput= null; + if (getInput() instanceof ICElement || getInput() instanceof ITypeInfo) + oldInput = getInput(); + + if (elementToSelect == null && !isValidInput(newInput) && (newInput == null && !isAncestorOf(o, oldInput))) + // Clear input + setInput(null); + else if (mustSetNewInput(elementToSelect, oldInput, newInput)) { + // Adjust input to selection + setInput(newInput); + // Recompute suitable element since it depends on the viewer's input + elementToSelect= getSuitableElement(elementToSelect); + } + + if (elementToSelect != null /*&& elementToSelect.exists()*/) + setSelection(new StructuredSelection(elementToSelect), true); + else + setSelection(StructuredSelection.EMPTY, true); + } + + /** + * Compute if a new input must be set. + * + * @return true if the input has to be set + * @since 3.0 + */ + private boolean mustSetNewInput(Object elementToSelect, Object oldInput, Object newInput) { + return (newInput == null || !newInput.equals(oldInput)) + && (elementToSelect == null + || oldInput == null); +// return (newInput == null || !newInput.equals(oldInput)) +// && (elementToSelect == null +// || oldInput == null +// || (!((elementToSelect instanceof IDeclaration) +// && (elementToSelect.getParent().equals(oldInput.getParent())) +// && (!isAncestorOf(getViewPartInput(), elementToSelect))))); + } + + /** + * Finds the closest Java element which can be used as input for + * this part and has the given Java element as child + * + * @param je the Java element for which to search the closest input + * @return the closest Java element used as input for this part + */ + abstract protected Object findInputForElement(Object element); + + /** + * Finds the element which has to be selected in this part. + * + * @param je the Java element which has the focus + */ + abstract protected Object findElementToSelect(Object obj); + + /** + * Converts the given Java element to one which is suitable for this + * view. It takes into account wether the view shows working copies or not. + * + * @param element the Java element to be converted + * @return an element suitable for this view + */ + Object getSuitableElement(Object obj) { + if (!(obj instanceof ICElement) && !(obj instanceof ITypeInfo)) + return null; + if (fTypeComparator.compare(obj, ICElement.C_UNIT) > 0) + return obj; + return obj; +// if (element.getElementType() == IJavaElement.CLASS_FILE) +// return element; +// if (isInputAWorkingCopy()) { +// IJavaElement wc= getWorkingCopy(element); +// if (wc != null) +// element= wc; +// return element; +// } +// else { +// return element.getPrimaryElement(); +// } + } + + protected final Object getSingleElementFromSelection(ISelection selection) { + if (!(selection instanceof StructuredSelection) || selection.isEmpty()) + return null; + + Iterator iter= ((StructuredSelection)selection).iterator(); + Object firstElement= iter.next(); + if (!(firstElement instanceof ICElement) && !(firstElement instanceof ITypeInfo)) { +// if (SearchUtil.isISearchResultViewEntry(firstElement)) { +// ICElement je= SearchUtil.getJavaElement(firstElement); +// if (je != null) +// return je; +// firstElement= SearchUtil.getResource(firstElement); +// } + if (firstElement instanceof IAdaptable) { + ICElement je= (ICElement)((IAdaptable)firstElement).getAdapter(ICElement.class); + if (je == null && firstElement instanceof IFile) { + IContainer parent= ((IFile)firstElement).getParent(); + if (parent != null) + return (ICElement)parent.getAdapter(ICElement.class); + else return null; + } else + return je; + + } else + return firstElement; + } + Object currentInput= getViewer().getInput(); + if (currentInput == null || !currentInput.equals(findInputForElement(firstElement))) + if (iter.hasNext()) + // multi selection and view is empty + return null; + else + // ok: single selection and view is empty + return firstElement; + + // be nice to multi selection + while (iter.hasNext()) { + Object element= iter.next(); + if (!(element instanceof ICElement) && !(element instanceof ITypeInfo)) +// if (!(element instanceof ICElement)) + return null; + if (!currentInput.equals(findInputForElement(element))) + return null; + } + return firstElement; + } + + /** + * Gets the typeComparator. + * @return Returns a JavaElementTypeComparator + */ + protected Comparator getTypeComparator() { + return fTypeComparator; + } + + /** + * Links to editor (if option enabled) + */ + private void linkToEditor(IStructuredSelection selection) { + Object obj= selection.getFirstElement(); + + if (selection.size() == 1) { + IEditorPart part= EditorUtility.isOpenInEditor(obj); + if (part != null) { + IWorkbenchPage page= getSite().getPage(); + page.bringToTop(part); + if (obj instanceof ICElement) + EditorUtility.revealInEditor(part, (ICElement) obj); + } + } + } + + private void setSelectionFromEditor(IWorkbenchPartReference ref) { + IWorkbenchPart part= ref.getPart(false); + setSelectionFromEditor(part); + } + + void setSelectionFromEditor(IWorkbenchPart part) { + if (!linkBrowsingViewSelectionToEditor()) + return; + + if (part == null) + return; + IWorkbenchPartSite site= part.getSite(); + if (site == null) + return; + ISelectionProvider provider= site.getSelectionProvider(); + if (provider != null) + setSelectionFromEditor(part, provider.getSelection()); + } + + private void setSelectionFromEditor(IWorkbenchPart part, ISelection selection) { + if (part instanceof IEditorPart) { + ICElement element= null; + if (selection instanceof IStructuredSelection) { + Object obj= getSingleElementFromSelection(selection); + if (obj instanceof ICElement) + element= (ICElement)obj; + } + IEditorInput ei= ((IEditorPart)part).getEditorInput(); + if (selection instanceof ITextSelection) { + int offset= ((ITextSelection)selection).getOffset(); + element= getElementAt(ei, offset); + } + if (element != null) { + adjustInputAndSetSelection(element); + return; + } + if (ei instanceof IFileEditorInput) { + IFile file= ((IFileEditorInput)ei).getFile(); + ICElement je= (ICElement)file.getAdapter(ICElement.class); + if (je == null) { + IContainer container= ((IFileEditorInput)ei).getFile().getParent(); + if (container != null) + je= (ICElement)container.getAdapter(ICElement.class); + } + if (je == null) { + setSelection(null, false); + return; + } + adjustInputAndSetSelection(je); +// } else if (ei instanceof IClassFileEditorInput) { +// IClassFile cf= ((IClassFileEditorInput)ei).getClassFile(); +// adjustInputAndSetSelection(cf); + } + } + } + + /** + * Returns the element contained in the EditorInput + */ + Object getElementOfInput(IEditorInput input) { +// if (input instanceof IClassFileEditorInput) +// return ((IClassFileEditorInput)input).getClassFile(); +// else + if (input instanceof IFileEditorInput) + return ((IFileEditorInput)input).getFile(); +// else if (input instanceof JarEntryEditorInput) +// return ((JarEntryEditorInput)input).getStorage(); + return null; + } + + protected void setSelection(ISelection selection, boolean reveal) { + if (selection != null && selection.equals(fViewer.getSelection())) + return; + fProcessSelectionEvents= false; + fViewer.setSelection(selection, reveal); + fProcessSelectionEvents= true; + } + + /** + * Tries to find the given element in a workingcopy. + */ + protected static ICElement getWorkingCopy(ICElement input) { + // MA: with new working copy story original == working copy + return input; + } + +// +// boolean isInputAWorkingCopy() { +// return ((BaseCElementContentProvider)getViewer().getContentProvider()).getProvideWorkingCopy(); +// } + + /** + * @see org.eclipse.jdt.internal.ui.javaeditor.JavaEditor#getElementAt(int) + */ + protected ICElement getElementAt(IEditorInput input, int offset) { +// if (input instanceof IClassFileEditorInput) { +// try { +// return ((IClassFileEditorInput)input).getClassFile().getElementAt(offset); +// } catch (CModelException ex) { +// return null; +// } +// } + + IWorkingCopyManager manager= CUIPlugin.getDefault().getWorkingCopyManager(); + ITranslationUnit unit= manager.getWorkingCopy(input); + if (unit != null) + try { + if (unit.isConsistent()) + return unit.getElementAtOffset(offset); + else { + /* + * XXX: We should set the selection later when the + * CU is reconciled. + * see https://bugs.eclipse.org/bugs/show_bug.cgi?id=51290 + */ + } + } catch (CModelException ex) { + // fall through + } + return null; + } + +/* protected ICElement getTypeForCU(ITranslationUnit cu) { + cu= (ITranslationUnit)getSuitableCElement(cu); + +// // Use primary type if possible +// ICElement primaryType= cu.findPrimaryType(); +// if (primaryType != null) +// return primaryType; + + // Use first top-level type + try { + final ICElement[] fTypes = new ICElement[]{ null }; + cu.accept(new ICElementVisitor() { + public boolean visit(ICElement element) throws CoreException { + // TODO Auto-generated method stub + switch(element.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: + fTypes[0] = element; + return false; + } + return true; + } + }); +// ICElement[] types= cu.getTypes(); +// if (types.length > 0) +// return types[0]; +// else +// return null; + return fTypes[0]; + } catch (CoreException ex) { + return null; + } + } +*/ + void setProcessSelectionEvents(boolean state) { + fProcessSelectionEvents= state; + } + + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.ui.viewsupport.IViewPartInputProvider#getViewPartInput() + */ + public Object getViewPartInput() { + if (fViewer != null) { + return fViewer.getInput(); + } + return null; + } + +// protected void setActionGroups(CompositeActionGroup actionGroups) { +// fActionGroups= actionGroups; +// } +// +// protected void setBuildActionGroup(BuildActionGroup actionGroup) { +// fBuildActionGroup= actionGroup; +// } +// +// protected void setCCPActionGroup(CCPActionGroup actionGroup) { +// fCCPActionGroup= actionGroup; +// } +// +// protected void setCustomFiltersActionGroup(CustomFiltersActionGroup customFiltersActionGroup) { +// fCustomFiltersActionGroup= customFiltersActionGroup; +// } + + protected boolean hasCustomFilter() { + return fHasCustomFilter; + } + + protected boolean hasWorkingSetFilter() { + return fHasWorkingSetFilter; + } + +// protected void setOpenEditorGroup(OpenEditorActionGroup openEditorGroup) { +// fOpenEditorGroup= openEditorGroup; +// } +// +// protected OpenEditorActionGroup getOpenEditorGroup() { +// return fOpenEditorGroup; +// } +// +// protected BuildActionGroup getBuildActionGroup() { +// return fBuildActionGroup; +// } +// +// protected CCPActionGroup getCCPActionGroup() { +// return fCCPActionGroup; +// } + + private boolean linkBrowsingViewSelectionToEditor() { + return isLinkingEnabled(); + } + + public void setLinkingEnabled(boolean enabled) { + fLinkingEnabled= enabled; + PreferenceConstants.getPreferenceStore().setValue(getLinkToEditorKey(), enabled); + if (enabled) { + IEditorPart editor = getSite().getPage().getActiveEditor(); + if (editor != null) { + setSelectionFromEditor(editor); + } + } + } + +} diff --git a/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/CBrowsingPerspectiveFactory.java b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/CBrowsingPerspectiveFactory.java new file mode 100644 index 00000000000..9aebaf81ead --- /dev/null +++ b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/CBrowsingPerspectiveFactory.java @@ -0,0 +1,212 @@ +package org.eclipse.cdt.internal.ui.browser.cbrowsing; + +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ + +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.ui.CUIPlugin; +import org.eclipse.cdt.ui.PreferenceConstants; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.search.ui.SearchUI; +import org.eclipse.ui.IFolderLayout; +import org.eclipse.ui.IPageLayout; +import org.eclipse.ui.IPerspectiveFactory; +import org.eclipse.ui.IPlaceholderFolderLayout; +import org.eclipse.ui.console.IConsoleConstants; + +public class CBrowsingPerspectiveFactory implements IPerspectiveFactory { + + /* + * XXX: This is a workaround for: http://dev.eclipse.org/bugs/show_bug.cgi?id=13070 + */ + static ICElement fgCElementFromAction; + + /** + * Constructs a new Default layout engine. + */ + public CBrowsingPerspectiveFactory() { + super(); + } + + /** + * @see IPerspectiveFactory#createInitialLayout + */ + public void createCViewInitialLayout(IPageLayout layout) { + String editorArea = layout.getEditorArea(); + + IFolderLayout folder1= layout.createFolder("topLeft", IPageLayout.LEFT, (float)0.25, editorArea); //$NON-NLS-1$ + folder1.addView(CUIPlugin.CVIEW_ID); + folder1.addView(IPageLayout.ID_RES_NAV); + folder1.addPlaceholder(IPageLayout.ID_BOOKMARKS); + + IFolderLayout folder2= layout.createFolder("bottom", IPageLayout.BOTTOM, (float)0.75, editorArea); //$NON-NLS-1$ + folder2.addView(IPageLayout.ID_PROBLEM_VIEW); + folder2.addView(IConsoleConstants.ID_CONSOLE_VIEW); + folder2.addView(IPageLayout.ID_PROP_SHEET); + + IFolderLayout folder3= layout.createFolder("topRight", IPageLayout.RIGHT,(float)0.75, editorArea); //$NON-NLS-1$ + folder3.addView(IPageLayout.ID_OUTLINE); + + layout.addActionSet(CUIPlugin.SEARCH_ACTION_SET_ID); + layout.addActionSet(CUIPlugin.FOLDER_ACTION_SET_ID); + + // views - build console + layout.addShowViewShortcut(IConsoleConstants.ID_CONSOLE_VIEW); + + // views - searching + layout.addShowViewShortcut(SearchUI.SEARCH_RESULT_VIEW_ID); + + // views - standard workbench + layout.addShowViewShortcut(IPageLayout.ID_OUTLINE); + layout.addShowViewShortcut(IPageLayout.ID_PROBLEM_VIEW); + layout.addShowViewShortcut(CUIPlugin.CVIEW_ID); + layout.addShowViewShortcut(IPageLayout.ID_RES_NAV); + layout.addShowViewShortcut(IPageLayout.ID_PROP_SHEET); + + // link - things we should do + layout.addShowInPart(CUIPlugin.CVIEW_ID); + layout.addShowInPart(IPageLayout.ID_RES_NAV); + + // new actions - C project creation wizard + layout.addNewWizardShortcut(CUIPlugin.CLASS_WIZARD_ID); + layout.addNewWizardShortcut(CUIPlugin.FILE_WIZARD_ID); + layout.addNewWizardShortcut(CUIPlugin.FOLDER_WIZARD_ID); + } + + public void createInitialLayout(IPageLayout layout) { + if (stackBrowsingViewsVertically()) + createVerticalLayout(layout); + else + createHorizontalLayout(layout); + + // action sets + layout.addActionSet(CUIPlugin.SEARCH_ACTION_SET_ID); + layout.addActionSet(CUIPlugin.FOLDER_ACTION_SET_ID); +// layout.addActionSet(IDebugUIConstants.LAUNCH_ACTION_SET); +// layout.addActionSet(JavaUI.ID_ACTION_SET); +// layout.addActionSet(JavaUI.ID_ELEMENT_CREATION_ACTION_SET); + layout.addActionSet(IPageLayout.ID_NAVIGATE_ACTION_SET); + + // views - java +// layout.addShowViewShortcut(CUIPlugin.ID_TYPE_HIERARCHY); + layout.addShowViewShortcut(CUIPlugin.CVIEW_ID); + layout.addShowViewShortcut(CUIPlugin.ID_PROJECTS_VIEW); + layout.addShowViewShortcut(CUIPlugin.ID_NAMESPACES_VIEW); + layout.addShowViewShortcut(CUIPlugin.ID_TYPES_VIEW); + layout.addShowViewShortcut(CUIPlugin.ID_MEMBERS_VIEW); +// layout.addShowViewShortcut(CUIPlugin.ID_SOURCE_VIEW); +// layout.addShowViewShortcut(CUIPlugin.ID_JAVADOC_VIEW); + + // views - search + layout.addShowViewShortcut(SearchUI.SEARCH_RESULT_VIEW_ID); + + // views - debugging + layout.addShowViewShortcut(IConsoleConstants.ID_CONSOLE_VIEW); + + // views - standard workbench + layout.addShowViewShortcut(IPageLayout.ID_OUTLINE); + layout.addShowViewShortcut(IPageLayout.ID_PROBLEM_VIEW); + layout.addShowViewShortcut(IPageLayout.ID_RES_NAV); + + // new actions - C project creation wizard + layout.addNewWizardShortcut(CUIPlugin.CLASS_WIZARD_ID); + layout.addNewWizardShortcut(CUIPlugin.FILE_WIZARD_ID); + layout.addNewWizardShortcut(CUIPlugin.FOLDER_WIZARD_ID); + } + + private void createVerticalLayout(IPageLayout layout) { + String relativePartId= IPageLayout.ID_EDITOR_AREA; + int relativePos= IPageLayout.LEFT; + + IPlaceholderFolderLayout placeHolderLeft= layout.createPlaceholderFolder("left", IPageLayout.LEFT, (float)0.25, IPageLayout.ID_EDITOR_AREA); //$NON-NLS-1$ +// placeHolderLeft.addPlaceholder(JavaUI.ID_TYPE_HIERARCHY); + placeHolderLeft.addPlaceholder(IPageLayout.ID_OUTLINE); + placeHolderLeft.addPlaceholder(CUIPlugin.CVIEW_ID); + placeHolderLeft.addPlaceholder(IPageLayout.ID_RES_NAV); + + if (shouldShowProjectsView()) { + layout.addView(CUIPlugin.ID_PROJECTS_VIEW, IPageLayout.LEFT, (float)0.25, IPageLayout.ID_EDITOR_AREA); + relativePartId= CUIPlugin.ID_PROJECTS_VIEW; + relativePos= IPageLayout.BOTTOM; + } + if (shouldShowNamespacesView()) { + layout.addView(CUIPlugin.ID_NAMESPACES_VIEW, relativePos, (float)0.25, relativePartId); + relativePartId= CUIPlugin.ID_NAMESPACES_VIEW; + relativePos= IPageLayout.BOTTOM; + } + layout.addView(CUIPlugin.ID_TYPES_VIEW, relativePos, (float)0.33, relativePartId); + layout.addView(CUIPlugin.ID_MEMBERS_VIEW, IPageLayout.BOTTOM, (float)0.50, CUIPlugin.ID_TYPES_VIEW); + + IPlaceholderFolderLayout placeHolderBottom= layout.createPlaceholderFolder("bottom", IPageLayout.BOTTOM, (float)0.75, IPageLayout.ID_EDITOR_AREA); //$NON-NLS-1$ + placeHolderBottom.addPlaceholder(IPageLayout.ID_PROBLEM_VIEW); + placeHolderBottom.addPlaceholder(SearchUI.SEARCH_RESULT_VIEW_ID); + placeHolderBottom.addPlaceholder(IConsoleConstants.ID_CONSOLE_VIEW); + placeHolderBottom.addPlaceholder(IPageLayout.ID_BOOKMARKS); +// placeHolderBottom.addPlaceholder(JavaUI.ID_SOURCE_VIEW); +// placeHolderBottom.addPlaceholder(JavaUI.ID_JAVADOC_VIEW); + } + + private void createHorizontalLayout(IPageLayout layout) { + String relativePartId= IPageLayout.ID_EDITOR_AREA; + int relativePos= IPageLayout.TOP; + + if (shouldShowProjectsView()) { + layout.addView(CUIPlugin.ID_PROJECTS_VIEW, IPageLayout.TOP, (float)0.25, IPageLayout.ID_EDITOR_AREA); + relativePartId= CUIPlugin.ID_PROJECTS_VIEW; + relativePos= IPageLayout.RIGHT; + } + if (shouldShowNamespacesView()) { + layout.addView(CUIPlugin.ID_NAMESPACES_VIEW, relativePos, (float)0.25, relativePartId); + relativePartId= CUIPlugin.ID_NAMESPACES_VIEW; + relativePos= IPageLayout.RIGHT; + } + layout.addView(CUIPlugin.ID_TYPES_VIEW, relativePos, (float)0.33, relativePartId); + layout.addView(CUIPlugin.ID_MEMBERS_VIEW, IPageLayout.RIGHT, (float)0.50, CUIPlugin.ID_TYPES_VIEW); + + IPlaceholderFolderLayout placeHolderLeft= layout.createPlaceholderFolder("left", IPageLayout.LEFT, (float)0.25, IPageLayout.ID_EDITOR_AREA); //$NON-NLS-1$ +// placeHolderLeft.addPlaceholder(JavaUI.ID_TYPE_HIERARCHY); + placeHolderLeft.addPlaceholder(IPageLayout.ID_OUTLINE); + placeHolderLeft.addPlaceholder(CUIPlugin.CVIEW_ID); + placeHolderLeft.addPlaceholder(IPageLayout.ID_RES_NAV); + + IPlaceholderFolderLayout placeHolderBottom= layout.createPlaceholderFolder("bottom", IPageLayout.BOTTOM, (float)0.75, IPageLayout.ID_EDITOR_AREA); //$NON-NLS-1$ + placeHolderBottom.addPlaceholder(IPageLayout.ID_PROBLEM_VIEW); + placeHolderBottom.addPlaceholder(SearchUI.SEARCH_RESULT_VIEW_ID); + placeHolderBottom.addPlaceholder(IConsoleConstants.ID_CONSOLE_VIEW); + placeHolderBottom.addPlaceholder(IPageLayout.ID_BOOKMARKS); +// placeHolderBottom.addPlaceholder(JavaUI.ID_SOURCE_VIEW); +// placeHolderBottom.addPlaceholder(JavaUI.ID_JAVADOC_VIEW); + } + + private boolean shouldShowProjectsView() { + return true; +// RETURN FGCELEMENTFROMACTION == NULL || FGCELEMENTFROMACTION.GETELEMENTTYPE() == ICELEMENT.C_MODEL; + } + + private boolean shouldShowNamespacesView() { + return true; +// if (fgCElementFromAction == null) +// return true; +// int type= fgCElementFromAction.getElementType(); +// return type == ICElement.C_MODEL || type == ICElement.C_PROJECT; +//// return type == ICElement.C_MODEL || type == ICElement.C_PROJECT || type == ICElement.PACKAGE_FRAGMENT_ROOT; + } + + private boolean stackBrowsingViewsVertically() { + return PreferenceConstants.getPreferenceStore().getBoolean(PreferenceConstants.BROWSING_STACK_VERTICALLY); + } + + /* + * XXX: This is a workaround for: http://dev.eclipse.org/bugs/show_bug.cgi?id=13070 + */ + static void setInputFromAction(IAdaptable input) { + if (input instanceof ICElement) + fgCElementFromAction= (ICElement)input; + else + fgCElementFromAction= null; + } +} + + diff --git a/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/CUILabelProvider.java b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/CUILabelProvider.java new file mode 100644 index 00000000000..2feefa3eae3 --- /dev/null +++ b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/CUILabelProvider.java @@ -0,0 +1,247 @@ +/******************************************************************************* + * 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 + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.browser.cbrowsing; + +import java.util.ArrayList; + +import org.eclipse.cdt.core.browser.ITypeInfo; +import org.eclipse.cdt.internal.ui.CElementImageProvider; +import org.eclipse.cdt.internal.ui.search.CElementLabels; +import org.eclipse.cdt.ui.browser.typeinfo.TypeInfoLabelProvider; +import org.eclipse.core.resources.IStorage; + +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Image; + +import org.eclipse.jface.viewers.IColorProvider; +import org.eclipse.jface.viewers.ILabelDecorator; +import org.eclipse.jface.viewers.ILabelProviderListener; +import org.eclipse.jface.viewers.LabelProvider; + +public class CUILabelProvider extends LabelProvider implements IColorProvider { + + protected static final TypeInfoLabelProvider fTypeInfoLabelProvider = new TypeInfoLabelProvider(TypeInfoLabelProvider.SHOW_FULLY_QUALIFIED); + protected CElementImageProvider fImageLabelProvider; + protected StorageLabelProvider fStorageLabelProvider; + + private ArrayList fLabelDecorators; + + private int fImageFlags; + private int fTextFlags; + + /** + * Creates a new label provider with default flags. + */ + public CUILabelProvider() { + this(CElementLabels.M_PARAMETER_TYPES, CElementImageProvider.OVERLAY_ICONS); + } + + /** + * @param textFlags Flags defined in JavaElementLabels. + * @param imageFlags Flags defined in JavaElementImageProvider. + */ + public CUILabelProvider(int textFlags, int imageFlags) { + fImageLabelProvider= new CElementImageProvider(); + fLabelDecorators= null; + + fStorageLabelProvider= new StorageLabelProvider(); + fImageFlags= imageFlags; + fTextFlags= textFlags; + } + + /** + * Adds a decorator to the label provider + */ + public void addLabelDecorator(ILabelDecorator decorator) { + if (fLabelDecorators == null) { + fLabelDecorators= new ArrayList(2); + } + fLabelDecorators.add(decorator); + } + + /** + * Sets the textFlags. + * @param textFlags The textFlags to set + */ + public final void setTextFlags(int textFlags) { + fTextFlags= textFlags; + } + + /** + * Sets the imageFlags + * @param imageFlags The imageFlags to set + */ + public final void setImageFlags(int imageFlags) { + fImageFlags= imageFlags; + } + + /** + * Gets the image flags. + * Can be overwriten by super classes. + * @return Returns a int + */ + public final int getImageFlags() { + return fImageFlags; + } + + /** + * Gets the text flags. + * @return Returns a int + */ + public final int getTextFlags() { + return fTextFlags; + } + + /** + * Evaluates the image flags for a element. + * Can be overwriten by super classes. + * @return Returns a int + */ + protected int evaluateImageFlags(Object element) { + return getImageFlags(); + } + + /** + * Evaluates the text flags for a element. Can be overwriten by super classes. + * @return Returns a int + */ + protected int evaluateTextFlags(Object element) { + return getTextFlags(); + } + + protected Image decorateImage(Image image, Object element) { + if (fLabelDecorators != null && image != null) { + for (int i= 0; i < fLabelDecorators.size(); i++) { + ILabelDecorator decorator= (ILabelDecorator) fLabelDecorators.get(i); + image= decorator.decorateImage(image, element); + } + } + return image; + } + + /* (non-Javadoc) + * @see ILabelProvider#getImage + */ + public Image getImage(Object element) { + if (element instanceof ITypeInfo) + return fTypeInfoLabelProvider.getImage(element); + + Image result= fImageLabelProvider.getImageLabel(element, evaluateImageFlags(element)); + if (result == null && (element instanceof IStorage)) { + result= fStorageLabelProvider.getImage(element); + } + + return decorateImage(result, element); + } + + protected String decorateText(String text, Object element) { + if (fLabelDecorators != null && text.length() > 0) { + for (int i= 0; i < fLabelDecorators.size(); i++) { + ILabelDecorator decorator= (ILabelDecorator) fLabelDecorators.get(i); + text= decorator.decorateText(text, element); + } + } + return text; + } + + + /* (non-Javadoc) + * @see ILabelProvider#getText + */ + public String getText(Object element) { + if (element instanceof ITypeInfo) + return fTypeInfoLabelProvider.getText(element); + + String result= CElementLabels.getTextLabel(element, evaluateTextFlags(element)); + if (result.length() == 0 && (element instanceof IStorage)) { + result= fStorageLabelProvider.getText(element); + } + + return decorateText(result, element); + } + + /* (non-Javadoc) + * @see IBaseLabelProvider#dispose + */ + public void dispose() { + if (fLabelDecorators != null) { + for (int i= 0; i < fLabelDecorators.size(); i++) { + ILabelDecorator decorator= (ILabelDecorator) fLabelDecorators.get(i); + decorator.dispose(); + } + fLabelDecorators= null; + } + fStorageLabelProvider.dispose(); + fImageLabelProvider.dispose(); + } + + /* (non-Javadoc) + * @see IBaseLabelProvider#addListener(ILabelProviderListener) + */ + public void addListener(ILabelProviderListener listener) { + if (fLabelDecorators != null) { + for (int i= 0; i < fLabelDecorators.size(); i++) { + ILabelDecorator decorator= (ILabelDecorator) fLabelDecorators.get(i); + decorator.addListener(listener); + } + } + super.addListener(listener); + } + + /* (non-Javadoc) + * @see IBaseLabelProvider#isLabelProperty(Object, String) + */ + public boolean isLabelProperty(Object element, String property) { + return true; + } + + /* (non-Javadoc) + * @see IBaseLabelProvider#removeListener(ILabelProviderListener) + */ + public void removeListener(ILabelProviderListener listener) { + if (fLabelDecorators != null) { + for (int i= 0; i < fLabelDecorators.size(); i++) { + ILabelDecorator decorator= (ILabelDecorator) fLabelDecorators.get(i); + decorator.removeListener(listener); + } + } + super.removeListener(listener); + } + + public static ILabelDecorator[] getDecorators(boolean errortick, ILabelDecorator extra) { + if (errortick) { + if (extra == null) { + return new ILabelDecorator[] {}; + } else { + return new ILabelDecorator[] { extra }; + } + } + if (extra != null) { + return new ILabelDecorator[] { extra }; + } + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.IColorProvider#getForeground(java.lang.Object) + */ + public Color getForeground(Object element) { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.IColorProvider#getBackground(java.lang.Object) + */ + public Color getBackground(Object element) { + return null; + } + +} diff --git a/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/DecoratingCLabelProvider.java b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/DecoratingCLabelProvider.java new file mode 100644 index 00000000000..b9a22020261 --- /dev/null +++ b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/DecoratingCLabelProvider.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * 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 + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.browser.cbrowsing; + +import org.eclipse.swt.graphics.Color; + +import org.eclipse.jface.viewers.DecoratingLabelProvider; +import org.eclipse.jface.viewers.IColorProvider; + +import org.eclipse.ui.PlatformUI; + +public class DecoratingCLabelProvider extends DecoratingLabelProvider implements IColorProvider { + + /** + * Decorating label provider for Java. Combines a JavaUILabelProvider + * with problem and override indicuator with the workbench decorator (label + * decorator extension point). + */ + public DecoratingCLabelProvider(CUILabelProvider labelProvider) { + this(labelProvider, true); + } + + /** + * Decorating label provider for Java. Combines a JavaUILabelProvider + * (if enabled with problem indicator) with the workbench + * decorator (label decorator extension point). + */ + public DecoratingCLabelProvider(CUILabelProvider labelProvider, boolean errorTick) { + super(labelProvider, PlatformUI.getWorkbench().getDecoratorManager().getLabelDecorator()); + if (errorTick) { + labelProvider.addLabelDecorator(new ProblemsLabelDecorator(null)); + } + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.IColorProvider#getForeground(java.lang.Object) + */ + public Color getForeground(Object element) { + // label provider is a JavaUILabelProvider + return ((IColorProvider) getLabelProvider()).getForeground(element); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.IColorProvider#getBackground(java.lang.Object) + */ + public Color getBackground(Object element) { + // label provider is a JavaUILabelProvider + return ((IColorProvider) getLabelProvider()).getBackground(element); + } + +} diff --git a/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/FilterUpdater.java b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/FilterUpdater.java new file mode 100644 index 00000000000..aeb4aecb44e --- /dev/null +++ b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/FilterUpdater.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * 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 + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.browser.cbrowsing; + +import org.eclipse.swt.widgets.Control; + +import org.eclipse.jface.util.Assert; +import org.eclipse.jface.viewers.StructuredViewer; + +import org.eclipse.core.resources.IResourceChangeEvent; +import org.eclipse.core.resources.IResourceChangeListener; +import org.eclipse.core.resources.IResourceDelta; + + +public class FilterUpdater implements IResourceChangeListener { + + private StructuredViewer fViewer; + + public FilterUpdater(StructuredViewer viewer) { + Assert.isNotNull(viewer); + fViewer= viewer; + } + + /* (non-Javadoc) + * @see org.eclipse.core.resources.IResourceChangeListener#resourceChanged(org.eclipse.core.resources.IResourceChangeEvent) + */ + public void resourceChanged(IResourceChangeEvent event) { + IResourceDelta delta= event.getDelta(); + if (delta == null) + return; + + IResourceDelta[] projDeltas = delta.getAffectedChildren(IResourceDelta.CHANGED); + for (int i= 0; i < projDeltas.length; i++) { + IResourceDelta pDelta= projDeltas[i]; + if ((pDelta.getFlags() & IResourceDelta.DESCRIPTION) != 0) { + final Control ctrl= fViewer.getControl(); + if (ctrl != null && !ctrl.isDisposed()) { + // async is needed due to bug 33783 + ctrl.getDisplay().asyncExec(new Runnable() { + public void run() { + if (!ctrl.isDisposed()) + fViewer.refresh(false); + } + }); + } + } + } + } +} diff --git a/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/LexicalSortingAction.java b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/LexicalSortingAction.java new file mode 100644 index 00000000000..dbefbe28273 --- /dev/null +++ b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/LexicalSortingAction.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * 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 + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.browser.cbrowsing; + +import org.eclipse.cdt.internal.ui.CPluginImages; +import org.eclipse.cdt.internal.ui.ICHelpContextIds; +import org.eclipse.cdt.ui.CUIPlugin; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.viewers.StructuredViewer; +import org.eclipse.swt.custom.BusyIndicator; +import org.eclipse.ui.help.WorkbenchHelp; + +/* + * XXX: This class should become part of the MemberFilterActionGroup + * which should be renamed to MemberActionsGroup + */ +public class LexicalSortingAction extends Action { + private TypeInfoSorter fSorter= new TypeInfoSorter(); + private StructuredViewer fViewer; + private String fPreferenceKey; + + public LexicalSortingAction(StructuredViewer viewer, String id) { + super(); + fViewer= viewer; + fPreferenceKey= "LexicalSortingAction." + id + ".isChecked"; //$NON-NLS-1$ //$NON-NLS-2$ + setText(CBrowsingMessages.getString("LexicalSortingAction.label")); //$NON-NLS-1$ + CPluginImages.setImageDescriptors(this, "T_LCL", CPluginImages.IMG_ALPHA_SORTING); //$NON-NLS-1$ //$NON-NLS-2$ + setToolTipText(CBrowsingMessages.getString("LexicalSortingAction.tooltip")); //$NON-NLS-1$ + setDescription(CBrowsingMessages.getString("LexicalSortingAction.description")); //$NON-NLS-1$ + boolean checked= CUIPlugin.getDefault().getPreferenceStore().getBoolean(fPreferenceKey); //$NON-NLS-1$ + valueChanged(checked, false); + WorkbenchHelp.setHelp(this, ICHelpContextIds.LEXICAL_SORTING_BROWSING_ACTION); + } + + public void run() { + valueChanged(isChecked(), true); + } + + private void valueChanged(final boolean on, boolean store) { + setChecked(on); + BusyIndicator.showWhile(fViewer.getControl().getDisplay(), new Runnable() { + public void run() { + if (on) + fViewer.setSorter(fSorter); + else + fViewer.setSorter(null); + } + }); + + if (store) + CUIPlugin.getDefault().getPreferenceStore().setValue(fPreferenceKey, on); + } +} diff --git a/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/MembersView.java b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/MembersView.java new file mode 100644 index 00000000000..ff7c2ce4a37 --- /dev/null +++ b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/MembersView.java @@ -0,0 +1,239 @@ +/******************************************************************************* + * 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 + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.browser.cbrowsing; + +import org.eclipse.cdt.core.browser.ITypeInfo; +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.core.model.ICModel; +import org.eclipse.cdt.core.model.ICProject; +import org.eclipse.cdt.core.model.IMember; +import org.eclipse.cdt.core.model.ISourceRoot; +import org.eclipse.cdt.internal.ui.ICHelpContextIds; +import org.eclipse.cdt.internal.ui.search.CElementLabels; +import org.eclipse.cdt.internal.ui.util.ProblemTreeViewer; +import org.eclipse.cdt.ui.CUIPlugin; +import org.eclipse.cdt.ui.PreferenceConstants; +import org.eclipse.jface.action.IToolBarManager; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.IContentProvider; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.StructuredViewer; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IMemento; +import org.eclipse.ui.part.IShowInTargetList; + +public class MembersView extends CBrowsingPart implements IPropertyChangeListener { + +// private MemberFilterActionGroup fMemberFilterActionGroup; + + + public MembersView() { + setHasWorkingSetFilter(false); + setHasCustomSetFilter(true); + CUIPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(this); + } + + /** + * Answer the property defined by key. + */ + public Object getAdapter(Class key) { + if (key == IShowInTargetList.class) { + return new IShowInTargetList() { + public String[] getShowInTargetIds() { + return new String[] { CUIPlugin.CVIEW_ID }; + } + + }; + } + return super.getAdapter(key); + } + + /** + * Creates and returns the label provider for this part. + * + * @return the label provider + * @see org.eclipse.jface.viewers.ILabelProvider + */ + protected LabelProvider createLabelProvider() { + return new AppearanceAwareLabelProvider( + AppearanceAwareLabelProvider.DEFAULT_TEXTFLAGS | CElementLabels.F_APP_TYPE_SIGNATURE, + AppearanceAwareLabelProvider.DEFAULT_IMAGEFLAGS + ); + } + + /** + * Returns the context ID for the Help system + * + * @return the string used as ID for the Help context + */ + protected String getHelpContextId() { + return ICHelpContextIds.MEMBERS_VIEW; + } + + protected String getLinkToEditorKey() { + return PreferenceConstants.LINK_BROWSING_MEMBERS_TO_EDITOR; + } + + /** + * Creates the the viewer of this part. + * + * @param parent the parent for the viewer + */ + protected StructuredViewer createViewer(Composite parent) { + ProblemTreeViewer viewer= new ProblemTreeViewer(parent, SWT.MULTI); +// fMemberFilterActionGroup= new MemberFilterActionGroup(viewer, JavaUI.ID_MEMBERS_VIEW); + return viewer; + } + + protected void fillToolBar(IToolBarManager tbm) { + tbm.add(new LexicalSortingAction(getViewer(), CUIPlugin.ID_MEMBERS_VIEW)); +// fMemberFilterActionGroup.contributeToToolBar(tbm); + super.fillToolBar(tbm); + } + + /** + * Answers if the given element is a valid + * input for this part. + * + * @param element the object to test + * @return if the given element is a valid input + */ + protected boolean isValidInput(Object element) { + if (element instanceof ITypeInfo) { + ITypeInfo type= (ITypeInfo)element; + if (type.getCElementType() == ICElement.C_NAMESPACE && exists(type)) + return true; + } + return false; + } + + /** + * Answers if the given element is a valid + * element for this part. + * + * @param element the object to test + * @return if the given element is a valid element + */ + protected boolean isValidElement(Object element) { + if (element instanceof ICElement) { + if (element instanceof ICModel || element instanceof ICProject || element instanceof ISourceRoot) + return false; + return true; + } + return false; + } + + /* + * Implements method from IViewPart. + */ + public void saveState(IMemento memento) { + super.saveState(memento); +// fMemberFilterActionGroup.saveState(memento); + } + + protected void restoreState(IMemento memento) { + super.restoreState(memento); +// fMemberFilterActionGroup.restoreState(memento); + getViewer().getControl().setRedraw(false); + getViewer().refresh(); + getViewer().getControl().setRedraw(true); + } + + protected void hookViewerListeners() { + super.hookViewerListeners(); + getViewer().addDoubleClickListener(new IDoubleClickListener() { + public void doubleClick(DoubleClickEvent event) { + TreeViewer viewer= (TreeViewer)getViewer(); + Object element= ((IStructuredSelection)event.getSelection()).getFirstElement(); + if (viewer.isExpandable(element)) + viewer.setExpandedState(element, !viewer.getExpandedState(element)); + } + }); + } + + boolean isInputAWorkingCopy() { + Object input= getViewer().getInput(); +// if (input instanceof ICElement) { +// ICompilationUnit cu= (ICompilationUnit)((IJavaElement)input).getAncestor(IJavaElement.COMPILATION_UNIT); +// if (cu != null) +// return cu.isWorkingCopy(); +// } + return false; + } + + protected void restoreSelection() { + IEditorPart editor= getViewSite().getPage().getActiveEditor(); + if (editor != null) + setSelectionFromEditor(editor); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent) + */ + public void propertyChange(PropertyChangeEvent event) { +// if (MembersOrderPreferenceCache.isMemberOrderProperty(event.getProperty())) { +// getViewer().refresh(); +// } + } + + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.ui.browsing.JavaBrowsingPart#dispose() + */ + public void dispose() { +// if (fMemberFilterActionGroup != null) { +// fMemberFilterActionGroup.dispose(); +// fMemberFilterActionGroup= null; +// } + super.dispose(); + CUIPlugin.getDefault().getPreferenceStore().removePropertyChangeListener(this); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.ui.browser.cbrowsing.CBrowsingPart#createContentProvider() + */ + protected IContentProvider createContentProvider() { + return new MembersViewContentProvider(this); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.ui.browser.cbrowsing.CBrowsingPart#findInputForElement(java.lang.Object) + */ + protected Object findInputForElement(Object element) { + return getMembersInput(element); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.ui.browser.cbrowsing.CBrowsingPart#findElementToSelect(java.lang.Object) + */ + protected Object findElementToSelect(Object element) { + if (element instanceof ICModel || element instanceof ICProject || element instanceof ISourceRoot) { + return null; + } + + if (element instanceof ICElement) { + ICElement parent = (ICElement)element; + while (parent != null) { + if (parent instanceof IMember && exists(parent)) + return parent; + parent = parent.getParent(); + } + } + + return null; + } +} diff --git a/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/MembersViewContentProvider.java b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/MembersViewContentProvider.java new file mode 100644 index 00000000000..e10d39aafa0 --- /dev/null +++ b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/MembersViewContentProvider.java @@ -0,0 +1,193 @@ +/******************************************************************************* + * 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 + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.browser.cbrowsing; + +import java.lang.reflect.InvocationTargetException; +import java.util.Iterator; + +import org.eclipse.cdt.core.browser.AllTypesCache; +import org.eclipse.cdt.core.browser.ITypeInfo; +import org.eclipse.cdt.core.browser.ITypeReference; +import org.eclipse.cdt.core.model.CModelException; +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.core.model.IParent; +import org.eclipse.cdt.internal.ui.browser.opentype.OpenTypeMessages; +import org.eclipse.cdt.internal.ui.util.ExceptionHandler; +import org.eclipse.cdt.ui.CUIPlugin; +import org.eclipse.core.runtime.IProgressMonitor; +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.util.Assert; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.widgets.Shell; + +class MembersViewContentProvider extends CBrowsingContentProvider { + + MembersViewContentProvider(CBrowsingPart browsingPart) { + super(browsingPart); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object) + */ + public boolean hasChildren(Object element) { + if (element == null || (element instanceof ITypeInfo && !((ITypeInfo)element).exists())) { + return false; + } + + try { + startReadInDisplayThread(); + + if (element instanceof ITypeInfo) { + ITypeInfo info = (ITypeInfo) element; + return (info.getCElementType() != ICElement.C_TYPEDEF); + } + + return false; +// } catch (CModelException e) { +// return false; + } finally { + finishedReadInDisplayThread(); + } + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object) + */ + public Object[] getChildren(Object element) { + if (element == null || (element instanceof ICElement && !((ICElement)element).exists())) { + return NO_CHILDREN; + } + + try { + startReadInDisplayThread(); + + if (element instanceof IStructuredSelection) { + Assert.isLegal(false); + Object[] result= new Object[0]; + Class clazz= null; + Iterator iter= ((IStructuredSelection)element).iterator(); + while (iter.hasNext()) { + Object item= iter.next(); + if (clazz == null) + clazz= item.getClass(); + if (clazz == item.getClass()) + result= concatenate(result, getChildren(item)); + else + return NO_CHILDREN; + } + return result; + } + + if (element instanceof ITypeInfo) { + ITypeInfo info = (ITypeInfo) element; + if (info.getCElementType() == ICElement.C_NAMESPACE) { + return NO_CHILDREN; // shouldn't get here... + } + ICElement elem = getCElement(info); + if (elem != null && elem instanceof IParent) { + return ((IParent)elem).getChildren(); + } + return NO_CHILDREN; + } + + return NO_CHILDREN; + } catch (CModelException e) { + return NO_CHILDREN; + } finally { + finishedReadInDisplayThread(); + } + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object) + */ + public Object getParent(Object element) { + if (element == null || (element instanceof ITypeInfo && !((ITypeInfo)element).exists())) { + return null; + } + + try { + startReadInDisplayThread(); + + if (element instanceof ITypeInfo) { + ITypeInfo info = (ITypeInfo)element; + if (info.isEnclosedType()) { + return info.getEnclosingType(); + } else { +// return info.getEnclosingProject(); + return null; + } + } + + return null; +// } catch (CModelException e) { +// return false; + } finally { + finishedReadInDisplayThread(); + } + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object) + */ + public Object[] getElements(Object inputElement) { + return getChildren(inputElement); + } + + private ICElement getCElement(ITypeInfo info) { + ITypeReference location = info.getResolvedReference(); + if (location == null) { + final ITypeInfo[] typesToResolve = new ITypeInfo[] { info }; + IRunnableWithProgress runnable = new IRunnableWithProgress() { + public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { + AllTypesCache.resolveTypeLocation(typesToResolve[0], monitor); + if (monitor.isCanceled()) { + throw new InterruptedException(); + } + } + }; + + IRunnableContext runnableContext = new ProgressMonitorDialog(getShell()); + 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 null; + } catch (InterruptedException e) { + // cancelled by user + return null; + } + + location = info.getResolvedReference(); + } + + ICElement elem = null; + if (location != null) + elem = location.getCElement(); + + if (elem == null) { + // could not resolve location + String title = OpenTypeMessages.getString("OpenTypeAction.errorTitle"); //$NON-NLS-1$ + String message = OpenTypeMessages.getFormattedString("OpenTypeAction.errorTypeNotFound", info.getQualifiedTypeName().toString()); //$NON-NLS-1$ + MessageDialog.openError(getShell(), title, message); + } + return elem; + } + + protected Shell getShell() { + return CUIPlugin.getActiveWorkbenchShell(); + } +} diff --git a/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/NamespacesView.java b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/NamespacesView.java new file mode 100644 index 00000000000..afa92cbf95e --- /dev/null +++ b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/NamespacesView.java @@ -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 + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.browser.cbrowsing; + +import org.eclipse.cdt.core.model.ICProject; +import org.eclipse.cdt.core.model.ISourceRoot; +import org.eclipse.cdt.internal.ui.ICHelpContextIds; +import org.eclipse.cdt.internal.ui.util.ProblemTableViewer; +import org.eclipse.cdt.ui.CUIPlugin; +import org.eclipse.cdt.ui.PreferenceConstants; +import org.eclipse.cdt.ui.browser.typeinfo.TypeInfoLabelProvider; +import org.eclipse.jface.viewers.IContentProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.StructuredViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.IActionBars; +import org.eclipse.ui.IPageLayout; +import org.eclipse.ui.part.IShowInTargetList; + +public class NamespacesView extends CBrowsingPart { + +// private SelectAllAction fSelectAllAction; + + /** + * Creates and returns the label provider for this part. + * + * @return the label provider + * @see org.eclipse.jface.viewers.ILabelProvider + */ + protected LabelProvider createLabelProvider() { + return new TypeInfoLabelProvider(TypeInfoLabelProvider.SHOW_FULLY_QUALIFIED); + } + + /** + * Answer the property defined by key. + */ + public Object getAdapter(Class key) { + if (key == IShowInTargetList.class) { + return new IShowInTargetList() { + public String[] getShowInTargetIds() { + return new String[] { CUIPlugin.CVIEW_ID, IPageLayout.ID_RES_NAV }; + } + + }; + } + return super.getAdapter(key); + } + + /** + * Creates the viewer of this part dependent on the current + * layout. + * + * @param parent the parent for the viewer + */ + protected StructuredViewer createViewer(Composite parent) { + StructuredViewer viewer; +// if(isInListState()) + viewer= createTableViewer(parent); +// else +// viewer= createTreeViewer(parent); + +// fWrappedViewer.setViewer(viewer); +// return fWrappedViewer; + return viewer; + } + private ProblemTableViewer createTableViewer(Composite parent) { + return new ProblemTableViewer(parent, SWT.MULTI); + } + + /** + * Creates the the content provider of this part. + */ + protected IContentProvider createContentProvider() { + return new NamespacesViewContentProvider(this); + } + + + + /** + * Adds filters the viewer of this part. + */ + protected void addFilters() { + super.addFilters(); +// getViewer().addFilter(new NonCElementFilter()); + } + + /** + * Answers if the given element is a valid + * input for this part. + * + * @param element the object to test + * @return if the given element is a valid input + */ + protected boolean isValidInput(Object element) { + return (element instanceof ICProject || element instanceof ISourceRoot); + } + + /** + * Answers if the given element is a valid + * element for this part. + * + * @param element the object to test + * @return if the given element is a valid element + */ + protected boolean isValidElement(Object element) { + return isValidNamespace(element); + } + + /** + * Returns the context ID for the Help system + * + * @return the string used as ID for the Help context + */ + protected String getHelpContextId() { + return ICHelpContextIds.TYPES_VIEW; + } + + protected String getLinkToEditorKey() { + return PreferenceConstants.LINK_BROWSING_TYPES_TO_EDITOR; + } + + protected void createActions() { + super.createActions(); +// fSelectAllAction= new SelectAllAction((TableViewer)getViewer()); + } + + protected void fillActionBars(IActionBars actionBars) { + super.fillActionBars(actionBars); + + // Add selectAll action handlers. +// actionBars.setGlobalActionHandler(IWorkbenchActionConstants.SELECT_ALL, fSelectAllAction); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.ui.browser.cbrowsing.CBrowsingPart#findInputForElement(java.lang.Object) + */ + protected Object findInputForElement(Object element) { + return getNamespaceInput(element); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.ui.browser.cbrowsing.CBrowsingPart#findElementToSelect(java.lang.Object) + */ + protected Object findElementToSelect(Object element) { + return getTypesInput(element); + } +} diff --git a/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/NamespacesViewContentProvider.java b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/NamespacesViewContentProvider.java new file mode 100644 index 00000000000..0204986db88 --- /dev/null +++ b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/NamespacesViewContentProvider.java @@ -0,0 +1,187 @@ +/******************************************************************************* + * 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 + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.browser.cbrowsing; + +import java.lang.reflect.InvocationTargetException; +import java.util.Iterator; + +import org.eclipse.cdt.core.browser.AllTypesCache; +import org.eclipse.cdt.core.browser.ITypeInfo; +import org.eclipse.cdt.core.browser.ITypeSearchScope; +import org.eclipse.cdt.core.browser.TypeSearchScope; +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.core.model.ICProject; +import org.eclipse.cdt.core.model.ISourceRoot; +import org.eclipse.cdt.internal.ui.browser.opentype.OpenTypeMessages; +import org.eclipse.cdt.internal.ui.util.ExceptionHandler; +import org.eclipse.cdt.ui.CUIPlugin; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jface.dialogs.ProgressMonitorDialog; +import org.eclipse.jface.operation.IRunnableContext; +import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.jface.util.Assert; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.widgets.Shell; + +class NamespacesViewContentProvider extends CBrowsingContentProvider { + + NamespacesViewContentProvider(CBrowsingPart browsingPart) { + super(browsingPart); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object) + */ + public boolean hasChildren(Object element) { + if (element == null || (element instanceof ICElement && !((ICElement)element).exists())) { + return false; + } + + try { + startReadInDisplayThread(); + + if (element instanceof ICProject) { + return true; +// TypeSearchScope scope = new TypeSearchScope(); +// scope.add((ICProject)element); +// return AllTypesCache.getNamespaces(scope, true); + } + + if (element instanceof ISourceRoot) { + return true; +// TypeSearchScope scope = new TypeSearchScope(); +// scope.add((ISourceRoot)element); +// return AllTypesCache.getNamespaces(scope, true); + } + + return false; +// } catch (CModelException e) { +// return false; + } finally { + finishedReadInDisplayThread(); + } + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object) + */ + public Object[] getChildren(Object element) { + if (element == null || (element instanceof ICElement && !((ICElement)element).exists())) { + return NO_CHILDREN; + } + + try { + startReadInDisplayThread(); + + if (element instanceof IStructuredSelection) { + Assert.isLegal(false); + Object[] result= new Object[0]; + Class clazz= null; + Iterator iter= ((IStructuredSelection)element).iterator(); + while (iter.hasNext()) { + Object item= iter.next(); + if (clazz == null) + clazz= item.getClass(); + if (clazz == item.getClass()) + result= concatenate(result, getChildren(item)); + else + return NO_CHILDREN; + } + return result; + } + + if (element instanceof ICProject) { + TypeSearchScope scope = new TypeSearchScope(); + scope.add((ICProject)element); + return getNamespaces(scope); + } + + if (element instanceof ISourceRoot) { + TypeSearchScope scope = new TypeSearchScope(); + scope.add((ISourceRoot)element); + return getNamespaces(scope); + } + + return NO_CHILDREN; +// } catch (CModelException e) { +// return NO_CHILDREN; + } finally { + finishedReadInDisplayThread(); + } + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object) + */ + public Object getParent(Object element) { + if (element == null || (element instanceof ITypeInfo && !((ITypeInfo)element).exists())) { + return null; + } + + try { + startReadInDisplayThread(); + + if (element instanceof ITypeInfo) { + ITypeInfo info = (ITypeInfo)element; + if (info.isEnclosedType()) { + return info.getEnclosingType(); + } else { +// return info.getEnclosingProject(); + return null; + } + } + + return null; +// } catch (CModelException e) { +// return false; + } finally { + finishedReadInDisplayThread(); + } + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object) + */ + public Object[] getElements(Object inputElement) { + return getChildren(inputElement); + } + + private Object[] getNamespaces(final ITypeSearchScope scope) { + if (!AllTypesCache.isCacheUpToDate(scope)) { + IRunnableWithProgress runnable = new IRunnableWithProgress() { + public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { + AllTypesCache.updateCache(scope, monitor); + if (monitor.isCanceled()) { + throw new InterruptedException(); + } + } + }; + + IRunnableContext runnableContext = new ProgressMonitorDialog(getShell()); + 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 NO_CHILDREN; + } catch (InterruptedException e) { + // cancelled by user + return NO_CHILDREN; + } + } + return AllTypesCache.getNamespaces(scope, true); + } + + protected Shell getShell() { + return CUIPlugin.getActiveWorkbenchShell(); + } +} diff --git a/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/OpenProjectAction.java b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/OpenProjectAction.java new file mode 100644 index 00000000000..c4c03db5397 --- /dev/null +++ b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/OpenProjectAction.java @@ -0,0 +1,218 @@ +/******************************************************************************* + * 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 + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.browser.cbrowsing; + +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.cdt.internal.ui.ICHelpContextIds; +import org.eclipse.cdt.internal.ui.actions.ActionMessages; +import org.eclipse.cdt.internal.ui.actions.WorkbenchRunnableAdapter; +import org.eclipse.cdt.internal.ui.util.ExceptionHandler; +import org.eclipse.cdt.ui.CElementLabelProvider; +import org.eclipse.cdt.ui.CUIPlugin; +import org.eclipse.cdt.ui.actions.SelectionDispatchAction; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.MultiStatus; +import org.eclipse.core.runtime.SubProgressMonitor; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResourceChangeEvent; +import org.eclipse.core.resources.IResourceChangeListener; +import org.eclipse.core.resources.IResourceDelta; +import org.eclipse.core.resources.IWorkspaceRunnable; +import org.eclipse.core.resources.ResourcesPlugin; + +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.window.Window; + +import org.eclipse.ui.IWorkbenchSite; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.actions.OpenResourceAction; +import org.eclipse.ui.dialogs.ElementListSelectionDialog; +import org.eclipse.ui.help.WorkbenchHelp; + +/** + * Action to open a closed project. Action either opens the closed projects + * provided by the strucutured selection or present a dialog from which the + * user can select the projects to be opened. + * + *

+ * This class may be instantiated; it is not intended to be subclassed. + *

+ * + * @since 2.0 + */ +public class OpenProjectAction extends SelectionDispatchAction implements IResourceChangeListener { + + private static final int EMPTY_SELECTION= 1; + private static final int ELEMENT_SELECTION= 2; + + private int fMode; + private OpenResourceAction fWorkbenchAction; + + /** + * Creates a new OpenProjectAction. The action requires + * that the selection provided by the site's selection provider is of type + * org.eclipse.jface.viewers.IStructuredSelection. + * + * @param site the site providing context information for this action + */ + public OpenProjectAction(IWorkbenchSite site) { + super(site); + fWorkbenchAction= new OpenResourceAction(site.getShell()); + setText(fWorkbenchAction.getText()); + setToolTipText(fWorkbenchAction.getToolTipText()); + setEnabled(hasCloseProjects()); + WorkbenchHelp.setHelp(this, ICHelpContextIds.OPEN_PROJECT_ACTION); + } + + /* + * @see IResourceChangeListener#resourceChanged(IResourceChangeEvent) + */ + public void resourceChanged(IResourceChangeEvent event) { + fWorkbenchAction.resourceChanged(event); + switch (fMode) { + case ELEMENT_SELECTION: + setEnabled(fWorkbenchAction.isEnabled()); + break; + case EMPTY_SELECTION: + internalResourceChanged(event); + break; + } + } + + private void internalResourceChanged(IResourceChangeEvent event) { + IResourceDelta delta = event.getDelta(); + if (delta != null) { + IResourceDelta[] projDeltas = delta.getAffectedChildren(IResourceDelta.CHANGED); + for (int i = 0; i < projDeltas.length; ++i) { + IResourceDelta projDelta = projDeltas[i]; + if ((projDelta.getFlags() & IResourceDelta.OPEN) != 0) { + setEnabled(hasCloseProjects()); + return; + } + } + } + } + + //---- normal selection ------------------------------------- + + /* (non-Javadoc) + * @see org.eclipse.jdt.ui.actions.SelectionDispatchAction#selectionChanged(org.eclipse.jface.viewers.ISelection) + */ + public void selectionChanged(ISelection selection) { + setEnabled(hasCloseProjects()); + fMode= EMPTY_SELECTION; + } + + /* (non-Javadoc) + * @see org.eclipse.jdt.ui.actions.SelectionDispatchAction#run(org.eclipse.jface.viewers.ISelection) + */ + public void run(ISelection selection) { + internalRun(); + } + + //---- structured selection --------------------------------------- + + /* (non-Javadoc) + * @see org.eclipse.jdt.ui.actions.SelectionDispatchAction#selectionChanged(org.eclipse.jface.viewers.IStructuredSelection) + */ + public void selectionChanged(IStructuredSelection selection) { + if (selection.isEmpty()) { + setEnabled(hasCloseProjects()); + fMode= EMPTY_SELECTION; + return; + } + fWorkbenchAction.selectionChanged(selection); + setEnabled(fWorkbenchAction.isEnabled()); + fMode= ELEMENT_SELECTION; + } + + + /* (non-Javadoc) + * @see org.eclipse.jdt.ui.actions.SelectionDispatchAction#run(org.eclipse.jface.viewers.IStructuredSelection) + */ + public void run(IStructuredSelection selection) { + if (selection.isEmpty()) { + internalRun(); + return; + } + fWorkbenchAction.run(); + } + + private void internalRun() { + ElementListSelectionDialog dialog= new ElementListSelectionDialog(getShell(), new CElementLabelProvider()); + dialog.setTitle(ActionMessages.getString("OpenProjectAction.dialog.title")); //$NON-NLS-1$ + dialog.setMessage(ActionMessages.getString("OpenProjectAction.dialog.message")); //$NON-NLS-1$ + dialog.setElements(getClosedProjects()); + dialog.setMultipleSelection(true); + int result= dialog.open(); + if (result != Window.OK) + return; + final Object[] projects= dialog.getResult(); + IWorkspaceRunnable runnable= createRunnable(projects); + try { + PlatformUI.getWorkbench().getProgressService().run(true, true, new WorkbenchRunnableAdapter(runnable)); + } catch (InvocationTargetException e) { + ExceptionHandler.handle(e, getShell(), + ActionMessages.getString("OpenProjectAction.dialog.title"), //$NON-NLS-1$ + ActionMessages.getString("OpenProjectAction.error.message")); //$NON-NLS-1$ + } catch (InterruptedException e) { + } + } + + private IWorkspaceRunnable createRunnable(final Object[] projects) { + return new IWorkspaceRunnable() { + public void run(IProgressMonitor monitor) throws CoreException { + monitor.beginTask("", projects.length); //$NON-NLS-1$ + MultiStatus errorStatus= null; + for (int i = 0; i < projects.length; i++) { + IProject project= (IProject)projects[i]; + try { + project.open(new SubProgressMonitor(monitor, 1)); + } catch (CoreException e) { + if (errorStatus == null) + errorStatus = new MultiStatus(CUIPlugin.getPluginId(), IStatus.ERROR, ActionMessages.getString("OpenProjectAction.error.message"), e); //$NON-NLS-1$ + errorStatus.merge(e.getStatus()); + } + } + monitor.done(); + if (errorStatus != null) + throw new CoreException(errorStatus); + } + }; + } + + private Object[] getClosedProjects() { + IProject[] projects= ResourcesPlugin.getWorkspace().getRoot().getProjects(); + List result= new ArrayList(5); + for (int i = 0; i < projects.length; i++) { + IProject project= projects[i]; + if (!project.isOpen()) + result.add(project); + } + return result.toArray(); + } + + private boolean hasCloseProjects() { + IProject[] projects= ResourcesPlugin.getWorkspace().getRoot().getProjects(); + for (int i = 0; i < projects.length; i++) { + if (!projects[i].isOpen()) + return true; + } + return false; + } +} diff --git a/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/ProblemsLabelDecorator.java b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/ProblemsLabelDecorator.java new file mode 100644 index 00000000000..fba095e9721 --- /dev/null +++ b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/ProblemsLabelDecorator.java @@ -0,0 +1,371 @@ +/******************************************************************************* + * 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 + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.browser.cbrowsing; + +import java.util.Iterator; +import java.util.Set; + +import org.eclipse.cdt.core.model.CModelException; +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.core.model.ISourceRange; +import org.eclipse.cdt.core.model.ISourceReference; +import org.eclipse.cdt.core.model.ITranslationUnit; +import org.eclipse.cdt.internal.corext.refactoring.ListenerList; +import org.eclipse.cdt.internal.ui.CPluginImages; +import org.eclipse.cdt.internal.ui.util.IProblemChangedListener; +import org.eclipse.cdt.internal.ui.util.ImageDescriptorRegistry; +import org.eclipse.cdt.internal.ui.viewsupport.ImageImageDescriptor; +import org.eclipse.cdt.ui.CElementImageDescriptor; +import org.eclipse.cdt.ui.CUIPlugin; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IResourceStatus; +import org.eclipse.core.runtime.CoreException; + +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Control; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.text.Position; +import org.eclipse.jface.text.source.Annotation; +import org.eclipse.jface.text.source.IAnnotationModel; +import org.eclipse.jface.viewers.IBaseLabelProvider; +import org.eclipse.jface.viewers.IDecoration; +import org.eclipse.jface.viewers.ILabelDecorator; +import org.eclipse.jface.viewers.ILabelProvider; +import org.eclipse.jface.viewers.ILabelProviderListener; +import org.eclipse.jface.viewers.ILightweightLabelDecorator; +import org.eclipse.jface.viewers.LabelProviderChangedEvent; + +import org.eclipse.ui.part.FileEditorInput; +import org.eclipse.ui.texteditor.MarkerAnnotation; + +/** + * LabelDecorator that decorates an element's image with error and warning overlays that + * represent the severity of markers attached to the element's underlying resource. To see + * a problem decoration for a marker, the marker needs to be a subtype of IMarker.PROBLEM. + *

+ * Note: Only images for elements in Java projects are currently updated on marker changes. + *

+ * + * @since 2.0 + */ +public class ProblemsLabelDecorator implements ILabelDecorator, ILightweightLabelDecorator { + + /** + * This is a special LabelProviderChangedEvent carring additional + * information whether the event orgins from a maker change. + *

+ * ProblemsLabelChangedEvents are only generated by + * ProblemsLabelDecorators. + *

+ */ + public static class ProblemsLabelChangedEvent extends LabelProviderChangedEvent { + + private boolean fMarkerChange; + + /** + * Note: This constructor is for internal use only. Clients should not call this constructor. + */ + public ProblemsLabelChangedEvent(IBaseLabelProvider source, IResource[] changedResource, boolean isMarkerChange) { + super(source, changedResource); + fMarkerChange= isMarkerChange; + } + + /** + * Returns whether this event origins from marker changes. If false an annotation + * model change is the origin. In this case viewers not displaying working copies can ignore these + * events. + * + * @return if this event origins from a marker change. + */ + public boolean isMarkerChange() { + return fMarkerChange; + } + + } + + private static final int ERRORTICK_WARNING= CElementImageDescriptor.WARNING; + private static final int ERRORTICK_ERROR= CElementImageDescriptor.ERROR; + + private ImageDescriptorRegistry fRegistry; + private boolean fUseNewRegistry= false; + private IProblemChangedListener fProblemChangedListener; + + private ListenerList fListeners; + + /** + * Creates a new ProblemsLabelDecorator. + */ + public ProblemsLabelDecorator() { + this(null); + fUseNewRegistry= true; + } + + /* + * Creates decorator with a shared image registry. + * + * @param registry The registry to use or null to use the Java plugin's + * image registry. + */ + /** + * Note: This constructor is for internal use only. Clients should not call this constructor. + */ + public ProblemsLabelDecorator(ImageDescriptorRegistry registry) { + fRegistry= registry; + fProblemChangedListener= null; + } + + private ImageDescriptorRegistry getRegistry() { + if (fRegistry == null) { + fRegistry= fUseNewRegistry ? new ImageDescriptorRegistry() : CUIPlugin.getImageDescriptorRegistry(); + } + return fRegistry; + } + + + /* (non-Javadoc) + * @see ILabelDecorator#decorateText(String, Object) + */ + public String decorateText(String text, Object element) { + return text; + } + + /* (non-Javadoc) + * @see ILabelDecorator#decorateImage(Image, Object) + */ + public Image decorateImage(Image image, Object obj) { + int adornmentFlags= computeAdornmentFlags(obj); + if (adornmentFlags != 0) { + ImageDescriptor baseImage= new ImageImageDescriptor(image); + Rectangle bounds= image.getBounds(); + return getRegistry().get(new CElementImageDescriptor(baseImage, adornmentFlags, new Point(bounds.width, bounds.height))); + } + return image; + } + + /** + * Note: This method is for internal use only. Clients should not call this method. + */ + protected int computeAdornmentFlags(Object obj) { + try { + if (obj instanceof ICElement) { + ICElement element= (ICElement) obj; + int type= element.getElementType(); + switch (type) { + case ICElement.C_PROJECT: + case ICElement.C_CCONTAINER: + return getErrorTicksFromMarkers(element.getResource(), IResource.DEPTH_INFINITE, null); +// case ICElement.PACKAGE_FRAGMENT: +// case ICElement.CLASS_FILE: +// return getErrorTicksFromMarkers(element.getResource(), IResource.DEPTH_ONE, null); +// case ICElement.COMPILATION_UNIT: +// case ICElement.PACKAGE_DECLARATION: +// case ICElement.IMPORT_DECLARATION: +// case ICElement.IMPORT_CONTAINER: +// case ICElement.TYPE: +// case ICElement.INITIALIZER: +// case ICElement.METHOD: +// case ICElement.FIELD: +// case ICElement.LOCAL_VARIABLE: +// ICompilationUnit cu= (ICompilationUnit) element.getAncestor(ICElement.COMPILATION_UNIT); +// if (cu != null) { +// ISourceReference ref= (type == ICElement.COMPILATION_UNIT) ? null : (ISourceReference) element; +// // The assumption is that only source elements in compilation unit can have markers +// if (cu.isWorkingCopy()) { +// // working copy: look at annotation model +// return getErrorTicksFromWorkingCopy(cu, ref); +// } +// return getErrorTicksFromMarkers(cu.getResource(), IResource.DEPTH_ONE, ref); +// } +// break; + default: + } + } else if (obj instanceof IResource) { + return getErrorTicksFromMarkers((IResource) obj, IResource.DEPTH_INFINITE, null); + } + } catch (CoreException e) { + if (e instanceof CModelException) { +// if (((CModelException) e).isDoesNotExist()) { +// return 0; +// } + } + if (e.getStatus().getCode() == IResourceStatus.MARKER_NOT_FOUND) { + return 0; + } + + CUIPlugin.getDefault().log(e); + } + return 0; + } + + private int getErrorTicksFromMarkers(IResource res, int depth, ISourceReference sourceElement) throws CoreException { + if (res == null || !res.isAccessible()) { + return 0; + } + int info= 0; + + IMarker[] markers= res.findMarkers(IMarker.PROBLEM, true, depth); + if (markers != null) { + for (int i= 0; i < markers.length && (info != ERRORTICK_ERROR); i++) { + IMarker curr= markers[i]; + if (sourceElement == null || isMarkerInRange(curr, sourceElement)) { + int priority= curr.getAttribute(IMarker.SEVERITY, -1); + if (priority == IMarker.SEVERITY_WARNING) { + info= ERRORTICK_WARNING; + } else if (priority == IMarker.SEVERITY_ERROR) { + info= ERRORTICK_ERROR; + } + } + } + } + return info; + } + + private boolean isMarkerInRange(IMarker marker, ISourceReference sourceElement) throws CoreException { + if (marker.isSubtypeOf(IMarker.TEXT)) { + int pos= marker.getAttribute(IMarker.CHAR_START, -1); + return isInside(pos, sourceElement); + } + return false; + } + + + private int getErrorTicksFromWorkingCopy(ITranslationUnit original, ISourceReference sourceElement) throws CoreException { + int info= 0; + FileEditorInput editorInput= new FileEditorInput((IFile) original.getResource()); +// IAnnotationModel model= CUIPlugin.getDefault().getTranslationUnitDocumentProvider().getAnnotationModel(editorInput); +// if (model != null) { +// Iterator iter= model.getAnnotationIterator(); +// while ((info != ERRORTICK_ERROR) && iter.hasNext()) { +// Annotation curr= (Annotation) iter.next(); +// IMarker marker= isAnnotationInRange(model, curr, sourceElement); +// if (marker != null) { +// int priority= marker.getAttribute(IMarker.SEVERITY, -1); +// if (priority == IMarker.SEVERITY_WARNING) { +// info= ERRORTICK_WARNING; +// } else if (priority == IMarker.SEVERITY_ERROR) { +// info= ERRORTICK_ERROR; +// } +// } +// } +// } + return info; + } + + private IMarker isAnnotationInRange(IAnnotationModel model, Annotation annot, ISourceReference sourceElement) throws CoreException { + if (annot instanceof MarkerAnnotation) { + IMarker marker= ((MarkerAnnotation) annot).getMarker(); + if (marker.exists() && marker.isSubtypeOf(IMarker.PROBLEM)) { + Position pos= model.getPosition(annot); + if (pos != null && (sourceElement == null || isInside(pos.getOffset(), sourceElement))) { + return marker; + } + } + } + return null; + } + + /** + * Tests if a position is inside the source range of an element. + * @param pos Position to be tested. + * @param sourceElement Source element (must be a ICElement) + * @return boolean Return true if position is located inside the source element. + * @throws CoreException Exception thrown if element range could not be accessed. + * + * @since 2.1 + */ + protected boolean isInside(int pos, ISourceReference sourceElement) throws CoreException { + ISourceRange range= sourceElement.getSourceRange(); + if (range != null) { + int rangeOffset= range.getStartPos(); + return (rangeOffset <= pos && rangeOffset + range.getLength() > pos); + } + return false; + } + + /* (non-Javadoc) + * @see IBaseLabelProvider#dispose() + */ + public void dispose() { + if (fProblemChangedListener != null) { + CUIPlugin.getDefault().getProblemMarkerManager().removeListener(fProblemChangedListener); + fProblemChangedListener= null; + } + if (fRegistry != null && fUseNewRegistry) { + fRegistry.dispose(); + } + } + + /* (non-Javadoc) + * @see IBaseLabelProvider#isLabelProperty(Object, String) + */ + public boolean isLabelProperty(Object element, String property) { + return true; + } + + /* (non-Javadoc) + * @see IBaseLabelProvider#addListener(ILabelProviderListener) + */ + public void addListener(ILabelProviderListener listener) { + if (fListeners == null) { + fListeners= new ListenerList(); + } + fListeners.add(listener); +// if (fProblemChangedListener == null) { +// fProblemChangedListener= new IProblemChangedListener() { +// public void problemsChanged(IResource[] changedResources, boolean isMarkerChange) { +// fireProblemsChanged(changedResources, isMarkerChange); +// } +// }; +// CUIPlugin.getDefault().getProblemMarkerManager().addListener(fProblemChangedListener); +// } + } + + /* (non-Javadoc) + * @see IBaseLabelProvider#removeListener(ILabelProviderListener) + */ + public void removeListener(ILabelProviderListener listener) { + if (fListeners != null) { + fListeners.remove(listener); + if (fListeners.isEmpty() && fProblemChangedListener != null) { + CUIPlugin.getDefault().getProblemMarkerManager().removeListener(fProblemChangedListener); + fProblemChangedListener= null; + } + } + } + + private void fireProblemsChanged(IResource[] changedResources, boolean isMarkerChange) { + if (fListeners != null && !fListeners.isEmpty()) { + LabelProviderChangedEvent event= new ProblemsLabelChangedEvent(this, changedResources, isMarkerChange); + Object[] listeners= fListeners.getListeners(); + for (int i= 0; i < listeners.length; i++) { + ((ILabelProviderListener) listeners[i]).labelProviderChanged(event); + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ILightweightLabelDecorator#decorate(java.lang.Object, org.eclipse.jface.viewers.IDecoration) + */ + public void decorate(Object element, IDecoration decoration) { + int adornmentFlags= computeAdornmentFlags(element); + if (adornmentFlags == ERRORTICK_ERROR) { + decoration.addOverlay(CPluginImages.DESC_OVR_ERROR); + } else if (adornmentFlags == ERRORTICK_WARNING) { + decoration.addOverlay(CPluginImages.DESC_OVR_WARNING); + } + } + +} diff --git a/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/ProjectActionGroup.java b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/ProjectActionGroup.java new file mode 100644 index 00000000000..22cd5ee8001 --- /dev/null +++ b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/ProjectActionGroup.java @@ -0,0 +1,109 @@ +/******************************************************************************* + * 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 + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.browser.cbrowsing; + +import org.eclipse.cdt.internal.ui.IContextMenuConstants; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.ResourcesPlugin; + +import org.eclipse.swt.widgets.Shell; + +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.IStructuredSelection; + +import org.eclipse.ui.IActionBars; +import org.eclipse.ui.IViewPart; +import org.eclipse.ui.IWorkbenchSite; +import org.eclipse.ui.actions.ActionGroup; +import org.eclipse.ui.actions.CloseResourceAction; +import org.eclipse.ui.ide.IDEActionFactory; + +/** + * Adds actions to open and close a project to the global menu bar. + * + *

+ * This class may be instantiated; it is not intended to be subclassed. + *

+ * + * @since 2.0 + */ +public class ProjectActionGroup extends ActionGroup { + + private IWorkbenchSite fSite; + + private OpenProjectAction fOpenAction; + private CloseResourceAction fCloseAction; + + /** + * Creates a new ProjectActionGroup. The group requires + * that the selection provided by the site's selection provider is of type + * org.eclipse.jface.viewers.IStructuredSelection. + * + * @param part the view part that owns this action group + */ + public ProjectActionGroup(IViewPart part) { + fSite = part.getSite(); + Shell shell= fSite.getShell(); + ISelectionProvider provider= fSite.getSelectionProvider(); + ISelection selection= provider.getSelection(); + + fCloseAction= new CloseResourceAction(shell); + fCloseAction.setActionDefinitionId("org.eclipse.ui.project.closeProject"); //$NON-NLS-1$ + fOpenAction= new OpenProjectAction(fSite); + fOpenAction.setActionDefinitionId("org.eclipse.ui.project.openProject"); //$NON-NLS-1$ + if (selection instanceof IStructuredSelection) { + IStructuredSelection s= (IStructuredSelection)selection; + fOpenAction.selectionChanged(s); + fCloseAction.selectionChanged(s); + } + provider.addSelectionChangedListener(fOpenAction); + provider.addSelectionChangedListener(fCloseAction); + IWorkspace workspace= ResourcesPlugin.getWorkspace(); + workspace.addResourceChangeListener(fOpenAction); + workspace.addResourceChangeListener(fCloseAction); + } + + /* (non-Javadoc) + * Method declared in ActionGroup + */ + public void fillActionBars(IActionBars actionBars) { + super.fillActionBars(actionBars); + actionBars.setGlobalActionHandler(IDEActionFactory.CLOSE_PROJECT.getId(), fCloseAction); + actionBars.setGlobalActionHandler(IDEActionFactory.OPEN_PROJECT.getId(), fOpenAction); + } + + /* (non-Javadoc) + * Method declared in ActionGroup + */ + public void fillContextMenu(IMenuManager menu) { + super.fillContextMenu(menu); + if (fOpenAction.isEnabled()) + menu.appendToGroup(IContextMenuConstants.GROUP_BUILD, fOpenAction); + if (fCloseAction.isEnabled()) + menu.appendToGroup(IContextMenuConstants.GROUP_BUILD, fCloseAction); + } + + + /* + * @see ActionGroup#dispose() + */ + public void dispose() { + ISelectionProvider provider= fSite.getSelectionProvider(); + provider.removeSelectionChangedListener(fOpenAction); + provider.removeSelectionChangedListener(fCloseAction); + IWorkspace workspace = ResourcesPlugin.getWorkspace(); + workspace.removeResourceChangeListener(fOpenAction); + workspace.removeResourceChangeListener(fCloseAction); + super.dispose(); + } +} diff --git a/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/ProjectsView.java b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/ProjectsView.java new file mode 100644 index 00000000000..be8da09c486 --- /dev/null +++ b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/ProjectsView.java @@ -0,0 +1,194 @@ +/******************************************************************************* + * 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 + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.browser.cbrowsing; + +import org.eclipse.cdt.core.browser.ITypeInfo; +import org.eclipse.cdt.core.model.CoreModel; +import org.eclipse.cdt.core.model.ICContainer; +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.core.model.ICModel; +import org.eclipse.cdt.core.model.ICProject; +import org.eclipse.cdt.internal.ui.ICHelpContextIds; +import org.eclipse.cdt.internal.ui.util.ProblemTreeViewer; +import org.eclipse.cdt.ui.CUIPlugin; +import org.eclipse.cdt.ui.PreferenceConstants; +import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.IContentProvider; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.StructuredViewer; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.IPageLayout; +import org.eclipse.ui.part.IShowInTargetList; + +public class ProjectsView extends CBrowsingPart { + +// private FilterUpdater fFilterUpdater; + + /** + * Creates the the viewer of this part. + * + * @param parent the parent for the viewer + */ + protected StructuredViewer createViewer(Composite parent) { + ProblemTreeViewer result= new ProblemTreeViewer(parent, SWT.MULTI); +// fFilterUpdater= new FilterUpdater(result); +// ResourcesPlugin.getWorkspace().addResourceChangeListener(fFilterUpdater); + return result; + } + + protected LabelProvider createLabelProvider() { + return new CUILabelProvider(); +// return new TypeInfoLabelProvider(TypeInfoLabelProvider.SHOW_TYPE_ONLY); + } + + /* (non-Javadoc) + * @see org.eclipse.jdt.internal.ui.browsing.JavaBrowsingPart#dispose() + */ + public void dispose() { +// if (fFilterUpdater != null) +// ResourcesPlugin.getWorkspace().removeResourceChangeListener(fFilterUpdater); + super.dispose(); + } + + /** + * Answer the property defined by key. + */ + public Object getAdapter(Class key) { + if (key == IShowInTargetList.class) { + return new IShowInTargetList() { + public String[] getShowInTargetIds() { + return new String[] { CUIPlugin.CVIEW_ID, IPageLayout.ID_RES_NAV }; + } + + }; + } + return super.getAdapter(key); + } + + + /** + * Creates the the content provider of this part. + */ + protected IContentProvider createContentProvider() { + return new ProjectsViewContentProvider(this); + } + + /** + * Returns the context ID for the Help system. + * + * @return the string used as ID for the Help context + */ + protected String getHelpContextId() { + return ICHelpContextIds.PROJECTS_VIEW; + } + + protected String getLinkToEditorKey() { + return PreferenceConstants.LINK_BROWSING_PROJECTS_TO_EDITOR; + } + + + /** + * Adds additional listeners to this view. + */ + protected void hookViewerListeners() { + super.hookViewerListeners(); + getViewer().addDoubleClickListener(new IDoubleClickListener() { + public void doubleClick(DoubleClickEvent event) { + TreeViewer viewer= (TreeViewer)getViewer(); + Object element= ((IStructuredSelection)event.getSelection()).getFirstElement(); + if (viewer.isExpandable(element)) + viewer.setExpandedState(element, !viewer.getExpandedState(element)); + } + }); + } + + protected void setInitialInput() { + ICElement root= CoreModel.create(CUIPlugin.getWorkspace().getRoot()); + getViewer().setInput(root); + updateTitle(); + } + + /** + * Answers if the given element is a valid + * input for this part. + * + * @param element the object to test + * @return if the given element is a valid input + */ + protected boolean isValidInput(Object element) { + return element instanceof ICModel; + } + + /** + * Answers if the given element is a valid + * element for this part. + * + * @param element the object to test + * @return if the given element is a valid element + */ + protected boolean isValidElement(Object element) { + return element instanceof ICProject || element instanceof ICContainer; + } + + /* + * @see JavaBrowsingPart#setInput(Object) + */ + protected void setInput(Object input) { + // Don't allow to clear input for this view + if (input != null) + super.setInput(input); + else + getViewer().setSelection(null); + } + + protected void createActions() { + super.createActions(); +// fActionGroups.addGroup(new ProjectActionGroup(this)); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.ui.browser.cbrowsing.CBrowsingPart#findInputForElement(java.lang.Object) + */ + protected Object findInputForElement(Object element) { + if (element instanceof ICModel) { + if (exists(element)) + return element; + } + + if (element instanceof ICElement) { //ICProject || element instanceof ISourceRoot) { + ICModel model = ((ICElement)element).getCModel(); + if (exists(model)) + return model; + } + + if (element instanceof ITypeInfo) { + ICProject cProject = findCProject((ITypeInfo)element); + if (cProject != null) { + ICModel model = cProject.getCModel(); + if (exists(model)) + return model; + } + } + + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.ui.browser.cbrowsing.CBrowsingPart#findElementToSelect(java.lang.Object) + */ + protected Object findElementToSelect(Object element) { + return getNamespaceInput(element); + } +} diff --git a/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/ProjectsViewContentProvider.java b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/ProjectsViewContentProvider.java new file mode 100644 index 00000000000..506baf7b8db --- /dev/null +++ b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/ProjectsViewContentProvider.java @@ -0,0 +1,175 @@ +/******************************************************************************* + * 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 + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.browser.cbrowsing; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.cdt.core.model.CModelException; +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.core.model.ICModel; +import org.eclipse.cdt.core.model.ICProject; +import org.eclipse.cdt.core.model.ISourceRoot; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.jface.util.Assert; +import org.eclipse.jface.viewers.IStructuredSelection; + +class ProjectsViewContentProvider extends CBrowsingContentProvider { + + ProjectsViewContentProvider(CBrowsingPart browsingPart) { + super(browsingPart); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object) + */ + public boolean hasChildren(Object element) { + if (element == null || (element instanceof ICElement && !((ICElement)element).exists())) { + return false; + } + + try { + startReadInDisplayThread(); + + if (element instanceof ICModel) { + ICModel cModel = (ICModel)element; + return cModel.hasChildren(); + } + + if (element instanceof ICProject) { + ICProject cProject = (ICProject)element; + if (cProject.exists() && cProject.isOpen()) + return cProject.hasChildren(); + return false; + } + + if (element instanceof ISourceRoot) { + return false; + } + + return false; +// } catch (CModelException e) { +// return false; + } finally { + finishedReadInDisplayThread(); + } + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object) + */ + public Object[] getChildren(Object element) { + if (element == null || (element instanceof ICElement && !((ICElement)element).exists())) { + return NO_CHILDREN; + } + + try { + startReadInDisplayThread(); + + if (element instanceof IStructuredSelection) { + Assert.isLegal(false); + Object[] result= new Object[0]; + Class clazz= null; + Iterator iter= ((IStructuredSelection)element).iterator(); + while (iter.hasNext()) { + Object item= iter.next(); + if (clazz == null) + clazz= item.getClass(); + if (clazz == item.getClass()) + result= concatenate(result, getChildren(item)); + else + return NO_CHILDREN; + } + return result; + } + + if (element instanceof ICModel) { + ICModel cModel = (ICModel)element; + return cModel.getCProjects(); + } + + if (element instanceof ICProject) + return getSourceRoots((ICProject)element); + + if (element instanceof ISourceRoot) + return NO_CHILDREN; + + return NO_CHILDREN; + } catch (CModelException e) { + return NO_CHILDREN; + } finally { + finishedReadInDisplayThread(); + } + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object) + */ + public Object getParent(Object element) { + if (element == null || (element instanceof ICElement && !((ICElement)element).exists())) { + return null; + } + + try { + startReadInDisplayThread(); + + if (element instanceof ICModel) { + return null; + } + + if (element instanceof ICProject) { + ICProject cProject = (ICProject)element; + return cProject.getCModel(); + } + + if (element instanceof ISourceRoot) { + ISourceRoot cSourceRoot = (ISourceRoot)element; + return cSourceRoot.getCProject(); + } + + return null; +// } catch (CModelException e) { +// return false; + } finally { + finishedReadInDisplayThread(); + } + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object) + */ + public Object[] getElements(Object inputElement) { + return getChildren(inputElement); + } + + protected Object[] getSourceRoots(ICProject project) throws CModelException { + if (!project.getProject().isOpen()) + return NO_CHILDREN; + + ISourceRoot[] roots= project.getSourceRoots(); + List list= new ArrayList(roots.length); + // filter out package fragments that correspond to projects and + // replace them with the package fragments directly + for (int i= 0; i < roots.length; i++) { + ISourceRoot root= roots[i]; + if (!isProjectSourceRoot(root)) + list.add(root); + } + return list.toArray(); + } + + protected boolean isProjectSourceRoot(ISourceRoot root) { + IResource resource= root.getResource(); + return (resource instanceof IProject); + } +} diff --git a/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/StatusBarUpdater.java b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/StatusBarUpdater.java new file mode 100644 index 00000000000..7b4bad915d0 --- /dev/null +++ b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/StatusBarUpdater.java @@ -0,0 +1,92 @@ +/******************************************************************************* + * 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 + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.browser.cbrowsing; + + +import org.eclipse.cdt.core.browser.ITypeInfo; +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.internal.ui.CUIMessages; +import org.eclipse.cdt.internal.ui.search.CElementLabels; +import org.eclipse.cdt.ui.browser.typeinfo.TypeInfoLabelProvider; +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IResource; + +import org.eclipse.jface.action.IStatusLineManager; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.SelectionChangedEvent; + +/** + * Add the StatusBarUpdater to your ViewPart to have the statusbar + * describing the selected elements. + */ +public class StatusBarUpdater implements ISelectionChangedListener { + + private final int LABEL_FLAGS= CElementLabels.DEFAULT_QUALIFIED | CElementLabels.ROOT_POST_QUALIFIED | CElementLabels.APPEND_ROOT_PATH | + CElementLabels.M_PARAMETER_TYPES | CElementLabels.M_PARAMETER_NAMES | CElementLabels.M_APP_RETURNTYPE | CElementLabels.M_EXCEPTIONS | + CElementLabels.F_APP_TYPE_SIGNATURE; + + private final TypeInfoLabelProvider fTypeInfoLabelProvider = new TypeInfoLabelProvider(TypeInfoLabelProvider.SHOW_FULLY_QUALIFIED + TypeInfoLabelProvider.SHOW_PATH); + + private IStatusLineManager fStatusLineManager; + + public StatusBarUpdater(IStatusLineManager statusLineManager) { + fStatusLineManager= statusLineManager; + } + + /* + * @see ISelectionChangedListener#selectionChanged + */ + public void selectionChanged(SelectionChangedEvent event) { + String statusBarMessage= formatMessage(event.getSelection()); + fStatusLineManager.setMessage(statusBarMessage); + } + + + protected String formatMessage(ISelection sel) { + if (sel instanceof IStructuredSelection && !sel.isEmpty()) { + IStructuredSelection selection= (IStructuredSelection) sel; + + int nElements= selection.size(); + if (nElements > 1) { + return CUIMessages.getFormattedString("StatusBarUpdater.num_elements_selected", String.valueOf(nElements)); //$NON-NLS-1$ + } else { + Object elem= selection.getFirstElement(); + if (elem instanceof ICElement) { + return formatCElementMessage((ICElement) elem); + } else if (elem instanceof ITypeInfo) { + return formatTypeInfoMessage((ITypeInfo) elem); + } else if (elem instanceof IResource) { + return formatResourceMessage((IResource) elem); + } + } + } + return ""; //$NON-NLS-1$ + } + + private String formatCElementMessage(ICElement element) { + return CElementLabels.getElementLabel(element, LABEL_FLAGS); + } + + private String formatTypeInfoMessage(ITypeInfo info) { + return fTypeInfoLabelProvider.getText(info); + } + + private String formatResourceMessage(IResource element) { + IContainer parent= element.getParent(); + if (parent != null && parent.getType() != IResource.ROOT) + return element.getName() + CElementLabels.CONCAT_STRING + parent.getFullPath().makeRelative().toString(); + else + return element.getName(); + } + +} diff --git a/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/StorageLabelProvider.java b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/StorageLabelProvider.java new file mode 100644 index 00000000000..2bba629c743 --- /dev/null +++ b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/StorageLabelProvider.java @@ -0,0 +1,129 @@ +/******************************************************************************* + * 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 + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.browser.cbrowsing; + + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import org.eclipse.core.resources.IStorage; +import org.eclipse.core.runtime.IPath; + +import org.eclipse.swt.graphics.Image; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.viewers.LabelProvider; + +import org.eclipse.ui.IEditorRegistry; +import org.eclipse.ui.IFileEditorMapping; +import org.eclipse.ui.PlatformUI; + +/** + * Standard label provider for IStorage objects. + * Use this class when you want to present IStorage objects in a viewer. + */ +public class StorageLabelProvider extends LabelProvider { + + private IEditorRegistry fEditorRegistry= PlatformUI.getWorkbench().getEditorRegistry(); + private Map fJarImageMap= new HashMap(10); + private Image fDefaultImage; + + /* (non-Javadoc) + * @see ILabelProvider#getImage + */ + public Image getImage(Object element) { + if (element instanceof IStorage) + return getImageForJarEntry((IStorage)element); + + return super.getImage(element); + } + + /* (non-Javadoc) + * @see ILabelProvider#getText + */ + public String getText(Object element) { + if (element instanceof IStorage) + return ((IStorage)element).getName(); + + return super.getText(element); + } + + /* (non-Javadoc) + * + * @see IBaseLabelProvider#dispose + */ + public void dispose() { + if (fJarImageMap != null) { + Iterator each= fJarImageMap.values().iterator(); + while (each.hasNext()) { + Image image= (Image)each.next(); + image.dispose(); + } + fJarImageMap= null; + } + if (fDefaultImage != null) + fDefaultImage.dispose(); + fDefaultImage= null; + } + + /* + * Gets and caches an image for a JarEntryFile. + * The image for a JarEntryFile is retrieved from the EditorRegistry. + */ + private Image getImageForJarEntry(IStorage element) { + if (fJarImageMap == null) + return getDefaultImage(); + + if (element == null || element.getName() == null) + return getDefaultImage(); + + // Try to find icon for full name + String name= element.getName(); + Image image= (Image)fJarImageMap.get(name); + if (image != null) + return image; + IFileEditorMapping[] mappings= fEditorRegistry.getFileEditorMappings(); + int i= 0; + while (i < mappings.length) { + if (mappings[i].getLabel().equals(name)) + break; + i++; + } + String key= name; + if (i == mappings.length) { + // Try to find icon for extension + IPath path= element.getFullPath(); + if (path == null) + return getDefaultImage(); + key= path.getFileExtension(); + if (key == null) + return getDefaultImage(); + image= (Image)fJarImageMap.get(key); + if (image != null) + return image; + } + + // Get the image from the editor registry + ImageDescriptor desc= fEditorRegistry.getImageDescriptor(name); + image= desc.createImage(); + + fJarImageMap.put(key, image); + + return image; + } + + private Image getDefaultImage() { + if (fDefaultImage == null) + fDefaultImage= fEditorRegistry.getImageDescriptor((String)null).createImage(); + return fDefaultImage; + } +} diff --git a/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/TypeInfoComparator.java b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/TypeInfoComparator.java new file mode 100644 index 00000000000..643915fb747 --- /dev/null +++ b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/TypeInfoComparator.java @@ -0,0 +1,86 @@ +/******************************************************************************* + * 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 + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.browser.cbrowsing; + +import java.util.Comparator; + +import org.eclipse.cdt.core.browser.ITypeInfo; +import org.eclipse.cdt.core.model.ICElement; + +public class TypeInfoComparator implements Comparator { + /** + * Compares two ITypeInfo/ICElement types. A type is considered to be + * greater if it may contain the other. + * + * @return an int less than 0 if object1 is less than object2, + * 0 if they are equal, and > 0 if object1 is greater + * + * @see Comparator#compare(Object, Object) + */ + public int compare(Object o1, Object o2) { + int t1 = getElementType(o1); + int t2 = getElementType(o2); + return getIdForElementType(t1) - getIdForElementType(t2); + } + + /** + * Compares two C element types. A type is considered to be + * greater if it may contain the other. + * + * @return an int < 0 if object1 is less than object2, + * 0 if they are equal, and > 0 if object1 is greater + * + * @see Comparator#compare(Object, Object) + */ + public int compare(Object o1, int elementType) { + int t1 = getElementType(o1); + if (t1 == 0) + throw new ClassCastException(); + return getIdForElementType(t1) - getIdForElementType(elementType); + } + + int getElementType(Object obj) { + if (obj instanceof ICElement) { + return ((ICElement)obj).getElementType(); + } else if (obj instanceof ITypeInfo) { + return ((ITypeInfo)obj).getCElementType(); + } else { + return 0; + } + } + + int getIdForElementType(int elementType) { + switch (elementType) { + case ICElement.C_MODEL: + return 100; + case ICElement.C_PROJECT: + return 90; + case ICElement.C_CCONTAINER: + return 80; + case ICElement.C_UNIT: + return 70; + case ICElement.C_NAMESPACE: + return 60; + case ICElement.C_CLASS: + return 50; + case ICElement.C_STRUCT: + return 40; + case ICElement.C_UNION: + return 30; + case ICElement.C_ENUMERATION: + return 20; + case ICElement.C_TYPEDEF: + return 10; + default : + return 1; + } + } +} diff --git a/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/TypeInfoSorter.java b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/TypeInfoSorter.java new file mode 100644 index 00000000000..c0b7860d82c --- /dev/null +++ b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/TypeInfoSorter.java @@ -0,0 +1,61 @@ +/* + * Created on May 18, 2004 + * + * TODO To change the template for this generated file go to + * Window - Preferences - Java - Code Style - Code Templates + */ +package org.eclipse.cdt.internal.ui.browser.cbrowsing; + +import org.eclipse.cdt.core.browser.ITypeInfo; +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerSorter; + +/** + * A sorter to sort the file and the folders in the C viewer in the following order: + * 1 Project + * 2 BinaryContainer + * 3 ArchiveContainer + * 4 LibraryContainer + * 5 IncludeContainer + * 6 Source roots + * 5 C Elements + * 6 non C Elements + */ +public class TypeInfoSorter extends ViewerSorter { + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ViewerSorter#compare(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object) + */ + public int compare(Viewer viewer, Object e1, Object e2) { + if (e1 instanceof ITypeInfo) { + return compare((ITypeInfo)e1, e2); + } else if (e1 instanceof ICElement) { + return compare((ICElement)e1, e2); + } + return 0; +// return getCollator().compare(name1, name2); + } + + int compare(ITypeInfo t1, Object o2) { + if (o2 instanceof ITypeInfo) { + ITypeInfo t2 = (ITypeInfo)o2; + return t1.compareTo(t2); + } else if (o2 instanceof ICElement) { + ICElement e2 = (ICElement)o2; + return getCollator().compare(t1.getName(), e2.getElementName()); + } + return 0; + } + + int compare(ICElement e1, Object o2) { + if (o2 instanceof ITypeInfo) { + ITypeInfo t2 = (ITypeInfo)o2; + return getCollator().compare(e1.getElementName(), t2.getName()); + } else if (o2 instanceof ICElement) { + ICElement e2 = (ICElement)o2; + return getCollator().compare(e1.getElementName(), e2.getElementName()); + } + return 0; + } +} diff --git a/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/TypesView.java b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/TypesView.java new file mode 100644 index 00000000000..42141621d38 --- /dev/null +++ b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/TypesView.java @@ -0,0 +1,166 @@ +/******************************************************************************* + * 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 + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.browser.cbrowsing; + +import org.eclipse.cdt.core.browser.ITypeInfo; +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.internal.ui.ICHelpContextIds; +import org.eclipse.cdt.internal.ui.util.ProblemTableViewer; +import org.eclipse.cdt.ui.CUIPlugin; +import org.eclipse.cdt.ui.PreferenceConstants; +import org.eclipse.cdt.ui.browser.typeinfo.TypeInfoLabelProvider; +import org.eclipse.jface.viewers.IContentProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.StructuredViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.IActionBars; +import org.eclipse.ui.IPageLayout; +import org.eclipse.ui.part.IShowInTargetList; + +public class TypesView extends CBrowsingPart { + +// private SelectAllAction fSelectAllAction; + + /** + * Creates and returns the label provider for this part. + * + * @return the label provider + * @see org.eclipse.jface.viewers.ILabelProvider + */ + protected LabelProvider createLabelProvider() { + return new TypeInfoLabelProvider(TypeInfoLabelProvider.SHOW_TYPE_ONLY); + } + + /** + * Answer the property defined by key. + */ + public Object getAdapter(Class key) { + if (key == IShowInTargetList.class) { + return new IShowInTargetList() { + public String[] getShowInTargetIds() { + return new String[] { CUIPlugin.CVIEW_ID, IPageLayout.ID_RES_NAV }; + } + + }; + } + return super.getAdapter(key); + } + + /** + * Creates the viewer of this part dependent on the current + * layout. + * + * @param parent the parent for the viewer + */ + protected StructuredViewer createViewer(Composite parent) { + StructuredViewer viewer; +// if(isInListState()) + viewer= createTableViewer(parent); +// else +// viewer= createTreeViewer(parent); + +// fWrappedViewer.setViewer(viewer); +// return fWrappedViewer; + return viewer; + } + private ProblemTableViewer createTableViewer(Composite parent) { + return new ProblemTableViewer(parent, SWT.MULTI); + } + + /** + * Creates the the content provider of this part. + */ + protected IContentProvider createContentProvider() { + return new TypesViewContentProvider(this); + } + + + + /** + * Adds filters the viewer of this part. + */ + protected void addFilters() { + super.addFilters(); +// getViewer().addFilter(new NonCElementFilter()); + } + + /** + * Answers if the given element is a valid + * input for this part. + * + * @param element the object to test + * @return if the given element is a valid input + */ + protected boolean isValidInput(Object element) { + return isValidNamespace(element); + } + + /** + * Answers if the given element is a valid + * element for this part. + * + * @param element the object to test + * @return if the given element is a valid element + */ + protected boolean isValidElement(Object element) { + if (element instanceof ITypeInfo) { + ITypeInfo info = (ITypeInfo)element; + if (info.exists()) { + switch (info.getCElementType()) { + case ICElement.C_CLASS: + case ICElement.C_STRUCT: + return true; + } + } + } + return false; + } + + /** + * Returns the context ID for the Help system + * + * @return the string used as ID for the Help context + */ + protected String getHelpContextId() { + return ICHelpContextIds.TYPES_VIEW; + } + + protected String getLinkToEditorKey() { + return PreferenceConstants.LINK_BROWSING_TYPES_TO_EDITOR; + } + + protected void createActions() { + super.createActions(); +// fSelectAllAction= new SelectAllAction((TableViewer)getViewer()); + } + + protected void fillActionBars(IActionBars actionBars) { + super.fillActionBars(actionBars); + + // Add selectAll action handlers. +// actionBars.setGlobalActionHandler(IWorkbenchActionConstants.SELECT_ALL, fSelectAllAction); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.ui.browser.cbrowsing.CBrowsingPart#findInputForElement(java.lang.Object) + */ + protected Object findInputForElement(Object element) { + return getTypesInput(element); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.ui.browser.cbrowsing.CBrowsingPart#findElementToSelect(java.lang.Object) + */ + protected Object findElementToSelect(Object element) { + return getMembersInput(element); + } +} diff --git a/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/TypesViewContentProvider.java b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/TypesViewContentProvider.java new file mode 100644 index 00000000000..d2ccf625bf2 --- /dev/null +++ b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/internal/ui/browser/cbrowsing/TypesViewContentProvider.java @@ -0,0 +1,129 @@ +/******************************************************************************* + * 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 + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.browser.cbrowsing; + +import java.util.Iterator; + +import org.eclipse.cdt.core.browser.ITypeInfo; +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.jface.util.Assert; +import org.eclipse.jface.viewers.IStructuredSelection; + +class TypesViewContentProvider extends CBrowsingContentProvider { + + TypesViewContentProvider(CBrowsingPart browsingPart) { + super(browsingPart); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object) + */ + public boolean hasChildren(Object element) { + if (element == null || (element instanceof ITypeInfo && !((ITypeInfo)element).exists())) { + return false; + } + + try { + startReadInDisplayThread(); + + if (element instanceof ITypeInfo) { + ITypeInfo info = (ITypeInfo)element; + return info.hasEnclosedTypes(); + } + + return false; +// } catch (CModelException e) { +// return false; + } finally { + finishedReadInDisplayThread(); + } + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object) + */ + public Object[] getChildren(Object element) { + if (element == null || (element instanceof ITypeInfo && !((ITypeInfo)element).exists())) { + return NO_CHILDREN; + } + + try { + startReadInDisplayThread(); + + if (element instanceof IStructuredSelection) { + Assert.isLegal(false); + Object[] result= new Object[0]; + Class clazz= null; + Iterator iter= ((IStructuredSelection)element).iterator(); + while (iter.hasNext()) { + Object item= iter.next(); + if (clazz == null) + clazz= item.getClass(); + if (clazz == item.getClass()) + result= concatenate(result, getChildren(item)); + else + return NO_CHILDREN; + } + return result; + } + + if (element instanceof ITypeInfo) { + ITypeInfo info = (ITypeInfo)element; + final int kinds[] = { ICElement.C_CLASS, ICElement.C_STRUCT }; +// ICElement.C_UNION, ICElement.C_ENUMERATION, +// ICElement.C_TYPEDEF}; + return info.getEnclosedTypes(kinds); + } + + return NO_CHILDREN; +// } catch (CModelException e) { +// return NO_CHILDREN; + } finally { + finishedReadInDisplayThread(); + } + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object) + */ + public Object getParent(Object element) { + if (element == null || (element instanceof ITypeInfo && !((ITypeInfo)element).exists())) { + return null; + } + + try { + startReadInDisplayThread(); + + if (element instanceof ITypeInfo) { + ITypeInfo info = (ITypeInfo)element; + if (info.isEnclosedType()) { + return info.getEnclosingType(); + } else { +// return info.getEnclosingProject(); + return null; + } + } + + return null; +// } catch (CModelException e) { +// return false; + } finally { + finishedReadInDisplayThread(); + } + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object) + */ + public Object[] getElements(Object inputElement) { + return getChildren(inputElement); + } +} diff --git a/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/ui/browser/typeinfo/TypeInfoLabelProvider.java b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/ui/browser/typeinfo/TypeInfoLabelProvider.java index 7488d8484f0..7e3f610338a 100644 --- a/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/ui/browser/typeinfo/TypeInfoLabelProvider.java +++ b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/ui/browser/typeinfo/TypeInfoLabelProvider.java @@ -26,7 +26,8 @@ public class TypeInfoLabelProvider extends LabelProvider { public static final int SHOW_TYPE_ONLY= 0x01; public static final int SHOW_ENCLOSING_TYPE_ONLY= 0x02; - public static final int SHOW_PATH= 0x04; + public static final int SHOW_FULLY_QUALIFIED= 0x04; + public static final int SHOW_PATH= 0x08; 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); @@ -71,6 +72,8 @@ public class TypeInfoLabelProvider extends LabelProvider { } else { buf.append(TypeInfoMessages.getString("TypeInfoLabelProvider.globalScope")); //$NON-NLS-1$ } + } else if (isSet(SHOW_FULLY_QUALIFIED)) { + buf.append(qualifiedName.getFullyQualifiedName()); } if (isSet(SHOW_PATH)) { diff --git a/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/ui/browser/typeinfo/TypeSelectionDialog.java b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/ui/browser/typeinfo/TypeSelectionDialog.java index 0d3ba571735..5c3ca9ff684 100644 --- a/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/ui/browser/typeinfo/TypeSelectionDialog.java +++ b/core/org.eclipse.cdt.ui/browser/org/eclipse/cdt/ui/browser/typeinfo/TypeSelectionDialog.java @@ -21,7 +21,6 @@ import java.util.Set; import org.eclipse.cdt.core.browser.IQualifiedTypeName; import org.eclipse.cdt.core.browser.ITypeInfo; import org.eclipse.cdt.core.browser.QualifiedTypeName; -import org.eclipse.cdt.core.browser.TypeInfo; import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.internal.ui.util.StringMatcher; import org.eclipse.cdt.ui.CUIPlugin; @@ -55,7 +54,7 @@ public class TypeSelectionDialog extends TwoPaneElementSelector { private StringMatcher fNameMatcher = null; private StringMatcher[] fSegmentMatchers = null; - private boolean fMatchRootQualifier = false; + private boolean fMatchGlobalNamespace = false; private Collection fVisibleTypes = new HashSet(); private boolean fShowLowLevelTypes = false; @@ -71,7 +70,7 @@ public class TypeSelectionDialog extends TwoPaneElementSelector { // append wildcard to innermost segment segments[length-1] = adjustPattern(segments[length-1]); - fMatchRootQualifier = false; + fMatchGlobalNamespace = false; fSegmentMatchers = new StringMatcher[length]; int count = 0; for (int i = 0; i < length; ++i) { @@ -80,7 +79,7 @@ public class TypeSelectionDialog extends TwoPaneElementSelector { fSegmentMatchers[count++] = new StringMatcher(segments[i], ignoreCase, ignoreWildCards); } else if (i == 0) { // allow outermost segment to be blank (e.g. "::foo*") - fMatchRootQualifier = true; + fMatchGlobalNamespace = true; } else { // skip over blank segments (e.g. treat "foo::::b*" as "foo::b*") } @@ -125,7 +124,7 @@ public class TypeSelectionDialog extends TwoPaneElementSelector { if (!(element instanceof ITypeInfo)) return false; - TypeInfo info = (TypeInfo) element; + ITypeInfo info = (ITypeInfo) element; IQualifiedTypeName qualifiedName = info.getQualifiedTypeName(); if (fVisibleTypes != null && !fVisibleTypes.contains(new Integer(info.getCElementType()))) @@ -133,57 +132,33 @@ public class TypeSelectionDialog extends TwoPaneElementSelector { if (!fShowLowLevelTypes && qualifiedName.isLowLevel()) return false; - - if (!fMatchRootQualifier && !fNameMatcher.match(qualifiedName.getName())) - return false; - - return matchQualifiedName(qualifiedName); + + if (fSegmentMatchers.length == 1 && !fMatchGlobalNamespace) + return fNameMatcher.match(qualifiedName.getName()); + + return matchQualifiedName(info); } - private boolean matchQualifiedName(IQualifiedTypeName qualifiedName) { + private boolean matchQualifiedName(ITypeInfo info) { + IQualifiedTypeName qualifiedName = info.getQualifiedTypeName(); String[] segments = qualifiedName.segments(); - boolean matchFound = false; - boolean moreNames = true; - int matchOffset = 0; - while (!matchFound && moreNames) { - matchFound = true; - for (int i = 0; i < fSegmentMatchers.length; ++i) { - int dropOut = 0; - if (i < (segments.length - matchOffset)) { - // ok to continue -// dropOut = false; - } else { - ++dropOut; - } - - if (matchOffset + i >= segments.length) { - ++dropOut; - } - - if (dropOut > 0) { - if (dropOut != 2) { - // shouldn't get here - matchFound = false; - moreNames = false; - } - matchFound = false; - moreNames = false; - break; - } - - StringMatcher matcher = fSegmentMatchers[i]; - String name = segments[matchOffset + i]; - if (name == null || !matcher.match(name)) { - matchFound = false; - break; - } - } - - if (fMatchRootQualifier) { - // must match outermost name (eg ::foo) - moreNames = false; - } else { - ++matchOffset; + if (fSegmentMatchers.length != segments.length) + return false; + + if (fMatchGlobalNamespace) { + // must match global namespace (eg ::foo) + if (info.getRootNamespace(false) != null) + return false; + } + + boolean matchFound = true; + int max = Math.min(fSegmentMatchers.length, segments.length); + for (int i = 0; i < max; ++i) { + StringMatcher matcher = fSegmentMatchers[i]; + String name = segments[i]; + if (name == null || !matcher.match(name)) { + matchFound = false; + break; } } return matchFound; diff --git a/core/org.eclipse.cdt.ui/icons/full/cview16/cbrowsing_pers.gif b/core/org.eclipse.cdt.ui/icons/full/cview16/cbrowsing_pers.gif new file mode 100644 index 0000000000000000000000000000000000000000..4efd8183b9411d9d178417c75c23612ed530b2d0 GIT binary patch literal 200 zcmZ?wbhEHb6krfw*vtR~4fE%(b`9OX?9_*(Is5JB+t<&p-+zCCMz|Wuq(h4$zfu$ti1n0ckc8;PWlFW`F)0cQIu!uYSt-(oy z>xuA@rLW%jZP?NxZvP-aM~b^OIdPGQbifLyi%yX;tSm~q3S#!%a5C%q5yg}Eaa*>T y!lh)_Lp>S`jwZ1>If^fq&F8F26)&xbY~`s=Z;ND$=jam8i?T0a6cc2y<^lk|LQfn3 literal 0 HcmV?d00001 diff --git a/core/org.eclipse.cdt.ui/icons/full/eview16/cbrowsing_pers.gif b/core/org.eclipse.cdt.ui/icons/full/eview16/cbrowsing_pers.gif new file mode 100644 index 0000000000000000000000000000000000000000..4efd8183b9411d9d178417c75c23612ed530b2d0 GIT binary patch literal 200 zcmZ?wbhEHb6krfw*vtR~4fE%(b`9OX?9_*(Is5JB+t<&p-+zCCMz|Wuq(h4$zfu$ti1n0ckc8;PWlFW`F)0cQIu!uYSt-(oy z>xuA@rLW%jZP?NxZvP-aM~b^OIdPGQbifLyi%yX;tSm~q3S#!%a5C%q5yg}Eaa*>T y!lh)_Lp>S`jwZ1>If^fq&F8F26)&xbY~`s=Z;ND$=jam8i?T0a6cc2y<^lk|LQfn3 literal 0 HcmV?d00001 diff --git a/core/org.eclipse.cdt.ui/icons/full/eview16/cprojects.gif b/core/org.eclipse.cdt.ui/icons/full/eview16/cprojects.gif new file mode 100644 index 0000000000000000000000000000000000000000..4cc01be572b07cfd25e564c3df1c0e467884deac GIT binary patch literal 366 zcmV-!0g?VkNk%w1VGsZi0M!5h%D}|s;No{~dv|VpZE1hS#@S6(j!jiRTVRAmPlrrZ zKTK9XO;$foSc*YTlR;0CMNy80k;pDXoGwJ0H%XT}O_d-#p&~k%B|e`eKc6Z?oH9t6 zlC|uTw(OF%>yozXKgIGt#`2!U@}9=>C}Ngzl&`7Q`Ki_Tsn+_TQHO z@xuT3;s5Ki?9q$=<)r`e(*N3t|KFDX(RKgTedED>*|Krata#C_dC;tR|NsC0|Nj60 z00000A^8LW002DzEC2ui01yBW000Jxz@BhOEE+#ZWQjyl5p_`AaH&#}hC7~?mlH0B zgFj%kV!>`W0bm&r5+bd*Jnmv!dx)2QuXoj%P6{!Dgo84N1w#-tGz$p^2ayU43I_`Z zJry&X4=J9XpAJ16HZ~L}CnhK+tf~}38Z{CkA|WFpBOoIq6GIpm92_4W9UdRT8ATS$ M%*{#9JwX6F3c((s!2kdN literal 0 HcmV?d00001 diff --git a/core/org.eclipse.cdt.ui/icons/full/eview16/members.gif b/core/org.eclipse.cdt.ui/icons/full/eview16/members.gif new file mode 100644 index 0000000000000000000000000000000000000000..7c3ccb06d1c343c45f5146edcac151f33541e6a2 GIT binary patch literal 345 zcmZ?wbhEHb6krfwxXQqATF>%kT-v?-@+VE5wmHkVTv{Z9?A7CD33zwNg-@Kd<4W?% z_KNK@R2uvZI-|LA%tZ=pB4)=%%#O)gomH?TeRYe}a(k)e4N~(;#O9QU&Bzs*oFOtJ zSM=Yd+R5p{|Mmy}|NozXmO$|*3nK%A0)r075|E!5*h(Gj3p{kV7*9O0e^_A9)?i=4 zAYddV;`Nx5iDO@r)(S&SZ>i%ARtj}4_a+_}lo8XDyLtT43>Q9efhxD=meyu2E;mt8 zH#Rm`aamb07cLHtPA5tEIr0+D9PI2I&a>_3D{yhLuyD>)keMXq%(``(i=1>@t0RLo F7XTCCQvLt{ literal 0 HcmV?d00001 diff --git a/core/org.eclipse.cdt.ui/icons/full/eview16/namespaces.gif b/core/org.eclipse.cdt.ui/icons/full/eview16/namespaces.gif new file mode 100644 index 0000000000000000000000000000000000000000..d0ccb309dee856d16a3fbd6eeb1d910a599b0542 GIT binary patch literal 361 zcmZ?wbhEHb6krfwxXQrr>)Wo+4>x^%y!FGqP48~6e{*x)r(3JuTwnL>@|rgnmwtJ6 z;oHm0-(FsMacs)-(+l2QSo-|*!l$Pf-&`DVV`0RD!*d=Uo%i_of(J+D-8(%0?xA^i z_RqSpd&cp0$4jdlu56ijefyM~yQW{?Iqg7&!QndV%bV;kZm_?yWzzNSQ}>ja@2|4l zUu|`2S^K15#TALVYf|;6L};!}H`thEv?bSMNvw8(wM3zv-2eao8E^x|pDc_F3}y^E zASEC_F|f5d%)SsNEoHyxV#iV$S$k!N$Eu}vtt;J@FY}GN(9fJNx{t?P7}hER5n|&aT2dT=Mz?{32T68q(_8rfLeR8vdqT literal 0 HcmV?d00001 diff --git a/core/org.eclipse.cdt.ui/icons/full/eview16/types.gif b/core/org.eclipse.cdt.ui/icons/full/eview16/types.gif new file mode 100644 index 0000000000000000000000000000000000000000..a498fda17542fa280e32fc9e3c1947736e30817c GIT binary patch literal 365 zcmZ?wbhEHb6krfwxXQq=Z~MNs%GJdwODeLL^)#&w^O%|$v#`2gLu&N=y0SG(=ACgU zS>alyXdyNuDP_;d1|QtoOt`gvmHBq z-KPh*PY?6}qG^Ht^F#gTg;uRCs9FO=g)2|={Qv)-fqFpkCkrD3gBpVl$ViZ%7}z=; zCKq_<@aao>KQm$xU}I_ckfa%@>vO>2psa_X@}v%vLo+zqORN$$<=o5f&J0*_oqd^C z`{Rc-T53!j&CN_|QeujV3Sv@f46K}!ScBR{MMV3Y7}!|Zrn(Aq@o)*dxd`*{ujW~{ sT#ZX;(pF literal 0 HcmV?d00001 diff --git a/core/org.eclipse.cdt.ui/plugin.properties b/core/org.eclipse.cdt.ui/plugin.properties index ebb11515ab7..89383c39f9a 100644 --- a/core/org.eclipse.cdt.ui/plugin.properties +++ b/core/org.eclipse.cdt.ui/plugin.properties @@ -10,6 +10,7 @@ editorRulerActionsName=Editor Ruler Actions completionContributorName=Completion Contribution nature.name=C Nature perspective.name=C/C++ +CBrowsing.perspective.name=C/C++ Browsing viewsCategory.name=&C CView.name=C/C++ Projects @@ -171,3 +172,12 @@ CPresentation.label= C/C++ CEditorPresentation.label= Editor CDTIndexerMarker.label= C/C++ Indexer Markers + +#Browsing +CBrowsing.perspectiveName= C/C++ Browsing +CBrowsing.viewCategoryName= C/C++ Browsing +CBrowsing.projectsViewName= Projects +CBrowsing.namespacesViewName= Namespaces +CBrowsing.typesViewName= Types +CBrowsing.membersViewName= Members +CBrowsing.preferencePageName= Browsing diff --git a/core/org.eclipse.cdt.ui/plugin.xml b/core/org.eclipse.cdt.ui/plugin.xml index ae439ab71d0..cf66b956836 100644 --- a/core/org.eclipse.cdt.ui/plugin.xml +++ b/core/org.eclipse.cdt.ui/plugin.xml @@ -131,6 +131,12 @@ class="org.eclipse.cdt.internal.ui.CPerspectiveFactory" id="org.eclipse.cdt.ui.CPerspective"> + + @@ -139,17 +145,17 @@ + + - - + id="org.eclipse.cdt.ui.CBrowsingPerspective"> - - - - + + + + + + + + + + + + + + + + diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/corext/util/CModelUtil.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/corext/util/CModelUtil.java index ba757258f08..681e5a49edf 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/corext/util/CModelUtil.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/corext/util/CModelUtil.java @@ -10,9 +10,13 @@ ***********************************************************************/ package org.eclipse.cdt.internal.corext.util; +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.core.model.ISourceRoot; import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.core.model.IWorkingCopy; import org.eclipse.cdt.internal.ui.util.EditorUtility; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; public class CModelUtil { /** @@ -35,4 +39,37 @@ public class CModelUtil { } return unit; } + + /** + * Returns the source root of ICElement. If the given + * element is already a source root, the element itself is returned. + */ + public static ISourceRoot getSourceRoot(ICElement element) { + ICElement root = element; + while (root != null) { + if (root instanceof ISourceRoot) + return (ISourceRoot)root; + ICElement parent = root.getAncestor(ICElement.C_CCONTAINER); + if (parent == root) + return null; + root = parent; + } + return null; + } + + /** + * Returns true if the given source root is + * referenced. This means it is own by a different project but is referenced + * by the root's parent. Returns false if the given root + * doesn't have an underlying resource. + */ + public static boolean isReferenced(ISourceRoot root) { + IResource resource= root.getResource(); + if (resource != null) { + IProject project= resource.getProject(); + IProject container= root.getCProject().getProject(); + return !container.equals(project); + } + return false; + } } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/ICHelpContextIds.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/ICHelpContextIds.java index 5caefdbbfae..3c3fb36b899 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/ICHelpContextIds.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/ICHelpContextIds.java @@ -82,5 +82,24 @@ public interface ICHelpContextIds { public static final String RENAME_TYPE_WIZARD_PAGE= PREFIX + "rename_type_wizard_page_context"; //$NON-NLS-1$ public static final String RENAME_FIELD_WIZARD_PAGE= PREFIX + "rename_field_wizard_page_context"; //$NON-NLS-1$ public static final String RENAME_RESOURCE_WIZARD_PAGE= PREFIX + "rename_resource_wizard_page_context"; //$NON-NLS-1$ - + + public static final String EDIT_WORKING_SET_ACTION= PREFIX + "edit_working_set_action"; //$NON-NLS-1$ + public static final String CLEAR_WORKING_SET_ACTION= PREFIX + "clear_working_set_action"; //$NON-NLS-1$ + public static final String SELECT_WORKING_SET_ACTION= PREFIX + "select_working_set_action"; //$NON-NLS-1$ + + // view parts + public static final String TYPE_HIERARCHY_VIEW= PREFIX + "type_hierarchy_view_context"; //$NON-NLS-1$ + public static final String PACKAGES_VIEW= PREFIX + "package_view_context"; //$NON-NLS-1$ + public static final String PROJECTS_VIEW= PREFIX + "projects_view_context"; //$NON-NLS-1$ + public static final String PACKAGES_BROWSING_VIEW= PREFIX + "packages_browsing_view_context"; //$NON-NLS-1$ + public static final String TYPES_VIEW= PREFIX + "types_view_context"; //$NON-NLS-1$ + public static final String MEMBERS_VIEW= PREFIX + "members_view_context"; //$NON-NLS-1$ + + public static final String OPEN_C_BROWSING_PERSPECTIVE_ACTION = PREFIX + "open_c_browsing_perspective_action"; //$NON-NLS-1$ + public static final String OPEN_PROJECT_ACTION = PREFIX + "open_project_action"; //$NON-NLS-1$ + + public static final String OPEN_TYPE_ACTION = PREFIX + "open_type_action"; //$NON-NLS-1$ + public static final String OPEN_TYPE_IN_HIERARCHY_ACTION = PREFIX + "open_type_in_hierarchy_action"; //$NON-NLS-1$ + + public static final String LEXICAL_SORTING_BROWSING_ACTION= PREFIX + "lexical_sorting_browsing_action"; //$NON-NLS-1$ } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/CElementLabels.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/CElementLabels.java index f33cec321f2..654b321b430 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/CElementLabels.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/CElementLabels.java @@ -14,10 +14,16 @@ package org.eclipse.cdt.internal.ui.search; import org.eclipse.cdt.core.model.CModelException; +import org.eclipse.cdt.core.model.ICContainer; import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.IMethod; +import org.eclipse.cdt.core.model.ISourceRoot; import org.eclipse.cdt.core.model.IStructure; +import org.eclipse.cdt.core.model.ITranslationUnit; +import org.eclipse.cdt.internal.corext.util.CModelUtil; +import org.eclipse.cdt.internal.ui.CUIMessages; import org.eclipse.cdt.ui.CUIPlugin; +import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.ui.model.IWorkbenchAdapter; @@ -268,8 +274,16 @@ public class CElementLabels { public static void getElementLabel(ICElement element, int flags, StringBuffer buf) { int type= element.getElementType(); + ISourceRoot root= null; - switch( type ){ + if (type != ICElement.C_MODEL && type != ICElement.C_PROJECT && !(type == ICElement.C_CCONTAINER && element instanceof ISourceRoot)) + root= CModelUtil.getSourceRoot(element); + if (root != null && getFlag(flags, PREPEND_ROOT_PATH)) { + getSourceRootLabel(root, ROOT_QUALIFIED, buf); + buf.append(CONCAT_STRING); + } + + switch (type) { case ICElement.C_METHOD : getMethodLabel( (IMethod) element, flags, buf ); break; @@ -277,7 +291,29 @@ public class CElementLabels { case ICElement.C_STRUCT: case ICElement.C_UNION: case ICElement.C_ENUMERATION: - // getTypeLabel( (IType) element, flags, buf ); + getTypeLabel( element, flags, buf ); + break; + case ICElement.C_UNIT: + getTranslationUnitLabel((ITranslationUnit) element, flags, buf); + break; + case ICElement.C_CCONTAINER: + ICContainer container = (ICContainer) element; + if (container instanceof ISourceRoot) + getSourceRootLabel((ISourceRoot) container, flags, buf); + else + getContainerLabel(container, flags, buf); + break; + case ICElement.C_PROJECT: + case ICElement.C_MODEL: + buf.append(element.getElementName()); + break; + default: + buf.append(element.getElementName()); + } + + if (root != null && getFlag(flags, APPEND_ROOT_PATH)) { + buf.append(CONCAT_STRING); + getSourceRootLabel(root, ROOT_QUALIFIED, buf); } } @@ -355,12 +391,104 @@ public class CElementLabels { } } - public static void getTypeLabel(ICElement type, int flags, StringBuffer buf) { - if( !(type instanceof IStructure) ){ - return; - } + /** + * Appends the label for a source root to a StringBuffer. Considers the ROOT_* flags. + */ + public static void getSourceRootLabel(ISourceRoot root, int flags, StringBuffer buf) { +// if (root.isArchive()) +// getArchiveLabel(root, flags, buf); +// else + getFolderLabel(root, flags, buf); } + /** + * Appends the label for a container to a StringBuffer. Considers the ROOT_* flags. + */ + public static void getContainerLabel(ICContainer container, int flags, StringBuffer buf) { + getFolderLabel(container, flags, buf); + } + + private static void getFolderLabel(ICContainer container, int flags, StringBuffer buf) { + IResource resource= container.getResource(); + boolean rootQualified= getFlag(flags, ROOT_QUALIFIED); + boolean referencedQualified= getFlag(flags, REFERENCED_ROOT_POST_QUALIFIED) + && (container instanceof ISourceRoot && CModelUtil.isReferenced((ISourceRoot)container)) + && resource != null; + if (rootQualified) { + buf.append(container.getPath().makeRelative().toString()); + } else { + if (resource != null) + buf.append(resource.getProjectRelativePath().toString()); + else + buf.append(container.getElementName()); + if (referencedQualified) { + buf.append(CONCAT_STRING); + buf.append(resource.getProject().getName()); + } else if (getFlag(flags, ROOT_POST_QUALIFIED)) { + buf.append(CONCAT_STRING); + buf.append(container.getParent().getElementName()); + } + } + } + + /** + * Appends the label for a translation unit to a StringBuffer. Considers the CU_* flags. + */ + public static void getTranslationUnitLabel(ITranslationUnit tu, int flags, StringBuffer buf) { + if (getFlag(flags, CU_QUALIFIED)) { + ISourceRoot root= CModelUtil.getSourceRoot(tu); +// if (!pack.isDefaultPackage()) { + buf.append(root.getElementName()); + buf.append('.'); +// } + } + buf.append(tu.getElementName()); + + if (getFlag(flags, CU_POST_QUALIFIED)) { + buf.append(CONCAT_STRING); + getSourceRootLabel((ISourceRoot) tu.getParent(), 0, buf); + } + } + + /** + * Appends the label for a type to a StringBuffer. Considers the T_* flags. + */ + public static void getTypeLabel(ICElement elem, int flags, StringBuffer buf) { + if (getFlag(flags, T_FULLY_QUALIFIED)) { + ISourceRoot root= CModelUtil.getSourceRoot(elem); + getSourceRootLabel(root, (flags & P_COMPRESSED), buf); + buf.append(root.getElementName()); + buf.append('.'); + } + + String typeName= elem.getElementName(); + if (typeName.length() == 0) { // anonymous +// try { +// String superclassName= Signature.getSimpleName(type.getSuperclassName()); +// typeName= CUIMessages.getFormattedString("JavaElementLabels.anonym_type" , superclassName); //$NON-NLS-1$ +// } catch (CModelException e) { +// //ignore +// typeName= CUIMessages.getString("JavaElementLabels.anonym"); //$NON-NLS-1$ +// } + } + buf.append(typeName); + +// // post qualification +// if (getFlag(flags, T_POST_QUALIFIED)) { +// buf.append(CONCAT_STRING); +// IType declaringType= type.getDeclaringType(); +// if (declaringType != null) { +// getTypeLabel(declaringType, T_FULLY_QUALIFIED | (flags & P_COMPRESSED), buf); +// int parentType= type.getParent().getElementType(); +// if (parentType == ICElement.METHOD || parentType == ICElement.FIELD || parentType == ICElement.INITIALIZER) { // anonymous or local +// buf.append('.'); +// getElementLabel(type.getParent(), 0, buf); +// } +// } else { +// getPackageFragmentLabel(type.getPackageFragment(), (flags & P_COMPRESSED), buf); +// } +// } + } private static boolean getFlag(int flags, int flag) { return (flags & flag) != 0; diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/ProblemTableViewer.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/ProblemTableViewer.java new file mode 100644 index 00000000000..2bb41e8dac4 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/ProblemTableViewer.java @@ -0,0 +1,136 @@ +/******************************************************************************* + * 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 + *******************************************************************************/ + +package org.eclipse.cdt.internal.ui.util; + +import java.util.ArrayList; + +import org.eclipse.cdt.internal.ui.browser.cbrowsing.ProblemsLabelDecorator.ProblemsLabelChangedEvent; +import org.eclipse.core.resources.IResource; + +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Item; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.Widget; + +import org.eclipse.jface.viewers.IBaseLabelProvider; +import org.eclipse.jface.viewers.LabelProviderChangedEvent; +import org.eclipse.jface.viewers.TableViewer; + +/** + * Extends a TableViewer to allow more performance when showing error ticks. + * A ProblemItemMapper is contained that maps all items in + * the tree to underlying resource + */ +public class ProblemTableViewer extends TableViewer { + + protected ResourceToItemsMapper fResourceToItemsMapper; + + /** + * Constructor for ProblemTableViewer. + * @param parent + */ + public ProblemTableViewer(Composite parent) { + super(parent); + initMapper(); + } + + /** + * Constructor for ProblemTableViewer. + * @param parent + * @param style + */ + public ProblemTableViewer(Composite parent, int style) { + super(parent, style); + initMapper(); + } + + /** + * Constructor for ProblemTableViewer. + * @param table + */ + public ProblemTableViewer(Table table) { + super(table); + initMapper(); + } + + private void initMapper() { + fResourceToItemsMapper= new ResourceToItemsMapper(this); + } + + /* + * @see StructuredViewer#mapElement(Object, Widget) + */ + protected void mapElement(Object element, Widget item) { + super.mapElement(element, item); + if (item instanceof Item) { + fResourceToItemsMapper.addToMap(element, (Item) item); + } + } + + /* + * @see StructuredViewer#unmapElement(Object, Widget) + */ + protected void unmapElement(Object element, Widget item) { + if (item instanceof Item) { + fResourceToItemsMapper.removeFromMap(element, (Item) item); + } + super.unmapElement(element, item); + } + + /* + * @see StructuredViewer#unmapAllElements() + */ + protected void unmapAllElements() { + fResourceToItemsMapper.clearMap(); + super.unmapAllElements(); + } + + /* + * @see ContentViewer#handleLabelProviderChanged(LabelProviderChangedEvent) + */ + protected void handleLabelProviderChanged(LabelProviderChangedEvent event) { + if (event instanceof ProblemsLabelChangedEvent) { + ProblemsLabelChangedEvent e= (ProblemsLabelChangedEvent) event; + if (!e.isMarkerChange() && canIgnoreChangesFromAnnotionModel()) { + return; + } + } + + Object[] changed= event.getElements(); + if (changed != null && !fResourceToItemsMapper.isEmpty()) { + ArrayList others= new ArrayList(changed.length); + for (int i= 0; i < changed.length; i++) { + Object curr= changed[i]; + if (curr instanceof IResource) { + fResourceToItemsMapper.resourceChanged((IResource) curr); + } else { + others.add(curr); + } + } + if (others.isEmpty()) { + return; + } + event= new LabelProviderChangedEvent((IBaseLabelProvider) event.getSource(), others.toArray()); + } + super.handleLabelProviderChanged(event); + } + + /** + * Answers whether this viewer can ignore label provider changes resulting from + * marker changes in annotation models + */ + private boolean canIgnoreChangesFromAnnotionModel() { +// Object contentProvider= getContentProvider(); +// return contentProvider instanceof IWorkingCopyProvider && !((IWorkingCopyProvider)contentProvider).providesWorkingCopies(); + return true; + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/ResourceToItemsMapper.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/ResourceToItemsMapper.java new file mode 100644 index 00000000000..0fd29eb379f --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/ResourceToItemsMapper.java @@ -0,0 +1,205 @@ +/******************************************************************************* + * 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 + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.util; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Stack; + +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.core.model.ITranslationUnit; +import org.eclipse.core.resources.IResource; + +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Item; + +import org.eclipse.jface.viewers.ContentViewer; +import org.eclipse.jface.viewers.ILabelProvider; +import org.eclipse.jface.viewers.IViewerLabelProvider; +import org.eclipse.jface.viewers.ViewerLabel; + +/** + * Helper class for updating error markers and other decorators that work on resources. + * Items are mapped to their element's underlying resource. + * Method resourceChanged updates all items that are affected from the changed + * elements. + */ +public class ResourceToItemsMapper { + + private static final int NUMBER_LIST_REUSE= 10; + + // map from resource to item + private HashMap fResourceToItem; + private Stack fReuseLists; + + private ContentViewer fContentViewer; + + public ResourceToItemsMapper(ContentViewer viewer) { + fResourceToItem= new HashMap(); + fReuseLists= new Stack(); + + fContentViewer= viewer; + } + + /** + * Must be called from the UI thread. + */ + public void resourceChanged(IResource changedResource) { + Object obj= fResourceToItem.get(changedResource); + if (obj == null) { + // not mapped + } else if (obj instanceof Item) { + updateItem((Item) obj); + } else { // List of Items + List list= (List) obj; + for (int k= 0; k < list.size(); k++) { + updateItem((Item) list.get(k)); + } + } + } + + private void updateItem(Item item) { + if (!item.isDisposed()) { // defensive code + ILabelProvider lprovider= (ILabelProvider) fContentViewer.getLabelProvider(); + + Object data= item.getData(); + + // If it is an IItemLabelProvider than short circuit: patch Tod (bug 55012) + if (lprovider instanceof IViewerLabelProvider) { + IViewerLabelProvider provider= (IViewerLabelProvider) lprovider; + + ViewerLabel updateLabel= new ViewerLabel(item.getText(), item.getImage()); + provider.updateLabel(updateLabel, data); + + if (updateLabel.hasNewImage()) { + item.setImage(updateLabel.getImage()); + } + if (updateLabel.hasNewText()) { + item.setText(updateLabel.getText()); + } + } else { + Image oldImage= item.getImage(); + Image image= lprovider.getImage(data); + if (image != null && !image.equals(oldImage)) { + item.setImage(image); + } + String oldText= item.getText(); + String text= lprovider.getText(data); + if (text != null && !text.equals(oldText)) { + item.setText(text); + } + } + } + } + + /** + * Adds a new item to the map. + * @param element Element to map + * @param item The item used for the element + */ + public void addToMap(Object element, Item item) { + IResource resource= getCorrespondingResource(element); + if (resource != null) { + Object existingMapping= fResourceToItem.get(resource); + if (existingMapping == null) { + fResourceToItem.put(resource, item); + } else if (existingMapping instanceof Item) { + if (existingMapping != item) { + List list= getNewList(); + list.add(existingMapping); + list.add(item); + fResourceToItem.put(resource, list); + } + } else { // List + List list= (List) existingMapping; + if (!list.contains(item)) { + list.add(item); + } + } + } + } + + /** + * Removes an element from the map. + */ + public void removeFromMap(Object element, Item item) { + IResource resource= getCorrespondingResource(element); + if (resource != null) { + Object existingMapping= fResourceToItem.get(resource); + if (existingMapping == null) { + return; + } else if (existingMapping instanceof Item) { + fResourceToItem.remove(resource); + } else { // List + List list= (List) existingMapping; + list.remove(item); + if (list.isEmpty()) { + fResourceToItem.remove(list); + releaseList(list); + } + } + } + } + + private List getNewList() { + if (!fReuseLists.isEmpty()) { + return (List) fReuseLists.pop(); + } + return new ArrayList(2); + } + + private void releaseList(List list) { + if (fReuseLists.size() < NUMBER_LIST_REUSE) { + fReuseLists.push(list); + } + } + + /** + * Clears the map. + */ + public void clearMap() { + fResourceToItem.clear(); + } + + /** + * Tests if the map is empty + */ + public boolean isEmpty() { + return fResourceToItem.isEmpty(); + } + + /** + * Method that decides which elements can have error markers + * Returns null if an element can not have error markers. + */ + private static IResource getCorrespondingResource(Object element) { + if (element instanceof ICElement) { + ICElement elem= (ICElement) element; + if (!elem.isReadOnly()) { // only modifieable elements can get error ticks + IResource res= elem.getResource(); + if (res == null) { + ITranslationUnit cu= (ITranslationUnit) elem.getAncestor(ICElement.C_UNIT); + if (cu != null) { + // elements in compilation units are mapped to the underlying resource of the original cu + res= cu.getResource(); + } + } + return res; + } + return null; + } else if (element instanceof IResource) { + return (IResource) element; + } + return null; + } + +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/IViewPartInputProvider.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/IViewPartInputProvider.java new file mode 100644 index 00000000000..524a601eb1a --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/IViewPartInputProvider.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * 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 + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.viewsupport; + +/** + * Interface common to all view parts that provide an input. + */ +public interface IViewPartInputProvider { + + /** + * Returns the input. + * + * @return the input object + */ + public Object getViewPartInput(); + +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/ImageImageDescriptor.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/ImageImageDescriptor.java new file mode 100644 index 00000000000..3fc2fad603e --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/ImageImageDescriptor.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * 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 + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.viewsupport; + +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.ImageData; + +import org.eclipse.jface.resource.ImageDescriptor; + +/** + */ +public class ImageImageDescriptor extends ImageDescriptor { + + private Image fImage; + + /** + * Constructor for ImagImageDescriptor. + */ + public ImageImageDescriptor(Image image) { + super(); + fImage= image; + } + + /* (non-Javadoc) + * @see ImageDescriptor#getImageData() + */ + public ImageData getImageData() { + return fImage.getImageData(); + } + + /* (non-Javadoc) + * @see Object#equals(Object) + */ + public boolean equals(Object obj) { + return (obj != null) && getClass().equals(obj.getClass()) && fImage.equals(((ImageImageDescriptor)obj).fImage); + } + + /* (non-Javadoc) + * @see Object#hashCode() + */ + public int hashCode() { + return fImage.hashCode(); + } + +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/workingsets/ClearWorkingSetAction.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/workingsets/ClearWorkingSetAction.java new file mode 100644 index 00000000000..db978b77902 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/workingsets/ClearWorkingSetAction.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * 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 + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.workingsets; + +import org.eclipse.cdt.internal.ui.ICHelpContextIds; +import org.eclipse.cdt.internal.ui.workingsets.WorkingSetMessages; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.util.Assert; + +import org.eclipse.ui.help.WorkbenchHelp; + +/** + * Clears the selected working set in the action group's view. + * + * @since 2.0 + */ +public class ClearWorkingSetAction extends Action { + + private WorkingSetFilterActionGroup fActionGroup; + + public ClearWorkingSetAction(WorkingSetFilterActionGroup actionGroup) { + super(WorkingSetMessages.getString("ClearWorkingSetAction.text")); //$NON-NLS-1$ + Assert.isNotNull(actionGroup); + setToolTipText(WorkingSetMessages.getString("ClearWorkingSetAction.toolTip")); //$NON-NLS-1$ + setEnabled(actionGroup.getWorkingSet() != null); + WorkbenchHelp.setHelp(this, ICHelpContextIds.CLEAR_WORKING_SET_ACTION); + fActionGroup= actionGroup; + } + + /* + * Overrides method from Action + */ + public void run() { + fActionGroup.setWorkingSet(null, true); + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/workingsets/EditWorkingSetAction.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/workingsets/EditWorkingSetAction.java new file mode 100644 index 00000000000..53cacd0a16b --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/workingsets/EditWorkingSetAction.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * 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 + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.workingsets; + +import org.eclipse.swt.widgets.Shell; + +import org.eclipse.cdt.internal.ui.ICHelpContextIds; +import org.eclipse.cdt.ui.CUIPlugin; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.util.Assert; +import org.eclipse.jface.window.Window; +import org.eclipse.jface.wizard.WizardDialog; + +import org.eclipse.ui.IWorkingSet; +import org.eclipse.ui.IWorkingSetManager; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.dialogs.IWorkingSetEditWizard; +import org.eclipse.ui.help.WorkbenchHelp; + + +/** + * Displays an IWorkingSetEditWizard for editing a working set. + * + * @since 2.1 + */ +public class EditWorkingSetAction extends Action { + private Shell fShell; + private WorkingSetFilterActionGroup fActionGroup; + + public EditWorkingSetAction(WorkingSetFilterActionGroup actionGroup, Shell shell) { + super(WorkingSetMessages.getString("EditWorkingSetAction.text")); //$NON-NLS-1$ + Assert.isNotNull(actionGroup); + setToolTipText(WorkingSetMessages.getString("EditWorkingSetAction.toolTip")); //$NON-NLS-1$ + setEnabled(actionGroup.getWorkingSet() != null); + fShell= shell; + fActionGroup= actionGroup; + WorkbenchHelp.setHelp(this, ICHelpContextIds.EDIT_WORKING_SET_ACTION); + } + + /* + * Overrides method from Action + */ + public void run() { + if (fShell == null) + fShell= CUIPlugin.getActiveWorkbenchShell(); + IWorkingSetManager manager= PlatformUI.getWorkbench().getWorkingSetManager(); + IWorkingSet workingSet= fActionGroup.getWorkingSet(); + if (workingSet == null) { + setEnabled(false); + return; + } + IWorkingSetEditWizard wizard= manager.createWorkingSetEditWizard(workingSet); + if (wizard == null) { + String title= WorkingSetMessages.getString("EditWorkingSetAction.nowizard.title"); //$NON-NLS-1$ + String message= WorkingSetMessages.getString("EditWorkingSetAction.nowizard.message"); //$NON-NLS-1$ + MessageDialog.openError(fShell, title, message); + return; + } + WizardDialog dialog= new WizardDialog(fShell, wizard); + dialog.create(); + if (dialog.open() == Window.OK) + fActionGroup.setWorkingSet(wizard.getSelection(), true); + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/workingsets/SelectWorkingSetAction.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/workingsets/SelectWorkingSetAction.java new file mode 100644 index 00000000000..bfbfb159efa --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/workingsets/SelectWorkingSetAction.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * 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 + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.workingsets; + +import org.eclipse.cdt.internal.ui.ICHelpContextIds; +import org.eclipse.cdt.ui.CUIPlugin; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.util.Assert; +import org.eclipse.jface.window.Window; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IWorkingSet; +import org.eclipse.ui.IWorkingSetManager; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.dialogs.IWorkingSetSelectionDialog; +import org.eclipse.ui.help.WorkbenchHelp; + +/** + * Displays an IWorkingSetSelectionDialog and sets the selected + * working set in the action group's view. + * + * @since 2.0 + */ +public class SelectWorkingSetAction extends Action { + private Shell fShell; + private WorkingSetFilterActionGroup fActionGroup; + + public SelectWorkingSetAction(WorkingSetFilterActionGroup actionGroup, Shell shell) { + super(WorkingSetMessages.getString("SelectWorkingSetAction.text")); //$NON-NLS-1$ + Assert.isNotNull(actionGroup); + setToolTipText(WorkingSetMessages.getString("SelectWorkingSetAction.toolTip")); //$NON-NLS-1$ + + fShell= shell; + fActionGroup= actionGroup; + WorkbenchHelp.setHelp(this, ICHelpContextIds.SELECT_WORKING_SET_ACTION); + } + + /* + * Overrides method from Action + */ + public void run() { + if (fShell == null) + fShell= CUIPlugin.getActiveWorkbenchShell(); + IWorkingSetManager manager= PlatformUI.getWorkbench().getWorkingSetManager(); + IWorkingSetSelectionDialog dialog= manager.createWorkingSetSelectionDialog(fShell, false); + IWorkingSet workingSet= fActionGroup.getWorkingSet(); + if (workingSet != null) + dialog.setSelection(new IWorkingSet[]{workingSet}); + + if (dialog.open() == Window.OK) { + IWorkingSet[] result= dialog.getSelection(); + if (result != null && result.length > 0) { + fActionGroup.setWorkingSet(result[0], true); + manager.addRecentWorkingSet(result[0]); + } + else + fActionGroup.setWorkingSet(null, true); + } + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/workingsets/WorkingSetComparator.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/workingsets/WorkingSetComparator.java new file mode 100644 index 00000000000..572ac12bed2 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/workingsets/WorkingSetComparator.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * 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 + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.workingsets; + +import java.text.Collator; +import java.util.Comparator; + +import org.eclipse.ui.IWorkingSet; + +class WorkingSetComparator implements Comparator { + + private Collator fCollator= Collator.getInstance(); + + /* + * @see Comparator#compare(Object, Object) + */ + public int compare(Object o1, Object o2) { + String name1= null; + String name2= null; + + if (o1 instanceof IWorkingSet) + name1= ((IWorkingSet)o1).getName(); + + if (o2 instanceof IWorkingSet) + name2= ((IWorkingSet)o2).getName(); + + return fCollator.compare(name1, name2); + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/workingsets/WorkingSetFilter.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/workingsets/WorkingSetFilter.java new file mode 100644 index 00000000000..ff57161f7f9 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/workingsets/WorkingSetFilter.java @@ -0,0 +1,207 @@ +/******************************************************************************* + * 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 + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.workingsets; + +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.core.model.ICProject; +import org.eclipse.cdt.core.model.IPathEntryContainer; +import org.eclipse.cdt.core.model.ISourceRoot; +import org.eclipse.cdt.core.model.ITranslationUnit; +import org.eclipse.cdt.internal.corext.util.CModelUtil; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IStorage; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IPath; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerFilter; +import org.eclipse.ui.IWorkingSet; + +/** + * Working set filter for Java viewers. + */ +public class WorkingSetFilter extends ViewerFilter { + private IWorkingSet fWorkingSet= null; + private IAdaptable[] fCachedWorkingSet= null; + + /** + * Returns the working set which is used by this filter. + * + * @return the working set + */ + public IWorkingSet getWorkingSet() { + return fWorkingSet; + } + + /** + * Sets this filter's working set. + * + * @param workingSet the working set + */ + public void setWorkingSet(IWorkingSet workingSet) { + fWorkingSet= workingSet; + } + + /* + * Overrides method from ViewerFilter. + */ + public boolean select(Viewer viewer, Object parentElement, Object element) { + if (fWorkingSet == null) + return true; + + if (element instanceof ICElement) + return isEnclosing((ICElement)element); + + if (element instanceof IResource) + return isEnclosing(((IResource)element).getFullPath()); + + if (element instanceof IPathEntryContainer) { + return isEnclosing((IPathEntryContainer)element); + } + + if (element instanceof IAdaptable) { + IAdaptable adaptable= (IAdaptable)element; + ICElement je= (ICElement)adaptable.getAdapter(ICElement.class); + if (je != null) + return isEnclosing(je); + + IResource resource= (IResource)adaptable.getAdapter(IResource.class); + if (resource != null) + return isEnclosing(resource.getFullPath()); + } + + return true; + } + + private boolean isEnclosing(IPathEntryContainer container) { + // check whether the containing packagefragment root is enclosed + return isEnclosing(container.getPath()); +// IPathEntry[] entries = container.getPathEntries(); +// if (entries != null && entries.length > 0) { +// return isEnclosing(entries[0].getPath()); +// } +// return false; + } + + /* + * Overrides method from ViewerFilter + */ + public Object[] filter(Viewer viewer, Object parent, Object[] elements) { + Object[] result= null; + if (fWorkingSet != null) + fCachedWorkingSet= fWorkingSet.getElements(); + try { + result= super.filter(viewer, parent, elements); + } finally { + fCachedWorkingSet= null; + } + return result; + } + + private boolean isEnclosing(IPath elementPath) { + if (elementPath == null) + return false; + + IAdaptable[] cachedWorkingSet= fCachedWorkingSet; + if (cachedWorkingSet == null) + cachedWorkingSet= fWorkingSet.getElements(); + + int length= cachedWorkingSet.length; + for (int i= 0; i < length; i++) { + if (isEnclosing(cachedWorkingSet[i], elementPath)) + return true; + } + return false; + } + + public boolean isEnclosing(ICElement element) { + IAdaptable[] cachedWorkingSet= fCachedWorkingSet; + if (cachedWorkingSet == null) + cachedWorkingSet= fWorkingSet.getElements(); + + boolean isElementPathComputed= false; + IPath elementPath= null; // will be lazy computed if needed + + int length= cachedWorkingSet.length; + for (int i= 0; i < length; i++) { + ICElement scopeElement= (ICElement)cachedWorkingSet[i].getAdapter(ICElement.class); + if (scopeElement != null) { + // compare Java elements + ICElement searchedElement= element; + while (scopeElement != null && searchedElement != null) { + if (searchedElement.equals(scopeElement)) + return true; + else { + if (scopeElement instanceof ICProject && searchedElement instanceof ISourceRoot) { +// ISourceRoot pkgRoot= (ISourceRoot)searchedElement; +// if (pkgRoot.isExternal() && pkgRoot.isArchive()) { +// if (((ICProject)scopeElement).isOnClasspath(searchedElement)) +// return true; +// } + } + searchedElement= searchedElement.getParent(); + if (searchedElement != null && searchedElement.getElementType() == ICElement.C_UNIT) { + ITranslationUnit cu= (ITranslationUnit)searchedElement; + cu= CModelUtil.toOriginal(cu); + } + } + } + while (scopeElement != null && element != null) { + if (element.equals(scopeElement)) + return true; + else + scopeElement= scopeElement.getParent(); + } + } else { + // compare resource paths + if (!isElementPathComputed) { + IResource elementResource= (IResource)element.getAdapter(IResource.class); + if (elementResource != null) + elementPath= elementResource.getFullPath(); + } + if (isEnclosing(cachedWorkingSet[i], elementPath)) + return true; + } + } + return false; + } + + private boolean isEnclosing(IAdaptable element, IPath path) { + if (path == null) + return false; + + IPath elementPath= null; + + IResource elementResource= (IResource)element.getAdapter(IResource.class); + if (elementResource != null) + elementPath= elementResource.getFullPath(); + + if (elementPath == null) { + ICElement cElement= (ICElement)element.getAdapter(ICElement.class); + if (cElement != null) + elementPath= cElement.getPath(); + } + + if (elementPath == null && element instanceof IStorage) + elementPath= ((IStorage)element).getFullPath(); + + if (elementPath == null) + return false; + + if (elementPath.isPrefixOf(path)) + return true; + + if (path.isPrefixOf(elementPath)) + return true; + + return false; + } + +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/workingsets/WorkingSetFilterActionGroup.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/workingsets/WorkingSetFilterActionGroup.java new file mode 100644 index 00000000000..d00296ebe71 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/workingsets/WorkingSetFilterActionGroup.java @@ -0,0 +1,256 @@ +/******************************************************************************* + * 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 + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.workingsets; + +import java.util.Arrays; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.swt.widgets.Shell; + +import org.eclipse.jface.action.IContributionItem; +import org.eclipse.jface.action.IMenuListener; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.IToolBarManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.jface.util.Assert; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.jface.viewers.ViewerFilter; + +import org.eclipse.ui.IActionBars; +import org.eclipse.ui.IMemento; +import org.eclipse.ui.IWorkingSet; +import org.eclipse.ui.IWorkingSetManager; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.actions.ActionGroup; + +/** + * Working set filter actions (set / clear) + * + * @since 2.0 + * + */ +public class WorkingSetFilterActionGroup extends ActionGroup { + + private static final String TAG_WORKING_SET_NAME= "workingSetName"; //$NON-NLS-1$ + private static final String SEPARATOR_ID= "workingSetGroupSeparator"; //$NON-NLS-1$ + + private WorkingSetFilter fWorkingSetFilter; + + private IWorkingSet fWorkingSet= null; + + private ClearWorkingSetAction fClearWorkingSetAction; + private SelectWorkingSetAction fSelectWorkingSetAction; + private EditWorkingSetAction fEditWorkingSetAction; + + private IPropertyChangeListener fWorkingSetListener; + + private IPropertyChangeListener fChangeListener; + + private int fLRUMenuCount; + private IMenuManager fMenuManager; + private IMenuListener fMenuListener; + + public WorkingSetFilterActionGroup(String viewId, Shell shell, IPropertyChangeListener changeListener) { + Assert.isNotNull(viewId); + Assert.isNotNull(shell); + Assert.isNotNull(changeListener); + + fChangeListener= changeListener; + fClearWorkingSetAction= new ClearWorkingSetAction(this); + fSelectWorkingSetAction= new SelectWorkingSetAction(this, shell); + fEditWorkingSetAction= new EditWorkingSetAction(this, shell); + + fWorkingSetListener= new IPropertyChangeListener() { + public void propertyChange(PropertyChangeEvent event) { + doPropertyChange(event); + } + }; + + fWorkingSetFilter= new WorkingSetFilter(); + + IWorkingSetManager manager= PlatformUI.getWorkbench().getWorkingSetManager(); + manager.addPropertyChangeListener(fWorkingSetListener); + + } + + /** + * Returns whether the current working set filters the given element + * + * @param parent the parent + * @param object the elemnt to test + * @return the working set + */ + public boolean isFiltered(Object parent, Object object) { + if (fWorkingSetFilter == null) + return false; + return !fWorkingSetFilter.select(null, parent, object); + } + + + /** + * Returns the working set which is used by the filter. + * + * @return the working set + */ + public IWorkingSet getWorkingSet() { + return fWorkingSet; + } + + /** + * Sets this filter's working set. + * + * @param workingSet the working set + * @param refreshViewer Indiactes if the viewer should be refreshed. + */ + public void setWorkingSet(IWorkingSet workingSet, boolean refreshViewer) { + // Update action + fClearWorkingSetAction.setEnabled(workingSet != null); + fEditWorkingSetAction.setEnabled(workingSet != null); + + fWorkingSet= workingSet; + + fWorkingSetFilter.setWorkingSet(workingSet); + if (refreshViewer) { + fChangeListener.propertyChange(new PropertyChangeEvent(this, IWorkingSetManager.CHANGE_WORKING_SET_CONTENT_CHANGE, null, workingSet)); + } + } + + /** + * Saves the state of the filter actions in a memento. + * + * @param memento the memento + */ + public void saveState(IMemento memento) { + String workingSetName= ""; //$NON-NLS-1$ + if (fWorkingSet != null) + workingSetName= fWorkingSet.getName(); + memento.putString(TAG_WORKING_SET_NAME, workingSetName); + } + + /** + * Restores the state of the filter actions from a memento. + *

+ * Note: This method does not refresh the viewer. + *

+ * @param memento + */ + public void restoreState(IMemento memento) { + String workingSetName= memento.getString(TAG_WORKING_SET_NAME); + IWorkingSet ws= PlatformUI.getWorkbench().getWorkingSetManager().getWorkingSet(workingSetName); + setWorkingSet(ws, false); + } + + + /* (non-Javadoc) + * @see ActionGroup#fillActionBars(IActionBars) + */ + public void fillActionBars(IActionBars actionBars) { + contributeToToolBar(actionBars.getToolBarManager()); + contributeToMenu(actionBars.getMenuManager()); + } + + /** + * Adds the filter actions to the tool bar + * + * @param tbm the tool bar manager + */ + public void contributeToToolBar(IToolBarManager tbm) { + // do nothing + } + + /** + * Adds the filter actions to the menu + * + * @param mm the menu manager + */ + public void contributeToMenu(IMenuManager mm) { + mm.add(fSelectWorkingSetAction); + mm.add(fClearWorkingSetAction); + mm.add(fEditWorkingSetAction); + mm.add(new Separator()); + mm.add(new Separator(SEPARATOR_ID)); + addLRUWorkingSetActions(mm); + + fMenuManager= mm; + fMenuListener= new IMenuListener() { + public void menuAboutToShow(IMenuManager manager) { + removePreviousLRUWorkingSetActions(manager); + addLRUWorkingSetActions(manager); + } + }; + fMenuManager.addMenuListener(fMenuListener); + } + + private void removePreviousLRUWorkingSetActions(IMenuManager mm) { + for (int i= 1; i <= fLRUMenuCount; i++) + mm.remove(WorkingSetMenuContributionItem.getId(i)); + } + + private void addLRUWorkingSetActions(IMenuManager mm) { + IWorkingSet[] workingSets= PlatformUI.getWorkbench().getWorkingSetManager().getRecentWorkingSets(); + List sortedWorkingSets= Arrays.asList(workingSets); + Collections.sort(sortedWorkingSets, new WorkingSetComparator()); + + Iterator iter= sortedWorkingSets.iterator(); + int i= 0; + while (iter.hasNext()) { + IWorkingSet workingSet= (IWorkingSet)iter.next(); + if (workingSet != null) { + IContributionItem item= new WorkingSetMenuContributionItem(++i, this, workingSet); + mm.insertBefore(SEPARATOR_ID, item); + } + } + fLRUMenuCount= i; + } + + /* (non-Javadoc) + * @see ActionGroup#dispose() + */ + public void dispose() { + if (fMenuManager != null) + fMenuManager.removeMenuListener(fMenuListener); + + if (fWorkingSetListener != null) { + PlatformUI.getWorkbench().getWorkingSetManager().removePropertyChangeListener(fWorkingSetListener); + fWorkingSetListener= null; + } + fChangeListener= null; // clear the reference to the viewer + + super.dispose(); + } + + /** + * @return Returns viewer filter always confugured with the current working set. + */ + public ViewerFilter getWorkingSetFilter() { + return fWorkingSetFilter; + } + + /* + * Called by the working set change listener + */ + private void doPropertyChange(PropertyChangeEvent event) { + String property= event.getProperty(); + if (IWorkingSetManager.CHANGE_WORKING_SET_NAME_CHANGE.equals(property)) { + fChangeListener.propertyChange(event); + } else if (IWorkingSetManager.CHANGE_WORKING_SET_CONTENT_CHANGE.equals(property)) { + IWorkingSet newWorkingSet= (IWorkingSet) event.getNewValue(); + if (newWorkingSet.equals(fWorkingSet)) { + fChangeListener.propertyChange(event); + } + } + } + + +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/workingsets/WorkingSetMenuContributionItem.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/workingsets/WorkingSetMenuContributionItem.java new file mode 100644 index 00000000000..15d89972fd8 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/workingsets/WorkingSetMenuContributionItem.java @@ -0,0 +1,96 @@ +/******************************************************************************* + * 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 + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.workingsets; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.MenuItem; + +import org.eclipse.jface.action.ContributionItem; +import org.eclipse.jface.util.Assert; + +import org.eclipse.ui.IWorkingSet; +import org.eclipse.ui.IWorkingSetManager; +import org.eclipse.ui.PlatformUI; + +/** + * Menu contribution item which shows and lets select a working set. + * + * @since 2.0 + */ +public class WorkingSetMenuContributionItem extends ContributionItem { + + private int fId; + private IWorkingSet fWorkingSet; + private WorkingSetFilterActionGroup fActionGroup; + private Image fImage; + + /** + * Constructor for WorkingSetMenuContributionItem. + * + * @param id the id + * @param actionGroup the action group + * @param workingSet the working set + */ + public WorkingSetMenuContributionItem(int id, WorkingSetFilterActionGroup actionGroup, IWorkingSet workingSet) { + super(getId(id)); + Assert.isNotNull(actionGroup); + Assert.isNotNull(workingSet); + fId= id; + fActionGroup= actionGroup; + fWorkingSet= workingSet; + } + + /* + * Overrides method from ContributionItem. + */ + public void fill(Menu menu, int index) { + MenuItem mi= new MenuItem(menu, SWT.RADIO, index); + mi.setText("&" + fId + " " + fWorkingSet.getName()); //$NON-NLS-1$ //$NON-NLS-2$ + if (fImage == null) + fImage= fWorkingSet.getImage().createImage(); + mi.setImage(fImage); + mi.setSelection(fWorkingSet.equals(fActionGroup.getWorkingSet())); + mi.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + IWorkingSetManager manager= PlatformUI.getWorkbench().getWorkingSetManager(); + fActionGroup.setWorkingSet(fWorkingSet, true); + manager.addRecentWorkingSet(fWorkingSet); + } + }); + } + + /* + * @see org.eclipse.jface.action.ContributionItem#dispose() + * @since 3.0 + */ + public void dispose() { + if (fImage != null && !fImage.isDisposed()) + fImage.dispose(); + fImage= null; + + super.dispose(); + } + + /* + * @see org.eclipse.jface.action.IContributionItem#isDynamic() + */ + public boolean isDynamic() { + return true; + } + + static String getId(int id) { + return WorkingSetMenuContributionItem.class.getName() + "." + id; //$NON-NLS-1$ + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/CUIPlugin.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/CUIPlugin.java index 08501853c22..382a4f1f677 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/CUIPlugin.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/CUIPlugin.java @@ -30,6 +30,7 @@ import org.eclipse.cdt.internal.core.model.IBufferFactory; import org.eclipse.cdt.internal.corext.refactoring.base.Refactoring; import org.eclipse.cdt.internal.ui.CElementAdapterFactory; import org.eclipse.cdt.internal.ui.CPluginImages; +import org.eclipse.cdt.internal.ui.ICStatusConstants; import org.eclipse.cdt.internal.ui.IContextMenuConstants; import org.eclipse.cdt.internal.ui.ResourceAdapterFactory; import org.eclipse.cdt.internal.ui.buildconsole.BuildConsoleManager; @@ -101,6 +102,61 @@ public class CUIPlugin extends AbstractUIPlugin { static String SEPARATOR = System.getProperty("file.separator"); //$NON-NLS-1$ private static final String CONTENTASSIST = CUIPlugin.PLUGIN_ID + "/debug/contentassist" ; //$NON-NLS-1$ + + + /** + * The id of the C perspective + * (value "org.eclipse.cdt.ui.CPerspective"). + */ + public static final String ID_CPERSPECTIVE = PLUGIN_ID + ".CPerspective"; //$NON-NLS-1$ + + /** + * The id of the C hierarchy perspective + * (value "org.eclipse.cdt.ui.CHierarchyPerspective"). + */ + public static final String ID_CHIERARCHY_PERSPECTIVE = PLUGIN_ID + ".CHierarchyPerspective"; //$NON-NLS-1$ + + /** + * The id of the C Browsing Perspective + * (value "org.eclipse.cdt.ui.CBrowsingPerspective"). + * + * @since 2.0 + */ + public static final String ID_CBROWSING_PERSPECTIVE = PLUGIN_ID + ".CBrowsingPerspective"; //$NON-NLS-1$ + + /** + * The view part id of the C Browsing Projects view + * (value "org.eclipse.cdt.ui.ProjectsView"). + * + * @since 2.0 + */ + public static String ID_PROJECTS_VIEW = PLUGIN_ID + ".ProjectsView"; //$NON-NLS-1$ + + /** + * The view part id of the C Browsing Namespaces view + * (value "org.eclipse.cdt.ui.NamespacesView"). + * + * @since 2.0 + */ + public static String ID_NAMESPACES_VIEW = PLUGIN_ID + ".NamespacesView"; //$NON-NLS-1$ + + /** + * The view part id of the C Browsing Types view + * (value "org.eclipse.cdt.ui.TypesView"). + * + * @since 2.0 + */ + public static String ID_TYPES_VIEW = PLUGIN_ID + ".TypesView"; //$NON-NLS-1$ + + /** + * The view part id of the C Browsing Members view + * (value "org.eclipse.cdt.ui.MembersView"). + * + * @since 2.0 + */ + public static String ID_MEMBERS_VIEW = PLUGIN_ID + ".MembersView"; //$NON-NLS-1$ + + // -------- static methods -------- @@ -182,6 +238,11 @@ public class CUIPlugin extends AbstractUIPlugin { public void log(IStatus status) { getLog().log(status); } + + public void logErrorMessage(String message) { + log(new Status(IStatus.ERROR, getPluginId(), ICStatusConstants.INTERNAL_ERROR, message, null)); + } + /** * Utility method with conventions diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/PreferenceConstants.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/PreferenceConstants.java index d41492b4112..60fd15f01dc 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/PreferenceConstants.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/PreferenceConstants.java @@ -147,6 +147,74 @@ public class PreferenceConstants { public static final String REFACTOR_OK_SEVERITY= "0"; //$NON-NLS-1$ public static final String REFACTOR_SAVE_ALL_EDITORS= "Refactoring.savealleditors"; //$NON-NLS-1$ + + /** + * A named preference that controls if the C Browsing views are linked to the active editor. + *

+ * Value is of type Boolean. + *

+ * + * @see #LINK_PACKAGES_TO_EDITOR + */ + public static final String BROWSING_LINK_VIEW_TO_EDITOR= "org.eclipse.cdt.ui.browsing.linktoeditor"; //$NON-NLS-1$ + + /** + * A named preference that controls the layout of the C Browsing views vertically. Boolean value. + *

+ * Value is of type Boolean. If true the views are stacked vertical. + * If false they are stacked horizontal. + *

+ */ + public static final String BROWSING_STACK_VERTICALLY= "org.eclipse.cdt.ui.browsing.stackVertically"; //$NON-NLS-1$ + + /** + * A named preference that controls whether the hierarchy view's selection is linked to the active editor. + *

+ * Value is of type Boolean. + *

+ */ + public static final String LINK_TYPEHIERARCHY_TO_EDITOR= "org.eclipse.cdt.ui.packages.linktypehierarchytoeditor"; //$NON-NLS-1$ + + /** + * A named preference that controls whether the projects view's selection is + * linked to the active editor. + *

+ * Value is of type Boolean. + *

+ * @since 2.1 + */ + public static final String LINK_BROWSING_PROJECTS_TO_EDITOR= "org.eclipse.cdt.ui.browsing.projectstoeditor"; //$NON-NLS-1$ + + /** + * A named preference that controls whether the namespace view's selection is + * linked to the active editor. + *

+ * Value is of type Boolean. + *

+ * @since 2.1 + */ + public static final String LINK_BROWSING_PACKAGES_TO_EDITOR= "org.eclipse.cdt.ui.browsing.packagestoeditor"; //$NON-NLS-1$ + + /** + * A named preference that controls whether the types view's selection is + * linked to the active editor. + *

+ * Value is of type Boolean. + *

+ * @since 2.1 + */ + public static final String LINK_BROWSING_TYPES_TO_EDITOR= "org.eclipse.cdt.ui.browsing.typestoeditor"; //$NON-NLS-1$ + + /** + * A named preference that controls whether the members view's selection is + * linked to the active editor. + *

+ * Value is of type Boolean. + *

+ * @since 2.1 + */ + public static final String LINK_BROWSING_MEMBERS_TO_EDITOR= "org.eclipse.cdt.ui.browsing.memberstoeditor"; //$NON-NLS-1$ + /** * Returns the JDT-UI preference store. * diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/wizards/NewClassWizardPage.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/wizards/NewClassWizardPage.java index 92076793ec3..5793374bd86 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/wizards/NewClassWizardPage.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/wizards/NewClassWizardPage.java @@ -25,7 +25,7 @@ import org.eclipse.cdt.core.browser.ITypeInfo; import org.eclipse.cdt.core.browser.ITypeReference; import org.eclipse.cdt.core.browser.ITypeSearchScope; import org.eclipse.cdt.core.browser.QualifiedTypeName; -import org.eclipse.cdt.core.browser.TypeInfo; +import org.eclipse.cdt.core.browser.UnknownTypeInfo; import org.eclipse.cdt.core.browser.TypeSearchScope; import org.eclipse.cdt.core.model.CModelException; import org.eclipse.cdt.core.model.CoreModel; @@ -1063,8 +1063,8 @@ public class NewClassWizardPage extends WizardPage implements Listener { private ITypeInfo findInList(ITypeInfo[] elements, IQualifiedTypeName typeName) { if (elements == null || elements.length == 0) return null; - - TypeInfo key = new TypeInfo(0, typeName, null); + + ITypeInfo key = new UnknownTypeInfo(typeName); int index = Arrays.binarySearch(elements, key, TYPE_NAME_COMPARATOR); if (index >= 0 && index < elements.length) { for (int i = index - 1; i >= 0; --i) {