1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Bug 45203. Organize Includes and Include Style preference pages.

Change-Id: I8227fdaa1bb26ded6026d893a864660738f3a38f
This commit is contained in:
Sergey Prigogin 2013-02-14 17:15:12 -08:00
parent b9396d3a4a
commit 83ba131410
17 changed files with 1255 additions and 626 deletions

View file

@ -196,7 +196,8 @@ CPluginFileTypesPreferencePage.name=File Types
CodeStylePreferencePage.name=Code Style
codeTemplatePreferencePage.name=Code Templates
codeFormatterPreferencePage.name=Formatter
includeStylePreferencePage.name=Includes
includeStylePreferencePage.name=Include Style
organizeIncludesPreferencePage.name=Organize Includes
nameStylePreferencePage.name=Name Style
CodeAssistPreferencePage.name=Content Assist
CodeAssistAdvancedPreferencePage.name=Advanced
@ -567,8 +568,9 @@ preferenceKeywords.common=c cpp cplusplus cdt
preferenceKeywords.codeformatter=profile codestyle project specific comment indentation brace white space blank line new control statement wrapping tab parenthesis bracket
preferenceKeywords.codestyle=class member visibility order ordering
preferenceKeywords.codetemplates=comment code constructor method file type content
preferenceKeywords.includestyle=include includes style header file system
preferenceKeywords.namestyle=name style file getter setter field variable
preferenceKeywords.includestyle=include includes style partner system header file system
preferenceKeywords.organizeincludes=include includes organize
preferenceKeywords.todo=case sensitive task tag todo xxx fix fixme project comments
preferenceKeywords.indexer=index skip references type macro search build configuration cache memory performance

View file

@ -1223,14 +1223,6 @@
<keywordReference id="org.eclipse.cdt.ui.codestyle"/>
<keywordReference id="org.eclipse.cdt.ui.common"/>
</page>
<page
name="%includeStylePreferencePage.name"
category="org.eclipse.cdt.ui.preferences.CodeStylePreferencePage"
class="org.eclipse.cdt.internal.ui.preferences.IncludeStylePreferencePage"
id="org.eclipse.cdt.ui.preferences.IncludeStylePreferencePage">
<keywordReference id="org.eclipse.cdt.ui.includestyle"/>
<keywordReference id="org.eclipse.cdt.ui.common"/>
</page>
<page
name="%nameStylePreferencePage.name"
category="org.eclipse.cdt.ui.preferences.CodeStylePreferencePage"
@ -1239,6 +1231,22 @@
<keywordReference id="org.eclipse.cdt.ui.namestyle"/>
<keywordReference id="org.eclipse.cdt.ui.common"/>
</page>
<page
name="%organizeIncludesPreferencePage.name"
category="org.eclipse.cdt.ui.preferences.CodeStylePreferencePage"
class="org.eclipse.cdt.internal.ui.preferences.OrganizeIncludesPreferencePage"
id="org.eclipse.cdt.ui.preferences.OrganizeIncludesPreferencePage">
<keywordReference id="org.eclipse.cdt.ui.organizeincludes"/>
<keywordReference id="org.eclipse.cdt.ui.common"/>
</page>
<page
name="%includeStylePreferencePage.name"
category="org.eclipse.cdt.ui.preferences.OrganizeIncludesPreferencePage"
class="org.eclipse.cdt.internal.ui.preferences.IncludeStylePreferencePage"
id="org.eclipse.cdt.ui.preferences.IncludeStylePreferencePage">
<keywordReference id="org.eclipse.cdt.ui.includestyle"/>
<keywordReference id="org.eclipse.cdt.ui.common"/>
</page>
<page
name="%markOccurrencesPreferencePage.name"
category="org.eclipse.cdt.ui.preferences.CEditorPreferencePage"
@ -1289,12 +1297,15 @@
<keyword
label="%preferenceKeywords.codetemplates"
id="org.eclipse.cdt.ui.codetemplates"/>
<keyword
label="%preferenceKeywords.namestyle"
id="org.eclipse.cdt.ui.namestyle"/>
<keyword
label="%preferenceKeywords.includestyle"
id="org.eclipse.cdt.ui.includestyle"/>
<keyword
label="%preferenceKeywords.namestyle"
id="org.eclipse.cdt.ui.namestyle"/>
label="%preferenceKeywords.organizeincludes"
id="org.eclipse.cdt.ui.organizeincludes"/>
<keyword
label="%preferenceKeywords.codeformatter"
id="org.eclipse.cdt.ui.codeformatter"/>

View file

@ -88,6 +88,7 @@ public interface ICHelpContextIds {
public static final String CODE_STYLE_PREFERENCE_PAGE = PREFIX + "code_style_preference_context"; //$NON-NLS-1$
public static final String CODE_TEMPLATES_PREFERENCE_PAGE = PREFIX + "code_templates_preference_context"; //$NON-NLS-1$
public static final String INCLUDE_STYLE_PREFERENCE_PAGE = PREFIX + "include_style_preference_context"; //$NON-NLS-1$
public static final String ORGANIZE_INCLUDES_PREFERENCE_PAGE = PREFIX + "organize_includes_preference_context"; //$NON-NLS-1$
public static final String NAME_STYLE_PREFERENCE_PAGE = PREFIX + "name_style_preference_context"; //$NON-NLS-1$
// Console view

View file

@ -10,8 +10,11 @@
*******************************************************************************/
package org.eclipse.cdt.internal.ui.preferences;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.core.resources.IProject;
import org.eclipse.jface.layout.PixelConverter;
@ -33,7 +36,6 @@ import org.eclipse.cdt.internal.ui.dialogs.IStatusChangeListener;
import org.eclipse.cdt.internal.ui.dialogs.StatusInfo;
import org.eclipse.cdt.internal.ui.refactoring.includes.IncludeGroupStyle;
import org.eclipse.cdt.internal.ui.refactoring.includes.IncludeGroupStyle.IncludeKind;
import org.eclipse.cdt.internal.ui.refactoring.includes.IncludePreferences;
import org.eclipse.cdt.internal.ui.wizards.dialogfields.DialogField;
import org.eclipse.cdt.internal.ui.wizards.dialogfields.IDialogFieldListener;
import org.eclipse.cdt.internal.ui.wizards.dialogfields.ITreeListAdapter;
@ -43,63 +45,39 @@ import org.eclipse.cdt.internal.ui.wizards.dialogfields.TreeListDialogField;
* The preference block for configuring styles of different categories of include statements.
*/
public class IncludeCategoriesBlock extends OptionsConfigurationBlock {
private static final Key KEY_STYLE_GROUP_RELATED = getCDTUIKey(IncludePreferences.INCLUDE_STYLE_GROUP_RELATED);
private static final Key KEY_STYLE_PARTNER = getCDTUIKey(IncludePreferences.INCLUDE_STYLE_PARTNER);
private static final Key KEY_STYLE_GROUP_PARTNER = getCDTUIKey(IncludePreferences.INCLUDE_STYLE_GROUP_PARTNER);
private static final Key KEY_STYLE_SAME_FOLDER = getCDTUIKey(IncludePreferences.INCLUDE_STYLE_SAME_FOLDER);
private static final Key KEY_STYLE_GROUP_SAME_FOLDER = getCDTUIKey(IncludePreferences.INCLUDE_STYLE_GROUP_SAME_FOLDER);
private static final Key KEY_STYLE_SUBFOLDER = getCDTUIKey(IncludePreferences.INCLUDE_STYLE_SUBFOLDER);
private static final Key KEY_STYLE_GROUP_SUBFOLDER = getCDTUIKey(IncludePreferences.INCLUDE_STYLE_GROUP_SUBFOLDER);
private static final Key KEY_STYLE_GROUP_SYSTEM = getCDTUIKey(IncludePreferences.INCLUDE_STYLE_GROUP_SYSTEM);
private static Key[] getAllKeys() {
return new Key[] {
KEY_STYLE_GROUP_RELATED,
KEY_STYLE_PARTNER,
KEY_STYLE_GROUP_PARTNER,
KEY_STYLE_SAME_FOLDER,
KEY_STYLE_GROUP_SAME_FOLDER,
KEY_STYLE_SUBFOLDER,
KEY_STYLE_GROUP_SUBFOLDER,
KEY_STYLE_GROUP_SYSTEM,
};
}
private final Category[] rootCategories;
private final List<IncludeGroupStyle> styles;
private final Map<IncludeKind, Category> categories = new HashMap<IncludeKind, Category>();
private TreeListDialogField<Category> categoryTree;
private PixelConverter pixelConverter;
private StackLayout editorAreaStack;
private Category selectedCategory;
public IncludeCategoriesBlock(IStatusChangeListener context, IProject project,
IWorkbenchPreferenceContainer container) {
super(context, project, getAllKeys(), container);
rootCategories = createCategories();
IWorkbenchPreferenceContainer container, List<IncludeGroupStyle> styles) {
super(context, project, new Key[0], container);
this.styles = styles;
createCategories();
}
private static Category[] createCategories() {
Category related = new Category(PreferencesMessages.IncludeCategoriesBlock_related_headers_node,
PreferencesMessages.IncludeCategoriesBlock_related_headers_node_description)
.setGroupingKey(KEY_STYLE_GROUP_RELATED);
new Category(PreferencesMessages.IncludeCategoriesBlock_partner_header_node,
PreferencesMessages.IncludeCategoriesBlock_partner_header_node_description, related)
.setIncludeKind(IncludeKind.PARTNER)
.setGroupingKey(KEY_STYLE_GROUP_PARTNER)
.setStyleKey(KEY_STYLE_PARTNER);
new Category(PreferencesMessages.IncludeCategoriesBlock_same_folder_header_node,
PreferencesMessages.IncludeCategoriesBlock_same_folder_header_node_description, related)
.setIncludeKind(IncludeKind.IN_SAME_FOLDER)
.setGroupingKey(KEY_STYLE_GROUP_SAME_FOLDER)
.setStyleKey(KEY_STYLE_SAME_FOLDER);
new Category(PreferencesMessages.IncludeCategoriesBlock_subfolder_header_node,
PreferencesMessages.IncludeCategoriesBlock_subfolder_header_node_description, related)
.setIncludeKind(IncludeKind.IN_SUBFOLDERS)
.setGroupingKey(KEY_STYLE_GROUP_SUBFOLDER)
.setStyleKey(KEY_STYLE_SUBFOLDER);
Category system = new Category(PreferencesMessages.IncludeCategoriesBlock_system_headers_node,
PreferencesMessages.IncludeCategoriesBlock_system_headers_node_description)
.setGroupingKey(KEY_STYLE_GROUP_SYSTEM);
return new Category[] { related, system };
private void createCategories() {
createCategory(IncludeKind.RELATED);
createCategory(IncludeKind.PARTNER);
createCategory(IncludeKind.IN_SAME_FOLDER);
createCategory(IncludeKind.IN_SUBFOLDER);
createCategory(IncludeKind.SYSTEM);
createCategory(IncludeKind.SYSTEM_WITH_EXTENSION);
createCategory(IncludeKind.SYSTEM_WITHOUT_EXTENSION);
createCategory(IncludeKind.OTHER);
createCategory(IncludeKind.IN_SAME_PROJECT);
createCategory(IncludeKind.IN_OTHER_PROJECT);
createCategory(IncludeKind.EXTERNAL);
}
private Category createCategory(IncludeKind includeKind) {
Category parentCategory = categories.get(includeKind.parent);
Category category = new Category(includeKind, parentCategory);
categories.put(category.getIncludeKind(), category);
return category;
}
public void postSetSelection(Object element) {
@ -123,31 +101,24 @@ public class IncludeCategoriesBlock extends OptionsConfigurationBlock {
IncludeStyleAdapter adapter = new IncludeStyleAdapter();
categoryTree = new TreeListDialogField<Category>(adapter, null, new IncludeStyleLabelProvider());
categoryTree.setDialogFieldListener(adapter);
categoryTree.setLabelText(PreferencesMessages.NameStyleBlock_categories_label);
categoryTree.setLabelText(PreferencesMessages.IncludeCategoriesBlock_header_categories);
categoryTree.setViewerComparator(adapter);
createCategories();
for (Category category : rootCategories) {
categoryTree.addElement(category);
for (Category category : categories.values()) {
if (category.parent == null)
categoryTree.addElement(category);
}
Label label = categoryTree.getLabelControl(composite);
GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
gd.verticalAlignment = GridData.BEGINNING;
label.setLayoutData(gd);
label.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, false, false));
Control tree = categoryTree.getTreeControl(composite);
gd = new GridData();
gd.horizontalAlignment = GridData.FILL;
gd.grabExcessHorizontalSpace = true;
gd.verticalAlignment = GridData.FILL;
gd.grabExcessVerticalSpace = false;
GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
gd.widthHint = pixelConverter.convertWidthInCharsToPixels(50);
gd.heightHint = pixelConverter.convertHeightInCharsToPixels(12);
gd.heightHint = pixelConverter.convertHeightInCharsToPixels(2);
tree.setLayoutData(gd);
createCategoryEditorArea(composite);
createCategoryEditors(composite);
categoryTree.setTreeExpansionLevel(2);
categoryTree.selectFirstElement();
@ -156,43 +127,37 @@ public class IncludeCategoriesBlock extends OptionsConfigurationBlock {
return composite;
}
private void createCategoryEditorArea(Composite parent) {
private void createCategoryEditors(Composite parent) {
Composite editorArea = new Composite(parent, SWT.NONE);
editorArea.setLayoutData(new GridData(GridData.FILL_BOTH));
editorArea.setLayoutData(new GridData(SWT.FILL, SWT.BOTTOM, true, false));
editorArea.setFont(parent.getFont());
editorAreaStack = new StackLayout();
editorArea.setLayout(editorAreaStack);
for (Category category : rootCategories) {
createCategoryEditor(editorArea, category);
Map<IncludeKind, IncludeGroupStyle> stylesByKind = new HashMap<IncludeKind, IncludeGroupStyle>();
for (IncludeGroupStyle style : styles) {
if (style.getIncludeKind() != IncludeKind.MATCHING_PATTERN)
stylesByKind.put(style.getIncludeKind(), style);
}
}
private void createCategoryEditor(Composite parent, Category category) {
IncludeGroupStyle style = null;
Key styleKey = category.getStyleKey();
if (styleKey != null) {
IncludeKind includeKind = category.getIncludeKind();
String str = getValue(styleKey);
if (str != null)
style = IncludeGroupStyle.fromString(str, includeKind);
if (style == null)
style = new IncludeGroupStyle(includeKind);
}
IncludeGroupStyleBlock block = new IncludeGroupStyleBlock(fContext, fProject, fContainer,
category.getDescription(), category.getGroupingKey(), style);
Control composite = block.createContents(parent);
category.setEditorArea(composite);
for (Category child : category.getChildren()) {
createCategoryEditor(parent, child);
for (Category category : categories.values()) {
IncludeGroupStyleBlock block = new IncludeGroupStyleBlock(fContext, fProject, fContainer,
category.getDescription());
IncludeGroupStyle style = stylesByKind.get(category.getIncludeKind());
block.setStyle(style);
Control composite = block.createContents(editorArea);
category.setEditor(block, composite);
}
}
@Override
protected void updateControls() {
super.updateControls();
// XXX Implement
// Refresh
categoryTree.refresh();
updateConfigurationBlock(categoryTree.getSelectedElements());
for (Category category : categories.values()) {
category.getEditor().updateControls();
}
}
private void updateConfigurationBlock(List<Object> selection) {
@ -203,56 +168,29 @@ public class IncludeCategoriesBlock extends OptionsConfigurationBlock {
editorAreaStack.topControl.getParent().layout();
}
@Override
public void performDefaults() {
super.performDefaults();
// Refresh
categoryTree.refresh();
updateConfigurationBlock(categoryTree.getSelectedElements());
}
@Override
public boolean performOk() {
return super.performOk();
}
@Override
protected void validateSettings(Key changedKey, String oldValue, String newValue) {
StatusInfo status = new StatusInfo();
fContext.statusChanged(status);
fContext.statusChanged(new StatusInfo());
}
/**
* Represents a category of settings.
*/
private final static class Category {
public final String name;
public final String description;
public final Category parent;
public final int index; // Index in the siblings list
private final List<Category> children;
private IncludeKind includeKind;
private Key styleKey;
private Key groupingKey;
private final IncludeKind includeKind;
private Control editorArea;
private IncludeGroupStyleBlock editor;
Category(String name, String description, Category parent) {
this.name = name;
this.description = description;
Category(IncludeKind includeKind, Category parent) {
this.includeKind = includeKind;
this.parent = parent;
children = new ArrayList<Category>();
index = parent != null ? parent.addChild(this) : 0;
}
/**
* @param name Category name
*/
Category(String name, String description) {
this(name, description, null);
}
private int addChild(Category category) {
children.add(category);
return children.size() - 1;
@ -268,47 +206,32 @@ public class IncludeCategoriesBlock extends OptionsConfigurationBlock {
@Override
public String toString() {
return name;
return includeKind.name;
}
IncludeKind getIncludeKind() {
return includeKind;
}
Category setIncludeKind(IncludeKind includeKind) {
this.includeKind = includeKind;
return this;
}
Key getStyleKey() {
return styleKey;
}
Category setStyleKey(Key key) {
this.styleKey = key;
return this;
}
Key getGroupingKey() {
return groupingKey;
}
Category setGroupingKey(Key key) {
this.groupingKey = key;
return this;
IncludeGroupStyleBlock getEditor() {
return editor;
}
Control getEditorArea() {
return editorArea;
}
Category setEditorArea(Control editorArea) {
void setEditor(IncludeGroupStyleBlock editor, Control editorArea) {
this.editor = editor;
this.editorArea = editorArea;
return this;
}
public String getDescription() {
return description;
String getName() {
return includeKind.name;
}
String getDescription() {
return includeKind.description;
}
}
@ -364,7 +287,7 @@ public class IncludeCategoriesBlock extends OptionsConfigurationBlock {
@Override
public String getText(Object element) {
return ((Category) element).name;
return ((Category) element).getName();
}
}
}

View file

@ -23,6 +23,7 @@ import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Widget;
import org.eclipse.ui.preferences.IWorkbenchPreferenceContainer;
import org.eclipse.cdt.utils.ui.controls.ControlFactory;
@ -36,20 +37,24 @@ import org.eclipse.cdt.internal.ui.refactoring.includes.IncludeGroupStyle;
*/
public class IncludeGroupStyleBlock extends OptionsConfigurationBlock {
private final String description;
private final Key groupingKey;
private final IncludeGroupStyle style;
@SuppressWarnings("hiding")
private final ArrayList<Button> fCheckBoxes = new ArrayList<Button>();
@SuppressWarnings("hiding")
private final ArrayList<Text> fTextBoxes = new ArrayList<Text>();
private IncludeGroupStyle style;
private final ArrayList<Button> checkBoxes = new ArrayList<Button>();
private final ArrayList<Text> textBoxes = new ArrayList<Text>();
private PixelConverter pixelConverter;
private Button checkBoxBlankLine;
private static final Key[] EMPTY_KEY_ARRAY = {};
public IncludeGroupStyleBlock(IStatusChangeListener context, IProject project,
IWorkbenchPreferenceContainer container, String description, Key groupingKey,
IncludeGroupStyle style) {
super(context, project, new Key[] { groupingKey }, container);
IWorkbenchPreferenceContainer container, String description) {
super(context, project, EMPTY_KEY_ARRAY, container);
this.description = description;
this.groupingKey = groupingKey;
}
public IncludeGroupStyle getStyle() {
return style;
}
public void setStyle(IncludeGroupStyle style) {
this.style = style;
}
@ -59,7 +64,7 @@ public class IncludeGroupStyleBlock extends OptionsConfigurationBlock {
setShell(parent.getShell());
Composite composite = new Composite(parent, SWT.NONE);
Composite composite = new Composite(parent, SWT.NONE);
composite.setFont(parent.getFont());
GridLayout layout = new GridLayout();
@ -77,28 +82,51 @@ public class IncludeGroupStyleBlock extends OptionsConfigurationBlock {
layout.marginWidth = 0;
envelope.setLayout(layout);
addCheckBox(envelope, PreferencesMessages.IncludeGroupStyleBlock_keep_includes_together,
groupingKey, TRUE_FALSE, 0);
if (style != null) {
addCheckBox(envelope, PreferencesMessages.IncludeGroupStyleBlock_use_relative_path,
addCheckBox(envelope, PreferencesMessages.IncludeGroupStyleBlock_keep_includes_together, 0,
new BooleanDataSource() {
@Override
public boolean get() {
return style.isKeepTogether();
}
@Override
public void set(boolean value) {
style.setKeepTogether(value);
}
});
checkBoxBlankLine = addCheckBox(envelope, PreferencesMessages.IncludeGroupStyleBlock_blank_line_before,
pixelConverter.convertHorizontalDLUsToPixels(10),
new BooleanDataSource() {
@Override
public boolean get() {
return style.isBlankLineBefore();
}
@Override
public void set(boolean value) {
style.setBlankLineBefore(value);
}
});
if (!style.getIncludeKind().hasChildren()) {
addCheckBox(envelope, PreferencesMessages.IncludeGroupStyleBlock_use_relative_path, 0,
new BooleanDataSource() {
@Override
public boolean get() {
return style.isRelativePath();
}
@Override
public void set(boolean value) {
style.setRelativePath(value);
}
});
addCheckBox(envelope, PreferencesMessages.IncludeGroupStyleBlock_use_angle_brackets,
addCheckBox(envelope, PreferencesMessages.IncludeGroupStyleBlock_use_angle_brackets, 0,
new BooleanDataSource() {
@Override
public boolean get() {
return style.isAngleBrackets();
}
@Override
public void set(boolean value) {
style.setAngleBrackets(value);
@ -107,12 +135,14 @@ public class IncludeGroupStyleBlock extends OptionsConfigurationBlock {
}
updateControls();
updateDependent();
return composite;
}
private Button addCheckBox(Composite parent, String label, BooleanDataSource dataSource) {
private Button addCheckBox(Composite parent, String label, int indent, BooleanDataSource dataSource) {
GridData gd= new GridData(GridData.HORIZONTAL_ALIGN_FILL);
gd.horizontalSpan= 3;
gd.horizontalIndent= indent;
Button checkBox= new Button(parent, SWT.CHECK);
checkBox.setFont(JFaceResources.getDialogFont());
@ -125,7 +155,7 @@ public class IncludeGroupStyleBlock extends OptionsConfigurationBlock {
checkBox.setSelection(dataSource.get());
fCheckBoxes.add(checkBox);
checkBoxes.add(checkBox);
return checkBox;
}
@ -133,19 +163,28 @@ public class IncludeGroupStyleBlock extends OptionsConfigurationBlock {
@Override
protected void updateControls() {
super.updateControls();
// XXX Implement
for (int i= checkBoxes.size() - 1; i >= 0; i--) {
updateCheckBox(checkBoxes.get(i));
}
}
@Override
public void performDefaults() {
super.performDefaults();
// XXX Implement
protected void updateCheckBox(Button checkBox) {
BooleanDataSource dataSource = (BooleanDataSource) checkBox.getData();
checkBox.setSelection(dataSource.get());
}
@Override
public boolean performOk() {
return super.performOk();
// XXX Implement
protected void controlChanged(Widget widget) {
if (widget instanceof Button) {
BooleanDataSource dataSource = (BooleanDataSource) widget.getData();
dataSource.set(((Button) widget).getSelection());
}
updateDependent();
}
private void updateDependent() {
checkBoxBlankLine.setEnabled(style.isKeepTogether());
}
@Override

View file

@ -10,34 +10,51 @@
*******************************************************************************/
package org.eclipse.cdt.internal.ui.preferences;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.core.resources.IProject;
import org.eclipse.jface.layout.PixelConverter;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.ui.preferences.IWorkbenchPreferenceContainer;
import org.eclipse.cdt.internal.ui.dialogs.IStatusChangeListener;
import org.eclipse.cdt.internal.ui.dialogs.StatusInfo;
import org.eclipse.cdt.internal.ui.refactoring.includes.IncludeGroupStyle;
import org.eclipse.cdt.internal.ui.refactoring.includes.IncludeGroupStyle.IncludeKind;
import org.eclipse.cdt.internal.ui.wizards.dialogfields.ListDialogField;
/**
* The preference block for configuring relative order of include statements.
*/
public class IncludeOrderBlock extends OptionsConfigurationBlock {
private static final int IDX_UP = 0;
private static final int IDX_DOWN = 1;
private static final String[] UP_DOWN_LABELS = {
PreferencesMessages.IncludeOrderBlock_up,
PreferencesMessages.IncludeOrderBlock_down
};
private static Key[] getAllKeys() {
return new Key[] {
};
}
private final List<IncludeGroupStyle> styles;
private Map<IncludeKind, IncludeGroupStyle> stylesByKind;
private GroupListField includeGroupList;
private PixelConverter pixelConverter;
public IncludeOrderBlock(IStatusChangeListener context, IProject project,
IWorkbenchPreferenceContainer container) {
super(context, project, getAllKeys(), container);
}
public void postSetSelection(Object element) {
IWorkbenchPreferenceContainer container, List<IncludeGroupStyle> styles) {
super(context, project, new Key[0], container);
this.styles = styles;
}
@Override
@ -49,23 +66,273 @@ public class IncludeOrderBlock extends OptionsConfigurationBlock {
Composite composite = new Composite(parent, SWT.NONE);
composite.setFont(parent.getFont());
GridLayout layout = new GridLayout();
GridLayout layout = new GridLayout(2, false);
layout.marginHeight = 0;
layout.marginWidth = 0;
composite.setLayout(layout);
includeGroupList = new GroupListField();
includeGroupList.setLabelText(PreferencesMessages.IncludeOrderBlock_order_of_includes);
Label label = includeGroupList.getLabelControl(composite);
label.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, false, false, 2, 1));
Control control = includeGroupList.getListControl(composite);
GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
gd.widthHint = pixelConverter.convertWidthInCharsToPixels(50);
gd.heightHint = pixelConverter.convertHeightInCharsToPixels(5);
control.setLayoutData(gd);
Control buttonsControl = includeGroupList.getButtonBox(composite);
buttonsControl.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, false, false));
updateControls();
return composite;
}
@Override
public void performDefaults() {
super.performDefaults();
// TODO Implement
protected void updateControls() {
super.updateControls();
stylesByKind = getStylesByKind(styles);
List<IncludeGroupStyle> orderedStyles = new ArrayList<IncludeGroupStyle>(styles);
Collections.sort(orderedStyles); // Sort according to values returned by getOrder() method.
List<IncludeGroupStyle> groupedStyles = new ArrayList<IncludeGroupStyle>();
int order = 0;
for (IncludeGroupStyle style : orderedStyles) {
style.setOrder(order++);
IncludeKind includeKind = style.getIncludeKind();
if (style.isKeepTogether() &&
(!includeKind.hasChildren() || hasUngroupedChildren(includeKind, stylesByKind))) {
groupedStyles.add(style);
}
}
// Adjust order of groups to satisfy higher order grouping.
for (int i = 0; i < groupedStyles.size(); i++) {
IncludeGroupStyle style = groupedStyles.get(i);
IncludeKind groupingKind = getGroupingParentKind(style);
if (groupingKind != null) {
while (++i < groupedStyles.size() && getGroupingParentKind(groupedStyles.get(i)) == groupingKind) {}
for (int j = i + 1; j < groupedStyles.size(); j++) {
if (getGroupingParentKind(groupedStyles.get(j)) == groupingKind) {
groupedStyles.add(i++, groupedStyles.remove(j));
}
}
}
}
includeGroupList.setElements(groupedStyles);
}
private boolean areKeptTogether(IncludeGroupStyle style1, IncludeGroupStyle style2) {
IncludeKind kind = getGroupingParentKind(style1);
return kind != null && kind == getGroupingParentKind(style2);
}
private IncludeKind getGroupingParentKind(IncludeGroupStyle style) {
IncludeKind kind = style.getIncludeKind().parent;
if (kind == null)
return null;
while (true) {
// "Other" include kind is special since it applies only to non grouped includes.
if (kind == IncludeKind.OTHER && style.isKeepTogether())
break;
IncludeGroupStyle parent = stylesByKind.get(kind);
if (parent != null && parent.isKeepTogether())
return kind;
if (kind == IncludeKind.OTHER)
break;
kind = IncludeKind.OTHER;
}
return null;
}
private static Map<IncludeKind, IncludeGroupStyle> getStylesByKind(List<IncludeGroupStyle> styles) {
Map<IncludeKind, IncludeGroupStyle> stylesByKind = new HashMap<IncludeKind, IncludeGroupStyle>();
for (IncludeGroupStyle style : styles) {
if (style.getIncludeKind() != IncludeKind.MATCHING_PATTERN)
stylesByKind.put(style.getIncludeKind(), style);
}
return stylesByKind;
}
private boolean hasUngroupedChildren(IncludeKind includeKind, Map<IncludeKind, IncludeGroupStyle> stylesByKind) {
// This code relies on the fact that IncludeKind hierarchy is only two levels deep.
for (IncludeKind childKind : includeKind.children) {
if (!stylesByKind.get(childKind).isKeepTogether())
return true;
}
// "Other" include kind is special since it effectively includes all other ungrouped includes.
if (includeKind == IncludeKind.OTHER) {
for (IncludeKind kind : stylesByKind.keySet()) {
if (kind != IncludeKind.OTHER && kind.hasChildren() && !stylesByKind.get(kind).isKeepTogether() &&
hasUngroupedChildren(kind, stylesByKind)) {
return true;
}
}
}
return false;
}
@Override
protected void validateSettings(Key changedKey, String oldValue, String newValue) {
// TODO Implement
fContext.statusChanged(new StatusInfo());
}
private class GroupListField extends ListDialogField<IncludeGroupStyle> {
GroupListField() {
super(null, UP_DOWN_LABELS, new GroupLabelProvider());
}
@Override
public void dialogFieldChanged() {
super.dialogFieldChanged();
int order = 0;
for (IncludeGroupStyle style : getElements()) {
style.setOrder(order++);
}
}
@Override
protected boolean getManagedButtonState(ISelection sel, int index) {
if (index == IDX_UP) {
return !sel.isEmpty() && canMoveUp();
} else if (index == IDX_DOWN) {
return !sel.isEmpty() && canMoveDown();
}
return true;
}
@Override
protected boolean managedButtonPressed(int index) {
if (index == IDX_UP) {
up();
} else if (index == IDX_DOWN) {
down();
} else {
return false;
}
return true;
}
private void up() {
boolean[] selected = getSelectionMask(false);
extendSelectionForMovingUp(selected, fElements);
if (selected != null) {
setElements(moveUp(fElements, selected));
fTable.reveal(fElements.get(getFirstSelected(selected)));
}
}
private void down() {
boolean[] selected = getSelectionMask(true);
List<IncludeGroupStyle> reversed = reverse(fElements);
extendSelectionForMovingUp(selected, reversed);
if (selected != null) {
setElements(reverse(moveUp(reversed, selected)));
fTable.reveal(fElements.get(getFirstSelected(selected)));
}
}
private List<IncludeGroupStyle> reverse(List<IncludeGroupStyle> p) {
List<IncludeGroupStyle> reverse = new ArrayList<IncludeGroupStyle>(p.size());
for (int i = p.size(); --i >= 0;) {
reverse.add(p.get(i));
}
return reverse;
}
private boolean[] getSelectionMask(boolean reverse) {
boolean[] selectionMask = null;
if (isOkToUse(fTableControl)) {
int nElements = fElements.size();
for (int i : fTable.getTable().getSelectionIndices()) {
if (selectionMask == null)
selectionMask = new boolean[nElements];
selectionMask[reverse ? nElements - 1 - i : i] = true;
}
}
return selectionMask;
}
private void extendSelectionForMovingUp(boolean[] selection, List<IncludeGroupStyle> styles) {
for (int i = 1; i < selection.length; i++) {
int j = i - 1;
if (!selection[i] && selection[j] && areKeptTogether(styles.get(i), styles.get(j))) {
selection[i] = true;
}
}
}
private List<IncludeGroupStyle> moveUp(List<IncludeGroupStyle> elements, boolean[] selected) {
int nElements= elements.size();
List<IncludeGroupStyle> res = new ArrayList<IncludeGroupStyle>(nElements);
List<IncludeGroupStyle> floating = new ArrayList<IncludeGroupStyle>();
for (int i = 0; i < nElements; i++) {
IncludeGroupStyle curr = elements.get(i);
if (selected[i]) {
res.add(curr);
} else {
if (!floating.isEmpty() && !areKeptTogether(curr, floating.get(0))) {
res.addAll(floating);
floating.clear();
}
floating.add(curr);
}
}
res.addAll(floating);
return res;
}
private int getFirstSelected(boolean[] selected) {
for (int i = 0; i < selected.length; i++) {
if (selected[i])
return i;
}
return -1;
}
private boolean canMoveUp() {
boolean[] selected = getSelectionMask(false);
if (selected == null || selected[0])
return false;
return canMoveUp(fElements, selected);
}
private boolean canMoveDown() {
boolean[] selected = getSelectionMask(true);
if (selected == null || selected[0])
return false;
return canMoveUp(reverse(fElements), selected);
}
private boolean canMoveUp(List<IncludeGroupStyle> elements, boolean[] selected) {
for (int i = 1; i < selected.length; i++) {
int j = i - 1;
if (selected[i] && !selected[j] && areKeptTogether(elements.get(i), elements.get(j))) {
while (++i < selected.length && selected[i]) {}
if (!areKeptTogether(elements.get(i - 1), elements.get(j)))
return false; // Cannot break a group.
}
}
return true;
}
}
private static class GroupLabelProvider extends LabelProvider {
@Override
public Image getImage(Object element) {
return null;
}
@Override
public String getText(Object element) {
IncludeGroupStyle style = (IncludeGroupStyle) element;
String name = style.getName();
if (name == null) {
name = style.getIncludeKind().name;
}
return name;
}
}
}

View file

@ -10,33 +10,113 @@
*******************************************************************************/
package org.eclipse.cdt.internal.ui.preferences;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.core.resources.IProject;
import org.eclipse.ui.preferences.IWorkbenchPreferenceContainer;
import org.eclipse.cdt.internal.ui.dialogs.IStatusChangeListener;
import org.eclipse.cdt.internal.ui.refactoring.includes.IncludeGroupStyle;
import org.eclipse.cdt.internal.ui.refactoring.includes.IncludeGroupStyle.IncludeKind;
import org.eclipse.cdt.internal.ui.refactoring.includes.IncludePreferences;
/**
* The preference block for configuring style of include statements.
*/
public class IncludeStyleBlock extends TabConfigurationBlock {
static final Key KEY_STYLE_RELATED = getCDTUIKey(IncludePreferences.PREF_INCLUDE_STYLE_RELATED);
static final Key KEY_STYLE_PARTNER = getCDTUIKey(IncludePreferences.PREF_INCLUDE_STYLE_PARTNER);
static final Key KEY_STYLE_SAME_FOLDER = getCDTUIKey(IncludePreferences.PREF_INCLUDE_STYLE_SAME_FOLDER);
static final Key KEY_STYLE_SUBFOLDER = getCDTUIKey(IncludePreferences.PREF_INCLUDE_STYLE_SUBFOLDER);
static final Key KEY_STYLE_SYSTEM = getCDTUIKey(IncludePreferences.PREF_INCLUDE_STYLE_SYSTEM);
static final Key KEY_STYLE_SYSTEM_WITH_EXTENSION = getCDTUIKey(IncludePreferences.PREF_INCLUDE_STYLE_SYSTEM_WITH_EXTENSION);
static final Key KEY_STYLE_SYSTEM_WITHOUT_EXTENSION = getCDTUIKey(IncludePreferences.PREF_INCLUDE_STYLE_SYSTEM_WITHOUT_EXTENSION);
static final Key KEY_STYLE_OTHER = getCDTUIKey(IncludePreferences.PREF_INCLUDE_STYLE_OTHER);
static final Key KEY_STYLE_SAME_PROJECT = getCDTUIKey(IncludePreferences.PREF_INCLUDE_STYLE_SAME_PROJECT);
static final Key KEY_STYLE_OTHER_PROJECT = getCDTUIKey(IncludePreferences.PREF_INCLUDE_STYLE_OTHER_PROJECT);
static final Key KEY_STYLE_EXTERNAL = getCDTUIKey(IncludePreferences.PREF_INCLUDE_STYLE_EXTERNAL);
static final Key KEY_STYLE_MATCHING_PATTERN = getCDTUIKey(IncludePreferences.PREF_INCLUDE_STYLE_MATCHING_PATTERN);
static final Map<IncludeKind, Key> KEY_MAP = createKeyMap();
static final Key[] STYLE_KEYS = KEY_MAP.values().toArray(new Key[KEY_MAP.size()]);
private static final String[] TAB_LABELS = {
PreferencesMessages.IncludeStyleBlock_categories_tab,
PreferencesMessages.IncludeStyleBlock_order_tab,
};
private final List<IncludeGroupStyle> styles;
public IncludeStyleBlock(IStatusChangeListener context, IProject project,
IWorkbenchPreferenceContainer container) {
super(context, project, getTabs(context, project, container), getTabLabels(), container);
this(context, project, container, new ArrayList<IncludeGroupStyle>());
}
private IncludeStyleBlock(IStatusChangeListener context, IProject project,
IWorkbenchPreferenceContainer container, List<IncludeGroupStyle> styles) {
super(context, project, createTabs(context, project, container, styles), TAB_LABELS, container);
this.styles = styles;
settingsUpdated();
}
private static OptionsConfigurationBlock[] getTabs(IStatusChangeListener context,
IProject project, IWorkbenchPreferenceContainer container) {
return new OptionsConfigurationBlock[] {
new IncludeCategoriesBlock(context, project, container),
new IncludeOrderBlock(context, project, container),
};
private static OptionsConfigurationBlock[] createTabs(IStatusChangeListener context,
IProject project, IWorkbenchPreferenceContainer container, List<IncludeGroupStyle> styles) {
IncludeCategoriesBlock includeCategoriesBlock = new IncludeCategoriesBlock(context, project, container, styles);
IncludeOrderBlock includeOrderBlock = new IncludeOrderBlock(context, project, container, styles);
return new OptionsConfigurationBlock[] { includeCategoriesBlock, includeOrderBlock };
}
private static String[] getTabLabels() {
return new String[] {
PreferencesMessages.IncludeStyleBlock_categories_tab,
PreferencesMessages.IncludeStyleBlock_order_tab,
};
private static Map<IncludeKind, Key> createKeyMap() {
Map<IncludeKind, Key> map = new HashMap<IncludeKind, Key>();
map.put(IncludeKind.RELATED, KEY_STYLE_RELATED);
map.put(IncludeKind.PARTNER, KEY_STYLE_PARTNER);
map.put(IncludeKind.IN_SAME_FOLDER, KEY_STYLE_SAME_FOLDER);
map.put(IncludeKind.IN_SUBFOLDER, KEY_STYLE_SUBFOLDER);
map.put(IncludeKind.SYSTEM, KEY_STYLE_SYSTEM);
map.put(IncludeKind.SYSTEM_WITH_EXTENSION, KEY_STYLE_SYSTEM_WITH_EXTENSION);
map.put(IncludeKind.SYSTEM_WITHOUT_EXTENSION, KEY_STYLE_SYSTEM_WITHOUT_EXTENSION);
map.put(IncludeKind.OTHER, KEY_STYLE_OTHER);
map.put(IncludeKind.IN_SAME_PROJECT, KEY_STYLE_SAME_PROJECT);
map.put(IncludeKind.IN_OTHER_PROJECT, KEY_STYLE_OTHER_PROJECT);
map.put(IncludeKind.EXTERNAL, KEY_STYLE_EXTERNAL);
return Collections.unmodifiableMap(map);
}
@Override
protected boolean processChanges(IWorkbenchPreferenceContainer container) {
boolean result = super.processChanges(container);
for (IncludeGroupStyle style : styles) {
IncludeKind includeKind = style.getIncludeKind();
Key key = KEY_MAP.get(includeKind);
if (includeKind != IncludeKind.MATCHING_PATTERN) {
setValue(key, style.toString());
} else {
// TODO(sprigogin): Support custom include categories.
}
}
return result;
}
@Override
protected void settingsUpdated() {
if (styles != null) {
styles.clear();
for (Map.Entry<IncludeKind, Key> entry : KEY_MAP.entrySet()) {
IncludeKind includeKind = entry.getKey();
IncludeGroupStyle style = null;
String str = getValue(entry.getValue());
if (str != null)
style = IncludeGroupStyle.fromString(str, includeKind);
if (style == null)
style = new IncludeGroupStyle(includeKind);
styles.add(style);
}
}
// TODO Propagate styles to tabs.
super.settingsUpdated();
}
}

View file

@ -0,0 +1,106 @@
/*******************************************************************************
* Copyright (c) 2013 Google, Inc 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:
* Sergey Prigogin (Google) - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.ui.preferences;
import org.eclipse.core.resources.IProject;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.ui.preferences.IWorkbenchPreferenceContainer;
import org.eclipse.cdt.internal.ui.dialogs.IStatusChangeListener;
import org.eclipse.cdt.internal.ui.dialogs.StatusInfo;
import org.eclipse.cdt.internal.ui.refactoring.includes.IncludePreferences;
import org.eclipse.cdt.internal.ui.refactoring.includes.IncludePreferences.UnusedStatementDisposition;
import org.eclipse.cdt.internal.ui.wizards.dialogfields.LayoutUtil;
/**
* The preference block for configuring Organize Includes command.
*/
public class OrganizeIncludesBlock extends OptionsConfigurationBlock {
private static final Key KEY_HEURISTIC_HEADER_SUBSTITUTION = getCDTUIKey(IncludePreferences.PREF_HEURISTIC_HEADER_SUBSTITUTION);
private static final Key KEY_INCLUDES_REORDERING = getCDTUIKey(IncludePreferences.PREF_INCLUDES_REORDERING);
private static final Key KEY_UNUSED_STATEMENTS_DISPOSITION = getCDTUIKey(IncludePreferences.PREF_UNUSED_STATEMENTS_DISPOSITION);
private static final Key KEY_FORWARD_DECLARE_COMPOSITE_TYPES = getCDTUIKey(IncludePreferences.PREF_FORWARD_DECLARE_COMPOSITE_TYPES);
private static final Key KEY_FORWARD_DECLARE_ENUMS = getCDTUIKey(IncludePreferences.PREF_FORWARD_DECLARE_ENUMS);
private static final Key KEY_FORWARD_DECLARE_FUNCTIONS = getCDTUIKey(IncludePreferences.PREF_FORWARD_DECLARE_FUNCTIONS);
private static final Key KEY_FORWARD_DECLARE_NAMESPACE_ELEMENTS = getCDTUIKey(IncludePreferences.PREF_FORWARD_DECLARE_NAMESPACE_ELEMENTS);
private static final String[] DISPOSITION_VALUES = {
UnusedStatementDisposition.REMOVE.toString(),
UnusedStatementDisposition.COMMENT_OUT.toString(),
UnusedStatementDisposition.KEEP.toString(),
};
private static final String[] DISPOSITION_LABELS = {
PreferencesMessages.OrganizeIncludesBlock_remove,
PreferencesMessages.OrganizeIncludesBlock_comment_out,
PreferencesMessages.OrganizeIncludesBlock_keep,
};
private static Key[] ALL_KEYS = {
KEY_HEURISTIC_HEADER_SUBSTITUTION,
KEY_INCLUDES_REORDERING,
KEY_UNUSED_STATEMENTS_DISPOSITION,
KEY_FORWARD_DECLARE_COMPOSITE_TYPES,
KEY_FORWARD_DECLARE_ENUMS,
KEY_FORWARD_DECLARE_FUNCTIONS,
KEY_FORWARD_DECLARE_NAMESPACE_ELEMENTS,
};
public OrganizeIncludesBlock(IStatusChangeListener context, IProject project,
IWorkbenchPreferenceContainer container) {
super(context, project, ALL_KEYS, container);
}
@Override
protected Control createContents(Composite parent) {
setShell(parent.getShell());
Composite composite = new Composite(parent, SWT.NONE);
composite.setFont(parent.getFont());
GridLayout layout = new GridLayout(2, false);
layout.marginHeight = 0;
layout.marginWidth = 0;
composite.setLayout(layout);
Control control = addCheckBox(composite, PreferencesMessages.OrganizeIncludesBlock_allow_reordering,
KEY_INCLUDES_REORDERING, FALSE_TRUE, 0);
LayoutUtil.setHorizontalSpan(control, 2);
control = addCheckBox(composite, PreferencesMessages.OrganizeIncludesBlock_heuristic_header_substitution,
KEY_HEURISTIC_HEADER_SUBSTITUTION, FALSE_TRUE, 0);
LayoutUtil.setHorizontalSpan(control, 2);
control = addCheckBox(composite, PreferencesMessages.OrganizeIncludesBlock_forward_declare_composite_types,
KEY_FORWARD_DECLARE_COMPOSITE_TYPES, FALSE_TRUE, 0);
LayoutUtil.setHorizontalSpan(control, 2);
control = addCheckBox(composite, PreferencesMessages.OrganizeIncludesBlock_forward_declare_enums,
KEY_FORWARD_DECLARE_ENUMS, FALSE_TRUE, 0);
LayoutUtil.setHorizontalSpan(control, 2);
control = addCheckBox(composite, PreferencesMessages.OrganizeIncludesBlock_forward_declare_functions,
KEY_FORWARD_DECLARE_FUNCTIONS, FALSE_TRUE, 0);
LayoutUtil.setHorizontalSpan(control, 2);
control = addCheckBox(composite, PreferencesMessages.OrganizeIncludesBlock_forward_declare_namespace_elements,
KEY_FORWARD_DECLARE_NAMESPACE_ELEMENTS, FALSE_TRUE, 0);
LayoutUtil.setHorizontalSpan(control, 2);
control = addComboBox(composite, PreferencesMessages.OrganizeIncludesBlock_unused_statements,
KEY_UNUSED_STATEMENTS_DISPOSITION, DISPOSITION_VALUES, DISPOSITION_LABELS, 0);
LayoutUtil.setHorizontalSpan(getLabel(control), 1);
updateControls();
return composite;
}
@Override
protected void validateSettings(Key changedKey, String oldValue, String newValue) {
StatusInfo status = new StatusInfo();
fContext.statusChanged(status);
}
}

View file

@ -0,0 +1,53 @@
/*******************************************************************************
* Copyright (c) 2013 Google, Inc 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:
* Sergey Prigogin (Google) - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.ui.preferences;
import org.eclipse.ui.preferences.IWorkbenchPreferenceContainer;
import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.internal.ui.ICHelpContextIds;
/*
* The preference page for configuring Organize Includes command.
*/
public class OrganizeIncludesPreferencePage extends ConfigurationBlockPropertyAndPreferencePage {
public static final String PREF_ID= "org.eclipse.cdt.ui.preferences.OrganizeIncludesPreferencePage"; //$NON-NLS-1$
public static final String PROP_ID= "org.eclipse.cdt.ui.propertyPages.OrganizeIncludesPreferencePage"; //$NON-NLS-1$
public OrganizeIncludesPreferencePage() {
setPreferenceStore(CUIPlugin.getDefault().getPreferenceStore());
// Only used when the page is shown programmatically.
setTitle(PreferencesMessages.OrganizeIncludesPreferencePage_title);
}
@Override
protected OptionsConfigurationBlock createConfigurationBlock(IWorkbenchPreferenceContainer container) {
return new OrganizeIncludesBlock(getNewStatusChangedListener(), getProject(), container);
}
@Override
protected String getHelpId() {
return ICHelpContextIds.ORGANIZE_INCLUDES_PREFERENCE_PAGE;
}
@Override
protected String getPreferencePageId() {
return PREF_ID;
}
@Override
protected String getPropertyPageId() {
return null;
// TODO(sprigogin): Project specific settings
// return PROP_ID;
}
}

View file

@ -369,8 +369,8 @@ public final class PreferencesMessages extends NLS {
public static String IncludeStyleBlock_order_tab;
public static String IncludeCategoriesBlock_external_headers_node;
public static String IncludeCategoriesBlock_external_headers_node_description;
public static String IncludeCategoriesBlock_other_headers_node;
public static String IncludeCategoriesBlock_other_headers_node_description;
public static String IncludeCategoriesBlock_unrelated_headers_node;
public static String IncludeCategoriesBlock_unrelated_headers_node_description;
public static String IncludeCategoriesBlock_other_project_headers_node;
public static String IncludeCategoriesBlock_other_project_headers_node_description;
public static String IncludeCategoriesBlock_partner_header_node;
@ -392,9 +392,14 @@ public final class PreferencesMessages extends NLS {
public static String IncludeCategoriesBlock_user_defined_categories_node;
public static String IncludeCategoriesBlock_user_defined_categories_node_description;
public static String IncludeGroupStyleBlock_keep_includes_together;
public static String IncludeCategoriesBlock_header_categories;
public static String IncludeGroupStyleBlock_blank_line_before;
public static String IncludeGroupStyleBlock_use_relative_path;
public static String IncludeGroupStyleBlock_use_angle_brackets;
public static String IncludeOrderBlock_up;
public static String IncludeOrderBlock_down;
public static String IncludeOrderBlock_order_of_includes;
public static String NameStylePreferencePage_title;
public static String NameStyleBlock_code_node;
public static String NameStyleBlock_files_node;
@ -433,6 +438,18 @@ public final class PreferencesMessages extends NLS {
public static String NameStyleBlock_invalid_word_delimiter;
public static String NameStyleBlock_invalid_suffix;
public static String OrganizeIncludesPreferencePage_title;
public static String OrganizeIncludesBlock_allow_reordering;
public static String OrganizeIncludesBlock_forward_declare_composite_types;
public static String OrganizeIncludesBlock_forward_declare_enums;
public static String OrganizeIncludesBlock_forward_declare_functions;
public static String OrganizeIncludesBlock_forward_declare_namespace_elements;
public static String OrganizeIncludesBlock_heuristic_header_substitution;
public static String OrganizeIncludesBlock_unused_statements;
public static String OrganizeIncludesBlock_comment_out;
public static String OrganizeIncludesBlock_keep;
public static String OrganizeIncludesBlock_remove;
public static String EditTemplateDialog_error_noname;
public static String EditTemplateDialog_error_invalidName;
public static String EditTemplateDialog_title_new;

View file

@ -419,22 +419,20 @@ CodeTemplateBlock_export_error_title= Export Templates
CodeTemplateBlock_export_error_hidden= Export failed.\n{0} is a hidden file.
CodeTemplateBlock_export_error_canNotWrite= Export failed.\n{0} cannot be modified.
IncludeStylePreferencePage_title= Includes
IncludeStylePreferencePage_title= Include Style
IncludeStyleBlock_categories_tab= Categories
IncludeStyleBlock_order_tab= Order
IncludeCategoriesBlock_related_headers_node= Closely Related Headers
IncludeCategoriesBlock_related_headers_node_description= Closely related header files
IncludeCategoriesBlock_external_headers_node= External Headers
IncludeCategoriesBlock_external_headers_node_description= Header files outside workspace
IncludeCategoriesBlock_other_headers_node= Other Headers
IncludeCategoriesBlock_other_headers_node_description= Header files in the workspace and outside it
IncludeCategoriesBlock_other_project_headers_node= Headers in Other Projects
IncludeCategoriesBlock_other_project_headers_node_description= Header files in projects this project depends upon
IncludeCategoriesBlock_other_project_headers_node_description= Header files in other projects
IncludeCategoriesBlock_partner_header_node= Partner Header
IncludeCategoriesBlock_partner_header_node_description= Header file with the same name
IncludeCategoriesBlock_same_project_headers_node= Headers in Same Project
IncludeCategoriesBlock_same_project_headers_node_description= Header files in the same project
IncludeCategoriesBlock_related_headers_node= Related Headers
IncludeCategoriesBlock_related_headers_node_description= Related header files
IncludeCategoriesBlock_same_project_headers_node_description= Header files in the same project as the including file
IncludeCategoriesBlock_same_folder_header_node= Headers in Same Folder
IncludeCategoriesBlock_same_folder_header_node_description= Header files in the same folder
IncludeCategoriesBlock_subfolder_header_node= Headers in Subfolders
@ -445,11 +443,18 @@ IncludeCategoriesBlock_system_headers_with_extension_node= System Headers with E
IncludeCategoriesBlock_system_headers_with_extension_node_description= System header files with extension, e.g. stdio.h
IncludeCategoriesBlock_system_headers_without_extension_node= System Headers without Extension
IncludeCategoriesBlock_system_headers_without_extension_node_description= System headers without extension, e.g. vector
IncludeCategoriesBlock_unrelated_headers_node= Other Headers
IncludeCategoriesBlock_unrelated_headers_node_description= Header files in the workspace and outside it
IncludeCategoriesBlock_user_defined_categories_node= User-defined Categories
IncludeCategoriesBlock_user_defined_categories_node_description= Categories of header files defined by the user
IncludeCategoriesBlock_header_categories= &Header File Categories
IncludeGroupStyleBlock_keep_includes_together= &Keep include statements together
IncludeGroupStyleBlock_use_relative_path= Use path &relative to including file
IncludeGroupStyleBlock_blank_line_before= Separate from previous includes by a &blank line
IncludeGroupStyleBlock_use_relative_path= Use path &relative to the including file
IncludeGroupStyleBlock_use_angle_brackets= Use &angle brackets
IncludeOrderBlock_up= &Up
IncludeOrderBlock_down= D&own
IncludeOrderBlock_order_of_includes= O&rder of Include Statements:
NameStylePreferencePage_title=Name Style
NameStyleBlock_code_node=Code
@ -489,6 +494,18 @@ NameStyleBlock_invalid_prefix=Invalid prefix
NameStyleBlock_invalid_word_delimiter=Invalid word delimiter
NameStyleBlock_invalid_suffix=Invalid suffix
OrganizeIncludesPreferencePage_title= Organize Includes
OrganizeIncludesBlock_allow_reordering= Allow &reordering of includes
OrganizeIncludesBlock_forward_declare_composite_types= Forward declare &classes, structs and unions
OrganizeIncludesBlock_forward_declare_enums= Forward declare &enums when possible
OrganizeIncludesBlock_forward_declare_functions= Forward declare &functions
OrganizeIncludesBlock_forward_declare_namespace_elements= Forward declare &namespace elements
OrganizeIncludesBlock_heuristic_header_substitution= Allow &heuristic header file substitution
OrganizeIncludesBlock_unused_statements= &Unused Includes and Forward Declarations:
OrganizeIncludesBlock_comment_out= Comment out
OrganizeIncludesBlock_keep= Keep
OrganizeIncludesBlock_remove= Remove
# edit template dialog
EditTemplateDialog_error_noname=Template name cannot be empty.
EditTemplateDialog_error_invalidName=Template name contains invalid characters.

View file

@ -18,6 +18,8 @@ import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.layout.PixelConverter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
@ -75,7 +77,7 @@ public class TabConfigurationBlock extends OptionsConfigurationBlock {
PixelConverter pixelConverter = new PixelConverter(parent);
final TabFolder folder = new TabFolder(parent, SWT.NONE);
folder.setLayout(new TabFolderLayout());
folder.setLayoutData(new GridData(GridData.FILL_BOTH));
folder.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
for (int i = 0; i < fTabs.length; i++) {
TabItem item = new TabItem(folder, SWT.NONE);
@ -90,6 +92,18 @@ public class TabConfigurationBlock extends OptionsConfigurationBlock {
fTabs[i].createContents(composite);
}
Dialog.applyDialogFont(folder);
folder.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
for (OptionsConfigurationBlock tab : fTabs) {
tab.updateControls();
}
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
}
});
return folder;
}
@ -103,4 +117,36 @@ public class TabConfigurationBlock extends OptionsConfigurationBlock {
}
fContext.statusChanged(fStatus);
}
@Override
public boolean performOk() {
for (OptionsConfigurationBlock tab : fTabs) {
tab.performOk();
}
return super.performOk();
}
@Override
public boolean performApply() {
for (OptionsConfigurationBlock tab : fTabs) {
tab.performApply();
}
return super.performApply();
}
@Override
public void performDefaults() {
super.performDefaults();
for (OptionsConfigurationBlock tab : fTabs) {
tab.performDefaults();
}
}
@Override
public void performRevert() {
super.performRevert();
for (OptionsConfigurationBlock tab : fTabs) {
tab.performRevert();
}
}
}

View file

@ -13,6 +13,8 @@ package org.eclipse.cdt.internal.ui.refactoring.includes;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
import org.eclipse.ui.IMemento;
@ -21,34 +23,86 @@ import org.eclipse.ui.XMLMemento;
import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.internal.ui.preferences.PreferencesMessages;
/**
* Style preferences for a category of include statements.
*/
public class IncludeGroupStyle {
public class IncludeGroupStyle implements Comparable<IncludeGroupStyle> {
public enum IncludeKind {
PARTNER,
IN_SAME_FOLDER,
IN_SUBFOLDERS,
SYSTEM_WITH_EXTENSION,
SYSTEM_WITHOUT_EXTENSION,
IN_WORKSPACE,
EXTERNAL,
MATCHING_PATTERN,
RELATED(PreferencesMessages.IncludeCategoriesBlock_related_headers_node,
PreferencesMessages.IncludeCategoriesBlock_related_headers_node_description,
null),
PARTNER(PreferencesMessages.IncludeCategoriesBlock_partner_header_node,
PreferencesMessages.IncludeCategoriesBlock_partner_header_node_description,
RELATED),
IN_SAME_FOLDER(PreferencesMessages.IncludeCategoriesBlock_same_folder_header_node,
PreferencesMessages.IncludeCategoriesBlock_same_folder_header_node_description,
RELATED),
IN_SUBFOLDER(PreferencesMessages.IncludeCategoriesBlock_subfolder_header_node,
PreferencesMessages.IncludeCategoriesBlock_subfolder_header_node_description,
RELATED),
SYSTEM(PreferencesMessages.IncludeCategoriesBlock_system_headers_node,
PreferencesMessages.IncludeCategoriesBlock_system_headers_node_description,
null),
SYSTEM_WITH_EXTENSION(PreferencesMessages.IncludeCategoriesBlock_system_headers_with_extension_node,
PreferencesMessages.IncludeCategoriesBlock_system_headers_with_extension_node_description,
SYSTEM),
SYSTEM_WITHOUT_EXTENSION(PreferencesMessages.IncludeCategoriesBlock_system_headers_without_extension_node,
PreferencesMessages.IncludeCategoriesBlock_system_headers_without_extension_node_description,
SYSTEM),
OTHER(PreferencesMessages.IncludeCategoriesBlock_unrelated_headers_node,
PreferencesMessages.IncludeCategoriesBlock_unrelated_headers_node_description,
null),
IN_SAME_PROJECT(PreferencesMessages.IncludeCategoriesBlock_same_project_headers_node,
PreferencesMessages.IncludeCategoriesBlock_same_project_headers_node_description,
OTHER),
IN_OTHER_PROJECT(PreferencesMessages.IncludeCategoriesBlock_other_project_headers_node,
PreferencesMessages.IncludeCategoriesBlock_other_project_headers_node_description,
OTHER),
EXTERNAL(PreferencesMessages.IncludeCategoriesBlock_external_headers_node,
PreferencesMessages.IncludeCategoriesBlock_external_headers_node_description,
OTHER),
MATCHING_PATTERN(PreferencesMessages.IncludeCategoriesBlock_user_defined_categories_node,
PreferencesMessages.IncludeCategoriesBlock_user_defined_categories_node_description,
null);
public final String name;
public final String description;
public final IncludeKind parent;
public final List<IncludeKind> children = new ArrayList<IncludeKind>();
private IncludeKind(String name, String description, IncludeKind parent) {
this.name = name;
this.description = description;
this.parent = parent;
if (parent != null)
parent.children.add(this);
}
public boolean hasChildren() {
return !children.isEmpty();
}
}
private static final String TAG_STYLE = "style"; //$NON-NLS-1$
private static final String TAG_NAME = "name"; //$NON-NLS-1$
private static final String TAG_PATTERN = "pattern"; //$NON-NLS-1$
private static final String TAG_DISABLED = "disabled"; //$NON-NLS-1$
private static final String TAG_KEEP_TOGETHER = "keep_together"; //$NON-NLS-1$
private static final String TAG_BLANK_LINE_BEFORE = "blank_line_before"; //$NON-NLS-1$
private static final String TAG_RELATIVE_PATH = "relative_path"; //$NON-NLS-1$
private static final String TAG_ANGLE_BRACKETS = "angle_brackets"; //$NON-NLS-1$
private static final String TAG_ORDER = "order"; //$NON-NLS-1$
private final IncludeKind includeKind;
private boolean disabled;
private boolean keepTogether;
private boolean blankLineBefore;
private boolean relativePath;
private boolean angleBrackets;
private Pattern headerNamePattern;
private String name;
private int order; // Relative position of the include group. Ignored if keepTogether is false.
public IncludeGroupStyle(IncludeKind includeKind) {
if (includeKind == null || includeKind == IncludeKind.MATCHING_PATTERN)
@ -66,28 +120,38 @@ public class IncludeGroupStyle {
this.headerNamePattern = headerNamePattern;
}
public boolean isDisabled() {
return disabled;
public boolean isKeepTogether() {
return keepTogether;
}
public void setDisabled(boolean disabled) {
this.disabled = disabled;
public void setKeepTogether(boolean value) {
this.keepTogether = value;
}
public boolean isBlankLineBefore() {
return blankLineBefore;
}
public void setBlankLineBefore(boolean value) {
this.blankLineBefore = value;
}
public boolean isRelativePath() {
return relativePath;
}
public void setRelativePath(boolean relativePath) {
this.relativePath = relativePath;
public void setRelativePath(boolean value) {
assert !includeKind.hasChildren();
this.relativePath = value;
}
public boolean isAngleBrackets() {
return angleBrackets;
}
public void setAngleBrackets(boolean angleBrackets) {
this.angleBrackets = angleBrackets;
public void setAngleBrackets(boolean value) {
assert !includeKind.hasChildren();
this.angleBrackets = value;
}
public Pattern getHeaderNamePattern() {
@ -110,6 +174,14 @@ public class IncludeGroupStyle {
return includeKind;
}
public int getOrder() {
return order;
}
public void setOrder(int order) {
this.order = order;
}
public static IncludeGroupStyle fromMemento(IMemento memento, IncludeKind includeKind) {
IncludeGroupStyle style;
if (includeKind == IncludeKind.MATCHING_PATTERN) {
@ -119,14 +191,24 @@ public class IncludeGroupStyle {
} else {
style = new IncludeGroupStyle(includeKind);
}
style.setDisabled(memento.getBoolean(TAG_DISABLED));
style.setRelativePath(memento.getBoolean(TAG_RELATIVE_PATH));
style.setAngleBrackets(memento.getBoolean(TAG_ANGLE_BRACKETS));
style.setKeepTogether(nullToFalse(memento.getBoolean(TAG_KEEP_TOGETHER)));
style.setBlankLineBefore(nullToFalse(memento.getBoolean(TAG_BLANK_LINE_BEFORE)));
if (!includeKind.hasChildren()) {
style.setRelativePath(nullToFalse(memento.getBoolean(TAG_RELATIVE_PATH)));
style.setAngleBrackets(nullToFalse(memento.getBoolean(TAG_ANGLE_BRACKETS)));
}
Integer order = memento.getInteger(TAG_ORDER);
if (order != null)
style.setOrder(order.intValue());
return style;
}
private static String nullToEmpty(String string) {
return string != null ? string : ""; //$NON-NLS-1$
private static boolean nullToFalse(Boolean val) {
return val != null && val.booleanValue();
}
private static String nullToEmpty(String val) {
return val != null ? val : ""; //$NON-NLS-1$
}
public void saveToMemento(IMemento memento) {
@ -134,9 +216,14 @@ public class IncludeGroupStyle {
memento.putString(TAG_NAME, name);
memento.putString(TAG_PATTERN, headerNamePattern.toString());
}
memento.putBoolean(TAG_DISABLED, disabled);
memento.putBoolean(TAG_RELATIVE_PATH, relativePath);
memento.putBoolean(TAG_ANGLE_BRACKETS, angleBrackets);
memento.putBoolean(TAG_KEEP_TOGETHER, keepTogether);
memento.putBoolean(TAG_BLANK_LINE_BEFORE, blankLineBefore);
if (!includeKind.hasChildren()) {
memento.putBoolean(TAG_RELATIVE_PATH, relativePath);
memento.putBoolean(TAG_ANGLE_BRACKETS, angleBrackets);
}
if (keepTogether)
memento.putInteger(TAG_ORDER, order);
}
@Override
@ -162,4 +249,17 @@ public class IncludeGroupStyle {
}
return fromMemento(memento, includeKind);
}
/**
* Compares styles according to their sorting order.
*/
@Override
public int compareTo(IncludeGroupStyle other) {
if (keepTogether != other.keepTogether)
return keepTogether ? -1 : 1;
int c = order - other.order;
if (c != 0)
return c;
return includeKind.ordinal() - other.includeKind.ordinal();
}
}

View file

@ -48,6 +48,10 @@ public class IncludeInfo {
this.isSystem = isSystem;
}
/**
* Returns the part of the include statement identifying the included header file without
* quotes or angle brackets.
*/
public final String getName() {
return name;
}

View file

@ -14,17 +14,19 @@ package org.eclipse.cdt.internal.ui.refactoring.includes;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.viewers.LabelProvider;
@ -34,6 +36,8 @@ import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.dialogs.ElementListSelectionDialog;
import org.eclipse.ui.texteditor.ITextEditor;
import com.ibm.icu.text.Collator;
import org.eclipse.cdt.core.dom.IName;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.EScopeKind;
@ -63,17 +67,30 @@ import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.utils.PathUtil;
import org.eclipse.cdt.internal.core.resources.PathCanonicalizationStrategy;
import org.eclipse.cdt.internal.core.resources.ResourceLookup;
import org.eclipse.cdt.internal.ui.editor.CEditorMessages;
import org.eclipse.cdt.internal.ui.refactoring.includes.IncludePreferences.IncludeType;
import org.eclipse.cdt.internal.ui.refactoring.includes.IncludeGroupStyle.IncludeKind;
/**
* Organizes the include directives and forward declarations of a source or header file.
*/
public class IncludeOrganizer {
// TODO(sprigogin): Move to a preference.
private static final String[] PARTNER_FILE_SUFFIXES = { "test", "unittest" }; //$NON-NLS-1$//$NON-NLS-2$
private static final Collator COLLATOR = Collator.getInstance();
private static final Comparator<IPath> PATH_COMPARATOR = new Comparator<IPath>() {
@Override
public int compare(IPath path1, IPath path2) {
int length1 = path1.segmentCount();
int length2 = path2.segmentCount();
for (int i = 0; i < length1 && i < length2; i++) {
int c = COLLATOR.compare(path1.segment(i), path2.segment(i));
if (c != 0)
return c;
}
return length1 - length2;
}
};
private final ITextEditor fEditor;
private final InclusionContext fContext;
@ -114,7 +131,8 @@ public class IncludeOrganizer {
// Create the forward declarations by examining the list of bindings which have to be
// declared.
Set<IBinding> bindings = removeBindingsDefinedInIncludedHeaders(resolver.getBindingsToDeclare(), reachableHeaders);
Set<IBinding> bindings =
removeBindingsDefinedInIncludedHeaders(resolver.getBindingsToDeclare(), reachableHeaders);
for (IBinding binding : bindings) {
// Create the text of the forward declaration of this binding.
StringBuilder declarationText = new StringBuilder();
@ -245,121 +263,124 @@ public class IncludeOrganizer {
forwardDeclarationListToUse.add(declarationText.toString());
}
// Obtain the final lists of library, project, and relative headers.
List<String> relativeIncludeDirectives = new ArrayList<String>();
List<String> projectIncludeDirectives = new ArrayList<String>();
List<String> libraryIncludeDirectives = new ArrayList<String>();
List<String> allIncludeDirectives = new ArrayList<String>();
Collections.sort(forwardDeclarations);
Collections.sort(functionForwardDeclarations);
IncludePreferences preferences = fContext.getPreferences();
Map<IPath, IncludeGroupStyle> classifiedHeaders =
new HashMap<IPath, IncludeGroupStyle>(fContext.getHeadersToInclude().size());
for (IPath file : fContext.getHeadersToInclude()) {
if (preferences.allowReordering && preferences.sortByHeaderLocation) {
// Add the created include directives to different lists.
createIncludeDirective(file, relativeIncludeDirectives, projectIncludeDirectives, libraryIncludeDirectives);
} else {
// Add all created include directives to the same list, making sure that no sort
// order is applied.
createIncludeDirective(file, allIncludeDirectives, allIncludeDirectives, allIncludeDirectives);
classifiedHeaders.put(file, getIncludeStyle(file));
}
@SuppressWarnings("unchecked")
List<IPath>[] orderedHeaders = (List<IPath>[]) new List<?>[classifiedHeaders.size()];
for (Map.Entry<IPath, IncludeGroupStyle> entry : classifiedHeaders.entrySet()) {
IPath path = entry.getKey();
IncludeGroupStyle style = entry.getValue();
IncludeGroupStyle groupingStyle = getGroupingStyle(style);
int position = groupingStyle.getOrder();
List<IPath> headers = orderedHeaders[position];
if (headers == null) {
headers = new ArrayList<IPath>();
orderedHeaders[position] = headers;
}
headers.add(path);
}
List<String> includeDirectives = new ArrayList<String>();
for (List<IPath> headers : orderedHeaders) {
if (headers != null && !headers.isEmpty()) {
Collections.sort(headers, PATH_COMPARATOR);
IncludeGroupStyle style = classifiedHeaders.get(headers.get(0));
IncludeGroupStyle groupingStyle = getGroupingStyle(style);
if (!includeDirectives.isEmpty() && groupingStyle.isBlankLineBefore())
includeDirectives.add(""); // Blank line separator //$NON-NLS-1$
for (IPath header : headers) {
style = classifiedHeaders.get(header);
includeDirectives.add(createIncludeDirective(header, style, "")); //$NON-NLS-1$
}
}
}
// Create the source code to insert into the editor.
IBuffer fBuffer = fContext.getTranslationUnit().getBuffer();
String lineSep = getLineSeparator(fBuffer);
String insertText = new String();
if (preferences.allowReordering) {
if (preferences.removeUnusedIncludes) {
// Remove *all* existing includes and forward declarations. Those which are required
// will be added again right afterwards.
StringBuilder buf = new StringBuilder();
for (String include : includeDirectives) {
buf.append(include);
buf.append(lineSep);
}
// TODO implement this
if (buf.length() != 0 && !forwardDeclarations.isEmpty())
buf.append(lineSep);
for (String declaration : forwardDeclarations) {
buf.append(declaration);
buf.append(lineSep);
}
if (buf.length() != 0 && !functionForwardDeclarations.isEmpty())
buf.append(lineSep);
for (String declaration : functionForwardDeclarations) {
buf.append(declaration);
buf.append(lineSep);
}
if (buf.length() != 0) {
buf.append(lineSep);
fBuffer.replace(0, 0, buf.toString());
}
}
private IncludeGroupStyle getGroupingStyle(IncludeGroupStyle style) {
if (style.isKeepTogether())
return style;
IncludeKind kind = style.getIncludeKind().parent;
if (kind != null) {
IncludeGroupStyle parent = fContext.getPreferences().includeStyles.get(kind);
if (parent != null && (parent.isKeepTogether() || parent.getIncludeKind() == IncludeKind.OTHER))
return parent;
}
return fContext.getPreferences().includeStyles.get(IncludeKind.OTHER);
}
private IncludeGroupStyle getIncludeStyle(IPath headerPath) {
IncludeKind includeKind;
IncludeInfo includeInfo = fContext.getIncludeForHeaderFile(headerPath);
if (includeInfo.isSystem()) {
if (headerPath.getFileExtension() == null) {
includeKind = IncludeKind.SYSTEM_WITHOUT_EXTENSION;
} else {
includeKind = IncludeKind.SYSTEM_WITH_EXTENSION;
}
if (preferences.sortByHeaderLocation) {
// Sort by header file location.
// Process the different types of include directives separately.
for (IncludeType includeType : preferences.groupOrder) {
List<String> stringList = null;
if (includeType == IncludeType.RELATIVE_HEADER) {
stringList = relativeIncludeDirectives;
} else if (includeType == IncludeType.PROJECT_HEADER) {
stringList = projectIncludeDirectives;
} else if (includeType == IncludeType.LIBRARY_HEADER) {
stringList = libraryIncludeDirectives;
} else if (includeType == IncludeType.FORWARD_DECLARATION) {
stringList = forwardDeclarations;
} else if (includeType == IncludeType.FUNCTION_FORWARD_DECLARATION) {
stringList = functionForwardDeclarations;
}
if (stringList == null || stringList.isEmpty()) {
continue;
}
// Sort alphabetically
if (preferences.sortAlphabetically) {
Collections.sort(stringList);
}
// Insert the actual text.
for (String str : stringList) {
insertText += str + lineSep;
}
// Insert blank line
if (preferences.separateIncludeBlocks) {
insertText += lineSep;
}
} else if (isPartnerFile(headerPath)) {
includeKind = IncludeKind.PARTNER;
} else {
IPath dir = fContext.getCurrentDirectory();
if (dir.isPrefixOf(headerPath)) {
if (headerPath.segmentCount() == dir.segmentCount() + 1) {
includeKind = IncludeKind.IN_SAME_FOLDER;
} else {
includeKind = IncludeKind.IN_SUBFOLDER;
}
} else {
// Don't sort by header file location.
// Sort alphabetically
if (preferences.sortAlphabetically) {
Collections.sort(allIncludeDirectives);
}
// Insert the actual text.
for (String str : allIncludeDirectives) {
insertText += str + lineSep;
}
}
} else {
// Existing include directives must not be reordered.
// Compare the list of existing include directives with the list of required include directives.
// TODO: Implement this. The following code template may be used for that:
/*for (IInclude includeDirective : fTu.getIncludes()) {
if (!allIncludeDirectives.contains(includeDirective)) {
// This include directive from the editor isn't present within the list of required includes and is therefore unused.
// Remove it from the editor, if enabled within the preferences.
if (OrganizeIncludesPreferences.getPreferenceStore().getBoolean(PREF_REMOVE_UNUSED_INCLUDES)) {
removeIncludeDirective(fTu, includeDirective);
}
IFile[] files = ResourceLookup.findFilesForLocation(headerPath);
if (files.length == 0) {
includeKind = IncludeKind.EXTERNAL;
} else {
// This include directive from the editor is required. Remove it from the list of required includes.
allIncludeDirectives.remove(includeDirective);
IProject project = fContext.getProject();
includeKind = IncludeKind.IN_OTHER_PROJECT;
for (IFile file : files) {
if (file.getProject().equals(project)) {
includeKind = IncludeKind.IN_SAME_PROJECT;
break;
}
}
}
}*/
// Insert those includes which still remain within the list of required includes (i.e. those include directives which have
// been added now).
for (String str : allIncludeDirectives) {
insertText += str + lineSep;
}
// Insert forward declarations.
for (String str : forwardDeclarations) {
insertText += str + lineSep;
}
}
if (!insertText.isEmpty()) {
// Insert the text plus a separating blank line into the editor.
insertText = insertText.trim() + lineSep + lineSep;
fBuffer.replace(0, 0, insertText);
}
Map<IncludeKind, IncludeGroupStyle> styles = fContext.getPreferences().includeStyles;
return styles.get(includeKind);
}
private Set<IBinding> removeBindingsDefinedInIncludedHeaders(Set<IBinding> bindings,
@ -513,7 +534,7 @@ public class IncludeOrganizer {
if (pos == sourceName.length())
return true;
String suffix = sourceName.substring(pos);
for (String s : PARTNER_FILE_SUFFIXES) {
for (String s : fContext.getPreferences().partnerFileSuffixes) {
if (suffix.equalsIgnoreCase(s))
return true;
}
@ -652,53 +673,22 @@ public class IncludeOrganizer {
}
}
/**
* Adds an include directive.
* @param headerFile The header file which should be included.
* @param relativeIncludeDirectives Out parameter. The list of relative headers to include.
* @param projectIncludeDirectives Out parameter. The list of project headers to include.
* @param libraryIncludeDirectives Out parameter. The list of library headers to include.
* @throws CoreException
*/
private void createIncludeDirective(IPath headerFile,
Collection<String> relativeIncludeDirectives,
Collection<String> projectIncludeDirectives,
Collection<String> libraryIncludeDirectives) throws CoreException {
IPath targetLocation = headerFile;
IPath targetDirectory = targetLocation.removeLastSegments(1);
targetDirectory = new Path(PathCanonicalizationStrategy.getCanonicalPath(targetDirectory.toFile()));
IPath sourceDirectory = fContext.getCurrentDirectory();
sourceDirectory = new Path(PathCanonicalizationStrategy.getCanonicalPath(sourceDirectory.toFile()));
IncludePreferences preferences = fContext.getPreferences();
boolean relativeToSource = false;
if (preferences.relativeHeaderInSameDir &&
PathUtil.equalPath(sourceDirectory, targetDirectory)) {
// The header is located within the same directory as the source file.
relativeToSource = true;
} else if (preferences.relativeHeaderInSubdir &&
PathUtil.isPrefix(sourceDirectory, targetLocation)) {
// The header is located within a subdirectory of the source file's directory.
relativeToSource = true;
} else if (preferences.relativeHeaderInParentDir &&
PathUtil.isPrefix(targetDirectory, sourceDirectory)) {
// The header is located within a parent directory of the source file's directory.
relativeToSource = true;
private String createIncludeDirective(IPath header, IncludeGroupStyle style, String lineComment) {
StringBuilder buf = new StringBuilder("#include "); //$NON-NLS-1$
buf.append(style.isAngleBrackets() ? '<' : '"');
String name = null;
if (style.isRelativePath()) {
IPath relativePath = PathUtil.makeRelativePath(header, fContext.getCurrentDirectory());
if (relativePath != null)
name = relativePath.toPortableString();
}
IncludeInfo includeInfo = null;
if (!relativeToSource)
includeInfo = fContext.getIncludeForHeaderFile(targetLocation);
Collection<String> headerList;
if (includeInfo != null) {
headerList = includeInfo.isSystem() ? libraryIncludeDirectives : projectIncludeDirectives;
} else {
// Include the header relative to the source file.
includeInfo = new IncludeInfo(PathUtil.makeRelativePath(targetLocation, sourceDirectory).toPortableString());
// Add this header to the relative headers.
headerList = relativeIncludeDirectives;
if (name == null) {
IncludeInfo includeInfo = fContext.getIncludeForHeaderFile(header);
name = includeInfo.getName();
}
headerList.add("#include " + includeInfo.toString()); //$NON-NLS-1$
buf.append(name);
buf.append(style.isAngleBrackets() ? '>' : '"');
buf.append(lineComment);
return buf.toString();
}
}

View file

@ -12,47 +12,56 @@ package org.eclipse.cdt.internal.ui.refactoring.includes;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.ui.PreferenceConstants;
import org.eclipse.cdt.internal.ui.refactoring.includes.IncludeGroupStyle.IncludeKind;
/**
* Preferences for managing of includes.
*/
public class IncludePreferences {
private static final String DEFAULT_PARTNER_FILE_SUFFIXES = "test,unittest"; //$NON-NLS-1$
public static enum UnusedStatementDisposition { REMOVE, COMMENT_OUT, KEEP }
public final Map<IncludeKind, IncludeGroupStyle> includeStyles;
public final boolean allowReordering;
public final boolean heuristicHeaderSubstitution;
public final boolean forwardDeclareCompositeTypes;
public final boolean forwardDeclareEnums;
public final boolean forwardDeclareFunctions;
public final boolean forwardDeclareNamespaceElements;
public final boolean relativeHeaderInSameDir;
public final boolean relativeHeaderInSubdir;
public final boolean relativeHeaderInParentDir;
public final boolean heuristicHeaderSubstitution;
public final boolean separateIncludeBlocks;
public final boolean sortAlphabetically;
public final boolean removeUnusedIncludes;
public final boolean commentOutUnusedIncludes;
public final boolean sortByHeaderLocation;
public final List<IncludeType> groupOrder; // TODO(sprigogin): Change to IncludeGroupOrder
public static enum IncludeGroupType {
SIBLING_HEADER, HEADERS_IN_SAME_FOLDER, HEADERS_IN_SUBFOLDERS,
SYSTEM_HEADERS, SYSTEM_C_HEADERS, SYSTEM_CPP_HEADERS,
PROJECT_HEADERS, EXTERNAL_HEADERS, SPECIAL_HEADERS,
TYPE_FORWARD_DECLARATIONS, FUNCTION_FORWARD_DECLARATIONS, USING_DECLARATIONS
}
public static class GroupStyle {
public boolean useRelativePath;
public boolean useAngleBrackets;
public boolean separateByBlankLine;
}
public final UnusedStatementDisposition unusedStatementsDisposition;
public final String[] partnerFileSuffixes;
public IncludePreferences(ICProject project) {
includeStyles = new HashMap<IncludeKind, IncludeGroupStyle>();
loadStyle(IncludeKind.RELATED, PREF_INCLUDE_STYLE_RELATED, project);
loadStyle(IncludeKind.PARTNER, PREF_INCLUDE_STYLE_PARTNER, project);
loadStyle(IncludeKind.IN_SAME_FOLDER, PREF_INCLUDE_STYLE_SAME_FOLDER, project);
loadStyle(IncludeKind.IN_SUBFOLDER, PREF_INCLUDE_STYLE_SUBFOLDER, project);
loadStyle(IncludeKind.SYSTEM, PREF_INCLUDE_STYLE_SYSTEM, project);
loadStyle(IncludeKind.SYSTEM_WITH_EXTENSION, PREF_INCLUDE_STYLE_SYSTEM_WITH_EXTENSION, project);
loadStyle(IncludeKind.SYSTEM_WITHOUT_EXTENSION, PREF_INCLUDE_STYLE_SYSTEM_WITHOUT_EXTENSION, project);
loadStyle(IncludeKind.OTHER, PREF_INCLUDE_STYLE_OTHER, project);
loadStyle(IncludeKind.IN_SAME_PROJECT, PREF_INCLUDE_STYLE_SAME_PROJECT, project);
loadStyle(IncludeKind.IN_OTHER_PROJECT, PREF_INCLUDE_STYLE_OTHER_PROJECT, project);
loadStyle(IncludeKind.EXTERNAL, PREF_INCLUDE_STYLE_EXTERNAL, project);
// Normalize order property of the styles to make sure that the numbers are sequential.
List<IncludeGroupStyle> styles = new ArrayList<IncludeGroupStyle>(includeStyles.values());
Collections.sort(styles);
for (int i = 0; i < styles.size(); i++) {
styles.get(i).setOrder(i);
}
// TODO(sprigogin): Load styles for headers matching patterns.
forwardDeclareCompositeTypes = PreferenceConstants.getPreference(
PREF_FORWARD_DECLARE_COMPOSITE_TYPES, project, true);
forwardDeclareEnums = PreferenceConstants.getPreference(
@ -62,108 +71,38 @@ public class IncludePreferences {
forwardDeclareNamespaceElements = PreferenceConstants.getPreference(
PREF_FORWARD_DECLARE_NAMESPACE_ELEMENTS, project, true);
// Relative headers preferences
relativeHeaderInSameDir = PreferenceConstants.getPreference(
PREF_RELATIVE_HEADER_IN_SAME_DIR, project, false);
relativeHeaderInSubdir = PreferenceConstants.getPreference(
PREF_RELATIVE_HEADER_IN_SUB_DIR, project, false);
relativeHeaderInParentDir = PreferenceConstants.getPreference(
PREF_RELATIVE_HEADER_IN_PARENT_DIR, project, false);
// Header resolution preferences
String value = PreferenceConstants.getPreference(
PREF_PARTNER_FILE_SUFFIXES, project, DEFAULT_PARTNER_FILE_SUFFIXES);
partnerFileSuffixes = value.split(","); //$NON-NLS-1$
heuristicHeaderSubstitution = PreferenceConstants.getPreference(
PREF_HEURISTIC_HEADER_SUBSTITUTION, project, true);
// Header sort order preferences
allowReordering = PreferenceConstants.getPreference(
PREF_ALLOW_TO_REORDER_INCLUDES, project, true);
sortByHeaderLocation = PreferenceConstants.getPreference(
PREF_SORT_BY_HEADER_LOCATION, project, true);
String order = PreferenceConstants.getPreference(
PREF_HEADER_LOCATION_SORT_ORDER, project,
IncludeType.RELATIVE_HEADER.toString() + ',' +
IncludeType.LIBRARY_HEADER.toString() + ',' +
IncludeType.PROJECT_HEADER.toString() + ',' +
IncludeType.FORWARD_DECLARATION.toString() + ',' +
IncludeType.FUNCTION_FORWARD_DECLARATION.toString());
String[] textSortOrder = order.split(","); //$NON-NLS-1$
List<IncludeType> list = new ArrayList<IncludeType>(textSortOrder.length);
for (String type : textSortOrder) {
list.add(IncludeType.valueOf(type));
}
groupOrder = Collections.unmodifiableList(list);
separateIncludeBlocks = PreferenceConstants.getPreference(
PREF_SEPARATE_INCLUDE_BLOCKS, project, true);
sortAlphabetically = PreferenceConstants.getPreference(
PREF_SORT_ALPHABETICALLY, project, true);
PREF_INCLUDES_REORDERING, project, true);
// Unused include handling preferences
removeUnusedIncludes = PreferenceConstants.getPreference(
PREF_REMOVE_UNUSED_INCLUDES, project, false);
commentOutUnusedIncludes = PreferenceConstants.getPreference(
PREF_COMMENT_OUT_UNUSED_INCLUDES, project, true);
value = PreferenceConstants.getPreference(PREF_UNUSED_STATEMENTS_DISPOSITION, project, null);
UnusedStatementDisposition disposition = null;
if (value != null)
disposition = UnusedStatementDisposition.valueOf(value);
if (disposition == null)
disposition = UnusedStatementDisposition.COMMENT_OUT;
unusedStatementsDisposition = disposition;
}
private void loadStyle(IncludeKind includeKind, String preferenceKey, ICProject project) {
String value = PreferenceConstants.getPreference(preferenceKey, project, null);
IncludeGroupStyle style = null;
if (value != null)
style = IncludeGroupStyle.fromString(value, includeKind);
if (style == null)
style = new IncludeGroupStyle(includeKind);
includeStyles.put(includeKind, style);
}
// TODO(sprigogin): Move the constants and defaults to PreferenceConstants.
/**
* Enumerates the different types of code constructs which the organize includes action can
* generate.
*/
public enum IncludeType {
/**
* A header which is located within the current file's directory.
*/
RELATIVE_HEADER,
/**
* A header which is located within the current file's project directory.
*/
PROJECT_HEADER,
/**
* A (library) header which is located outside of the current file's project directory.
*/
LIBRARY_HEADER,
/**
* A forward declaration.
*/
FORWARD_DECLARATION,
/**
* A forward declaration of a function.
*/
FUNCTION_FORWARD_DECLARATION,
/**
* A problem like e.g. an unresolved symbol.
*/
FOUND_PROBLEM
}
/**
* Enumerates the different options for having a protection against multiple header file
* inclusion.
*/
public enum MultipleInclusionProtectionType {
/**
* No protection against multiple header file inclusion.
*/
NONE,
/**
* Use include guards to avoid multiple header file inclusion.
*/
INCLUDE_GUARDS,
/**
* Use pragma once to avoid multiple header file inclusion.
*/
PRAGMA_ONCE
}
/**
* Whether composite types should be forward declared if possible.
*
@ -199,131 +138,162 @@ public class IncludePreferences {
public static final String PREF_FORWARD_DECLARE_NAMESPACE_ELEMENTS = "forward_declare_namespace_elements"; //$NON-NLS-1$
/**
* Whether headers located within the same directory as the source file should always
* be included relative to the source file.
* Defines a list of file name suffixes. A header file and the including file are considered
* partners if their file names without extensions are either identical or differ by one of
* these suffixes.
*/
public static final String PREF_RELATIVE_HEADER_IN_SAME_DIR = "relative_header_in_same_dir"; //$NON-NLS-1$
public static final String PREF_PARTNER_FILE_SUFFIXES = "include_partner_file_suffixes"; //$NON-NLS-1$
/**
* Whether headers located within a subdirectory of the source file's directory should always
* be included relative to the source file.
* Whether a heuristic approach should be used to decide which C++ header files to include.
* The heuristic prefers headers which have no file extension and / or are named like the symbol
* which should be defined. This often works out nicely since it's a commonly used naming
* convention for C++ library headers.
*/
public static final String PREF_RELATIVE_HEADER_IN_SUB_DIR = "relative_header_in_sub_dir"; //$NON-NLS-1$
public static final String PREF_HEURISTIC_HEADER_SUBSTITUTION = "organize_includes_heuristic_header_substitution"; //$NON-NLS-1$
/**
* Whether headers located within a parent directory of the source file's directory should
* always be included relative to the source file.
* Whether it's allowed to reorder existing include directives. If this preference is set to
* false, the original order is kept as far as possible. This may be necessary to avoid breaking
* code which makes assumptions about the order of the include directives. If this is set to
* true, a different sort order can be applied. Groups of includes are ordered according to
* the values returned by
* {@link org.eclipse.cdt.internal.ui.refactoring.includes.IncludeGroupStyle#getOrder()} method.
* Includes within each group are ordered alphabetically.
*/
public static final String PREF_RELATIVE_HEADER_IN_PARENT_DIR = "relative_header_in_parent_dir"; //$NON-NLS-1$
public static final String PREF_INCLUDES_REORDERING = "organize_includes_allow_reordering"; //$NON-NLS-1$
/**
* Whether a heuristic approach should be used to resolve C++ header files. The heuristic
* prefers headers which have no file extension and / or are named like the symbol which should
* be defined. This often works out nicely since it's a commonly used naming convention for C++
* (library) headers.
* Determines what should be done with any unused include directives and forward declarations.
* This preference may have one of the three values defined by
* {@link UnusedStatementDisposition} enumeration ("REMOVE", "COMMENT_OUT", "KEEP").
*/
public static final String PREF_HEURISTIC_HEADER_SUBSTITUTION = "heuristic_header_resolution"; //$NON-NLS-1$
public static final String PREF_UNUSED_STATEMENTS_DISPOSITION = "organize_includes_unused_statements"; //$NON-NLS-1$
/**
* Whether it's allowed to reorder existing include directives. If this is set to false,
* the original order is kept as far as possible. This may be necessary to avoid breaking code
* which makes assumptions about the order of the include directives. If this is set to true,
* a different sort order can be applied. Also see the other sort order preferences for further
* details.
* Include style for headers closely related to the including file.
* The value of the preference is an XML representation of
* {@link org.eclipse.cdt.internal.ui.refactoring.includes.IncludeGroupStyle}.
*/
public static final String PREF_ALLOW_TO_REORDER_INCLUDES = "allow_to_reorder_includes"; //$NON-NLS-1$
public static final String PREF_INCLUDE_STYLE_RELATED = "include_style_related"; //$NON-NLS-1$
/**
* Include style for the header with the same name as the including file.
* The value of the preference is an XML representation of
* {@link org.eclipse.cdt.internal.ui.refactoring.includes.IncludeGroupStyle}.
*/
public static final String PREF_INCLUDE_STYLE_PARTNER = "include_style_partner"; //$NON-NLS-1$
/**
* Include style for headers in the same folder as the including file.
* The value of the preference is an XML representation of
* {@link org.eclipse.cdt.internal.ui.refactoring.includes.IncludeGroupStyle}.
*/
public static final String PREF_INCLUDE_STYLE_SAME_FOLDER = "include_style_same_folder"; //$NON-NLS-1$
/**
* Include style for headers in subfolders of the folder containing the including file.
* The value of the preference is an XML representation of
* {@link org.eclipse.cdt.internal.ui.refactoring.includes.IncludeGroupStyle}.
*/
public static final String PREF_INCLUDE_STYLE_SUBFOLDER = "include_style_subfolder"; //$NON-NLS-1$
/**
* Include style for system headers.
* The value of the preference is an XML representation of
* {@link org.eclipse.cdt.internal.ui.refactoring.includes.IncludeGroupStyle}.
*/
public static final String PREF_INCLUDE_STYLE_SYSTEM = "include_style_system"; //$NON-NLS-1$
/**
* Include style for C-style system headers with a file name extension.
* The value of the preference is an XML representation of
* {@link org.eclipse.cdt.internal.ui.refactoring.includes.IncludeGroupStyle}.
*/
public static final String PREF_INCLUDE_STYLE_SYSTEM_WITH_EXTENSION = "include_style_system_with_extension"; //$NON-NLS-1$
/**
* Include style for C++-style system headers without a file name extension.
* The value of the preference is an XML representation of
* {@link org.eclipse.cdt.internal.ui.refactoring.includes.IncludeGroupStyle}.
*/
public static final String PREF_INCLUDE_STYLE_SYSTEM_WITHOUT_EXTENSION = "include_style_system_without_extension"; //$NON-NLS-1$
/**
* Include style for headers not closely related to the including file.
* The value of the preference is an XML representation of
* {@link org.eclipse.cdt.internal.ui.refactoring.includes.IncludeGroupStyle}.
*/
public static final String PREF_INCLUDE_STYLE_OTHER = "include_style_other"; //$NON-NLS-1$
/**
* Include style for headers in the same project as the including file.
* The value of the preference is an XML representation of
* {@link org.eclipse.cdt.internal.ui.refactoring.includes.IncludeGroupStyle}.
*/
public static final String PREF_INCLUDE_STYLE_SAME_PROJECT = "include_style_in_same_project"; //$NON-NLS-1$
/**
* Include style for headers in a different project than the including file.
* The value of the preference is an XML representation of
* {@link org.eclipse.cdt.internal.ui.refactoring.includes.IncludeGroupStyle}.
*/
public static final String PREF_INCLUDE_STYLE_OTHER_PROJECT = "include_style_in_other_project"; //$NON-NLS-1$
/**
* Include style for headers outside Eclipse workspace.
* The value of the preference is an XML representation of
* {@link org.eclipse.cdt.internal.ui.refactoring.includes.IncludeGroupStyle}.
*/
public static final String PREF_INCLUDE_STYLE_EXTERNAL = "include_style_external"; //$NON-NLS-1$
/**
* Include styles for headers matching user-defined patterns.
* The value of the preference is an XML representation of one or more
* {@link org.eclipse.cdt.internal.ui.refactoring.includes.IncludeGroupStyle}s.
*/
public static final String PREF_INCLUDE_STYLE_MATCHING_PATTERN = "include_style_matching_pattern"; //$NON-NLS-1$
/**
* Whether the include directives should be sorted by header file location. Ignored if
* PREF_ALLOW_TO_REORDER_INCLUDES is false.
*/
public static final String PREF_SORT_BY_HEADER_LOCATION = "sort_by_header_location"; //$NON-NLS-1$
/**
* Defines the header location sort order. Ignored if either PREF_ALLOW_TO_REORDER_INCLUDES or
* PREF_SORT_BY_HEADER_LOCATION is false. An example location sort order would be:
* Relative headers > Project headers > Library headers > Forward declarations
*/
public static final String PREF_HEADER_LOCATION_SORT_ORDER = "header_location_sort_order"; //$NON-NLS-1$
/**
* Whether the different blocks of include directives should be separated by a blank line.
* Ignored if either PREF_ALLOW_TO_REORDER_INCLUDES or PREF_SORT_BY_HEADER_LOCATION is false.
* Initializes the given preference store with the default values.
*
* Example:
* // Relative headers
* #include "..."
*
* // Project headers
* #include "..."
*
* // Library headers
* #include <...>
*
* // Forward declarations
* class ...;
* @param store the preference store to be initialized
*/
public static final String PREF_SEPARATE_INCLUDE_BLOCKS = "separate_include_blocks"; //$NON-NLS-1$
public static void initializeDefaultValues(IPreferenceStore store) {
IncludeGroupStyle style = new IncludeGroupStyle(IncludeKind.RELATED);
store.setDefault(PREF_INCLUDE_STYLE_RELATED, style.toString());
style = new IncludeGroupStyle(IncludeKind.PARTNER);
style.setKeepTogether(true);
style.setBlankLineBefore(true);
style.setOrder(0);
store.setDefault(PREF_INCLUDE_STYLE_PARTNER, style.toString());
style = new IncludeGroupStyle(IncludeKind.IN_SAME_FOLDER);
store.setDefault(PREF_INCLUDE_STYLE_SAME_FOLDER, style.toString());
style = new IncludeGroupStyle(IncludeKind.IN_SUBFOLDER);
store.setDefault(PREF_INCLUDE_STYLE_SUBFOLDER, style.toString());
style = new IncludeGroupStyle(IncludeKind.SYSTEM);
style.setKeepTogether(true);
style.setBlankLineBefore(true);
store.setDefault(PREF_INCLUDE_STYLE_SYSTEM, style.toString());
style = new IncludeGroupStyle(IncludeKind.SYSTEM_WITH_EXTENSION);
style.setKeepTogether(true);
style.setAngleBrackets(true);
style.setOrder(1);
store.setDefault(PREF_INCLUDE_STYLE_SYSTEM_WITH_EXTENSION, style.toString());
style = new IncludeGroupStyle(IncludeKind.SYSTEM_WITHOUT_EXTENSION);
style.setKeepTogether(true);
style.setAngleBrackets(true);
style.setOrder(2);
store.setDefault(PREF_INCLUDE_STYLE_SYSTEM_WITHOUT_EXTENSION, style.toString());
style = new IncludeGroupStyle(IncludeKind.OTHER);
style.setKeepTogether(true);
style.setBlankLineBefore(true);
style.setOrder(3);
store.setDefault(PREF_INCLUDE_STYLE_OTHER, style.toString());
style = new IncludeGroupStyle(IncludeKind.IN_SAME_PROJECT);
store.setDefault(PREF_INCLUDE_STYLE_SAME_PROJECT, style.toString());
style = new IncludeGroupStyle(IncludeKind.IN_OTHER_PROJECT);
store.setDefault(PREF_INCLUDE_STYLE_OTHER_PROJECT, style.toString());
style = new IncludeGroupStyle(IncludeKind.EXTERNAL);
store.setDefault(PREF_INCLUDE_STYLE_EXTERNAL, style.toString());
store.setDefault(PREF_INCLUDE_STYLE_MATCHING_PATTERN, ""); //$NON-NLS-1$
/**
* Whether the include directives should be sorted alphabetically. Ignored if
* PREF_ALLOW_TO_REORDER_INCLUDES is false.
*/
public static final String PREF_SORT_ALPHABETICALLY = "sort_alphabetically"; //$NON-NLS-1$
/**
* Whether any unused include directives and forward declarations should be removed. It might be
* helpful to disable this if some include directives tend to become removed incorrectly, as it
* might happen when using e.g. conditional compilations.
*/
public static final String PREF_REMOVE_UNUSED_INCLUDES = "remove_unused_includes"; //$NON-NLS-1$
public static final String PREF_COMMENT_OUT_UNUSED_INCLUDES = "comment_out_unused_includes"; //$NON-NLS-1$
public static final String INCLUDE_STYLE_GROUP_RELATED = "allow_to_reorder_includes"; //$NON-NLS-1$
public static final String INCLUDE_STYLE_PARTNER = "include_style_partner"; //$NON-NLS-1$
public static final String INCLUDE_STYLE_GROUP_PARTNER = "include_style_group_partner"; //$NON-NLS-1$
public static final String INCLUDE_STYLE_SAME_FOLDER = "include_style_same_folder"; //$NON-NLS-1$
public static final String INCLUDE_STYLE_GROUP_SAME_FOLDER = "include_style_group_same_folder"; //$NON-NLS-1$
public static final String INCLUDE_STYLE_SUBFOLDER = "include_style_subfolder"; //$NON-NLS-1$
public static final String INCLUDE_STYLE_GROUP_SUBFOLDER = "include_style_group_subfolder"; //$NON-NLS-1$
public static final String INCLUDE_STYLE_GROUP_SYSTEM = "include_style_group_system"; //$NON-NLS-1$
/**
* Initializes the given preference store with the default values.
*
* @param store the preference store to be initialized
*/
public static void initializeDefaultValues(IPreferenceStore store) {
store.setDefault(PREF_PARTNER_FILE_SUFFIXES, DEFAULT_PARTNER_FILE_SUFFIXES);
store.setDefault(PREF_HEURISTIC_HEADER_SUBSTITUTION, true);
store.setDefault(PREF_INCLUDES_REORDERING, true);
store.setDefault(PREF_FORWARD_DECLARE_COMPOSITE_TYPES, true);
store.setDefault(PREF_FORWARD_DECLARE_ENUMS, false);
store.setDefault(PREF_FORWARD_DECLARE_FUNCTIONS, false);
store.setDefault(PREF_FORWARD_DECLARE_NAMESPACE_ELEMENTS, true);
// Relative headers preferences
store.setDefault(PREF_RELATIVE_HEADER_IN_SAME_DIR, false);
store.setDefault(PREF_RELATIVE_HEADER_IN_SUB_DIR, false);
store.setDefault(PREF_RELATIVE_HEADER_IN_PARENT_DIR, false);
// Header resolution preferences
store.setDefault(PREF_HEURISTIC_HEADER_SUBSTITUTION, true);
// Header sort order preferences
store.setDefault(PREF_ALLOW_TO_REORDER_INCLUDES, true);
store.setDefault(PREF_SORT_BY_HEADER_LOCATION, true);
store.setDefault(PREF_HEADER_LOCATION_SORT_ORDER,
IncludeType.RELATIVE_HEADER.toString() + ' ' +
IncludeType.LIBRARY_HEADER.toString() + ' ' +
IncludeType.PROJECT_HEADER.toString() + ' ' +
IncludeType.FORWARD_DECLARATION.toString() + ' ' +
IncludeType.FUNCTION_FORWARD_DECLARATION.toString() + ' ' +
IncludeType.FOUND_PROBLEM.toString());
store.setDefault(PREF_SEPARATE_INCLUDE_BLOCKS, true);
store.setDefault(PREF_SORT_ALPHABETICALLY, true);
// Unused include handling preferences
store.setDefault(PREF_REMOVE_UNUSED_INCLUDES, true);
store.setDefault(PREF_COMMENT_OUT_UNUSED_INCLUDES, true);
}
store.setDefault(PREF_UNUSED_STATEMENTS_DISPOSITION, UnusedStatementDisposition.COMMENT_OUT.toString());
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2003, 2011 IBM Corporation and others.
* Copyright (c) 2003, 2013 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
@ -7,6 +7,7 @@
*
* Contributors:
* QNX Software Systems - Initial implementation
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.ui;
@ -28,6 +29,7 @@ import org.eclipse.cdt.internal.ui.preferences.CEditorPreferencePage;
import org.eclipse.cdt.internal.ui.preferences.CPluginPreferencePage;
import org.eclipse.cdt.internal.ui.preferences.CodeAssistPreferencePage;
import org.eclipse.cdt.internal.ui.preferences.WorkInProgressPreferencePage;
import org.eclipse.cdt.internal.ui.refactoring.includes.IncludePreferences;
/**
* This class implements the setting of the CUI initial preference store settings.
@ -49,6 +51,7 @@ public class CUIPreferenceInitializer extends AbstractPreferenceInitializer {
CView.initDefaults(store);
CEditorPreferencePage.initDefaults(store);
CodeAssistPreferencePage.initDefaults(store);
IncludePreferences.initializeDefaultValues(store);
SemanticHighlightings.initDefaults(store);
WorkInProgressPreferencePage.initDefaults(store);