### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.ui Index: ui/org/eclipse/jdt/internal/ui/preferences/CodeAssistAdvancedConfigurationBlock.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/CodeAssistAdvancedConfigurationBlock.java,v retrieving revision 1.14 diff -u -r1.14 CodeAssistAdvancedConfigurationBlock.java --- ui/org/eclipse/jdt/internal/ui/preferences/CodeAssistAdvancedConfigurationBlock.java 1 Mar 2011 11:50:45 -0000 1.14 +++ ui/org/eclipse/jdt/internal/ui/preferences/CodeAssistAdvancedConfigurationBlock.java 6 Sep 2011 17:52:37 -0000 @@ -1,5 +1,4 @@ /******************************************************************************* - * Copyright (c) 2005, 2011 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -19,19 +18,25 @@ import java.util.Map; import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.ScrolledComposite; +import org.eclipse.swt.dnd.DND; +import org.eclipse.swt.dnd.DragSource; +import org.eclipse.swt.dnd.DragSourceAdapter; +import org.eclipse.swt.dnd.DragSourceEvent; +import org.eclipse.swt.dnd.DragSourceListener; +import org.eclipse.swt.dnd.TextTransfer; +import org.eclipse.swt.dnd.Transfer; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Link; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.swt.widgets.TableItem; import org.eclipse.core.commands.Command; import org.eclipse.core.commands.CommandManager; @@ -46,16 +51,17 @@ import org.eclipse.jface.bindings.BindingManager; import org.eclipse.jface.bindings.Scheme; import org.eclipse.jface.bindings.TriggerSequence; +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; import org.eclipse.jface.layout.PixelConverter; +import org.eclipse.jface.layout.TableColumnLayout; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.resource.JFaceResources; import org.eclipse.jface.viewers.ArrayContentProvider; -import org.eclipse.jface.viewers.CheckStateChangedEvent; -import org.eclipse.jface.viewers.CheckboxTableViewer; -import org.eclipse.jface.viewers.ICheckStateListener; -import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ColumnWeightData; import org.eclipse.jface.viewers.ITableLabelProvider; import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.ViewerComparator; import org.eclipse.ui.PlatformUI; @@ -66,39 +72,26 @@ import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds; -import org.eclipse.jdt.core.JavaCore; - import org.eclipse.jdt.internal.corext.util.Messages; -import org.eclipse.jdt.ui.PreferenceConstants; - import org.eclipse.jdt.internal.ui.JavaPlugin; import org.eclipse.jdt.internal.ui.dialogs.StatusInfo; import org.eclipse.jdt.internal.ui.text.java.CompletionProposalCategory; +import org.eclipse.jdt.internal.ui.text.java.CompletionProposalCategoryComposite; import org.eclipse.jdt.internal.ui.text.java.CompletionProposalComputerRegistry; -import org.eclipse.jdt.internal.ui.util.SWTUtil; +import org.eclipse.jdt.internal.ui.text.java.CompletionProposalComputerRegistryComposite; +import org.eclipse.jdt.internal.ui.text.java.CompletionProposalComputerRegistryComposite.LazyArrayList; +import org.eclipse.jdt.internal.ui.text.java.CompletionProposalComputerRegistryComposite.LazyArrayList.ListEntryCreator; import org.eclipse.jdt.internal.ui.wizards.IStatusChangeListener; /** - * + * * @since 3.2 */ final class CodeAssistAdvancedConfigurationBlock extends OptionsConfigurationBlock { - private static final Key PREF_EXCLUDED_CATEGORIES= getJDTUIKey(PreferenceConstants.CODEASSIST_EXCLUDED_CATEGORIES); - private static final Key PREF_CATEGORY_ORDER= getJDTUIKey(PreferenceConstants.CODEASSIST_CATEGORY_ORDER); - private static final Key PREF_CODEASSIST_TIMEOUT_FOR_PARAMETER_NAME_FROM_ATTACHED_JAVADOC= getJDTCoreKey(JavaCore.TIMEOUT_FOR_PARAMETER_NAME_FROM_ATTACHED_JAVADOC); - - private static Key[] getAllKeys() { - return new Key[] { - PREF_EXCLUDED_CATEGORIES, - PREF_CATEGORY_ORDER, - PREF_CODEASSIST_TIMEOUT_FOR_PARAMETER_NAME_FROM_ATTACHED_JAVADOC - }; - } - - private final class DefaultTableLabelProvider extends LabelProvider implements ITableLabelProvider { + public final class DefaultTableLabelProvider extends LabelProvider implements ITableLabelProvider { /* * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnImage(java.lang.Object, int) @@ -114,14 +107,14 @@ */ public String getColumnText(Object element, int columnIndex) { switch (columnIndex) { - case 0: - return ((ModelElement) element).getName(); - case 1: - return ((ModelElement) element).getKeybindingAsString(); - default: - Assert.isTrue(false); - return null; - } + case 0: + return ((ModelElement) element).getName(); + case 1: + return ((ModelElement) element).getKeybindingAsString(); + default: + Assert.isTrue(false); + return null; + } } /* @@ -129,34 +122,10 @@ */ @Override public String getText(Object element) { - return getColumnText(element, 0); // needed to make the sorter work + return getColumnText(element, 0); // needed to make the sorter work } } - private final class SeparateTableLabelProvider extends LabelProvider implements ITableLabelProvider { - - /* - * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnImage(java.lang.Object, int) - */ - public Image getColumnImage(Object element, int columnIndex) { - if (columnIndex == 0) - return ((ModelElement) element).getImage(); - return null; - } - - /* - * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnText(java.lang.Object, int) - */ - public String getColumnText(Object element, int columnIndex) { - switch (columnIndex) { - case 0: - return ((ModelElement) element).getName(); - default: - Assert.isTrue(false); - return null; - } - } - } private final Comparator fCategoryComparator= new Comparator() { private int getRank(ModelElement o) { @@ -168,12 +137,11 @@ } }; - private final class PreferenceModel { + protected final class PreferenceModel { private static final int LIMIT= 65535; - private static final String COLON= ":"; //$NON-NLS-1$ - private static final String SEPARATOR= "\0"; //$NON-NLS-1$ private final List fElements; + /** * The read-only list of elements. */ @@ -192,82 +160,96 @@ elements= Collections.unmodifiableList(fElements); } - public void moveUp(ModelElement category) { - int index= fElements.indexOf(category); - if (index > 0) { - ModelElement item= fElements.remove(index); - fElements.add(index - 1, item); - writeOrderPreference(null, false); - } - } - - public void moveDown(ModelElement category) { - int index= fElements.indexOf(category); - if (index < fElements.size() - 1) { - ModelElement item= fElements.remove(index); - fElements.add(index + 1, item); - writeOrderPreference(null, false); - } - } - - private void writeInclusionPreference(ModelElement changed, boolean isInDefaultCategory) { - StringBuffer buf= new StringBuffer(); - for (Iterator it= fElements.iterator(); it.hasNext();) { - ModelElement item= it.next(); - boolean included= changed == item ? isInDefaultCategory : item.isInDefaultCategory(); - if (!included) - buf.append(item.getId() + SEPARATOR); - } - - String newValue= buf.toString(); - String oldValue= setValue(PREF_EXCLUDED_CATEGORIES, newValue); - validateSettings(PREF_EXCLUDED_CATEGORIES, oldValue, newValue); - } - - private void writeOrderPreference(ModelElement changed, boolean isSeparate) { - StringBuffer buf= new StringBuffer(); - int i= 0; - for (Iterator it= fElements.iterator(); it.hasNext(); i++) { - ModelElement item= it.next(); - boolean separate= changed == item ? isSeparate : item.isSeparateCommand(); - int rank= separate ? i : i + LIMIT; - buf.append(item.getId() + COLON + rank + SEPARATOR); - } - - String newValue= buf.toString(); - String oldValue= setValue(PREF_CATEGORY_ORDER, newValue); - validateSettings(PREF_CATEGORY_ORDER, oldValue, newValue); - } - - - private boolean readInclusionPreference(CompletionProposalCategory cat) { - String[] ids= getTokens(getValue(PREF_EXCLUDED_CATEGORIES), SEPARATOR); - for (int i= 0; i < ids.length; i++) { - if (ids[i].equals(cat.getId())) - return false; - } - return true; - } - - private int readOrderPreference(CompletionProposalCategory cat) { - String[] sortOrderIds= getTokens(getValue(PREF_CATEGORY_ORDER), SEPARATOR); - for (int i= 0; i < sortOrderIds.length; i++) { - String[] idAndRank= getTokens(sortOrderIds[i], COLON); - if (idAndRank[0].equals(cat.getId())) - return Integer.parseInt(idAndRank[1]); - } + private void writeOrderPreferenceExtended() { + final String newPreferenceString= this.createPreferenceString(); + this.validateOrderPreferenceExtended(newPreferenceString); + } + + + private String createPreferenceString() { + final StringBuffer buffer= new StringBuffer(); + final List proposalGroups= proposalsGroupList.getCompositeProposalGroups(); + for (Iterator it= fElements.iterator(); it.hasNext();) { + final ModelElement model= it.next(); + Integer order= new Integer(0); + final List orders= new ArrayList(); + for (final CodeAssistAdvancedProposalsGroup proposalGroup : proposalGroups) { + if (!proposalGroup.getTable().isDisposed()) { + for (final TableItem tableItem : proposalGroup.getTable().getItems()) { + if (model.equals(tableItem.getData())) { + orders.add(order); + } + } + order= new Integer(order.intValue() + 1); + } + } + final String rank= this.listToString(orders); + if (rank != null) { + buffer.append(model.getId() + CodeAssistAdvancedConstants.COLON + rank + CodeAssistAdvancedConstants.SEPARATOR); + } + } + return buffer.toString(); + } + + + private void validateOrderPreferenceExtended(final String newPreferenceString) { + final String oldPreferenceString= setValue(CodeAssistAdvancedConstants.PREF_CATEGORY_ORDER_EXTENDED, newPreferenceString); + validateSettings(CodeAssistAdvancedConstants.PREF_CATEGORY_ORDER_EXTENDED, oldPreferenceString, newPreferenceString); + if (newPreferenceString != null && !newPreferenceString.equals(oldPreferenceString)) { + final String newNonDefaultPreferenceString= "NON_DEFAULT"; //$NON-NLS-1$ + final String oldNonDefaultPreferenceString= setValue(CodeAssistAdvancedConstants.PREF_CATEGORY_ORDER_EXTENDED_NON_DEFAULT, newNonDefaultPreferenceString); + validateSettings(CodeAssistAdvancedConstants.PREF_CATEGORY_ORDER_EXTENDED_NON_DEFAULT, oldNonDefaultPreferenceString, newNonDefaultPreferenceString); + if (!newNonDefaultPreferenceString.equals(oldNonDefaultPreferenceString)) { + CompletionProposalComputerRegistryComposite.getDefault().setNonDefaultProperty(newNonDefaultPreferenceString); + } + CompletionProposalComputerRegistryComposite.getDefault().setPreferenceString(newPreferenceString); + CompletionProposalComputerRegistryComposite.getDefault().reload(); + } + } + + private String listToString(List list) { + String result= null; + for (final Integer listElement : list) { + if (result == null) { + result= listElement.toString(); + } else { + result+= CodeAssistAdvancedConstants.LIST_SEPERATOR + listElement; + } + } + return result; + } + + private boolean readInclusionPreference(CompletionProposalCategory cat) { + String[] ids= getTokens(getValue(CodeAssistAdvancedConstants.PREF_EXCLUDED_CATEGORIES), CodeAssistAdvancedConstants.SEPARATOR); + for (int i= 0; i < ids.length; i++) { + if (ids[i].equals(cat.getId())) + return false; + } + return true; + } + + private int readOrderPreference(CompletionProposalCategory cat) { + String[] sortOrderIds= getTokens(getValue(CodeAssistAdvancedConstants.PREF_CATEGORY_ORDER), CodeAssistAdvancedConstants.SEPARATOR); + for (int i= 0; i < sortOrderIds.length; i++) { + String[] idAndRank= getTokens(sortOrderIds[i], CodeAssistAdvancedConstants.COLON); + if (idAndRank[0].equals(cat.getId())) + return Integer.parseInt(idAndRank[1]); + } return LIMIT - 1; - } + } - public void update() { + public void update() { Collections.sort(fElements, fCategoryComparator); - } + } } - private final class ModelElement { + public class ModelElement { private final CompletionProposalCategory fCategory; + private final Command fCommand; + private final IParameter fParam; + private final PreferenceModel fPreferenceModel; ModelElement(CompletionProposalCategory category, PreferenceModel model) { @@ -284,71 +266,83 @@ fParam= type; fPreferenceModel= model; } + Image getImage() { return CodeAssistAdvancedConfigurationBlock.this.getImage(fCategory.getImageDescriptor()); } + String getName() { return fCategory.getDisplayName(); } + String getKeybindingAsString() { final Parameterization[] params= { new Parameterization(fParam, fCategory.getId()) }; final ParameterizedCommand pCmd= new ParameterizedCommand(fCommand, params); String key= getKeyboardShortcut(pCmd); return key; } + boolean isInDefaultCategory() { return fPreferenceModel.readInclusionPreference(fCategory); } - void setInDefaultCategory(boolean included) { - if (included != isInDefaultCategory()) - fPreferenceModel.writeInclusionPreference(this, included); - } + + String getId() { return fCategory.getId(); } + int getRank() { int rank= getInternalRank(); if (rank > PreferenceModel.LIMIT) return rank - PreferenceModel.LIMIT; return rank; } - void moveUp() { - fPreferenceModel.moveUp(this); - } - void moveDown() { - fPreferenceModel.moveDown(this); - } + private int getInternalRank() { return fPreferenceModel.readOrderPreference(fCategory); } + boolean isSeparateCommand() { return getInternalRank() < PreferenceModel.LIMIT; } - void setSeparateCommand(boolean separate) { - if (separate != isSeparateCommand()) - fPreferenceModel.writeOrderPreference(this, separate); - } - void update() { fCategory.setIncluded(isInDefaultCategory()); int rank= getInternalRank(); fCategory.setSortOrder(rank); fCategory.setSeparateCommand(rank < PreferenceModel.LIMIT); + fPreferenceModel.writeOrderPreferenceExtended(); + } + + @Override + public boolean equals(Object obj) { + boolean result= false; + if (obj instanceof ModelElement) { + ModelElement e= (ModelElement) obj; + result= this.fCategory.equals(e.fCategory); + } + return result; + } + + @Override + public int hashCode() { + return fCategory.hashCode(); } + + } /** element type: {@link ModelElement}. */ private final PreferenceModel fModel; + private final Map fImages= new HashMap(); - private CheckboxTableViewer fDefaultViewer; - private CheckboxTableViewer fSeparateViewer; - private Button fUpButton; - private Button fDownButton; + private TableViewer fDefaultViewer; + + private CodeAssistAdvancedProposalsGroupList proposalsGroupList; CodeAssistAdvancedConfigurationBlock(IStatusChangeListener statusListener, IWorkbenchPreferenceContainer container) { - super(statusListener, null, getAllKeys(), container); + super(statusListener, null, CodeAssistAdvancedConstants.getAllKeys(), container); fModel= new PreferenceModel(CompletionProposalComputerRegistry.getDefault()); } @@ -357,272 +351,261 @@ */ @Override protected Control createContents(Composite parent) { + final Composite composite= this.createWrappingComposite(parent); + this.createLeftColumn(composite); + this.createRightColumn(composite); + this.setDefaultSelection(); - ScrolledPageContent scrolled= new ScrolledPageContent(parent, SWT.H_SCROLL | SWT.V_SCROLL); - - scrolled.setExpandHorizontal(true); - scrolled.setExpandVertical(true); - - Composite composite= new Composite(scrolled, SWT.NONE); - int columns= 2; - GridLayout layout= new GridLayout(columns, false); - layout.marginWidth= 0; - layout.marginHeight= 0; - composite.setLayout(layout); - + return composite; + } - createDefaultLabel(composite, columns); - createDefaultViewer(composite, columns); - createKeysLink(composite, columns); + private Composite createWrappingComposite(final Composite parent) { + final Composite composite= new Composite(parent, SWT.NONE); + composite.setLayout(GridLayoutFactory.fillDefaults().numColumns(2).create()); + return composite; + } - createFiller(composite, columns); + private void setDefaultSelection() { + if (getModel().elements.size() > 0) { + getDefaultViewer().getTable().select(0); + } + } - createSeparateLabel(composite, columns); - createSeparateSection(composite); + private void createLeftColumn(final Composite composite) { + final Composite leftColumn= this.createLeftWrappingComposite(composite); - createFiller(composite, columns); + this.createDefaultLabel(leftColumn); + this.createDefaultViewer(leftColumn); + this.createKeysLink(leftColumn); + this.createParameterTimeoutControl(leftColumn); + } - createParameterTimeoutControl(composite, columns); + private Composite createLeftWrappingComposite(final Composite composite) { + final Composite leftColumn= new Composite(composite, SWT.NONE); + leftColumn.setLayout(GridLayoutFactory.fillDefaults().create()); + + leftColumn.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).create()); + return leftColumn; + } - updateControls(); - if (fModel.elements.size() > 0) { - fDefaultViewer.getTable().select(0); - fSeparateViewer.getTable().select(0); - handleTableSelection(); - } - scrolled.setContent(composite); - scrolled.setMinSize(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT)); - return scrolled; - } - private void createDefaultLabel(Composite composite, int h_span) { - final ICommandService commandSvc= (ICommandService) PlatformUI.getWorkbench().getAdapter(ICommandService.class); + private void createDefaultLabel(Composite composite) { + final ICommandService commandSvc= (ICommandService) PlatformUI.getWorkbench().getAdapter(ICommandService.class); final Command command= commandSvc.getCommand(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS); - ParameterizedCommand pCmd= new ParameterizedCommand(command, null); + final ParameterizedCommand pCmd= new ParameterizedCommand(command, null); String key= getKeyboardShortcut(pCmd); if (key == null) key= PreferencesMessages.CodeAssistAdvancedConfigurationBlock_no_shortcut; - PixelConverter pixelConverter= new PixelConverter(composite); - int width= pixelConverter.convertWidthInCharsToPixels(40); + final PixelConverter pixelConverter= new PixelConverter(composite); + final int width= pixelConverter.convertWidthInCharsToPixels(40); + + final Label pageDescriptionLabel= new Label(composite, SWT.NONE | SWT.WRAP); + pageDescriptionLabel.setText(Messages.format(PreferencesMessages.CodeAssistAdvancedConfigurationBlock_page_description, new Object[] { key })); + pageDescriptionLabel.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).hint(width,SWT.DEFAULT).create()); + + this.createFiller(composite); + + final Label defaultTablelDescriptionLabel= new Label(composite, SWT.NONE | SWT.WRAP); + defaultTablelDescriptionLabel.setText(PreferencesMessages.CodeAssistAdvancedConfigurationBlock_default_table_description); + defaultTablelDescriptionLabel.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).hint(width, SWT.DEFAULT).create()); + } + + private void createDefaultViewer(final Composite composite) { + final Composite defaultViewerComposite= this.setupDefaultWrappingComposite(composite); + final DefaultTableLabelProvider labelProvider= this.setupLabelProvider(); + this.setupDefaultTable(defaultViewerComposite, labelProvider); + this.initializeDefaultViewerDragListener(); + } - Label label= new Label(composite, SWT.NONE | SWT.WRAP); - label.setText(Messages.format(PreferencesMessages.CodeAssistAdvancedConfigurationBlock_page_description, new Object[] { key })); - GridData gd= new GridData(GridData.FILL, GridData.FILL, true, false, h_span, 1); - gd.widthHint= width; - label.setLayoutData(gd); - - createFiller(composite, h_span); - - label= new Label(composite, SWT.NONE | SWT.WRAP); - label.setText(PreferencesMessages.CodeAssistAdvancedConfigurationBlock_default_table_description); - gd= new GridData(GridData.FILL, GridData.FILL, true, false, h_span, 1); - gd.widthHint= width; - label.setLayoutData(gd); - } - - private void createDefaultViewer(Composite composite, int h_span) { - fDefaultViewer= CheckboxTableViewer.newCheckList(composite, SWT.SINGLE | SWT.BORDER); - Table table= fDefaultViewer.getTable(); + private Composite setupDefaultWrappingComposite(final Composite composite) { + final Composite defaultViewerComposite= new Composite(composite, SWT.NONE); + defaultViewerComposite.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).create()); + this.fDefaultViewer= new TableViewer(defaultViewerComposite, SWT.HIDE_SELECTION | SWT.MULTI | SWT.BORDER); + return defaultViewerComposite; + } + + private void setupDefaultTable(final Composite defaultViewerComposite, final DefaultTableLabelProvider labelProvider) { + final Table table= this.fDefaultViewer.getTable(); table.setHeaderVisible(true); table.setLinesVisible(false); - table.setLayoutData(new GridData(GridData.FILL, GridData.BEGINNING, false, false, h_span, 1)); - - TableColumn nameColumn= new TableColumn(table, SWT.NONE); + final TableColumn nameColumn= new TableColumn(table, SWT.NONE); nameColumn.setText(PreferencesMessages.CodeAssistAdvancedConfigurationBlock_default_table_category_column_title); nameColumn.setResizable(false); - TableColumn keyColumn= new TableColumn(table, SWT.NONE); + final TableColumn keyColumn= new TableColumn(table, SWT.NONE); keyColumn.setText(PreferencesMessages.CodeAssistAdvancedConfigurationBlock_default_table_keybinding_column_title); keyColumn.setResizable(false); - fDefaultViewer.addCheckStateListener(new ICheckStateListener() { - public void checkStateChanged(CheckStateChangedEvent event) { - boolean checked= event.getChecked(); - ModelElement element= (ModelElement) event.getElement(); - element.setInDefaultCategory(checked); - } - }); - - fDefaultViewer.setContentProvider(new ArrayContentProvider()); - - DefaultTableLabelProvider labelProvider= new DefaultTableLabelProvider(); - fDefaultViewer.setLabelProvider(labelProvider); - fDefaultViewer.setInput(fModel.elements); - fDefaultViewer.setComparator(new ViewerComparator()); // sort alphabetically - - final int ICON_AND_CHECKBOX_WITH= 50; - final int HEADER_MARGIN= 20; + // compute-clumnWeight + final int ICON_WITH= 25; + final int HEADER_MARGIN= 0; int minNameWidth= computeWidth(table, nameColumn.getText()) + HEADER_MARGIN; int minKeyWidth= computeWidth(table, keyColumn.getText()) + HEADER_MARGIN; - for (int i= 0; i < fModel.elements.size(); i++) { - minNameWidth= Math.max(minNameWidth, computeWidth(table, labelProvider.getColumnText(fModel.elements.get(i), 0)) + ICON_AND_CHECKBOX_WITH); - minKeyWidth= Math.max(minKeyWidth, computeWidth(table, labelProvider.getColumnText(fModel.elements.get(i), 1))); - } - + for (int i= 0; i < getModel().elements.size(); i++) { + minNameWidth= Math.max(minNameWidth, computeWidth(table, labelProvider.getColumnText(getModel().elements.get(i), 0)) + ICON_WITH); + minKeyWidth= Math.max(minKeyWidth, computeWidth(table, labelProvider.getColumnText(getModel().elements.get(i), 1))); + } + defaultViewerComposite.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).create()); + final TableColumnLayout tableColumnLayout= new TableColumnLayout(); + final int nameWeight= (int) (((double) minNameWidth / (minNameWidth + minKeyWidth)) * 100); + final int keyWeight= 100 - nameWeight; + tableColumnLayout.setColumnData(nameColumn, new ColumnWeightData(nameWeight, minNameWidth, false)); + tableColumnLayout.setColumnData(keyColumn, new ColumnWeightData(keyWeight, minKeyWidth, false)); + defaultViewerComposite.setLayout(tableColumnLayout); nameColumn.setWidth(minNameWidth); - keyColumn.setWidth(minKeyWidth); } - private void createKeysLink(Composite composite, int h_span) { - Link link= new Link(composite, SWT.NONE | SWT.WRAP); - link.setText(PreferencesMessages.CodeAssistAdvancedConfigurationBlock_key_binding_hint); - link.addSelectionListener(new SelectionAdapter() { + private DefaultTableLabelProvider setupLabelProvider() { + final DefaultTableLabelProvider labelProvider= new DefaultTableLabelProvider(); + this.fDefaultViewer.setContentProvider(new ArrayContentProvider()); + this.fDefaultViewer.setLabelProvider(new DefaultTableLabelProvider()); + this.fDefaultViewer.setInput(getModel().elements); + this.fDefaultViewer.setComparator(new ViewerComparator()); // sort alphabetically + return labelProvider; + } + + private void initializeDefaultViewerDragListener() { + final DragSourceAdapter dragSourceAdepter= this.createDefaultViewerDragSourceAdapter(); + this.registerDefaultViewerDragListener(dragSourceAdepter); + } + + private DragSourceAdapter createDefaultViewerDragSourceAdapter() { + return new DragSourceAdapter() { @Override - public void widgetSelected(SelectionEvent e) { - PreferencesUtil.createPreferenceDialogOn(getShell(), e.text, null, null); + public void dragSetData(DragSourceEvent event) { + event.data= getDragData(event); } - }); - PixelConverter pixelConverter= new PixelConverter(composite); - int width= pixelConverter.convertWidthInCharsToPixels(40); - - // limit the size of the Link as it would take all it can get - GridData gd= new GridData(GridData.FILL, GridData.FILL, false, false, h_span, 1); - gd.widthHint= width; - link.setLayoutData(gd); - } + @Override + public void dragStart(DragSourceEvent event) { + super.dragStart(event); + proposalsGroupList.setModelElementDragId(getDragData(event)); + } - private void createFiller(Composite composite, int h_span) { - Label filler= new Label(composite, SWT.NONE); - filler.setVisible(false); - filler.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false, h_span, 1)); - } + private String getDragData(final DragSourceEvent event) { + final DragSource dragSource= (DragSource) event.widget; + final Table dragTable= (Table) dragSource.getControl(); + final TableItem[] selection= dragTable.getSelection(); + final StringBuffer buffer= new StringBuffer(); + for (int i= 0, n= selection.length; i < n; i++) { + if (!(selection[i].getData() instanceof ModelElement)) { + continue; + } + if (buffer.length() != 0) { + buffer.append(CodeAssistAdvancedConstants.LIST_SEPERATOR); + } + buffer.append(((ModelElement) selection[i].getData()).getId()); + } - private void createSeparateLabel(Composite composite, int h_span) { - PixelConverter pixelConverter= new PixelConverter(composite); - int width= pixelConverter.convertWidthInCharsToPixels(40); + return buffer.toString(); + } - Label label= new Label(composite, SWT.NONE | SWT.WRAP); - label.setText(PreferencesMessages.CodeAssistAdvancedConfigurationBlock_separate_table_description); - GridData gd= new GridData(GridData.FILL, GridData.FILL, false, false, h_span, 1); - gd.widthHint= width; - label.setLayoutData(gd); + @Override + public void dragFinished(final DragSourceEvent event) { + proposalsGroupList.setFocus(); + proposalsGroupList.setModelElementDragId(null); + } + }; } - private void createSeparateSection(Composite composite) { - createSeparateViewer(composite); - createButtonList(composite); + private void registerDefaultViewerDragListener(final DragSourceListener dragSourceListener) { + final DragSource source= new DragSource(this.fDefaultViewer.getTable(), DND.DROP_MOVE | DND.DROP_COPY); + source.setTransfer(new Transfer[] { TextTransfer.getInstance() }); + source.addDragListener(dragSourceListener); } - private void createSeparateViewer(Composite composite) { - fSeparateViewer= CheckboxTableViewer.newCheckList(composite, SWT.SINGLE | SWT.BORDER); - Table table= fSeparateViewer.getTable(); - table.setHeaderVisible(false); - table.setLinesVisible(false); - table.setLayoutData(new GridData(GridData.FILL, GridData.BEGINNING, true, false, 1, 1)); + private void createRightColumn(final Composite composite) { + this.createRightWrappingComposite(composite); + this.fillProposalsGroupList(); + } - TableColumn nameColumn= new TableColumn(table, SWT.NONE); - nameColumn.setText(PreferencesMessages.CodeAssistAdvancedConfigurationBlock_separate_table_category_column_title); - nameColumn.setResizable(false); + private void createRightWrappingComposite(final Composite composite) { + final ScrolledComposite scroller= new ScrolledComposite(composite, SWT.V_SCROLL | SWT.BORDER); + this.proposalsGroupList= new CodeAssistAdvancedProposalsGroupList(scroller, SWT.NONE, fDefaultViewer.getTable().getColumn(0).getWidth(), this); + } - fSeparateViewer.setContentProvider(new ArrayContentProvider()); + private void fillProposalsGroupList() { + final List compositeCategories= CompletionProposalComputerRegistryComposite.getDefault().getProposalCategories(); + final ArrayList> proposalLists= createProposalGroupList(); + for (final CompletionProposalCategory category : compositeCategories) { + if (!(category instanceof CompletionProposalCategoryComposite)) { + continue; + } + final CompletionProposalCategoryComposite compositeCategory= (CompletionProposalCategoryComposite) category; + this.fillProposalsGroup(compositeCategory, proposalLists); + } + this.createCompositeProposalGroups(proposalLists); + } - ITableLabelProvider labelProvider= new SeparateTableLabelProvider(); - fSeparateViewer.setLabelProvider(labelProvider); - fSeparateViewer.setInput(fModel.elements); + private ArrayList> createProposalGroupList() { + final ListEntryCreator> creator= new ListEntryCreator>() { + public List createListEntry() { + return new ArrayList(); + } + }; + return new LazyArrayList>(creator); + } - final int ICON_AND_CHECKBOX_WITH= 50; - final int HEADER_MARGIN= 20; - int minNameWidth= computeWidth(table, nameColumn.getText()) + HEADER_MARGIN; - for (int i= 0; i < fModel.elements.size(); i++) { - minNameWidth= Math.max(minNameWidth, computeWidth(table, labelProvider.getColumnText(fModel.elements.get(i), 0)) + ICON_AND_CHECKBOX_WITH); + private void fillProposalsGroup(final CompletionProposalCategoryComposite compositeCategory, final ArrayList> proposalsLists) { + final List containingCategories= compositeCategory.getCategories(); + final int order= compositeCategory.getSortOrder(); + for (final CompletionProposalCategory standardCat : containingCategories) { + for (final ModelElement model : getModel().elements) { + if (!model.fCategory.equals(standardCat)) { + continue; + } + proposalsLists.get(order).add(model); + } } + } - nameColumn.setWidth(minNameWidth); + private void createCompositeProposalGroups(final ArrayList> proposalLists) { + this.proposalsGroupList.setResizeBlocked(true); - fSeparateViewer.addCheckStateListener(new ICheckStateListener() { - public void checkStateChanged(CheckStateChangedEvent event) { - boolean checked= event.getChecked(); - ModelElement element= (ModelElement) event.getElement(); - element.setSeparateCommand(checked); + for (final List proposalList : proposalLists) { + if (proposalList.size() <= 0) { + continue; } - }); + final CodeAssistAdvancedProposalsGroup compositeProposalTable= this.proposalsGroupList.createCompositeProposalTable(); + for (final ModelElement proposal : proposalList) { + compositeProposalTable.getTableViewer().add(proposal); + } + } + this.proposalsGroupList.setResizeBlocked(false); + this.proposalsGroupList.resize(); + } - table.addSelectionListener(new SelectionAdapter() { + private void createKeysLink(final Composite composite) { + final Link link= new Link(composite, SWT.NONE | SWT.WRAP); + link.setText(PreferencesMessages.CodeAssistAdvancedConfigurationBlock_key_binding_hint); + link.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { - handleTableSelection(); + PreferencesUtil.createPreferenceDialogOn(getShell(), e.text, null, null); } }); - } - - private void createButtonList(Composite parent) { - Composite composite= new Composite(parent, SWT.NONE); - composite.setLayoutData(new GridData(SWT.BEGINNING, SWT.BEGINNING, false, false)); - - GridLayout layout= new GridLayout(); - layout.marginWidth= 0; - layout.marginHeight= 0; - composite.setLayout(layout); - - fUpButton= new Button(composite, SWT.PUSH | SWT.CENTER); - fUpButton.setText(PreferencesMessages.CodeAssistAdvancedConfigurationBlock_Up); - fUpButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - int index= getSelectionIndex(); - if (index != -1) { - fModel.elements.get(index).moveUp(); - fSeparateViewer.refresh(); - handleTableSelection(); - } - } - }); - fUpButton.setLayoutData(new GridData()); - SWTUtil.setButtonDimensionHint(fUpButton); - - fDownButton= new Button(composite, SWT.PUSH | SWT.CENTER); - fDownButton.setText(PreferencesMessages.CodeAssistAdvancedConfigurationBlock_Down); - fDownButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - int index= getSelectionIndex(); - if (index != -1) { - fModel.elements.get(index).moveDown(); - fSeparateViewer.refresh(); - handleTableSelection(); - } - } - }); - fDownButton.setLayoutData(new GridData()); - SWTUtil.setButtonDimensionHint(fDownButton); - } - - private void createParameterTimeoutControl(Composite composite, int h_span) { - Composite timeoutComposite= new Composite(composite, SWT.NONE); - GridLayout layout= new GridLayout(4, false); - layout.marginWidth= 0; - layout.marginHeight= 0; - timeoutComposite.setLayout(layout); - GridData gd= new GridData(GridData.FILL, GridData.FILL, true, false, h_span, 1); - timeoutComposite.setLayoutData(gd); - - PixelConverter pixelConverter= new PixelConverter(composite); - String str= PreferencesMessages.CodeAssistAdvancedConfigurationBlock_parameterNameFromAttachedJavadoc_timeout; - addTextField(timeoutComposite, str, PREF_CODEASSIST_TIMEOUT_FOR_PARAMETER_NAME_FROM_ATTACHED_JAVADOC, 0, pixelConverter.convertWidthInCharsToPixels(7)); - - } + final PixelConverter pixelConverter= new PixelConverter(composite); + final int width= pixelConverter.convertWidthInCharsToPixels(40); - private void handleTableSelection() { - ModelElement item= getSelectedItem(); - if (item != null) { - int index= getSelectionIndex(); - fUpButton.setEnabled(index > 0); - fDownButton.setEnabled(index < fModel.elements.size() - 1); - } else { - fUpButton.setEnabled(false); - fDownButton.setEnabled(false); - } + // limit the size of the Link as it would take all it can get + link.setLayoutData(GridDataFactory.fillDefaults().hint(width, SWT.DEFAULT).create()); } - private ModelElement getSelectedItem() { - return (ModelElement) ((IStructuredSelection) fSeparateViewer.getSelection()).getFirstElement(); + private void createFiller(Composite composite) { + Label filler= new Label(composite, SWT.NONE); + filler.setVisible(false); + filler.setLayoutData(GridDataFactory.fillDefaults().create()); } - private int getSelectionIndex() { - return fSeparateViewer.getTable().getSelectionIndex(); + private void createParameterTimeoutControl(final Composite composite) { + final Composite timeoutComposite= new Composite(composite, SWT.NONE); + timeoutComposite.setLayout(GridLayoutFactory.fillDefaults().numColumns(4).create()); + timeoutComposite.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).create()); + final PixelConverter pixelConverter= new PixelConverter(composite); + final String str= PreferencesMessages.CodeAssistAdvancedConfigurationBlock_parameterNameFromAttachedJavadoc_timeout; + addTextField(timeoutComposite, str, CodeAssistAdvancedConstants.PREF_CODEASSIST_TIMEOUT_FOR_PARAMETER_NAME_FROM_ATTACHED_JAVADOC, 0, pixelConverter.convertWidthInCharsToPixels(7)); } /* @@ -632,36 +615,62 @@ protected void updateControls() { super.updateControls(); - fModel.update(); + getModel().update(); updateCheckedState(); - fDefaultViewer.refresh(); - fSeparateViewer.refresh(); - handleTableSelection(); + getDefaultViewer().refresh(); + restoreDefaultProposalsGroupList(); } private void updateCheckedState() { - final int size= fModel.elements.size(); + final int size= getModel().elements.size(); List defaultChecked= new ArrayList(size); List separateChecked= new ArrayList(size); - for (Iterator it= fModel.elements.iterator(); it.hasNext();) { + for (Iterator it= getModel().elements.iterator(); it.hasNext();) { ModelElement element= it.next(); if (element.isInDefaultCategory()) defaultChecked.add(element); if (element.isSeparateCommand()) separateChecked.add(element); } + } + + private void restoreDefaultProposalsGroupList() { + this.disposeOldProposalGroups(); + final ArrayList> proposalLists= this.getDefaultProposalList(); + this.createCompositeProposalGroups(proposalLists); + } + + + private void disposeOldProposalGroups() { + for (final CodeAssistAdvancedProposalsGroup dropTable : this.proposalsGroupList.getCompositeProposalGroups()) { + dropTable.dispose(); + } + this.proposalsGroupList.getCompositeProposalGroups().clear(); + } + + private ArrayList> getDefaultProposalList() { + final ArrayList> proposalLists= this.createProposalGroupList(); - fDefaultViewer.setCheckedElements(defaultChecked.toArray(new Object[defaultChecked.size()])); - fSeparateViewer.setCheckedElements(separateChecked.toArray(new Object[separateChecked.size()])); + for (Iterator it= getModel().elements.iterator(); it.hasNext();) { + final ModelElement element= it.next(); + if (element.isInDefaultCategory()) { + proposalLists.get(0).add(element); + } + if (element.isSeparateCommand()) { + proposalLists.get(element.getRank()).add(element); + } + } + return proposalLists; } + /* * @see org.eclipse.jdt.internal.ui.preferences.OptionsConfigurationBlock#processChanges(org.eclipse.ui.preferences.IWorkbenchPreferenceContainer) */ @Override protected boolean processChanges(IWorkbenchPreferenceContainer container) { - for (Iterator it= fModel.elements.iterator(); it.hasNext();) { + for (Iterator it= getModel().elements.iterator(); it.hasNext();) { ModelElement item= it.next(); item.update(); } @@ -674,7 +683,7 @@ */ @Override protected void validateSettings(Key changedKey, String oldValue, String newValue) { - if (changedKey == PREF_CODEASSIST_TIMEOUT_FOR_PARAMETER_NAME_FROM_ATTACHED_JAVADOC) { + if (changedKey == CodeAssistAdvancedConstants.PREF_CODEASSIST_TIMEOUT_FOR_PARAMETER_NAME_FROM_ATTACHED_JAVADOC) { final StatusInfo status= new StatusInfo(); if (newValue.length() == 0) status.setError(PreferencesMessages.CodeAssistAdvancedConfigurationBlock_parameterNameFromAttachedJavadoc_timeout_emptyInput); @@ -685,7 +694,7 @@ int max= 5000; if (number < min || number > max) { String msgFormat= PreferencesMessages.CodeAssistAdvancedConfigurationBlock_parameterNameFromAttachedJavadoc_timeout_invalidRange; - String msg= Messages.format(msgFormat, new Object[] {new Integer(min), new Integer(max)}); + String msg= Messages.format(msgFormat, new Object[] { new Integer(min), new Integer(max) }); status.setError(msg); } } catch (NumberFormatException ex) { @@ -735,11 +744,11 @@ private static BindingManager fgLocalBindingManager; static { fgLocalBindingManager= new BindingManager(new ContextManager(), new CommandManager()); - final IBindingService bindingService= (IBindingService)PlatformUI.getWorkbench().getService(IBindingService.class); + final IBindingService bindingService= (IBindingService) PlatformUI.getWorkbench().getService(IBindingService.class); final Scheme[] definedSchemes= bindingService.getDefinedSchemes(); if (definedSchemes != null) { try { - for (int i = 0; i < definedSchemes.length; i++) { + for (int i= 0; i < definedSchemes.length; i++) { final Scheme scheme= definedSchemes[i]; final Scheme copy= fgLocalBindingManager.getScheme(scheme.getId()); copy.define(scheme.getName(), scheme.getDescription(), scheme.getParentId()); @@ -781,4 +790,11 @@ return img; } + protected TableViewer getDefaultViewer() { + return fDefaultViewer; + } + + protected PreferenceModel getModel() { + return fModel; + } } Index: ui/org/eclipse/jdt/internal/ui/preferences/CodeAssistAdvancedConstants.java =================================================================== RCS file: ui/org/eclipse/jdt/internal/ui/preferences/CodeAssistAdvancedConstants.java diff -N ui/org/eclipse/jdt/internal/ui/preferences/CodeAssistAdvancedConstants.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ui/org/eclipse/jdt/internal/ui/preferences/CodeAssistAdvancedConstants.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,69 @@ +/** + * Copyright (c) 2011 Gerrit Hendrik Freise. + * 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: + * Gerrit Hendrik Freise - initial API and implementation. + */ +package org.eclipse.jdt.internal.ui.preferences; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.widgets.Display; + +import org.eclipse.jdt.core.JavaCore; + +import org.eclipse.jdt.ui.PreferenceConstants; + +import org.eclipse.jdt.internal.ui.preferences.OptionsConfigurationBlock.Key; + + +public class CodeAssistAdvancedConstants { + + protected static final Color COLOR_DRAG_OVER= Display.getCurrent().getSystemColor(SWT.COLOR_LIST_SELECTION); + + protected static final Color COLOR_TABLE_HEADER= Display.getCurrent().getSystemColor(SWT.COLOR_WIDGET_LIGHT_SHADOW); + + + + protected static final Key PREF_CODEASSIST_TIMEOUT_FOR_PARAMETER_NAME_FROM_ATTACHED_JAVADOC= OptionsConfigurationBlock.getJDTCoreKey(JavaCore.TIMEOUT_FOR_PARAMETER_NAME_FROM_ATTACHED_JAVADOC); + + protected static final Key PREF_CATEGORY_ORDER_EXTENDED_NON_DEFAULT= OptionsConfigurationBlock.getJDTUIKey(PreferenceConstants.CODEASSIST_CATEGORY_ORDER_EXTENDED_NON_DEFAULT); + + protected static final Key PREF_CATEGORY_ORDER_EXTENDED= OptionsConfigurationBlock.getJDTUIKey(PreferenceConstants.CODEASSIST_CATEGORY_ORDER_EXTENDED); + + protected static final Key PREF_CATEGORY_ORDER= OptionsConfigurationBlock.getJDTUIKey(PreferenceConstants.CODEASSIST_CATEGORY_ORDER); + + protected static final Key PREF_EXCLUDED_CATEGORIES= OptionsConfigurationBlock.getJDTUIKey(PreferenceConstants.CODEASSIST_EXCLUDED_CATEGORIES); + + static Key[] getAllKeys() { + return new Key[] { + PREF_EXCLUDED_CATEGORIES, + PREF_CATEGORY_ORDER, + PREF_CODEASSIST_TIMEOUT_FOR_PARAMETER_NAME_FROM_ATTACHED_JAVADOC, + PREF_CATEGORY_ORDER_EXTENDED, + PREF_CATEGORY_ORDER_EXTENDED_NON_DEFAULT + }; + } + + + + protected static final int SPACING= 15; + + + + protected static final String LIST_SEPERATOR= ","; //$NON-NLS-1$ + + protected static final String SEPARATOR= "\0"; //$NON-NLS-1$ + + protected static final String COLON= ":"; //$NON-NLS-1$ + + + + protected static final String PROPOSALS_GROUP_NAMEPREFIX= "Proposals Group #"; //$NON-NLS-1$ + + static final int POPSALSGROUP_SURROUNDING_SPACE= 11; +} Index: ui/org/eclipse/jdt/internal/ui/preferences/CodeAssistAdvancedEmptySpacingComposite.java =================================================================== RCS file: ui/org/eclipse/jdt/internal/ui/preferences/CodeAssistAdvancedEmptySpacingComposite.java diff -N ui/org/eclipse/jdt/internal/ui/preferences/CodeAssistAdvancedEmptySpacingComposite.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ui/org/eclipse/jdt/internal/ui/preferences/CodeAssistAdvancedEmptySpacingComposite.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,183 @@ +/** + * Copyright (c) 2011 Gerrit Hendrik Freise. + * 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: + * Gerrit Hendrik Freise - initial API and implementation. + */ +package org.eclipse.jdt.internal.ui.preferences; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.dnd.DND; +import org.eclipse.swt.dnd.DropTarget; +import org.eclipse.swt.dnd.DropTargetAdapter; +import org.eclipse.swt.dnd.DropTargetEvent; +import org.eclipse.swt.dnd.DropTargetListener; +import org.eclipse.swt.dnd.TextTransfer; +import org.eclipse.swt.dnd.Transfer; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseTrackListener; +import org.eclipse.swt.layout.RowData; +import org.eclipse.swt.widgets.Composite; + +import org.eclipse.jface.layout.RowDataFactory; + +/** + * Empty Composite to Drop Elements between the CompositeProposalTables + * + * @author Gerrit Hendrik Freise + * + */ +public final class CodeAssistAdvancedEmptySpacingComposite extends Composite { + + private int insertIndex= -1; + + private final CodeAssistAdvancedProposalsGroupList proposalsGroupList; + + private final CodeAssistAdvancedEmptySpacingComposite instance; + + private final int defaultRowWidth; + + private int compositeWidth; + + public CodeAssistAdvancedEmptySpacingComposite(final CodeAssistAdvancedProposalsGroupList parent, final int insertIndex, final int defaultRowWidth) { + super(parent, SWT.NONE); + this.instance= this; + this.proposalsGroupList= parent; + this.insertIndex= insertIndex; + this.defaultRowWidth= defaultRowWidth + CodeAssistAdvancedConstants.POPSALSGROUP_SURROUNDING_SPACE; + + this.init(); + } + + private void init() { + this.initialzeDefaultLayout(); + + this.initializeDropListener(); + this.initializeMouseTrackListener(); + } + + + + private void initialzeDefaultLayout() { + this.compositeWidth= this.defaultRowWidth; + if (this.proposalsGroupList.getCompositeProposalGroups().size() != 0) { + this.proposalsGroupList.getCompositeProposalGroups().get(0).pack(); + this.compositeWidth= Math.max(compositeWidth, this.proposalsGroupList.getCompositeProposalGroups().get(0).getSize().x); + } + this.setLayoutData(RowDataFactory.swtDefaults().hint(compositeWidth, CodeAssistAdvancedConstants.SPACING).create()); + } + + protected void resize(final int newHeight) { + if (this.proposalsGroupList.getCompositeProposalGroups().size() != 0) { + this.compositeWidth= Math.max(compositeWidth, this.proposalsGroupList.getCompositeProposalGroups().get(0).getSize().x); + } + final RowData data= (RowData) this.getLayoutData(); + data.width= compositeWidth; + data.height= newHeight; + this.setSize(compositeWidth, newHeight); + } + + private void initializeDropListener() { + final DropTargetAdapter dropListener= this.createDropTargetAdapter(); + this.registerDropListener(dropListener); + } + + private DropTargetAdapter createDropTargetAdapter() { + final DropTargetAdapter dropTargetAdaoter= new DropTargetAdapter() { + @Override + public void dragEnter(final DropTargetEvent event) { + setDragEvent(event); + setDataType(event); + } + + private void setDragEvent(final DropTargetEvent event) { + if (event.detail == DND.DROP_DEFAULT) { + if ((event.operations & DND.DROP_COPY) != 0) { + event.detail= DND.DROP_COPY; + } else if ((event.operations & DND.DROP_MOVE) != 0) { + event.detail= DND.DROP_MOVE; + } else { + event.detail= DND.DROP_NONE; + } + } + } + + private void setDataType(final DropTargetEvent event) { + for (int i= 0, n= event.dataTypes.length; i < n; i++) { + if (TextTransfer.getInstance().isSupportedType(event.dataTypes[i])) { + event.currentDataType= event.dataTypes[i]; + } + } + } + + @Override + public void dragOver(final DropTargetEvent event) { + if (event.detail != DND.DROP_NONE) { + instance.setBackground(CodeAssistAdvancedConstants.COLOR_DRAG_OVER); + } + } + + @Override + public void dragLeave(final DropTargetEvent event) { + instance.setBackground(null); + } + + @Override + public void drop(final DropTargetEvent event) { + if (TextTransfer.getInstance().isSupportedType(event.currentDataType)) { + final int position= getInsertIndex(); + final CodeAssistAdvancedProposalsGroup proposalGroup= instance.proposalsGroupList.createCompositeProposalTable(SWT.HIDE_SELECTION | SWT.MULTI, position); + proposalGroup.getDropListener().drop(event); + } + } + }; + return dropTargetAdaoter; + } + + private void registerDropListener(final DropTargetListener dropListener) { + final DropTarget target= new DropTarget(this, DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_DEFAULT); + final Transfer[] types= new Transfer[] { TextTransfer.getInstance() }; + target.setTransfer(types); + target.addDropListener(dropListener); + } + + private void initializeMouseTrackListener() { + final MouseTrackListener mouseTrackListener= this.createMouseTrackListener(); + this.registerMouseTrackListener(mouseTrackListener); + } + + private MouseTrackListener createMouseTrackListener() { + return new MouseTrackListener() { + + public void mouseHover(final MouseEvent e) { + proposalsGroupList.getParent().setFocus(); + } + + public void mouseExit(final MouseEvent e) { + proposalsGroupList.getParent().setFocus(); + } + + public void mouseEnter(final MouseEvent e) { + proposalsGroupList.getParent().setFocus(); + } + }; + } + + private void registerMouseTrackListener(final MouseTrackListener mouseTrackListener) { + this.addMouseTrackListener(mouseTrackListener); + } + + protected int getInsertIndex() { + return this.insertIndex; + } + + protected void setInsertIndex(final int insertIndex) { + this.insertIndex= insertIndex; + } + + +} Index: ui/org/eclipse/jdt/internal/ui/preferences/CodeAssistAdvancedProposalsGroup.java =================================================================== RCS file: ui/org/eclipse/jdt/internal/ui/preferences/CodeAssistAdvancedProposalsGroup.java diff -N ui/org/eclipse/jdt/internal/ui/preferences/CodeAssistAdvancedProposalsGroup.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ui/org/eclipse/jdt/internal/ui/preferences/CodeAssistAdvancedProposalsGroup.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,450 @@ +/** + * Copyright (c) 2011 Gerrit Hendrik Freise. + * 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: + * Gerrit Hendrik Freise - initial API and implementation. + */ +package org.eclipse.jdt.internal.ui.preferences; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.dnd.DND; +import org.eclipse.swt.dnd.DragSource; +import org.eclipse.swt.dnd.DragSourceAdapter; +import org.eclipse.swt.dnd.DragSourceEvent; +import org.eclipse.swt.dnd.DragSourceListener; +import org.eclipse.swt.dnd.DropTarget; +import org.eclipse.swt.dnd.DropTargetAdapter; +import org.eclipse.swt.dnd.DropTargetEvent; +import org.eclipse.swt.dnd.DropTargetListener; +import org.eclipse.swt.dnd.TextTransfer; +import org.eclipse.swt.dnd.Transfer; +import org.eclipse.swt.events.KeyAdapter; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseTrackAdapter; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.RowData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.MenuItem; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.swt.widgets.TableItem; + +import org.eclipse.jface.layout.RowDataFactory; +import org.eclipse.jface.layout.RowLayoutFactory; +import org.eclipse.jface.layout.TableColumnLayout; +import org.eclipse.jface.viewers.ArrayContentProvider; +import org.eclipse.jface.viewers.ColumnPixelData; +import org.eclipse.jface.viewers.ColumnWeightData; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.ViewerComparator; + +import org.eclipse.ui.ISharedImages; +import org.eclipse.ui.PlatformUI; + +import org.eclipse.jdt.internal.ui.preferences.CodeAssistAdvancedConfigurationBlock.DefaultTableLabelProvider; +import org.eclipse.jdt.internal.ui.preferences.CodeAssistAdvancedConfigurationBlock.ModelElement; + + +/** + * Class, that holds the dropped ModelElements + * + * @author Gerrit Hendrik Freise + * + */ +public final class CodeAssistAdvancedProposalsGroup extends Composite { + private DropTargetListener dropTargetAdapter; + + private final CodeAssistAdvancedProposalsGroupList proposalsGroupList; + + private final CodeAssistAdvancedProposalsGroup instance; + + private final TableViewer tableViewer; + + private final Composite tableComposite; + + private final Composite headerComposite; + + private final Label headerLabel; + + private final int minimumWidth; + + private final CodeAssistAdvancedConfigurationBlock configurationBlock; + + private final int marginWidth= 1; + + protected CodeAssistAdvancedProposalsGroup(final CodeAssistAdvancedProposalsGroupList proposalsGroupList, final int style, final int defaultWidth, + final CodeAssistAdvancedConfigurationBlock configurationBlock) { + super(proposalsGroupList, SWT.NONE); + + this.instance= this; + this.configurationBlock= configurationBlock; + this.proposalsGroupList= proposalsGroupList; + this.minimumWidth= defaultWidth; + this.headerComposite= new Composite(this, SWT.NONE); + this.headerLabel= new Label(this.headerComposite, SWT.NONE); + this.tableComposite= new Composite(this, SWT.NONE); + this.tableViewer= new TableViewer(this.tableComposite, style); + + this.init(); + } + + private void init() { + + this.initializeWrappingComposite(); + this.initializeHeader(); + this.initializeBody(); + + this.initializeDragListener(); + this.initializeDropListener(); + this.initializeKeyListener(); + this.initializeTableMenu(); + this.initializeHeaderMenu(); + this.initializeMouseTrackListener(); + + this.pack(); + this.proposalsGroupList.resize(); + } + + private void initializeWrappingComposite() { + this.setLayout(RowLayoutFactory.swtDefaults().type(SWT.VERTICAL).spacing(0).margins(this.marginWidth, this.marginWidth).create()); + this.setLayoutData(new RowData(this.minimumWidth + CodeAssistAdvancedConstants.POPSALSGROUP_SURROUNDING_SPACE, SWT.DEFAULT)); + } + + private void initializeHeader() { + this.headerComposite.setLayout(RowLayoutFactory.swtDefaults().margins(this.marginWidth, this.marginWidth).create()); + this.headerComposite.setLayoutData(RowDataFactory.swtDefaults().hint(this.minimumWidth + 2 * this.marginWidth, SWT.DEFAULT).create()); + this.headerComposite.setBackground(CodeAssistAdvancedConstants.COLOR_TABLE_HEADER); + this.headerLabel.setBackground(CodeAssistAdvancedConstants.COLOR_TABLE_HEADER); + } + + private void initializeBody() { + this.setupTableViewer(); + this.setupTableColumn(); + } + + private void setupTableViewer() { + final DefaultTableLabelProvider labelProvider= configurationBlock.new DefaultTableLabelProvider(); + this.tableViewer.setLabelProvider(labelProvider); + this.tableViewer.setComparator(new ViewerComparator()); // sort alphabetically + this.tableViewer.setContentProvider(new ArrayContentProvider()); + } + + private void setupTableColumn() { + final TableColumn nameColumn= new TableColumn(this.getTable(), SWT.FULL_SELECTION); + nameColumn.setResizable(false); + nameColumn.setWidth(this.minimumWidth); + + final TableColumnLayout tableColumnLayout= new TableColumnLayout(); + this.tableComposite.setLayout(tableColumnLayout); + this.tableComposite.setLayoutData(RowDataFactory.swtDefaults().hint(this.minimumWidth + 2 * this.marginWidth, SWT.DEFAULT).create()); + tableColumnLayout.setColumnData(nameColumn, new ColumnPixelData(this.minimumWidth)); + tableColumnLayout.setColumnData(nameColumn, new ColumnWeightData(100, this.minimumWidth, false)); + } + + private void initializeDropListener() { + this.dropTargetAdapter= this.createDropTargetAdapter(); + this.registerDropTargetListener(this.dropTargetAdapter); + } + + private DropTargetAdapter createDropTargetAdapter() { + return new DropTargetAdapter() { + + @Override + public void dragEnter(final DropTargetEvent event) { + this.coverDuplicates(event); + this.setDragEvent(event); + this.setDataType(event); + } + + private void coverDuplicates(final DropTargetEvent event) { + final String[] ids= instance.proposalsGroupList.getModelElementDragId().split(CodeAssistAdvancedConstants.LIST_SEPERATOR); + for (TableItem tableElement : instance.getTable().getItems()) { + if (!(tableElement.getData() instanceof ModelElement)) { + continue; + } + final ModelElement m= (ModelElement) tableElement.getData(); + for (String id : ids) { + if (m.getId().equals(id)) { + event.detail= DND.DROP_NONE; + return; + } + } + } + } + + private void setDragEvent(final DropTargetEvent event) { + if (event.detail == DND.DROP_DEFAULT) { + if ((event.operations & DND.DROP_COPY) != 0) { + event.detail= DND.DROP_COPY; + } else if ((event.operations & DND.DROP_MOVE) != 0) { + event.detail= DND.DROP_MOVE; + } else { + event.detail= DND.DROP_NONE; + } + } + } + + private void setDataType(final DropTargetEvent event) { + if (event.detail == DND.DROP_NONE) { + return; + } + for (int j= 0, n= event.dataTypes.length; j < n; j++) { + if (TextTransfer.getInstance().isSupportedType(event.dataTypes[j])) { + event.currentDataType= event.dataTypes[j]; + } + } + } + + @Override + public void dragOver(final DropTargetEvent event) { + if (event.detail != DND.DROP_NONE) { + event.feedback= DND.FEEDBACK_SCROLL | DND.FEEDBACK_INSERT_AFTER; + instance.setBackground(CodeAssistAdvancedConstants.COLOR_DRAG_OVER); + } else { + event.feedback= DND.FEEDBACK_NONE; + } + } + + @Override + public void drop(final DropTargetEvent event) { + if (!TextTransfer.getInstance().isSupportedType(event.currentDataType)) { + return; + } + + final Object data= event.data; + String[] dataArray= new String[0]; + if (data instanceof String) { + dataArray= ((String) data).split(CodeAssistAdvancedConstants.LIST_SEPERATOR); + } + final List droppingElements= new ArrayList(); + for (final ModelElement modelElement : configurationBlock.getModel().elements) { + for (String str : dataArray) { + if (modelElement.getId().equals(str)) { + droppingElements.add(modelElement); + } + } + } + instance.add(droppingElements, event.detail == DND.DROP_COPY); + } + + @Override + public void dragLeave(final DropTargetEvent event) { + instance.setBackground(null); + } + + }; + } + + private void registerDropTargetListener(final DropTargetListener dropTargetListener) { + final DropTarget target= new DropTarget(this, DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_DEFAULT); + target.setTransfer(new Transfer[] { TextTransfer.getInstance() }); + target.addDropListener(dropTargetListener); + } + + private void initializeDragListener() { + final DragSourceAdapter dragSourceAdapter= this.createDragSourceAdapter(); + this.registerDragSourceListener(dragSourceAdapter); + } + + private DragSourceAdapter createDragSourceAdapter() { + return new DragSourceAdapter() { + @Override + public void dragSetData(final DragSourceEvent event) { + event.data= getDragData(event); + } + + @Override + public void dragStart(final DragSourceEvent event) { + instance.proposalsGroupList.setModelElementDragId(getDragData(event)); + } + + private String getDragData(final DragSourceEvent event) { + final DragSource dragSource= (DragSource) event.widget; + final Table dragTable= instance.getTable(); + TableItem[] selection= dragTable.getSelection(); + if (dragSource.getControl() == headerComposite || dragSource.getControl() == headerLabel) { + dragTable.selectAll(); + selection= dragTable.getSelection(); + } + final StringBuffer buffer= new StringBuffer(); + for (int i= 0, n= selection.length; i < n; i++) { + if (!(selection[i].getData() instanceof ModelElement)) { + continue; + } + if (buffer.length() != 0) { + buffer.append(CodeAssistAdvancedConstants.LIST_SEPERATOR); + } + buffer.append(((ModelElement) selection[i].getData()).getId()); + } + return buffer.toString(); + } + + @Override + public void dragFinished(final DragSourceEvent event) { + final DragSource dragSource= (DragSource) event.widget; + if (event.detail == DND.DROP_MOVE) { + removeSelectedItems(true); + } else if (dragSource.getControl() == headerComposite || dragSource.getControl() == headerLabel) { + instance.getTable().deselectAll(); + } + instance.proposalsGroupList.setModelElementDragId(null); + } + }; + } + + private void registerDragSourceListener(final DragSourceListener dragSourceListener) { + final DragSource sourceTable= new DragSource(this.getTable(), DND.DROP_MOVE); + final DragSource sourceLabelComposite= new DragSource(this.headerComposite, DND.DROP_MOVE); + final DragSource sourceLabel= new DragSource(this.headerLabel, DND.DROP_MOVE); + + final Transfer[] types= new Transfer[] { TextTransfer.getInstance() }; + sourceLabelComposite.setTransfer(types); + sourceLabel.setTransfer(types); + sourceTable.setTransfer(types); + + sourceTable.addDragListener(dragSourceListener); + sourceLabelComposite.addDragListener(dragSourceListener); + sourceLabel.addDragListener(dragSourceListener); + } + + private void initializeKeyListener() { + this.getTable().addKeyListener(new KeyAdapter() { + @Override + public void keyPressed(KeyEvent e) { + if (e.keyCode == SWT.DEL) { + instance.removeSelectedItems(true); + } + + } + }); + } + + private void initializeTableMenu() { + final Menu menu= this.createTableMenu(); + this.createDeleteItemsEntry(menu); + this.createDeleteTableEntry(menu); + } + + private Menu createTableMenu() { + final Menu menu= new Menu(this.getTable()); + this.getTable().setMenu(menu); + return menu; + } + + private void initializeHeaderMenu() { + final Menu menu= this.createHeaderMenu(); + this.createDeleteTableEntry(menu); + } + + private Menu createHeaderMenu() { + final Menu menu= new Menu(this.getTable()); + this.headerComposite.setMenu(menu); + this.headerLabel.setMenu(menu); + + return menu; + } + + private void createDeleteItemsEntry(final Menu menu) { + final MenuItem deleteItemsEntry= new MenuItem(menu, SWT.NONE); + deleteItemsEntry.setImage(PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_ELCL_REMOVE)); + deleteItemsEntry.setText("remove selected item(s)"); //$NON-NLS-1$ + deleteItemsEntry.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(final SelectionEvent e) { + instance.removeSelectedItems(true); + } + }); + } + + private void createDeleteTableEntry(final Menu menu) { + final MenuItem deleteTableEntry= new MenuItem(menu, SWT.NONE); + deleteTableEntry.setImage(PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_ELCL_REMOVEALL)); + deleteTableEntry.setText("remove table"); //$NON-NLS-1$ + deleteTableEntry.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(final SelectionEvent e) { + while (!instance.getTable().isDisposed() && instance.getTable().getItemCount() > 0) { + instance.getTable().selectAll(); + instance.removeSelectedItems(true); + } + } + }); + } + + private void initializeMouseTrackListener() { + this.addMouseTrackListener(new MouseTrackAdapter() { + + @Override + public void mouseExit(MouseEvent e) { + instance.proposalsGroupList.getParent().setFocus(); + } + + @Override + public void mouseEnter(MouseEvent e) { + instance.proposalsGroupList.getParent().setFocus(); + } + }); + } + + private void add(final List elements, final boolean forceResize) { + for (ModelElement element : elements) { + this.resizeTableComposite(this.getTable().getSize().y + this.getTable().getItemHeight()); + this.tableViewer.add(element); + } + if (forceResize) { + instance.proposalsGroupList.resize(); + } + } + + private void removeSelectedItems(final boolean forceResize) { + final int[] selection= this.getTable().getSelectionIndices(); + this.getTable().remove(selection); + if (this.getTable().getItemCount() == 0) { + this.dispose(); + instance.proposalsGroupList.getCompositeProposalGroups().remove(this); + } + if (forceResize) { + this.proposalsGroupList.resize(); + } + } + + @Override + public void pack() { + this.tableViewer.getTable().pack(); + this.resizeTableComposite(this.getTable().getSize().y - this.getTable().getItemHeight() + 3); + this.headerLabel.pack(); + } + + private void resizeTableComposite(int newCompositeHeight) { + ((RowData) this.tableComposite.getLayoutData()).height= newCompositeHeight; + this.tableComposite.setSize(this.tableComposite.getSize().x, newCompositeHeight); + } + + protected DropTargetListener getDropListener() { + return this.dropTargetAdapter; + } + + protected TableViewer getTableViewer() { + return this.tableViewer; + } + + protected Table getTable() { + return this.getTableViewer().getTable(); + } + + protected Label getHeaderLabel() { + return this.headerLabel; + } + +} Index: ui/org/eclipse/jdt/internal/ui/preferences/CodeAssistAdvancedProposalsGroupList.java =================================================================== RCS file: ui/org/eclipse/jdt/internal/ui/preferences/CodeAssistAdvancedProposalsGroupList.java diff -N ui/org/eclipse/jdt/internal/ui/preferences/CodeAssistAdvancedProposalsGroupList.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ui/org/eclipse/jdt/internal/ui/preferences/CodeAssistAdvancedProposalsGroupList.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,255 @@ +/** + * Copyright (c) 2011 Gerrit Hendrik Freise. + * 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: + * Gerrit Hendrik Freise - initial API and implementation. + */ +package org.eclipse.jdt.internal.ui.preferences; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.ScrolledComposite; +import org.eclipse.swt.events.ControlAdapter; +import org.eclipse.swt.events.ControlEvent; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseTrackListener; +import org.eclipse.swt.events.MouseWheelListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.RowLayoutFactory; + +import org.eclipse.jdt.internal.ui.text.java.CompletionProposalComputerRegistryComposite.LazyArrayList; +import org.eclipse.jdt.internal.ui.text.java.CompletionProposalComputerRegistryComposite.LazyArrayList.ListEntryCreator; + +/** + * This class holds the Group with the DropTables + * + * @author Gerrit Hendrik Freise + * + */ +public final class CodeAssistAdvancedProposalsGroupList extends Composite { + private final CodeAssistAdvancedProposalsGroupList instance; + + private boolean resizeBlocked= false; + + private final List compositeProposalsGroups= new ArrayList(); + + private final ListEntryCreator emptySpacingCompositeCreator= new ListEntryCreator() { + public CodeAssistAdvancedEmptySpacingComposite createListEntry() { + return new CodeAssistAdvancedEmptySpacingComposite(instance, -1, minimumWidth); + } + }; + + private final ArrayList emptySpacingComposites= new LazyArrayList(emptySpacingCompositeCreator); + + private final CodeAssistAdvancedConfigurationBlock configurationBlock; + + private final int minimumWidth; + + /** + * An id, that is used to identify the id from the dragObject + */ + private String modelElementDragId= null; + + private final ScrolledComposite scrollPanel; + + protected CodeAssistAdvancedProposalsGroupList(final ScrolledComposite parent, final int style, final int minimumWidth, final CodeAssistAdvancedConfigurationBlock configurationBlock) { + super(parent, style); + this.scrollPanel= parent; + this.instance= this; + this.configurationBlock= configurationBlock; + this.minimumWidth= minimumWidth; + + this.init(); + } + + private void init() { + this.initializeMainComposite(); + this.initializeScrollPanel(); + + this.initializeMouseWheelListener(); + this.initializeMouseTrackListener(); + this.initializeResizeListener(); + } + + private void initializeMainComposite() { + this.setLayout(RowLayoutFactory.fillDefaults().spacing(0).type(SWT.VERTICAL).create()); + } + + private void initializeScrollPanel() { + this.scrollPanel.setAlwaysShowScrollBars(true); + this.scrollPanel.setContent(this); + this.scrollPanel.setLayout(new ScaleOneDimensionLayout(SWT.HORIZONTAL)); + this.scrollPanel.setLayoutData(GridDataFactory.swtDefaults().align(SWT.BEGINNING, SWT.BEGINNING).create()); + + this.scrollPanel.pack(); + } + + private void initializeResizeListener() { + this.scrollPanel.addControlListener(new ControlAdapter() { + @Override + public void controlResized(ControlEvent e) { + instance.resizeContent(); + } + }); + } + + private void initializeMouseWheelListener() { + MouseWheelListener wheelListener= new MouseWheelListener() { + public void mouseScrolled(MouseEvent mouseEvent) { + instance.scroll(mouseEvent.count); + } + }; + this.scrollPanel.addMouseWheelListener(wheelListener); + this.addMouseWheelListener(wheelListener); + } + + private void scroll(int scrollAmount) { + this.scrollPanel.getVerticalBar().setIncrement(scrollAmount); + } + + private void initializeMouseTrackListener() { + this.addMouseTrackListener(new MouseTrackListener() { + public void mouseHover(MouseEvent e) { + instance.setFocus(); + } + + public void mouseExit(MouseEvent e) { + instance.setFocus(); + } + + public void mouseEnter(MouseEvent e) { + instance.setFocus(); + } + }); + } + + /** + * Resizes the Proposalgroup, in this case, the Labels of the DropTables will be set + */ + protected void resize() { + if (!this.resizeBlocked) { + this.setVisible(false); + this.resizeProposalGroups(); + this.resizeContent(); + this.setVisible(true); + } + } + + private void resizeContent() { + this.resizeScrollpanel(); + this.resizeMainComposite(); + this.resizeLastSpacingComposite(); + } + + + + private void resizeProposalGroups() { + + for (final CodeAssistAdvancedProposalsGroup proposalGroup : this.compositeProposalsGroups) { + final String columname= CodeAssistAdvancedConstants.PROPOSALS_GROUP_NAMEPREFIX + (this.compositeProposalsGroups.indexOf(proposalGroup) + 1); + proposalGroup.getHeaderLabel().setText(columname); + proposalGroup.pack(); + } + + } + + private void resizeScrollpanel() { + this.pack(); + final Composite scrollpanelParent= this.scrollPanel.getParent(); + if (this.scrollPanel.getSize().y != scrollpanelParent.getSize().y) { + final GridData gridData= (GridData) scrollPanel.getLayoutData(); + gridData.minimumHeight= scrollpanelParent.getSize().y; + gridData.heightHint= scrollpanelParent.getSize().y; + this.scrollPanel.setSize(this.scrollPanel.getSize().x, scrollpanelParent.getSize().y); + } + } + + private void resizeMainComposite() { + if (this.getSize().y <= this.scrollPanel.getSize().y - 5) { + this.setSize(this.getSize().x, this.scrollPanel.getSize().y - 5); + } + if (this.getSize().x < this.scrollPanel.getSize().x) { + this.setSize(this.scrollPanel.getSize().x, this.getSize().y); + } + } + + private void resizeLastSpacingComposite() { + final CodeAssistAdvancedEmptySpacingComposite spacingComposite= this.emptySpacingComposites.get(emptySpacingComposites.size() - 1); + int newHeight= this.getSize().y - spacingComposite.getLocation().y; + newHeight= Math.max(newHeight, CodeAssistAdvancedConstants.SPACING); + spacingComposite.resize(newHeight); + } + + protected CodeAssistAdvancedProposalsGroup createCompositeProposalTable() { + return this.createCompositeProposalTable(SWT.HIDE_SELECTION | SWT.MULTI, -1); + } + + protected CodeAssistAdvancedProposalsGroup createCompositeProposalTable(final int style, final int position) { + final CodeAssistAdvancedProposalsGroup table= new CodeAssistAdvancedProposalsGroup(this, style, this.minimumWidth, this.configurationBlock); + if (position >= 0 && position <= this.compositeProposalsGroups.size()) { + this.compositeProposalsGroups.add(position, table); + } else { + this.compositeProposalsGroups.add(table); + } + this.resize(); + return table; + } + + protected List getCompositeProposalGroups() { + return compositeProposalsGroups; + } + + protected void setResizeBlocked(boolean resizeBlocked) { + this.resizeBlocked= resizeBlocked; + } + + protected String getModelElementDragId() { + return this.modelElementDragId; + } + + protected void setModelElementDragId(final String modelElementDragId) { + this.modelElementDragId= modelElementDragId; + } + + @Override + public Control[] getChildren() { + this.disposeUnnecessaryEmptySpacingComposites(); + return this.getSortedChildren(); + } + + private void disposeUnnecessaryEmptySpacingComposites() { + while (this.compositeProposalsGroups.size() + 1 < this.emptySpacingComposites.size()) { + this.emptySpacingComposites.get(this.emptySpacingComposites.size() - 1).dispose(); + this.emptySpacingComposites.remove(this.emptySpacingComposites.size() - 1); + } + this.emptySpacingComposites.trimToSize(); + } + + private Control[] getSortedChildren() { + final int proposalGroupListSize= this.compositeProposalsGroups.size(); + final int childSize= proposalGroupListSize * 2 + 1; + final ArrayList children= new ArrayList(); + for (int proposalGroupIndex= 0; proposalGroupIndex <= proposalGroupListSize; proposalGroupIndex++) { + final CodeAssistAdvancedEmptySpacingComposite emptySpacingComposite= this.emptySpacingComposites.get(proposalGroupIndex); + emptySpacingComposite.setInsertIndex(proposalGroupIndex); + emptySpacingComposite.resize(CodeAssistAdvancedConstants.SPACING); + children.add(emptySpacingComposite); + + if (children.size() < childSize) { + children.add(this.compositeProposalsGroups.get(proposalGroupIndex)); + } + } + + return children.toArray(new Control[0]); + } +} Index: ui/org/eclipse/jdt/internal/ui/preferences/ScaleOneDimensionLayout.java =================================================================== RCS file: ui/org/eclipse/jdt/internal/ui/preferences/ScaleOneDimensionLayout.java diff -N ui/org/eclipse/jdt/internal/ui/preferences/ScaleOneDimensionLayout.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ui/org/eclipse/jdt/internal/ui/preferences/ScaleOneDimensionLayout.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,58 @@ +/** + * Copyright (c) 2010 Darmstadt University of Technology. + * 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: + * Johannes Lerch - initial API and implementation. + */ +package org.eclipse.jdt.internal.ui.preferences; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Layout; + +/** + * Layouts all children to have the same width and height as the parent composite. For computing + * size of the component only the dimension given as parameter to the constructor will be used.
+ */ +public class ScaleOneDimensionLayout extends Layout { + + private final int dimension; + + /** + * @param dimension Dimension which should be scaled, either SWT.VERTICAL or SWT.HORIZONTAL + */ + public ScaleOneDimensionLayout(final int dimension) { + this.dimension= dimension; + } + + @Override + protected Point computeSize(final Composite composite, final int wHint, final int hHint, final boolean flushCache) { + final Control[] children= composite.getChildren(); + int max= 0; + for (final Control child : children) { + final Point childSize= child.computeSize(wHint, hHint); + max= Math.max(max, dimension == SWT.HORIZONTAL ? childSize.x : childSize.y); + } + if (dimension == SWT.HORIZONTAL) { + return new Point(max, 0); + } else { + return new Point(0, max); + } + } + + @Override + protected void layout(final Composite composite, final boolean flushCache) { + final Control[] children= composite.getChildren(); + final Rectangle bounds= composite.getClientArea(); + for (final Control child : children) { + child.setBounds(bounds); + } + } +} Index: ui/org/eclipse/jdt/internal/ui/text/java/CompletionProposalCategory.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/CompletionProposalCategory.java,v retrieving revision 1.19 diff -u -r1.19 CompletionProposalCategory.java --- ui/org/eclipse/jdt/internal/ui/text/java/CompletionProposalCategory.java 1 Mar 2011 11:50:36 -0000 1.19 +++ ui/org/eclipse/jdt/internal/ui/text/java/CompletionProposalCategory.java 6 Sep 2011 17:52:39 -0000 @@ -45,7 +45,7 @@ * * @since 3.2 */ -public final class CompletionProposalCategory { +public class CompletionProposalCategory { /** The extension schema name of the icon attribute. */ private static final String ICON= "icon"; //$NON-NLS-1$ Index: ui/org/eclipse/jdt/internal/ui/text/java/CompletionProposalCategoryComposite.java =================================================================== RCS file: ui/org/eclipse/jdt/internal/ui/text/java/CompletionProposalCategoryComposite.java diff -N ui/org/eclipse/jdt/internal/ui/text/java/CompletionProposalCategoryComposite.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ui/org/eclipse/jdt/internal/ui/text/java/CompletionProposalCategoryComposite.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,135 @@ +/** + * Copyright (c) 2011 Gerrit Hendrik Freise. + * 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: + * Gerrit Hendrik Freise - initial API and implementation. + */ +package org.eclipse.jdt.internal.ui.text.java; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.eclipse.core.runtime.SubProgressMonitor; + +import org.eclipse.jface.resource.ImageDescriptor; + +import org.eclipse.jface.text.contentassist.ICompletionProposal; +import org.eclipse.jface.text.contentassist.IContextInformation; + +import org.eclipse.jdt.ui.text.java.ContentAssistInvocationContext; + +/** + * composite-Class (facade) from a CompletionProposalCategory: contains multiple intances of + * CompletionProposalCategorys and looks like one simple Category + * + * @author Gerrit Hendrik Freise + * + */ +public final class CompletionProposalCategoryComposite extends CompletionProposalCategory { + + private final List categories= new ArrayList(); + + protected CompletionProposalCategoryComposite(final String id, final String name, final CompletionProposalComputerRegistry registry, final Collection categorys, + final boolean enabled, final boolean included, final int order) { + super(id, name, registry); + this.categories.addAll(categorys); + this.setEnabled(enabled); + this.setIncluded(included); + this.setSortOrder(order); + this.setSeparateCommand(!included); + } + + @Override + public ImageDescriptor getImageDescriptor() { + ImageDescriptor imageDescriptor= null; + for (int i= 0; i < categories.size() && imageDescriptor != null; i++) { + imageDescriptor= categories.get(i).getImageDescriptor(); + } + return imageDescriptor; + } + + @Override + public boolean hasComputers() { + boolean hasComputers= false; + for (final CompletionProposalCategory cat : categories) { + hasComputers|= cat.hasComputers(); + } + return hasComputers; + } + + @Override + public boolean hasComputers(String partition) { + boolean hasComputers= false; + for (final CompletionProposalCategory cat : categories) { + hasComputers|= cat.hasComputers(partition); + } + return hasComputers; + } + + + @Override + public List computeCompletionProposals(ContentAssistInvocationContext context, String partition, SubProgressMonitor monitor) { + ArrayList proposals= new ArrayList(); + for (final CompletionProposalCategory category : categories) { + proposals.addAll(category.computeCompletionProposals(context, partition, monitor)); + } + return proposals; + } + + @Override + public List computeContextInformation(ContentAssistInvocationContext context, String partition, SubProgressMonitor monitor) { + final ArrayList contextInformation= new ArrayList(); + for (final CompletionProposalCategory category : categories) { + contextInformation.addAll(category.computeContextInformation(context, partition, monitor)); + } + return contextInformation; + } + + @Override + public String getErrorMessage() { + String errorMessage= null; + for (final CompletionProposalCategory category : categories) { + String catErrormessage= category.getErrorMessage(); + if (errorMessage == null || errorMessage.length() == 0) { + errorMessage= catErrormessage; + } else { + errorMessage+= ", " + catErrormessage; //$NON-NLS-1$ + } + } + return errorMessage; + } + + @Override + public void setSortOrder(final int sortOrder) { + super.setSortOrder(sortOrder); + for (CompletionProposalCategory cat : categories) { + cat.setSortOrder(sortOrder); + } + } + + @Override + public void sessionStarted() { + for (final CompletionProposalCategory category : categories) { + category.sessionStarted(); + } + + } + + @Override + public void sessionEnded() { + for (final CompletionProposalCategory category : categories) { + category.sessionEnded(); + } + } + + public List getCategories() { + return categories; + } + + +} Index: ui/org/eclipse/jdt/internal/ui/text/java/CompletionProposalComputerRegistry.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/CompletionProposalComputerRegistry.java,v retrieving revision 1.23 diff -u -r1.23 CompletionProposalComputerRegistry.java --- ui/org/eclipse/jdt/internal/ui/text/java/CompletionProposalComputerRegistry.java 1 Mar 2011 11:50:36 -0000 1.23 +++ ui/org/eclipse/jdt/internal/ui/text/java/CompletionProposalComputerRegistry.java 6 Sep 2011 17:52:41 -0000 @@ -62,7 +62,7 @@ * * @since 3.2 */ -public final class CompletionProposalComputerRegistry { +public class CompletionProposalComputerRegistry { private static final String EXTENSION_POINT= "javaCompletionProposalComputer"; //$NON-NLS-1$ private static final String NUM_COMPUTERS_PREF_KEY= "content_assist_number_of_computers"; //$NON-NLS-1$ Index: ui/org/eclipse/jdt/internal/ui/text/java/CompletionProposalComputerRegistryComposite.java =================================================================== RCS file: ui/org/eclipse/jdt/internal/ui/text/java/CompletionProposalComputerRegistryComposite.java diff -N ui/org/eclipse/jdt/internal/ui/text/java/CompletionProposalComputerRegistryComposite.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ui/org/eclipse/jdt/internal/ui/text/java/CompletionProposalComputerRegistryComposite.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,300 @@ +/** + * Copyright (c) 2011 Gerrit Hendrik Freise. + * 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: + * Gerrit Hendrik Freise - initial API and implementation. + */ +package org.eclipse.jdt.internal.ui.text.java; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.StringTokenizer; + +import org.eclipse.jface.preference.IPreferenceStore; + +import org.eclipse.jdt.ui.PreferenceConstants; + +import org.eclipse.jdt.internal.ui.JavaPlugin; +import org.eclipse.jdt.internal.ui.text.java.CompletionProposalComputerRegistryComposite.LazyArrayList.ListEntryCreator; + +/** + * Registry to manage the CompletionProposalCategoryComposites + * + * @author Gerrit Hendrik Freise + * + */ +public final class CompletionProposalComputerRegistryComposite extends CompletionProposalComputerRegistry { + + private final CompletionProposalComputerRegistry defaultRegistry; + + private final List compositeCategories= new ArrayList(); + + private final Map standardCategoryMap= new HashMap(); + + private static CompletionProposalComputerRegistryComposite instance; + + + private String preferenceString= null; + + private String nonDefaultProperty= null; + + /** + * Creator for the pageCategorys(LazyArray)List + */ + private final ListEntryCreator> creator= new ListEntryCreator>() { + public Set createListEntry() { + return new HashSet(); + } + }; + + private final List> pageCategoriesList= new LazyArrayList>(creator); + + private static final String SEPARATOR= "\0"; //$NON-NLS-1$ + + private static final String LIST_SEPERATOR= ","; //$NON-NLS-1$ + + private static final String COLON= ":"; //$NON-NLS-1$ + + private static final String PROPSALS_NAME_PREFIX= "#"; //$NON-NLS-1$ + + private static final String NULL_STRING= "null";//$NON-NLS-1$ + + private static final Integer INTEGER_0= new Integer(0); + + public static synchronized CompletionProposalComputerRegistryComposite getDefault() { + if (instance == null) { + instance= new CompletionProposalComputerRegistryComposite(); + instance.reload(); + } + return instance; + } + + private CompletionProposalComputerRegistryComposite() { + super(); + this.defaultRegistry= super.getDefault(); + } + + @Override + public List getProposalCategories() { + return compositeCategories; + } + + @Override + public boolean hasUninstalledComputers(final String partition, final List included) { + final ArrayList categoriesList= new ArrayList(); + for (final CompletionProposalCategory cat : included) { + if (cat instanceof CompletionProposalCategoryComposite) { + categoriesList.addAll(((CompletionProposalCategoryComposite) cat).getCategories()); + } else { + categoriesList.add(cat); + } + } + return this.defaultRegistry.hasUninstalledComputers(partition, categoriesList); + } + + @Override + public void resetUnistalledComputers() { + this.defaultRegistry.resetUnistalledComputers(); + } + + @Override + public void reload() { + this.reloadStandardCategorys(); + this.reloadCycleOrderPreferences(); + this.createCompositeCategories(); + } + + private void reloadStandardCategorys() { + this.standardCategoryMap.clear(); + final List standardCtegories= this.defaultRegistry.getProposalCategories(); + for (final CompletionProposalCategory category : standardCtegories) { + this.standardCategoryMap.put(category.getId(), category); + } + } + + private void reloadCycleOrderPreferences() { + this.pageCategoriesList.clear(); + final boolean preferencesLoaded= this.loadPreferencesString(); + if ((this.preferenceString == null || this.preferenceString.length() == 0) && !preferencesLoaded) { + this.loadDefaultCompositeCategories(); + } else { + this.loadCompositeCategoriesFromPreferences(); + } + } + + private boolean loadPreferencesString() { + final IPreferenceStore store= JavaPlugin.getDefault().getPreferenceStore(); + if (this.nonDefaultProperty == null || this.nonDefaultProperty.length() == 0) { + this.nonDefaultProperty= store.getString(PreferenceConstants.CODEASSIST_CATEGORY_ORDER_EXTENDED_NON_DEFAULT); + } + final boolean nonDefaultPropertySet= this.nonDefaultProperty == null || this.nonDefaultProperty.length() == 0; + boolean preferencesLoaded= false; + if (this.preferenceString == null) { + if (!nonDefaultPropertySet) { + this.preferenceString= store.getString(PreferenceConstants.CODEASSIST_CATEGORY_ORDER_EXTENDED); + preferencesLoaded= true; + } + } + return preferencesLoaded; + } + + private void loadDefaultCompositeCategories() { + final IPreferenceStore store= JavaPlugin.getDefault().getPreferenceStore(); + final String preferences= store.getString(PreferenceConstants.CODEASSIST_CATEGORY_ORDER_EXTENDED_NON_DEFAULT); + if (preferences == null || preferences.length() == 0) { + for (final CompletionProposalCategory category : defaultRegistry.getProposalCategories()) { + if (category.isIncluded()) { + this.pageCategoriesList.get(0).add(category); + } + if (category.isSeparateCommand()) { + this.pageCategoriesList.get(category.getSortOrder()).add(category); + } + } + } + } + + private void loadCompositeCategoriesFromPreferences() { + StringTokenizer tokenizer= new StringTokenizer(this.preferenceString, SEPARATOR); + while (tokenizer.hasMoreTokens()) { + final StringTokenizer innerTokenizer= new StringTokenizer(tokenizer.nextToken(), COLON); + if (!innerTokenizer.hasMoreTokens()) { + continue; + } + final String id= innerTokenizer.nextToken(); + if (!innerTokenizer.hasMoreTokens()) { + continue; + } + final List compositePages= this.getOrderListFromTokenizer(new StringTokenizer(innerTokenizer.nextToken(), LIST_SEPERATOR)); + for (final Integer page : compositePages) { + final CompletionProposalCategory standardCategory= this.standardCategoryMap.get(id); + if (standardCategory != null) { + this.pageCategoriesList.get(page.intValue()).add(standardCategory); + } + } + } + } + + private void createCompositeCategories() { + this.compositeCategories.clear(); + Integer order= INTEGER_0; + for (final Set containingCategories : pageCategoriesList) { + if (containingCategories.size() != 0) { + compositeCategories.add(createCompositeCategory(order, containingCategories)); + order= new Integer(order.intValue() + 1); + } + } + } + + private CompletionProposalCategoryComposite createCompositeCategory(final Integer order, final Set containingCategories) { + final boolean isDefaultProposal= order.equals(INTEGER_0) ? true : false; + final boolean enabled= true; + final LinkedList categoryIds= new LinkedList(); + final LinkedList categoryNames= new LinkedList(); + final LinkedList nullCategories= new LinkedList(); + for (final CompletionProposalCategory category : containingCategories) { + if (category != null) { + categoryIds.add(category.getId()); + categoryNames.add(category.getName()); + } else { + nullCategories.add(category); + } + } + containingCategories.removeAll(nullCategories); + final Integer visibleOrder= new Integer(order.intValue() + 1); + final String id= visibleOrder + COLON + " " + getStringFromList(categoryIds); //$NON-NLS-1$ + final String name= PROPSALS_NAME_PREFIX + visibleOrder + COLON + " " + getStringFromList(categoryNames); //$NON-NLS-1$ + return new CompletionProposalCategoryComposite(id, name, defaultRegistry, containingCategories, enabled, isDefaultProposal, order.intValue()); + } + + private String getStringFromList(final List list) { + String result= null; + for (String str : list) { + if (result == null || result.length() == 0) { + result= str; + } else { + result+= LIST_SEPERATOR + " " + str; //$NON-NLS-1$ + } + } + return result; + } + + /** + * + * @param tokenizer the given Tokenizer + * @return a List of Integers + */ + private List getOrderListFromTokenizer(final StringTokenizer tokenizer) { + final List orderList= new ArrayList(); + while (tokenizer.hasMoreTokens()) { + final String orderString= tokenizer.nextToken(); + if (orderString != null && !orderString.equals(NULL_STRING)) { + final Integer order= new Integer(Integer.parseInt(orderString)); + orderList.add(order); + } + + } + return orderList; + } + + /** + * @return the preferenceString + */ + public String getPreferenceString() { + return this.preferenceString; + } + + /** + * @param preferenceString the preferenceString to set + */ + public void setPreferenceString(final String preferenceString) { + this.preferenceString= preferenceString; + } + + /** + * @param nonDefaultProperty the nonDefaultProperty to set + */ + public void setNonDefaultProperty(final String nonDefaultProperty) { + this.nonDefaultProperty= nonDefaultProperty; + } + + /** + * Fill an ArrayList automatically with missing entrys + * + * @author Gerrit Hendrik Freise + * + * @param the generic param + */ + public final static class LazyArrayList extends ArrayList { + + private static final long serialVersionUID= -8861677428978177499L; + + private final ListEntryCreator listEntryCreator; + + public LazyArrayList(final ListEntryCreator listEntryCreator) { + this.listEntryCreator= listEntryCreator; + } + + @Override + public E get(final int index) { + while (this.size() <= index) { + E e= listEntryCreator.createListEntry(); + this.add(e); + } + return super.get(index); + } + + public static interface ListEntryCreator { + public E createListEntry(); + } + } + +} Index: ui/org/eclipse/jdt/internal/ui/text/java/ContentAssistProcessor.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/ContentAssistProcessor.java,v retrieving revision 1.26 diff -u -r1.26 ContentAssistProcessor.java --- ui/org/eclipse/jdt/internal/ui/text/java/ContentAssistProcessor.java 1 Mar 2011 11:50:36 -0000 1.26 +++ ui/org/eclipse/jdt/internal/ui/text/java/ContentAssistProcessor.java 6 Sep 2011 17:52:43 -0000 @@ -219,7 +219,7 @@ Assert.isNotNull(partition); Assert.isNotNull(assistant); fPartition= partition; - fComputerRegistry= CompletionProposalComputerRegistry.getDefault(); + fComputerRegistry= CompletionProposalComputerRegistryComposite.getDefault(); fCategories= fComputerRegistry.getProposalCategories(); fAssistant= assistant; fAssistant.addCompletionListener(new CompletionListener()); @@ -582,8 +582,9 @@ private String getCategoryLabel(int repetition) { int iteration= repetition % fCategoryIteration.size(); - if (iteration == 0) + if (fCategoryIteration.size() <= 1 || fCategoryIteration.get(iteration).size() ==0){ return JavaTextMessages.ContentAssistProcessor_defaultProposalCategory; + } return toString(fCategoryIteration.get(iteration).get(0)); } Index: ui/org/eclipse/jdt/ui/PreferenceConstants.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/ui/PreferenceConstants.java,v retrieving revision 1.259 diff -u -r1.259 PreferenceConstants.java --- ui/org/eclipse/jdt/ui/PreferenceConstants.java 5 Jan 2011 10:18:40 -0000 1.259 +++ ui/org/eclipse/jdt/ui/PreferenceConstants.java 6 Sep 2011 17:52:44 -0000 @@ -3200,6 +3200,28 @@ public static final String CODEASSIST_CATEGORY_ORDER= "content_assist_category_order"; //$NON-NLS-1$ /** + * A named preference that controls which the page of the specific code assist commands. + *

+ * Value is of type String, a "\0"-separated list with categoryId:cycleOrderList where + *

    + *
  • categoryId is the String holding the category ID
  • + *
  • cycleOrderList value is of type String with order1,order2,order3 ... which specifies the ProposalPage + *
+ * + *

+ * + * @since 3.8 + */ + public static final String CODEASSIST_CATEGORY_ORDER_EXTENDED= "content_assist_category_order_extended"; //$NON-NLS-1$ + + /** + * After first save of the advanced codassist, this flag will be set + * + * @since 3.8 + */ + public static final String CODEASSIST_CATEGORY_ORDER_EXTENDED_NON_DEFAULT= "content_assist_category_order_extended_non_default"; //$NON-NLS-1$ + + /** * A named preference that controls whether folding is enabled in the Java editor. *

* Value is of type Boolean.