/*******************************************************************************
* Copyright (c) 2005, 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
* QNX Software System
* Anton Leherbauer (Wind River Systems)
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.ui;
import java.util.Comparator;
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.jface.preference.IPreferenceStore;
import org.eclipse.jface.viewers.ContentViewer;
import org.eclipse.jface.viewers.IBaseLabelProvider;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.ui.model.IWorkbenchAdapter;
import org.eclipse.cdt.core.model.CModelException;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.IArchiveContainer;
import org.eclipse.cdt.core.model.IBinaryContainer;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.IIncludeReference;
import org.eclipse.cdt.core.model.ILibraryReference;
import org.eclipse.cdt.core.model.IMember;
import org.eclipse.cdt.core.model.IMethodDeclaration;
import org.eclipse.cdt.core.model.ISourceRoot;
/**
* 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
*
* @noextend This class is not intended to be subclassed by clients.
*/
public class CElementSorter extends ViewerSorter {
protected static final int CMODEL = 0;
protected static final int PROJECTS = 10;
protected static final int BINARYCONTAINER = 12;
protected static final int ARCHIVECONTAINER = 13;
protected static final int INCLUDEREFCONTAINER = 14;
protected static final int LIBRARYREFCONTAINER = 15;
protected static final int SOURCEROOTS = 16;
protected static final int CCONTAINERS = 17;
protected static final int LIBRARYREFERENCES = 18;
protected static final int INCLUDEREFERENCES = 19;
protected static final int TRANSLATIONUNIT_HEADERS = 20;
protected static final int TRANSLATIONUNIT_SOURCE = 21;
protected static final int TRANSLATIONUNITS = 22;
protected static final int BINARIES = 23;
protected static final int ARCHIVES = 24;
protected static final int INCLUDES = 28;
protected static final int MACROS = 29;
protected static final int USINGS = 30;
protected static final int NAMESPACES = 32;
protected static final int NAMESPACES_RESERVED = 33;
protected static final int NAMESPACES_SYSTEM = 34;
/**
* @since 5.1
*/
protected static final int TYPES = 35;
@Deprecated
protected static final int VARIABLEDECLARATIONS = 36;
@Deprecated
protected static final int FUNCTIONDECLARATIONS = 37;
protected static final int VARIABLES = 38;
protected static final int VARIABLES_RESERVED = 39;
protected static final int VARIABLES_SYSTEM = 40;
protected static final int FUNCTIONS = 41;
protected static final int FUNCTIONS_RESERVED = 42;
protected static final int FUNCTIONS_SYSTEM = 43;
@Deprecated
protected static final int METHODDECLARATIONS = 44;
protected static final int CELEMENTS = 100;
protected static final int CELEMENTS_RESERVED = 101;
protected static final int CELEMENTS_SYSTEM = 102;
protected static final int RESOURCEFOLDERS= 200;
protected static final int RESOURCES= 201;
protected static final int STORAGE= 202;
protected static final int OTHERS= 500;
/*
* Constants added for names starting with '_' or '__'
*/
private static final int NORMAL = 0;
private static final int RESERVED = 1;
private static final int SYSTEM = 2;
/*
* Constants for ordering different member kinds.
*/
private static final int STATIC_MEMBER = 0;
private static final int CONSTRUCTOR = 1;
private static final int DESTRUCTOR = 2;
private static final int MEMBER = 3;
/**
* Flag indicating whether header files and source files should be separated.
* If true, header files will be sorted before source files,
* otherwise header and source files will be sorted by name.
*/
private boolean fSeparateHeaderAndSource;
private boolean fKeepSortOrderOfExcludedFiles;
/**
* Default constructor for use as executable extension.
*/
public CElementSorter() {
final IPreferenceStore store= CUIPlugin.getDefault().getPreferenceStore();
fSeparateHeaderAndSource= store.getBoolean(PreferenceConstants.CVIEW_SEPARATE_HEADER_AND_SOURCE);
fKeepSortOrderOfExcludedFiles= store.getBoolean(PreferenceConstants.SORT_ORDER_OF_EXCLUDED_FILES);
}
@Override
public int category (Object element) {
if (element instanceof ICElement) {
ICElement cElement = (ICElement) element;
switch (cElement.getElementType()) {
case ICElement.C_MODEL:
return CMODEL;
case ICElement.C_PROJECT:
return PROJECTS;
case ICElement.C_CCONTAINER:
if (element instanceof ISourceRoot) {
return SOURCEROOTS;
}
return CCONTAINERS;
case ICElement.C_VCONTAINER:
if (element instanceof IBinaryContainer) {
return BINARYCONTAINER;
} else if (element instanceof IArchiveContainer) {
return ARCHIVECONTAINER;
} else if (element instanceof ILibraryReference) {
return LIBRARYREFERENCES;
} else if (element instanceof IIncludeReference) {
return INCLUDEREFERENCES;
}
return CCONTAINERS;
case ICElement.C_UNIT:
return getTranslationUnitCategory(cElement.getCProject().getProject(), cElement.getElementName());
case ICElement.C_INCLUDE:
return INCLUDES;
case ICElement.C_MACRO:
return MACROS;
case ICElement.C_NAMESPACE:
return NAMESPACES + getNameKind(cElement.getElementName());
case ICElement.C_USING:
return USINGS;
case ICElement.C_TYPEDEF:
case ICElement.C_CLASS:
case ICElement.C_CLASS_DECLARATION:
case ICElement.C_TEMPLATE_CLASS:
case ICElement.C_TEMPLATE_CLASS_DECLARATION:
case ICElement.C_STRUCT:
case ICElement.C_STRUCT_DECLARATION:
case ICElement.C_TEMPLATE_STRUCT:
case ICElement.C_TEMPLATE_STRUCT_DECLARATION:
case ICElement.C_UNION:
case ICElement.C_UNION_DECLARATION:
case ICElement.C_TEMPLATE_UNION:
case ICElement.C_TEMPLATE_UNION_DECLARATION:
case ICElement.C_ENUMERATION:
return TYPES;
case ICElement.C_VARIABLE_DECLARATION:
case ICElement.C_VARIABLE:
case ICElement.C_TEMPLATE_VARIABLE:
case ICElement.C_FIELD:
return VARIABLES + getNameKind(cElement.getElementName());
case ICElement.C_FUNCTION_DECLARATION:
case ICElement.C_FUNCTION:
case ICElement.C_TEMPLATE_FUNCTION_DECLARATION:
case ICElement.C_TEMPLATE_FUNCTION:
case ICElement.C_METHOD_DECLARATION:
case ICElement.C_METHOD:
case ICElement.C_TEMPLATE_METHOD_DECLARATION:
case ICElement.C_TEMPLATE_METHOD:
return FUNCTIONS + getNameKind(cElement.getElementName());
case ICElement.C_ARCHIVE:
return ARCHIVES;
case ICElement.C_BINARY:
return BINARIES;
default:
return CELEMENTS + getNameKind(cElement.getElementName());
}
} else if (element instanceof IResource) {
IResource resource = (IResource) element;
switch (resource.getType()) {
case IResource.PROJECT:
return PROJECTS;
case IResource.FOLDER:
return RESOURCEFOLDERS;
default: // translation unit that was excluded from the build
if(fKeepSortOrderOfExcludedFiles &&
CoreModel.isValidTranslationUnitName(resource.getProject(), resource.getName())) {
return getTranslationUnitCategory(resource.getProject(), resource.getName());
}
return RESOURCES;
}
} else if (element instanceof IStorage) {
return STORAGE;
} else if (element instanceof CElementGrouping) {
int type = ((CElementGrouping)element).getType();
switch (type) {
case CElementGrouping.INCLUDES_GROUPING:
return INCLUDES;
case CElementGrouping.MACROS_GROUPING:
return MACROS;
case CElementGrouping.CLASS_GROUPING:
return TYPES;
case CElementGrouping.NAMESPACE_GROUPING:
return NAMESPACES;
case CElementGrouping.LIBRARY_REF_CONTAINER:
return LIBRARYREFCONTAINER;
case CElementGrouping.INCLUDE_REF_CONTAINER:
return INCLUDEREFCONTAINER;
}
}
return OTHERS;
}
private int getNameKind(String name) {
int length = name.length();
if (length > 0 && name.charAt(0) == '_') {
if (length > 1 && name.charAt(1) == '_') {
return SYSTEM;
}
return RESERVED;
}
return NORMAL;
}
private int getTranslationUnitCategory(IProject project, String name) {
if (fSeparateHeaderAndSource) {
if (CoreModel.isValidHeaderUnitName(project, name)) {
return TRANSLATIONUNIT_HEADERS;
}
if (CoreModel.isValidSourceUnitName(project, name)) {
return TRANSLATIONUNIT_SOURCE;
}
}
return TRANSLATIONUNITS;
}
@Override
public int compare(Viewer viewer, Object e1, Object e2) {
int cat1 = category(e1);
int cat2 = category(e2);
if (cat1 != cat2)
return cat1 - cat2;
// cat1 == cat2
@SuppressWarnings("unchecked")
final Comparator