Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 199831 Details for
Bug 340876
[preferences][content assist] Request for more flexible configuration of content assist lists
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
[patch]
Patch for prototype of new content assist lists
org.eclipse.jdt.ui_3.7.1_patch.txt (text/plain), 178.63 KB, created by
Thomas Schlosser
on 2011-07-18 09:57:46 EDT
(
hide
)
Description:
Patch for prototype of new content assist lists
Filename:
MIME Type:
Creator:
Thomas Schlosser
Created:
2011-07-18 09:57:46 EDT
Size:
178.63 KB
patch
obsolete
>### Eclipse Workspace Patch 1.0 >#P org.eclipse.jdt.ui >Index: META-INF/MANIFEST.MF >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/META-INF/MANIFEST.MF,v >retrieving revision 1.89 >diff -u -r1.89 MANIFEST.MF >--- META-INF/MANIFEST.MF 4 Mar 2011 18:57:13 -0000 1.89 >+++ META-INF/MANIFEST.MF 18 Jul 2011 13:26:50 -0000 >@@ -2,7 +2,7 @@ > Bundle-ManifestVersion: 2 > Bundle-Name: %pluginName > Bundle-SymbolicName: org.eclipse.jdt.ui; singleton:=true >-Bundle-Version: 3.7.0.qualifier >+Bundle-Version: 3.7.1.qualifier > Bundle-Activator: org.eclipse.jdt.internal.ui.JavaPlugin > Bundle-ActivationPolicy: lazy > Bundle-Vendor: %providerName >Index: ui/org/eclipse/jdt/internal/ui/javaeditor/SpecificContentAssistExecutor.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/javaeditor/SpecificContentAssistExecutor.java,v >retrieving revision 1.8 >diff -u -r1.8 SpecificContentAssistExecutor.java >--- ui/org/eclipse/jdt/internal/ui/javaeditor/SpecificContentAssistExecutor.java 27 Apr 2011 07:48:36 -0000 1.8 >+++ ui/org/eclipse/jdt/internal/ui/javaeditor/SpecificContentAssistExecutor.java 18 Jul 2011 13:26:50 -0000 >@@ -7,11 +7,15 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Thomas Schlosser <schlosser@stud.tu-darmstadt.de> - 340876 [preferences][content assist] Request for more flexible configuration of content assist lists - https://bugs.eclipse.org/bugs/show_bug.cgi?id=340876 > *******************************************************************************/ > package org.eclipse.jdt.internal.ui.javaeditor; > >+import java.util.ArrayList; > import java.util.Collection; >+import java.util.HashSet; > import java.util.Iterator; >+import java.util.Set; > > import org.eclipse.core.runtime.Assert; > >@@ -24,8 +28,9 @@ > import org.eclipse.jdt.internal.ui.text.java.CompletionProposalComputerRegistry; > > /** >- * A content assist executor can invoke content assist for a specific proposal category on an editor. >- * >+ * A content assist executor can invoke content assist for a specific proposal category on an >+ * editor. >+ * > * @since 3.2 > */ > public final class SpecificContentAssistExecutor { >@@ -34,7 +39,7 @@ > > /** > * Creates a new executor. >- * >+ * > * @param registry the computer registry to use for the enablement of proposal categories > */ > public SpecificContentAssistExecutor(CompletionProposalComputerRegistry registry) { >@@ -45,21 +50,18 @@ > /** > * Invokes content assist on <code>editor</code>, showing only proposals computed by the > * <code>CompletionProposalCategory</code> with the given <code>categoryId</code>. >- * >+ * > * @param editor the editor to invoke code assist on > * @param categoryId the id of the proposal category to show proposals for > */ > public void invokeContentAssist(final ITextEditor editor, String categoryId) { > Collection<CompletionProposalCategory> categories= fRegistry.getProposalCategories(); >- boolean[] inclusionState= new boolean[categories.size()]; >- boolean[] separateState= new boolean[categories.size()]; >- int i= 0; >- for (Iterator<CompletionProposalCategory> it= categories.iterator(); it.hasNext(); i++) { >- CompletionProposalCategory cat= it.next(); >- inclusionState[i]= cat.isIncluded(); >- cat.setIncluded(cat.getId().equals(categoryId)); >- separateState[i]= cat.isSeparateCommand(); >- cat.setSeparateCommand(false); >+ ArrayList<Set<Integer>> categoriesState= new ArrayList<Set<Integer>>(categories.size()); >+ for (CompletionProposalCategory cat : categories) { >+ categoriesState.add(new HashSet<Integer>(cat.getProposalListIndices())); >+ cat.clearProposalListIndices(); >+ if (cat.getId().equals(categoryId)) >+ cat.addProposalListIndex(Integer.valueOf(0)); > } > > try { >@@ -67,11 +69,11 @@ > if (target != null && target.canDoOperation(ISourceViewer.CONTENTASSIST_PROPOSALS)) > target.doOperation(ISourceViewer.CONTENTASSIST_PROPOSALS); > } finally { >- i= 0; >+ int i= 0; > for (Iterator<CompletionProposalCategory> it= categories.iterator(); it.hasNext(); i++) { > CompletionProposalCategory cat= it.next(); >- cat.setIncluded(inclusionState[i]); >- cat.setSeparateCommand(separateState[i]); >+ cat.clearProposalListIndices(); >+ cat.addAllProposalListIndices(categoriesState.get(i)); > } > } > } >Index: ui/org/eclipse/jdt/internal/ui/preferences/CodeAssistAdvancedConfigurationBlock.java >=================================================================== >RCS file: ui/org/eclipse/jdt/internal/ui/preferences/CodeAssistAdvancedConfigurationBlock.java >diff -N ui/org/eclipse/jdt/internal/ui/preferences/CodeAssistAdvancedConfigurationBlock.java >--- ui/org/eclipse/jdt/internal/ui/preferences/CodeAssistAdvancedConfigurationBlock.java 1 Mar 2011 11:50:45 -0000 1.14 >+++ /dev/null 1 Jan 1970 00:00:00 -0000 >@@ -1,784 +0,0 @@ >-/******************************************************************************* >- * Copyright (c) 2005, 2011 IBM Corporation and others. >- * All rights reserved. This program and the accompanying materials >- * are made available under the terms of the Eclipse Public License v1.0 >- * which accompanies this distribution, and is available at >- * http://www.eclipse.org/legal/epl-v10.html >- * >- * Contributors: >- * IBM Corporation - initial API and implementation >- *******************************************************************************/ >-package org.eclipse.jdt.internal.ui.preferences; >- >-import java.util.ArrayList; >-import java.util.Collections; >-import java.util.Comparator; >-import java.util.HashMap; >-import java.util.Iterator; >-import java.util.List; >-import java.util.Map; >- >-import org.eclipse.swt.SWT; >-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.core.commands.Command; >-import org.eclipse.core.commands.CommandManager; >-import org.eclipse.core.commands.IParameter; >-import org.eclipse.core.commands.Parameterization; >-import org.eclipse.core.commands.ParameterizedCommand; >-import org.eclipse.core.commands.common.NotDefinedException; >-import org.eclipse.core.commands.contexts.ContextManager; >- >-import org.eclipse.core.runtime.Assert; >- >-import org.eclipse.jface.bindings.BindingManager; >-import org.eclipse.jface.bindings.Scheme; >-import org.eclipse.jface.bindings.TriggerSequence; >-import org.eclipse.jface.layout.PixelConverter; >-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.ITableLabelProvider; >-import org.eclipse.jface.viewers.LabelProvider; >-import org.eclipse.jface.viewers.ViewerComparator; >- >-import org.eclipse.ui.PlatformUI; >-import org.eclipse.ui.commands.ICommandService; >-import org.eclipse.ui.dialogs.PreferencesUtil; >-import org.eclipse.ui.keys.IBindingService; >-import org.eclipse.ui.preferences.IWorkbenchPreferenceContainer; >- >-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.CompletionProposalComputerRegistry; >-import org.eclipse.jdt.internal.ui.util.SWTUtil; >-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 { >- >- /* >- * @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(); >- case 1: >- return ((ModelElement) element).getKeybindingAsString(); >- default: >- Assert.isTrue(false); >- return null; >- } >- } >- >- /* >- * @see org.eclipse.jface.viewers.LabelProvider#getText(java.lang.Object) >- */ >- @Override >- public String getText(Object element) { >- 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<ModelElement> fCategoryComparator= new Comparator<ModelElement>() { >- private int getRank(ModelElement o) { >- return o.getRank(); >- } >- >- public int compare(ModelElement o1, ModelElement o2) { >- return getRank(o1) - getRank(o2); >- } >- }; >- >- private 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<ModelElement> fElements; >- /** >- * The read-only list of elements. >- */ >- final List<ModelElement> elements; >- >- public PreferenceModel(CompletionProposalComputerRegistry registry) { >- List<CompletionProposalCategory> categories= registry.getProposalCategories(); >- fElements= new ArrayList<ModelElement>(); >- for (Iterator<CompletionProposalCategory> it= categories.iterator(); it.hasNext();) { >- CompletionProposalCategory category= it.next(); >- if (category.hasComputers()) { >- fElements.add(new ModelElement(category, this)); >- } >- } >- Collections.sort(fElements, fCategoryComparator); >- 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<ModelElement> 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<ModelElement> 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]); >- } >- return LIMIT - 1; >- } >- >- public void update() { >- Collections.sort(fElements, fCategoryComparator); >- } >- } >- >- private final class ModelElement { >- private final CompletionProposalCategory fCategory; >- private final Command fCommand; >- private final IParameter fParam; >- private final PreferenceModel fPreferenceModel; >- >- ModelElement(CompletionProposalCategory category, PreferenceModel model) { >- fCategory= category; >- ICommandService commandSvc= (ICommandService) PlatformUI.getWorkbench().getAdapter(ICommandService.class); >- fCommand= commandSvc.getCommand("org.eclipse.jdt.ui.specific_content_assist.command"); //$NON-NLS-1$ >- IParameter type; >- try { >- type= fCommand.getParameters()[0]; >- } catch (NotDefinedException x) { >- Assert.isTrue(false); >- type= null; >- } >- 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); >- } >- } >- >- /** element type: {@link ModelElement}. */ >- private final PreferenceModel fModel; >- private final Map<ImageDescriptor, Image> fImages= new HashMap<ImageDescriptor, Image>(); >- >- private CheckboxTableViewer fDefaultViewer; >- private CheckboxTableViewer fSeparateViewer; >- private Button fUpButton; >- private Button fDownButton; >- >- CodeAssistAdvancedConfigurationBlock(IStatusChangeListener statusListener, IWorkbenchPreferenceContainer container) { >- super(statusListener, null, getAllKeys(), container); >- fModel= new PreferenceModel(CompletionProposalComputerRegistry.getDefault()); >- } >- >- /* >- * @see org.eclipse.jdt.internal.ui.preferences.OptionsConfigurationBlock#createContents(org.eclipse.swt.widgets.Composite) >- */ >- @Override >- protected Control createContents(Composite parent) { >- >- 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); >- >- >- createDefaultLabel(composite, columns); >- createDefaultViewer(composite, columns); >- createKeysLink(composite, columns); >- >- createFiller(composite, columns); >- >- createSeparateLabel(composite, columns); >- createSeparateSection(composite); >- >- createFiller(composite, columns); >- >- createParameterTimeoutControl(composite, columns); >- >- 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); >- final Command command= commandSvc.getCommand(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS); >- 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); >- >- 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(); >- 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); >- nameColumn.setText(PreferencesMessages.CodeAssistAdvancedConfigurationBlock_default_table_category_column_title); >- nameColumn.setResizable(false); >- 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; >- 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))); >- } >- >- 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() { >- @Override >- public void widgetSelected(SelectionEvent e) { >- PreferencesUtil.createPreferenceDialogOn(getShell(), e.text, null, null); >- } >- }); >- >- 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); >- } >- >- 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 void createSeparateLabel(Composite composite, int h_span) { >- PixelConverter pixelConverter= new PixelConverter(composite); >- int width= pixelConverter.convertWidthInCharsToPixels(40); >- >- 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); >- } >- >- private void createSeparateSection(Composite composite) { >- createSeparateViewer(composite); >- createButtonList(composite); >- } >- >- 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)); >- >- TableColumn nameColumn= new TableColumn(table, SWT.NONE); >- nameColumn.setText(PreferencesMessages.CodeAssistAdvancedConfigurationBlock_separate_table_category_column_title); >- nameColumn.setResizable(false); >- >- fSeparateViewer.setContentProvider(new ArrayContentProvider()); >- >- ITableLabelProvider labelProvider= new SeparateTableLabelProvider(); >- fSeparateViewer.setLabelProvider(labelProvider); >- fSeparateViewer.setInput(fModel.elements); >- >- 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); >- } >- >- nameColumn.setWidth(minNameWidth); >- >- fSeparateViewer.addCheckStateListener(new ICheckStateListener() { >- public void checkStateChanged(CheckStateChangedEvent event) { >- boolean checked= event.getChecked(); >- ModelElement element= (ModelElement) event.getElement(); >- element.setSeparateCommand(checked); >- } >- }); >- >- table.addSelectionListener(new SelectionAdapter() { >- @Override >- public void widgetSelected(SelectionEvent e) { >- handleTableSelection(); >- } >- }); >- >- } >- >- 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)); >- >- } >- >- 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); >- } >- } >- >- private ModelElement getSelectedItem() { >- return (ModelElement) ((IStructuredSelection) fSeparateViewer.getSelection()).getFirstElement(); >- } >- >- private int getSelectionIndex() { >- return fSeparateViewer.getTable().getSelectionIndex(); >- } >- >- /* >- * @see org.eclipse.jdt.internal.ui.preferences.OptionsConfigurationBlock#updateControls() >- */ >- @Override >- protected void updateControls() { >- super.updateControls(); >- >- fModel.update(); >- updateCheckedState(); >- fDefaultViewer.refresh(); >- fSeparateViewer.refresh(); >- handleTableSelection(); >- } >- >- private void updateCheckedState() { >- final int size= fModel.elements.size(); >- List<ModelElement> defaultChecked= new ArrayList<ModelElement>(size); >- List<ModelElement> separateChecked= new ArrayList<ModelElement>(size); >- >- for (Iterator<ModelElement> it= fModel.elements.iterator(); it.hasNext();) { >- ModelElement element= it.next(); >- if (element.isInDefaultCategory()) >- defaultChecked.add(element); >- if (element.isSeparateCommand()) >- separateChecked.add(element); >- } >- >- fDefaultViewer.setCheckedElements(defaultChecked.toArray(new Object[defaultChecked.size()])); >- fSeparateViewer.setCheckedElements(separateChecked.toArray(new Object[separateChecked.size()])); >- } >- >- /* >- * @see org.eclipse.jdt.internal.ui.preferences.OptionsConfigurationBlock#processChanges(org.eclipse.ui.preferences.IWorkbenchPreferenceContainer) >- */ >- @Override >- protected boolean processChanges(IWorkbenchPreferenceContainer container) { >- for (Iterator<ModelElement> it= fModel.elements.iterator(); it.hasNext();) { >- ModelElement item= it.next(); >- item.update(); >- } >- >- return super.processChanges(container); >- } >- >- /* >- * @see org.eclipse.jdt.internal.ui.preferences.OptionsConfigurationBlock#validateSettings(org.eclipse.jdt.internal.ui.preferences.OptionsConfigurationBlock.Key, java.lang.String, java.lang.String) >- */ >- @Override >- protected void validateSettings(Key changedKey, String oldValue, String newValue) { >- if (changedKey == 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); >- else { >- try { >- int number= Integer.parseInt(newValue); >- int min= 0; >- 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)}); >- status.setError(msg); >- } >- } catch (NumberFormatException ex) { >- String msgFormat= PreferencesMessages.CodeAssistAdvancedConfigurationBlock_parameterNameFromAttachedJavadoc_timeout_invalidInput; >- String msg= Messages.format(msgFormat, newValue); >- status.setError(msg); >- } >- } >- fContext.statusChanged(status); >- } >- } >- >- /* >- * @see org.eclipse.jdt.internal.ui.preferences.OptionsConfigurationBlock#getFullBuildDialogStrings(boolean) >- */ >- @Override >- protected String[] getFullBuildDialogStrings(boolean workspaceSettings) { >- // no builds triggered by our settings >- return null; >- } >- >- /* >- * @see org.eclipse.jdt.internal.ui.preferences.OptionsConfigurationBlock#dispose() >- */ >- @Override >- public void dispose() { >- for (Iterator<Image> it= fImages.values().iterator(); it.hasNext();) { >- Image image= it.next(); >- image.dispose(); >- } >- >- super.dispose(); >- } >- >- private int computeWidth(Control control, String name) { >- if (name == null) >- return 0; >- GC gc= new GC(control); >- try { >- gc.setFont(JFaceResources.getDialogFont()); >- return gc.stringExtent(name).x + 10; >- } finally { >- gc.dispose(); >- } >- } >- >- private static BindingManager fgLocalBindingManager; >- static { >- fgLocalBindingManager= new BindingManager(new ContextManager(), new CommandManager()); >- 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++) { >- final Scheme scheme= definedSchemes[i]; >- final Scheme copy= fgLocalBindingManager.getScheme(scheme.getId()); >- copy.define(scheme.getName(), scheme.getDescription(), scheme.getParentId()); >- } >- } catch (final NotDefinedException e) { >- JavaPlugin.log(e); >- } >- } >- fgLocalBindingManager.setLocale(bindingService.getLocale()); >- fgLocalBindingManager.setPlatform(bindingService.getPlatform()); >- } >- >- private static String getKeyboardShortcut(ParameterizedCommand command) { >- IBindingService bindingService= (IBindingService) PlatformUI.getWorkbench().getAdapter(IBindingService.class); >- fgLocalBindingManager.setBindings(bindingService.getBindings()); >- try { >- Scheme activeScheme= bindingService.getActiveScheme(); >- if (activeScheme != null) >- fgLocalBindingManager.setActiveScheme(activeScheme); >- } catch (NotDefinedException e) { >- JavaPlugin.log(e); >- } >- >- TriggerSequence[] bindings= fgLocalBindingManager.getActiveBindingsDisregardingContextFor(command); >- if (bindings.length > 0) >- return bindings[0].format(); >- return null; >- } >- >- private Image getImage(ImageDescriptor imgDesc) { >- if (imgDesc == null) >- return null; >- >- Image img= fImages.get(imgDesc); >- if (img == null) { >- img= imgDesc.createImage(false); >- fImages.put(imgDesc, img); >- } >- return img; >- } >- >-} >Index: ui/org/eclipse/jdt/internal/ui/preferences/CodeAssistAdvancedPreferencePage.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/CodeAssistAdvancedPreferencePage.java,v >retrieving revision 1.6 >diff -u -r1.6 CodeAssistAdvancedPreferencePage.java >--- ui/org/eclipse/jdt/internal/ui/preferences/CodeAssistAdvancedPreferencePage.java 27 Apr 2011 07:51:28 -0000 1.6 >+++ ui/org/eclipse/jdt/internal/ui/preferences/CodeAssistAdvancedPreferencePage.java 18 Jul 2011 13:26:50 -0000 >@@ -7,6 +7,7 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Thomas Schlosser <schlosser@stud.tu-darmstadt.de> - 340876 [preferences][content assist] Request for more flexible configuration of content assist lists - https://bugs.eclipse.org/bugs/show_bug.cgi?id=340876 > *******************************************************************************/ > package org.eclipse.jdt.internal.ui.preferences; > >@@ -19,6 +20,7 @@ > import org.eclipse.ui.preferences.IWorkbenchPreferenceContainer; > > import org.eclipse.jdt.internal.ui.IJavaHelpContextIds; >+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.CodeAssistAdvancedConfigurationBlock; > > public final class CodeAssistAdvancedPreferencePage extends PropertyAndPreferencePage { > >Index: ui/org/eclipse/jdt/internal/ui/preferences/PreferencesMessages.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/PreferencesMessages.java,v >retrieving revision 1.143 >diff -u -r1.143 PreferencesMessages.java >--- ui/org/eclipse/jdt/internal/ui/preferences/PreferencesMessages.java 27 Apr 2011 07:51:27 -0000 1.143 >+++ ui/org/eclipse/jdt/internal/ui/preferences/PreferencesMessages.java 18 Jul 2011 13:26:52 -0000 >@@ -11,6 +11,7 @@ > * Sebastian Davids, sdavids@gmx.de - 187316 [preferences] Mark Occurences Pref Page; Link to > * Benjamin Muskalla <b.muskalla@gmx.net> - [preferences] Add preference for new compiler warning: MissingSynchronizedModifierInInheritedMethod - https://bugs.eclipse.org/bugs/show_bug.cgi?id=245240 > * Guven Demir <guven.internet+eclipse@gmail.com> - [package explorer] Alternative package name shortening: abbreviation - https://bugs.eclipse.org/bugs/show_bug.cgi?id=299514 >+ * Thomas Schlosser <schlosser@stud.tu-darmstadt.de> - 340876 [preferences][content assist] Request for more flexible configuration of content assist lists - https://bugs.eclipse.org/bugs/show_bug.cgi?id=340876 > *******************************************************************************/ > package org.eclipse.jdt.internal.ui.preferences; > >@@ -41,16 +42,13 @@ > public static String ClasspathVariablesPreferencePage_savechanges_message; > public static String CleanUpPreferencePage_Description; > public static String CleanUpPreferencePage_Title; >- public static String CodeAssistAdvancedConfigurationBlock_default_table_category_column_title; >- public static String CodeAssistAdvancedConfigurationBlock_default_table_description; >- public static String CodeAssistAdvancedConfigurationBlock_default_table_keybinding_column_title; >+ public static String CodeAssistAdvancedConfigurationBlock_provided_table_category_column_title; >+ public static String CodeAssistAdvancedConfigurationBlock_provided_table_description; >+ public static String CodeAssistAdvancedConfigurationBlock_provided_table_keybinding_column_title; > public static String CodeAssistAdvancedConfigurationBlock_key_binding_hint; >+ public static String CodeAssistAdvancedConfigurationBlock_proposal_list_table_title; > public static String CodeAssistAdvancedConfigurationBlock_page_description; >- public static String CodeAssistAdvancedConfigurationBlock_separate_table_category_column_title; >- public static String CodeAssistAdvancedConfigurationBlock_separate_table_description; > public static String CodeAssistAdvancedConfigurationBlock_no_shortcut; >- public static String CodeAssistAdvancedConfigurationBlock_Up; >- public static String CodeAssistAdvancedConfigurationBlock_Down; > public static String CodeAssistAdvancedConfigurationBlock_parameterNameFromAttachedJavadoc_timeout; > public static String CodeAssistAdvancedConfigurationBlock_parameterNameFromAttachedJavadoc_timeout_emptyInput; > public static String CodeAssistAdvancedConfigurationBlock_parameterNameFromAttachedJavadoc_timeout_invalidInput; >Index: ui/org/eclipse/jdt/internal/ui/preferences/PreferencesMessages.properties >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/preferences/PreferencesMessages.properties,v >retrieving revision 1.530 >diff -u -r1.530 PreferencesMessages.properties >--- ui/org/eclipse/jdt/internal/ui/preferences/PreferencesMessages.properties 4 May 2011 11:04:12 -0000 1.530 >+++ ui/org/eclipse/jdt/internal/ui/preferences/PreferencesMessages.properties 18 Jul 2011 13:26:53 -0000 >@@ -11,6 +11,7 @@ > # Sebastian Davids, sdavids@gmx.de - 187316 [preferences] Mark Occurrences Pref Page; Link to > # Benjamin Muskalla <b.muskalla@gmx.net> - [preferences] Add preference for new compiler warning: MissingSynchronizedModifierInInheritedMethod - https://bugs.eclipse.org/bugs/show_bug.cgi?id=245240 > # Guven Demir <guven.internet+eclipse@gmail.com> - [package explorer] Alternative package name shortening: abbreviation - https://bugs.eclipse.org/bugs/show_bug.cgi?id=299514 >+# Thomas Schlosser <schlosser@stud.tu-darmstadt.de> - 340876 [preferences][content assist] Request for more flexible configuration of content assist lists - https://bugs.eclipse.org/bugs/show_bug.cgi?id=340876 > ############################################################################### > > BuildPathsPropertyPage_error_message=An error occurred while setting the build path. >@@ -848,15 +849,12 @@ > CodeAssistAdvancedConfigurationBlock_page_description=Configure the behavior of the content assist ({0}) command. > # stand-in text if there is no keyboard shortcut in above statement > CodeAssistAdvancedConfigurationBlock_no_shortcut=no shortcut >-CodeAssistAdvancedConfigurationBlock_default_table_description=&Select the proposal kinds contained in the 'default' content assist list: >-CodeAssistAdvancedConfigurationBlock_default_table_category_column_title=Default Proposal Kinds >-CodeAssistAdvancedConfigurationBlock_default_table_keybinding_column_title=Key Binding >+CodeAssistAdvancedConfigurationBlock_provided_table_description=Drag proposal kinds to lists on the right to configure which proposals you want to have on each position while repeatedly invoking content assist. >+CodeAssistAdvancedConfigurationBlock_provided_table_category_column_title=Proposal Kinds >+CodeAssistAdvancedConfigurationBlock_provided_table_keybinding_column_title=Key Binding > # do not translate the href argument (org.eclipse.ui.preferencePages.Keys) > CodeAssistAdvancedConfigurationBlock_key_binding_hint=Individual key bindings can be assigned to each proposal kind on the <a href="org.eclipse.ui.preferencePages.Keys">'Keys'</a> preference page. >-CodeAssistAdvancedConfigurationBlock_separate_table_description=&Content assist cycling: Select the proposal kinds that are cycled through when repeatedly invoking content assist: >-CodeAssistAdvancedConfigurationBlock_separate_table_category_column_title=Separate Proposal Kinds >-CodeAssistAdvancedConfigurationBlock_Up=&Up >-CodeAssistAdvancedConfigurationBlock_Down=D&own >+CodeAssistAdvancedConfigurationBlock_proposal_list_table_title={0}. Proposal List > CodeAssistAdvancedConfigurationBlock_parameterNameFromAttachedJavadoc_timeout=&Timeout for fetching a parameter name from attached Javadoc (ms): > > CodeAssistAdvancedConfigurationBlock_parameterNameFromAttachedJavadoc_timeout_emptyInput=Empty input. >Index: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/CodeAssistAdvancedConfigurationBlock.java >=================================================================== >RCS file: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/CodeAssistAdvancedConfigurationBlock.java >diff -N ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/CodeAssistAdvancedConfigurationBlock.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/CodeAssistAdvancedConfigurationBlock.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,459 @@ >+/******************************************************************************* >+ * Copyright (c) 2005, 2011 IBM Corporation and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * IBM Corporation - initial API and implementation >+ * Thomas Schlosser <schlosser@stud.tu-darmstadt.de> - 340876 [preferences][content assist] Request for more flexible configuration of content assist lists - https://bugs.eclipse.org/bugs/show_bug.cgi?id=340876 >+ *******************************************************************************/ >+package org.eclipse.jdt.internal.ui.preferences.codeassist.advanced; >+ >+import java.util.HashMap; >+import java.util.Iterator; >+import java.util.Map; >+ >+import org.eclipse.swt.SWT; >+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.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.core.commands.Command; >+import org.eclipse.core.commands.CommandManager; >+import org.eclipse.core.commands.ParameterizedCommand; >+import org.eclipse.core.commands.common.NotDefinedException; >+import org.eclipse.core.commands.contexts.ContextManager; >+ >+import org.eclipse.core.runtime.Assert; >+ >+import org.eclipse.jface.bindings.BindingManager; >+import org.eclipse.jface.bindings.Scheme; >+import org.eclipse.jface.bindings.TriggerSequence; >+import org.eclipse.jface.layout.PixelConverter; >+import org.eclipse.jface.resource.ImageDescriptor; >+import org.eclipse.jface.resource.JFaceResources; >+import org.eclipse.jface.viewers.ArrayContentProvider; >+import org.eclipse.jface.viewers.ITableLabelProvider; >+import org.eclipse.jface.viewers.LabelProvider; >+import org.eclipse.jface.viewers.TableViewer; >+ >+import org.eclipse.ui.PlatformUI; >+import org.eclipse.ui.commands.ICommandService; >+import org.eclipse.ui.dialogs.PreferencesUtil; >+import org.eclipse.ui.keys.IBindingService; >+import org.eclipse.ui.preferences.IWorkbenchPreferenceContainer; >+ >+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.preferences.OptionsConfigurationBlock; >+import org.eclipse.jdt.internal.ui.preferences.PreferencesMessages; >+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.dnd.DragProvidedCategoryListener; >+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.dnd.DropIntoProvidedListener; >+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.dnd.ProposalListCategoryTransfer; >+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.dnd.ProposalListTransfer; >+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.dnd.ProposalTransfer; >+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.dnd.ProvidedCategoryTransfer; >+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.model.ModelElement; >+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.model.PreferenceModel; >+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.widgets.ProposalListSection; >+import org.eclipse.jdt.internal.ui.text.java.CompletionProposalComputerRegistry; >+import org.eclipse.jdt.internal.ui.wizards.IStatusChangeListener; >+ >+ >+/** >+ * >+ * @since 3.2 >+ */ >+public final class CodeAssistAdvancedConfigurationBlock extends OptionsConfigurationBlock { >+ >+ protected static final Key PREF_PROPOSAL_LISTS= getJDTUIKey(PreferenceConstants.CODEASSIST_PROPOSAL_LISTS); >+ >+ 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_PROPOSAL_LISTS, >+ PREF_CODEASSIST_TIMEOUT_FOR_PARAMETER_NAME_FROM_ATTACHED_JAVADOC >+ }; >+ } >+ >+ private static final int NUMBER_OF_PAGE_COLUMNS= 2; >+ >+ private final class ProvidedTableLabelProvider 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(); >+ case 1: >+ return ((ModelElement) element).getKeybindingAsString(); >+ default: >+ Assert.isTrue(false); >+ return null; >+ } >+ } >+ } >+ >+ private final PreferenceModel fModel; >+ >+ private final Map<ImageDescriptor, Image> fImages= new HashMap<ImageDescriptor, Image>(); >+ >+ private TableViewer fProvidedViewer; >+ >+ private ProposalListSection fProposalListSection; >+ >+ private final CodeAssistAdvancedUtilitiesProxy fUtilitiesProxy; >+ >+ public CodeAssistAdvancedConfigurationBlock(IStatusChangeListener statusListener, IWorkbenchPreferenceContainer container) { >+ super(statusListener, null, getAllKeys(), container); >+ fUtilitiesProxy= new CodeAssistAdvancedUtilitiesProxy(this); >+ fModel= new PreferenceModel(CompletionProposalComputerRegistry.getDefault(), fUtilitiesProxy); >+ } >+ >+ /* >+ * @see org.eclipse.jdt.internal.ui.preferences.OptionsConfigurationBlock#createContents(org.eclipse.swt.widgets.Composite) >+ */ >+ @Override >+ public Control createContents(Composite parent) { >+ Composite composite= createWrappingComposite(parent); >+ >+ createPageDescription(composite); >+ >+ createProvidedSection(composite); >+ fProposalListSection= new ProposalListSection(composite, fModel, fUtilitiesProxy); >+ >+ createFiller(composite); >+ >+ createParameterTimeoutControl(composite); >+ >+ updateControls(); >+ selectFirstProvidedCategory(); >+ >+ return composite; >+ } >+ >+ private Composite createWrappingComposite(Composite parent) { >+ Composite composite= new Composite(parent, SWT.NONE); >+ GridLayout layout= new GridLayout(NUMBER_OF_PAGE_COLUMNS, false); >+ layout.marginWidth= 0; >+ layout.marginHeight= 0; >+ composite.setLayout(layout); >+ return composite; >+ } >+ >+ private void createPageDescription(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); >+ String key= getKeyboardShortcut(pCmd); >+ if (key == null) >+ key= PreferencesMessages.CodeAssistAdvancedConfigurationBlock_no_shortcut; >+ >+ PixelConverter pixelConverter= new PixelConverter(composite); >+ int width= pixelConverter.convertWidthInCharsToPixels(40); >+ >+ 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, NUMBER_OF_PAGE_COLUMNS, 1); >+ gd.widthHint= width; >+ label.setLayoutData(gd); >+ } >+ >+ private void createProvidedSection(Composite composite) { >+ Composite providedContainer= new Composite(composite, SWT.NONE); >+ GridLayout layout= new GridLayout(); >+ layout.marginWidth= 0; >+ layout.marginHeight= 0; >+ providedContainer.setLayout(layout); >+ providedContainer.setLayoutData(new GridData(GridData.FILL_BOTH)); >+ >+ createProvidedViewer(providedContainer); >+ createProvidedLabel(providedContainer); >+ createKeysLink(providedContainer); >+ } >+ >+ private void createProvidedViewer(Composite composite) { >+ fProvidedViewer= new TableViewer(composite, SWT.SINGLE | SWT.BORDER | SWT.V_SCROLL); >+ Table table= fProvidedViewer.getTable(); >+ table.setHeaderVisible(true); >+ table.setLinesVisible(false); >+ GridData gridData= new GridData(SWT.FILL, SWT.FILL, true, true); >+ gridData.heightHint= 0; >+ table.setLayoutData(gridData); >+ >+ TableColumn nameColumn= new TableColumn(table, SWT.NONE); >+ nameColumn.setText(PreferencesMessages.CodeAssistAdvancedConfigurationBlock_provided_table_category_column_title); >+ nameColumn.setResizable(false); >+ TableColumn keyColumn= new TableColumn(table, SWT.NONE); >+ keyColumn.setText(PreferencesMessages.CodeAssistAdvancedConfigurationBlock_provided_table_keybinding_column_title); >+ keyColumn.setResizable(false); >+ >+ fProvidedViewer.setContentProvider(new ArrayContentProvider()); >+ ProvidedTableLabelProvider labelProvider= new ProvidedTableLabelProvider(); >+ fProvidedViewer.setLabelProvider(labelProvider); >+ fProvidedViewer.setInput(fModel.elements); >+ fProvidedViewer.setComparator(new ModelElement.ModelElementViewerComparator()); // sort alphabetically >+ >+ final int ICON_WIDTH= 16; >+ final int HEADER_MARGIN= 20; >+ 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_WIDTH); >+ minKeyWidth= Math.max(minKeyWidth, computeWidth(table, labelProvider.getColumnText(fModel.elements.get(i), 1))); >+ } >+ nameColumn.setWidth(minNameWidth); >+ keyColumn.setWidth(minKeyWidth); >+ >+ // add drag support for provided categories >+ Transfer[] transferTypes= new Transfer[] { ProvidedCategoryTransfer.getInstance() }; >+ fProvidedViewer.addDragSupport(ProposalTransfer.ALL_DRAG_OPERATIONS, transferTypes, new DragProvidedCategoryListener(fProvidedViewer)); >+ >+ // add drop support for proposal lists and proposal list categories >+ transferTypes= new Transfer[] { ProposalListTransfer.getInstance(), ProposalListCategoryTransfer.getInstance() }; >+ fProvidedViewer.addDropSupport(ProposalTransfer.ALL_DRAG_OPERATIONS, transferTypes, new DropIntoProvidedListener(fProvidedViewer, fModel, fUtilitiesProxy)); >+ } >+ >+ private void createProvidedLabel(Composite composite) { >+ PixelConverter pixelConverter= new PixelConverter(composite); >+ int width= pixelConverter.convertWidthInCharsToPixels(40); >+ >+ Label label= new Label(composite, SWT.NONE | SWT.WRAP); >+ label.setText(PreferencesMessages.CodeAssistAdvancedConfigurationBlock_provided_table_description); >+ GridData gd= new GridData(GridData.FILL, GridData.FILL, true, false); >+ gd.widthHint= width; >+ label.setLayoutData(gd); >+ } >+ >+ private void createKeysLink(Composite composite) { >+ 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) { >+ PreferencesUtil.createPreferenceDialogOn(getShell(), e.text, null, null); >+ } >+ }); >+ >+ 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); >+ gd.widthHint= width; >+ link.setLayoutData(gd); >+ } >+ >+ private void createFiller(Composite composite) { >+ Label filler= new Label(composite, SWT.NONE); >+ filler.setVisible(false); >+ filler.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false, NUMBER_OF_PAGE_COLUMNS, 1)); >+ } >+ >+ private void createParameterTimeoutControl(Composite composite) { >+ 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, NUMBER_OF_PAGE_COLUMNS, 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)); >+ } >+ >+ private void selectFirstProvidedCategory() { >+ if (fModel.elements.size() > 0) { >+ fProvidedViewer.getTable().select(0); >+ } >+ } >+ >+ /* >+ * @see org.eclipse.jdt.internal.ui.preferences.OptionsConfigurationBlock#settingsUpdated() >+ */ >+ @Override >+ protected void settingsUpdated() { >+ if (fModel != null) >+ fModel.updatePreferenceModel(); >+ } >+ >+ /* >+ * @see org.eclipse.jdt.internal.ui.preferences.OptionsConfigurationBlock#updateControls() >+ */ >+ @Override >+ protected void updateControls() { >+ super.updateControls(); >+ fProvidedViewer.refresh(); >+ fProposalListSection.updateControls(); >+ } >+ >+ /* >+ * @see org.eclipse.jdt.internal.ui.preferences.OptionsConfigurationBlock#processChanges(org.eclipse.ui.preferences.IWorkbenchPreferenceContainer) >+ */ >+ @Override >+ protected boolean processChanges(IWorkbenchPreferenceContainer container) { >+ fModel.updatePreferenceModel(); >+ return super.processChanges(container); >+ } >+ >+ /* >+ * @see org.eclipse.jdt.internal.ui.preferences.OptionsConfigurationBlock#setValue(Key, String) >+ */ >+ @Override >+ protected String setValue(Key key, String value) { >+ return super.setValue(key, value); >+ } >+ >+ /* >+ * @see org.eclipse.jdt.internal.ui.preferences.OptionsConfigurationBlock#getValue(Key) >+ */ >+ @Override >+ protected String getValue(Key key) { >+ return super.getValue(key); >+ } >+ >+ /* >+ * @see org.eclipse.jdt.internal.ui.preferences.OptionsConfigurationBlock#validateSettings(org.eclipse.jdt.internal.ui.preferences.OptionsConfigurationBlock.Key, java.lang.String, java.lang.String) >+ */ >+ @Override >+ protected void validateSettings(Key changedKey, String oldValue, String newValue) { >+ if (changedKey == 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); >+ else { >+ try { >+ int number= Integer.parseInt(newValue); >+ int min= 0; >+ 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) }); >+ status.setError(msg); >+ } >+ } catch (NumberFormatException ex) { >+ String msgFormat= PreferencesMessages.CodeAssistAdvancedConfigurationBlock_parameterNameFromAttachedJavadoc_timeout_invalidInput; >+ String msg= Messages.format(msgFormat, newValue); >+ status.setError(msg); >+ } >+ } >+ fContext.statusChanged(status); >+ } >+ } >+ >+ /* >+ * @see org.eclipse.jdt.internal.ui.preferences.OptionsConfigurationBlock#getFullBuildDialogStrings(boolean) >+ */ >+ @Override >+ protected String[] getFullBuildDialogStrings(boolean workspaceSettings) { >+ // no builds triggered by our settings >+ return null; >+ } >+ >+ /* >+ * @see org.eclipse.jdt.internal.ui.preferences.OptionsConfigurationBlock#dispose() >+ */ >+ @Override >+ public void dispose() { >+ for (Iterator<Image> it= fImages.values().iterator(); it.hasNext();) { >+ Image image= it.next(); >+ image.dispose(); >+ } >+ super.dispose(); >+ } >+ >+ protected int computeWidth(Control control, String name) { >+ if (name == null) >+ return 0; >+ GC gc= new GC(control); >+ try { >+ gc.setFont(JFaceResources.getDialogFont()); >+ return gc.stringExtent(name).x + 10; >+ } finally { >+ gc.dispose(); >+ } >+ } >+ >+ protected Image getImage(ImageDescriptor imgDesc) { >+ if (imgDesc == null) >+ return null; >+ >+ Image img= fImages.get(imgDesc); >+ if (img == null) { >+ img= imgDesc.createImage(false); >+ fImages.put(imgDesc, img); >+ } >+ return img; >+ } >+ >+ private static BindingManager fgLocalBindingManager; >+ static { >+ fgLocalBindingManager= new BindingManager(new ContextManager(), new CommandManager()); >+ 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++) { >+ final Scheme scheme= definedSchemes[i]; >+ final Scheme copy= fgLocalBindingManager.getScheme(scheme.getId()); >+ copy.define(scheme.getName(), scheme.getDescription(), scheme.getParentId()); >+ } >+ } catch (final NotDefinedException e) { >+ JavaPlugin.log(e); >+ } >+ } >+ fgLocalBindingManager.setLocale(bindingService.getLocale()); >+ fgLocalBindingManager.setPlatform(bindingService.getPlatform()); >+ } >+ >+ protected static String getKeyboardShortcut(ParameterizedCommand command) { >+ IBindingService bindingService= (IBindingService) PlatformUI.getWorkbench().getAdapter(IBindingService.class); >+ fgLocalBindingManager.setBindings(bindingService.getBindings()); >+ try { >+ Scheme activeScheme= bindingService.getActiveScheme(); >+ if (activeScheme != null) >+ fgLocalBindingManager.setActiveScheme(activeScheme); >+ } catch (NotDefinedException e) { >+ JavaPlugin.log(e); >+ } >+ >+ TriggerSequence[] bindings= fgLocalBindingManager.getActiveBindingsDisregardingContextFor(command); >+ if (bindings.length > 0) >+ return bindings[0].format(); >+ return null; >+ } >+} >Index: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/CodeAssistAdvancedUtilitiesProxy.java >=================================================================== >RCS file: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/CodeAssistAdvancedUtilitiesProxy.java >diff -N ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/CodeAssistAdvancedUtilitiesProxy.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/CodeAssistAdvancedUtilitiesProxy.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,103 @@ >+/** >+ * Copyright (c) 2011 Thomas Schlosser. >+ * 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: >+ * Thomas Schlosser <schlosser@stud.tu-darmstadt.de> - initial API and implementation. >+ */ >+package org.eclipse.jdt.internal.ui.preferences.codeassist.advanced; >+ >+import org.eclipse.swt.SWT; >+import org.eclipse.swt.dnd.DND; >+import org.eclipse.swt.dnd.TransferData; >+import org.eclipse.swt.graphics.Color; >+import org.eclipse.swt.graphics.Image; >+import org.eclipse.swt.widgets.Control; >+import org.eclipse.swt.widgets.Display; >+ >+import org.eclipse.core.commands.ParameterizedCommand; >+ >+import org.eclipse.jface.resource.ImageDescriptor; >+ >+import org.eclipse.ui.plugin.AbstractUIPlugin; >+ >+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.dnd.ProposalListCategoryTransfer; >+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.dnd.ProposalListTransfer; >+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.dnd.ProvidedCategoryTransfer; >+ >+/** >+ * >+ * @since 3.8 >+ */ >+public class CodeAssistAdvancedUtilitiesProxy { >+ public static final Color SELECTED_COLOR= Display.getCurrent().getSystemColor(SWT.COLOR_LIST_SELECTION); >+ >+ public static final Color SELECTED_TEXT_COLOR= Display.getCurrent().getSystemColor(SWT.COLOR_LIST_SELECTION_TEXT); >+ >+ public static final Color UNSELECTED_COLOR= Display.getCurrent().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND); >+ >+ public static final Color UNSELECTED_TEXT_COLOR= Display.getCurrent().getSystemColor(SWT.COLOR_WIDGET_FOREGROUND); >+ >+ public static final Color UNSELECTED_BORDER_COLOR= Display.getCurrent().getSystemColor(SWT.COLOR_GRAY); >+ >+ private static final ImageDescriptor REMOVE_PROPOSAL_LIST_ICON_DESCRIPTOR= AbstractUIPlugin.imageDescriptorFromPlugin("org.eclipse.jdt.ui", "$nl$/icons/full/elcl16/remove_proposal_list.gif"); //$NON-NLS-1$ //$NON-NLS-2$ >+ >+ private static final ImageDescriptor REMOVE_PROPOSAL_LIST_OVER_ICON_DESCRIPTOR= AbstractUIPlugin.imageDescriptorFromPlugin( >+ "org.eclipse.jdt.ui", "$nl$/icons/full/elcl16/remove_proposal_list_over.gif"); //$NON-NLS-1$ //$NON-NLS-2$ >+ >+ private CodeAssistAdvancedConfigurationBlock fConfigurationBlock; >+ >+ public final Image fRemoveProposalListImage; >+ >+ public final Image fRemoveProposalListOverImage; >+ >+ public CodeAssistAdvancedUtilitiesProxy(CodeAssistAdvancedConfigurationBlock configurationBlock) { >+ this.fConfigurationBlock= configurationBlock; >+ fRemoveProposalListImage= getImage(REMOVE_PROPOSAL_LIST_ICON_DESCRIPTOR); >+ fRemoveProposalListOverImage= getImage(REMOVE_PROPOSAL_LIST_OVER_ICON_DESCRIPTOR); >+ } >+ >+ public void updateControls() { >+ fConfigurationBlock.updateControls(); >+ } >+ >+ public int computeWidth(Control control, String name) { >+ return fConfigurationBlock.computeWidth(control, name); >+ } >+ >+ public Image getImage(ImageDescriptor imgDesc) { >+ return fConfigurationBlock.getImage(imgDesc); >+ } >+ >+ public String getKeyboardShortcut(ParameterizedCommand command) { >+ return CodeAssistAdvancedConfigurationBlock.getKeyboardShortcut(command); >+ } >+ >+ public String setValue(String value) { >+ return fConfigurationBlock.setValue(CodeAssistAdvancedConfigurationBlock.PREF_PROPOSAL_LISTS, value); >+ } >+ >+ public String getValue() { >+ return fConfigurationBlock.getValue(CodeAssistAdvancedConfigurationBlock.PREF_PROPOSAL_LISTS); >+ } >+ >+ public void validateSettings(String oldValue, String newValue) { >+ fConfigurationBlock.validateSettings(CodeAssistAdvancedConfigurationBlock.PREF_PROPOSAL_LISTS, oldValue, newValue); >+ } >+ >+ public static int getCompatibleOperation(int operation, int supportedOperations, TransferData currentDataType) { >+ int result= ProvidedCategoryTransfer.getInstance().getCompatibleOperation(operation, supportedOperations, currentDataType); >+ if (result != -1) >+ return result; >+ result= ProposalListTransfer.getInstance().getCompatibleOperation(operation, supportedOperations, currentDataType); >+ if (result != -1) >+ return result; >+ result= ProposalListCategoryTransfer.getInstance().getCompatibleOperation(operation, supportedOperations, currentDataType); >+ if (result != -1) >+ return result; >+ return DND.DROP_NONE; >+ } >+} >Index: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/AutoscrollDropTargetListener.java >=================================================================== >RCS file: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/AutoscrollDropTargetListener.java >diff -N ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/AutoscrollDropTargetListener.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/AutoscrollDropTargetListener.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,52 @@ >+/** >+ * Copyright (c) 2011 Thomas Schlosser. >+ * 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: >+ * Thomas Schlosser <schlosser@stud.tu-darmstadt.de> - initial API and implementation. >+ */ >+package org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.dnd; >+ >+import org.eclipse.swt.dnd.DND; >+import org.eclipse.swt.dnd.DropTargetEvent; >+import org.eclipse.swt.dnd.DropTargetListener; >+ >+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.widgets.ProposalListSection; >+ >+/** >+ * >+ * @since 3.8 >+ */ >+public final class AutoscrollDropTargetListener implements DropTargetListener { >+ private ProposalListSection fProposalListSection; >+ >+ public AutoscrollDropTargetListener(ProposalListSection proposalListSection) { >+ this.fProposalListSection= proposalListSection; >+ } >+ >+ public void dragEnter(DropTargetEvent event) { >+ event.detail= DND.DROP_NONE; >+ } >+ >+ public void dragLeave(DropTargetEvent event) { >+ } >+ >+ public void dragOperationChanged(DropTargetEvent event) { >+ event.detail= DND.DROP_NONE; >+ } >+ >+ public void dragOver(DropTargetEvent event) { >+ fProposalListSection.autoScroll(event); >+ } >+ >+ public void drop(DropTargetEvent event) { >+ event.detail= DND.DROP_NONE; >+ } >+ >+ public void dropAccept(DropTargetEvent event) { >+ event.detail= DND.DROP_NONE; >+ } >+} >Index: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/DragProposalListCategoryListener.java >=================================================================== >RCS file: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/DragProposalListCategoryListener.java >diff -N ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/DragProposalListCategoryListener.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/DragProposalListCategoryListener.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,54 @@ >+/** >+ * Copyright (c) 2011 Thomas Schlosser. >+ * 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: >+ * Thomas Schlosser <schlosser@stud.tu-darmstadt.de> - initial API and implementation. >+ */ >+package org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.dnd; >+ >+import org.eclipse.swt.dnd.DragSourceEvent; >+import org.eclipse.swt.dnd.DragSourceListener; >+ >+import org.eclipse.jface.viewers.IStructuredSelection; >+import org.eclipse.jface.viewers.TableViewer; >+ >+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.model.ModelElement; >+ >+/** >+ * >+ * @since 3.8 >+ */ >+public final class DragProposalListCategoryListener implements DragSourceListener { >+ private final TableViewer fViewer; >+ >+ private final Integer fListIndex; >+ >+ public DragProposalListCategoryListener(TableViewer viewer, int listIndex) { >+ this.fViewer= viewer; >+ this.fListIndex= Integer.valueOf(listIndex); >+ } >+ >+ public void dragSetData(DragSourceEvent event) { >+ if (ProposalListCategoryTransfer.getInstance().isSupportedType(event.dataType)) { >+ IStructuredSelection selection= (IStructuredSelection) fViewer.getSelection(); >+ if (fViewer.getSelection() != null && !fViewer.getSelection().isEmpty()) { >+ ModelElement firstElement= (ModelElement) selection.getFirstElement(); >+ if (firstElement != null) >+ event.data= new ProposalTransferType[] { new ProposalTransferType(firstElement.getId(), fListIndex) }; >+ } >+ } >+ } >+ >+ public void dragStart(DragSourceEvent event) { >+ if (fViewer.getSelection() == null || fViewer.getSelection().isEmpty() || ((IStructuredSelection) fViewer.getSelection()).getFirstElement() == null) { >+ event.doit= false; >+ } >+ } >+ >+ public void dragFinished(DragSourceEvent event) { >+ } >+} >Index: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/DragProposalListListener.java >=================================================================== >RCS file: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/DragProposalListListener.java >diff -N ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/DragProposalListListener.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/DragProposalListListener.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,38 @@ >+/** >+ * Copyright (c) 2011 Thomas Schlosser. >+ * 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: >+ * Thomas Schlosser <schlosser@stud.tu-darmstadt.de> - initial API and implementation. >+ */ >+package org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.dnd; >+ >+import org.eclipse.swt.dnd.DragSourceEvent; >+import org.eclipse.swt.dnd.DragSourceListener; >+ >+/** >+ * >+ * @since 3.8 >+ */ >+public final class DragProposalListListener implements DragSourceListener { >+ private final Integer fListIndex; >+ >+ public DragProposalListListener(int listIndex) { >+ this.fListIndex= Integer.valueOf(listIndex); >+ } >+ >+ public void dragSetData(DragSourceEvent event) { >+ if (ProposalListTransfer.getInstance().isSupportedType(event.dataType)) { >+ event.data= new ProposalTransferType[] { new ProposalTransferType(fListIndex) }; >+ } >+ } >+ >+ public void dragStart(DragSourceEvent event) { >+ } >+ >+ public void dragFinished(DragSourceEvent event) { >+ } >+} >Index: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/DragProvidedCategoryListener.java >=================================================================== >RCS file: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/DragProvidedCategoryListener.java >diff -N ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/DragProvidedCategoryListener.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/DragProvidedCategoryListener.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,51 @@ >+/** >+ * Copyright (c) 2011 Thomas Schlosser. >+ * 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: >+ * Thomas Schlosser <schlosser@stud.tu-darmstadt.de> - initial API and implementation. >+ */ >+package org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.dnd; >+ >+import org.eclipse.swt.dnd.DragSourceEvent; >+import org.eclipse.swt.dnd.DragSourceListener; >+ >+import org.eclipse.jface.viewers.IStructuredSelection; >+import org.eclipse.jface.viewers.TableViewer; >+ >+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.model.ModelElement; >+ >+/** >+ * >+ * @since 3.8 >+ */ >+public final class DragProvidedCategoryListener implements DragSourceListener { >+ private final TableViewer fViewer; >+ >+ public DragProvidedCategoryListener(TableViewer viewer) { >+ this.fViewer= viewer; >+ } >+ >+ public void dragSetData(DragSourceEvent event) { >+ if (ProvidedCategoryTransfer.getInstance().isSupportedType(event.dataType)) { >+ IStructuredSelection selection= (IStructuredSelection) fViewer.getSelection(); >+ if (fViewer.getSelection() != null && !fViewer.getSelection().isEmpty()) { >+ ModelElement firstElement= (ModelElement) selection.getFirstElement(); >+ if (firstElement != null) >+ event.data= new ProposalTransferType[] { new ProposalTransferType(firstElement.getId()) }; >+ } >+ } >+ } >+ >+ public void dragStart(DragSourceEvent event) { >+ if (fViewer.getSelection() == null || fViewer.getSelection().isEmpty() || ((IStructuredSelection) fViewer.getSelection()).getFirstElement() == null) { >+ event.doit= false; >+ } >+ } >+ >+ public void dragFinished(DragSourceEvent event) { >+ } >+} >Index: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/DropIntoProposalListListener.java >=================================================================== >RCS file: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/DropIntoProposalListListener.java >diff -N ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/DropIntoProposalListListener.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/DropIntoProposalListListener.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,144 @@ >+/** >+ * Copyright (c) 2011 Thomas Schlosser. >+ * 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: >+ * Thomas Schlosser <schlosser@stud.tu-darmstadt.de> - initial API and implementation. >+ */ >+package org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.dnd; >+ >+import org.eclipse.swt.dnd.DND; >+import org.eclipse.swt.dnd.DropTargetEvent; >+import org.eclipse.swt.dnd.TransferData; >+ >+import org.eclipse.jface.viewers.ViewerDropAdapter; >+ >+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.CodeAssistAdvancedUtilitiesProxy; >+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.model.PreferenceModel; >+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.widgets.ProposalList; >+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.widgets.ProposalListSection; >+ >+/** >+ * >+ * @since 3.8 >+ */ >+public final class DropIntoProposalListListener extends ViewerDropAdapter { >+ private final PreferenceModel fModel; >+ >+ private final CodeAssistAdvancedUtilitiesProxy fUtilitiesProxy; >+ >+ private final int fListIndex; >+ >+ private final ProposalListSection fProposalListSection; >+ >+ private final ProposalList fProposalList; >+ >+ public DropIntoProposalListListener(ProposalList proposalList, int listIndex, PreferenceModel model, CodeAssistAdvancedUtilitiesProxy utilitiesProxy, ProposalListSection proposalListSection) { >+ super(proposalList.getTableViewer()); >+ this.fListIndex= listIndex; >+ this.fProposalList= proposalList; >+ this.fModel= model; >+ this.fUtilitiesProxy= utilitiesProxy; >+ this.fProposalListSection= proposalListSection; >+ } >+ >+ @Override >+ public void dragEnter(DropTargetEvent event) { >+ event.detail= CodeAssistAdvancedUtilitiesProxy.getCompatibleOperation(event.detail, event.operations, event.currentDataType); >+ } >+ >+ @Override >+ public void drop(DropTargetEvent event) { >+ super.drop(event); >+ drop: { >+ if (event.data == null) >+ break drop; >+ ProposalTransferType data= ((ProposalTransferType[]) event.data)[0]; >+ if (data.getListIndex() == null && fModel.isValidCategoryId(data.getCategoryId())) { >+ // category dragged from provided list >+ switch (event.detail) { >+ case DND.DROP_COPY: >+ fModel.getElement(data.getCategoryId()).setInProposalList(fListIndex); >+ break; >+ default: >+ break drop; >+ } >+ fUtilitiesProxy.updateControls(); >+ return; >+ } >+ if (data.getListIndex() == null) >+ break drop; >+ int sourceListIndex= data.getListIndex().intValue(); >+ if (sourceListIndex == fListIndex) >+ break drop; >+ if (data.getCategoryId() == null) { >+ // proposal list has been dragged >+ switch (event.detail) { >+ case DND.DROP_COPY: >+ // COPY all elements from source list to this list >+ fModel.mergeLists(sourceListIndex, fListIndex, false); >+ break; >+ case DND.DROP_MOVE: >+ // MOVE all elements from source list to this list >+ fModel.mergeLists(sourceListIndex, fListIndex, true); >+ break; >+ default: >+ break drop; >+ } >+ fUtilitiesProxy.updateControls(); >+ return; >+ } >+ if (fModel.isValidCategoryId(data.getCategoryId())) { >+ // category dragged from proposal list >+ switch (event.detail) { >+ case DND.DROP_COPY: >+ fModel.getElement(data.getCategoryId()).setInProposalList(fListIndex); >+ break; >+ case DND.DROP_MOVE: >+ fModel.getElement(data.getCategoryId()).moveToProposalList(sourceListIndex, fListIndex); >+ break; >+ default: >+ break drop; >+ } >+ fUtilitiesProxy.updateControls(); >+ return; >+ } >+ } >+ event.detail= DND.DROP_NONE; >+ } >+ >+ @Override >+ public boolean performDrop(Object data) { >+ return true; // behavior completely implemented in drop-method >+ } >+ >+ @Override >+ public void dragOperationChanged(DropTargetEvent event) { >+ event.detail= CodeAssistAdvancedUtilitiesProxy.getCompatibleOperation(event.detail, event.operations, event.currentDataType); >+ if (event.detail == DND.DROP_NONE) >+ fProposalList.highlight(false); >+ } >+ >+ @Override >+ public boolean validateDrop(Object target, int operation, TransferData transferType) { >+ return ProvidedCategoryTransfer.getInstance().isSupportedType(transferType) || >+ ProposalListCategoryTransfer.getInstance().isSupportedType(transferType) || >+ ProposalListTransfer.getInstance().isSupportedType(transferType); >+ } >+ >+ @Override >+ public void dragOver(DropTargetEvent event) { >+ event.feedback= DND.FEEDBACK_NONE; >+ if (event.detail != DND.DROP_NONE) >+ fProposalList.highlight(true); >+ fProposalListSection.autoScroll(event); >+ } >+ >+ @Override >+ public void dragLeave(DropTargetEvent event) { >+ fProposalList.highlight(false); >+ } >+} >Index: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/DropIntoProvidedListener.java >=================================================================== >RCS file: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/DropIntoProvidedListener.java >diff -N ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/DropIntoProvidedListener.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/DropIntoProvidedListener.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,82 @@ >+/** >+ * Copyright (c) 2011 Thomas Schlosser. >+ * 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: >+ * Thomas Schlosser <schlosser@stud.tu-darmstadt.de> - initial API and implementation. >+ */ >+package org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.dnd; >+ >+import org.eclipse.swt.dnd.DND; >+import org.eclipse.swt.dnd.DropTargetEvent; >+import org.eclipse.swt.dnd.TransferData; >+ >+import org.eclipse.jface.viewers.TableViewer; >+import org.eclipse.jface.viewers.ViewerDropAdapter; >+ >+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.CodeAssistAdvancedUtilitiesProxy; >+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.model.PreferenceModel; >+ >+/** >+ * >+ * @since 3.8 >+ */ >+public final class DropIntoProvidedListener extends ViewerDropAdapter { >+ private final PreferenceModel fModel; >+ >+ private final CodeAssistAdvancedUtilitiesProxy fUtilitiesProxy; >+ >+ public DropIntoProvidedListener(TableViewer viewer, PreferenceModel model, CodeAssistAdvancedUtilitiesProxy utilitiesProxy) { >+ super(viewer); >+ this.fModel= model; >+ this.fUtilitiesProxy= utilitiesProxy; >+ } >+ >+ @Override >+ public boolean validateDrop(Object target, int operation, TransferData transferType) { >+ return ProposalListCategoryTransfer.getInstance().isSupportedType(transferType) || >+ ProposalListTransfer.getInstance().isSupportedType(transferType); >+ } >+ >+ @Override >+ public boolean performDrop(Object data) { >+ ProposalTransferType transferData= ((ProposalTransferType[]) data)[0]; >+ if (transferData.getListIndex() != null) { >+ int listIndex= transferData.getListIndex().intValue(); >+ if (fModel.isValidCategoryId(transferData.getCategoryId())) >+ // category dragged from proposal list >+ fModel.getElement(transferData.getCategoryId()).removeInProposalList(listIndex); >+ else if (transferData.getCategoryId() == null) >+ // proposal list has been dragged >+ fModel.removeList(listIndex); >+ fUtilitiesProxy.updateControls(); >+ return true; >+ } >+ return false; >+ } >+ >+ @Override >+ public void dragEnter(DropTargetEvent event) { >+ event.detail= this.getCompatibleOperation(event.detail, event.operations, event.currentDataType); >+ } >+ >+ @Override >+ public void dragOperationChanged(DropTargetEvent event) { >+ event.detail= this.getCompatibleOperation(event.detail, event.operations, event.currentDataType); >+ } >+ >+ @Override >+ public void dragOver(DropTargetEvent event) { >+ event.feedback= DND.FEEDBACK_NONE; >+ } >+ >+ private int getCompatibleOperation(int detail, int operations, TransferData currentDataType) { >+ int operation= CodeAssistAdvancedUtilitiesProxy.getCompatibleOperation(detail, operations, currentDataType); >+ if (operation != DND.DROP_MOVE) >+ return DND.DROP_NONE; >+ return operation; >+ } >+} >Index: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/DropNewProposalListListener.java >=================================================================== >RCS file: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/DropNewProposalListListener.java >diff -N ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/DropNewProposalListListener.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/DropNewProposalListListener.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,138 @@ >+/** >+ * Copyright (c) 2011 Thomas Schlosser. >+ * 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: >+ * Thomas Schlosser <schlosser@stud.tu-darmstadt.de> - initial API and implementation. >+ */ >+package org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.dnd; >+ >+import java.util.Arrays; >+ >+import org.eclipse.swt.dnd.DND; >+import org.eclipse.swt.dnd.DropTargetEvent; >+import org.eclipse.swt.dnd.DropTargetListener; >+import org.eclipse.swt.widgets.Composite; >+ >+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.CodeAssistAdvancedUtilitiesProxy; >+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.model.PreferenceModel; >+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.widgets.ProposalListSection; >+ >+/** >+ * >+ * @since 3.8 >+ */ >+public final class DropNewProposalListListener implements DropTargetListener { >+ >+ private final ProposalListSection fProposalListSection; >+ >+ private final Composite fHighlightComposite; >+ >+ private final int fListIndex; >+ >+ private final PreferenceModel fModel; >+ >+ private final CodeAssistAdvancedUtilitiesProxy fUtilitiesProxy; >+ >+ public DropNewProposalListListener(Composite highlightComposite, int listIndex, PreferenceModel model, CodeAssistAdvancedUtilitiesProxy utilitiesProxy, ProposalListSection proposalListSection) { >+ this.fHighlightComposite= highlightComposite; >+ this.fListIndex= listIndex; >+ this.fModel= model; >+ this.fUtilitiesProxy= utilitiesProxy; >+ this.fProposalListSection= proposalListSection; >+ } >+ >+ public void dragEnter(DropTargetEvent event) { >+ event.detail= CodeAssistAdvancedUtilitiesProxy.getCompatibleOperation(event.detail, event.operations, event.currentDataType); >+ } >+ >+ public void dragOperationChanged(DropTargetEvent event) { >+ event.detail= CodeAssistAdvancedUtilitiesProxy.getCompatibleOperation(event.detail, event.operations, event.currentDataType); >+ if (event.detail == DND.DROP_NONE) >+ highlight(false); >+ } >+ >+ public void dragOver(DropTargetEvent event) { >+ if (event.detail != DND.DROP_NONE) { >+ highlight(true); >+ } >+ fProposalListSection.autoScroll(event); >+ } >+ >+ public void dragLeave(DropTargetEvent event) { >+ highlight(false); >+ } >+ >+ private void highlight(boolean selected) { >+ if (selected) >+ fHighlightComposite.setBackground(CodeAssistAdvancedUtilitiesProxy.SELECTED_COLOR); >+ else >+ fHighlightComposite.setBackground(CodeAssistAdvancedUtilitiesProxy.UNSELECTED_COLOR); >+ fHighlightComposite.update(); >+ } >+ >+ public void drop(DropTargetEvent event) { >+ drop: { >+ if (event.data == null) >+ break drop; >+ ProposalTransferType data= ((ProposalTransferType[]) event.data)[0]; >+ if (data.getListIndex() == null && fModel.isValidCategoryId(data.getCategoryId())) { >+ // category dragged from provided list >+ switch (event.detail) { >+ case DND.DROP_COPY: >+ fModel.addNewList(fListIndex, Arrays.asList(data.getCategoryId())); >+ break; >+ default: >+ break drop; >+ } >+ fUtilitiesProxy.updateControls(); >+ return; >+ } >+ if (data.getListIndex() == null) >+ break drop; >+ int sourceListIndex= data.getListIndex().intValue(); >+ if (data.getCategoryId() == null) { >+ // proposal list has been dragged >+ switch (event.detail) { >+ case DND.DROP_COPY: >+ fModel.addNewList(fListIndex, fModel.getCategoryIds(sourceListIndex)); >+ break; >+ case DND.DROP_MOVE: >+ if (sourceListIndex != fListIndex && sourceListIndex + 1 != fListIndex) >+ fModel.moveList(sourceListIndex, fListIndex); >+ else >+ break drop; >+ break; >+ default: >+ break drop; >+ } >+ fUtilitiesProxy.updateControls(); >+ return; >+ } >+ if (fModel.isValidCategoryId(data.getCategoryId())) { >+ // category dragged from proposal list >+ switch (event.detail) { >+ case DND.DROP_MOVE: >+ fModel.addNewList(fListIndex, Arrays.asList(data.getCategoryId())); >+ int removeIndex= fListIndex > sourceListIndex ? sourceListIndex : sourceListIndex + 1; >+ fModel.getElement(data.getCategoryId()).removeInProposalList(removeIndex); >+ break; >+ case DND.DROP_COPY: >+ fModel.addNewList(fListIndex, Arrays.asList(data.getCategoryId())); >+ break; >+ default: >+ break drop; >+ } >+ fUtilitiesProxy.updateControls(); >+ return; >+ } >+ } >+ event.detail= DND.DROP_NONE; >+ } >+ >+ public void dropAccept(DropTargetEvent event) { >+ } >+} >Index: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/ProposalListCategoryTransfer.java >=================================================================== >RCS file: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/ProposalListCategoryTransfer.java >diff -N ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/ProposalListCategoryTransfer.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/ProposalListCategoryTransfer.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,45 @@ >+/** >+ * Copyright (c) 2011 Thomas Schlosser. >+ * 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: >+ * Thomas Schlosser <schlosser@stud.tu-darmstadt.de> - initial API and implementation. >+ */ >+package org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.dnd; >+ >+import org.eclipse.swt.dnd.DND; >+ >+/** >+ * >+ * @since 3.8 >+ */ >+public final class ProposalListCategoryTransfer extends ProposalTransfer { >+ private static final String TRANSFER_NAME= "ProposalListCategoryTransfer"; //$NON-NLS-1$ >+ >+ private static final ProposalListCategoryTransfer instance= new ProposalListCategoryTransfer(); >+ >+ private ProposalListCategoryTransfer() { >+ super(TRANSFER_NAME); >+ } >+ >+ public static ProposalListCategoryTransfer getInstance() { >+ return instance; >+ } >+ >+ @Override >+ public int getDefaultOperation(int supportedOperations) { >+ if ((supportedOperations & DND.DROP_MOVE) != 0) >+ return DND.DROP_MOVE; >+ else if ((supportedOperations & DND.DROP_COPY) != 0) >+ return DND.DROP_COPY; >+ return DND.DROP_NONE; >+ } >+ >+ @Override >+ public boolean isSupportedOperation(int operation) { >+ return operation == DND.DROP_COPY || operation == DND.DROP_MOVE; >+ } >+} >Index: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/ProposalListTransfer.java >=================================================================== >RCS file: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/ProposalListTransfer.java >diff -N ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/ProposalListTransfer.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/ProposalListTransfer.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,45 @@ >+/** >+ * Copyright (c) 2011 Thomas Schlosser. >+ * 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: >+ * Thomas Schlosser <schlosser@stud.tu-darmstadt.de> - initial API and implementation. >+ */ >+package org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.dnd; >+ >+import org.eclipse.swt.dnd.DND; >+ >+/** >+ * >+ * @since 3.8 >+ */ >+public final class ProposalListTransfer extends ProposalTransfer { >+ private static final String TRANSFER_NAME= "ProposalListTransfer"; //$NON-NLS-1$ >+ >+ private static final ProposalListTransfer instance= new ProposalListTransfer(); >+ >+ private ProposalListTransfer() { >+ super(TRANSFER_NAME); >+ } >+ >+ public static ProposalListTransfer getInstance() { >+ return instance; >+ } >+ >+ @Override >+ public int getDefaultOperation(int supportedOperations) { >+ if ((supportedOperations & DND.DROP_MOVE) != 0) >+ return DND.DROP_MOVE; >+ else if ((supportedOperations & DND.DROP_COPY) != 0) >+ return DND.DROP_COPY; >+ return DND.DROP_NONE; >+ } >+ >+ @Override >+ public boolean isSupportedOperation(int operation) { >+ return operation == DND.DROP_COPY || operation == DND.DROP_MOVE; >+ } >+} >Index: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/ProposalTransfer.java >=================================================================== >RCS file: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/ProposalTransfer.java >diff -N ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/ProposalTransfer.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/ProposalTransfer.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,148 @@ >+/** >+ * Copyright (c) 2011 Thomas Schlosser. >+ * 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: >+ * Thomas Schlosser <schlosser@stud.tu-darmstadt.de> - initial API and implementation. >+ */ >+package org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.dnd; >+ >+import java.io.ByteArrayInputStream; >+import java.io.ByteArrayOutputStream; >+import java.io.DataInputStream; >+import java.io.DataOutputStream; >+import java.io.IOException; >+import java.util.ArrayList; >+import java.util.List; >+ >+import org.eclipse.swt.dnd.ByteArrayTransfer; >+import org.eclipse.swt.dnd.DND; >+import org.eclipse.swt.dnd.TransferData; >+ >+/** >+ * >+ * @since 3.8 >+ */ >+public abstract class ProposalTransfer extends ByteArrayTransfer { >+ public static final int ALL_DRAG_OPERATIONS= DND.DROP_COPY | DND.DROP_DEFAULT | DND.DROP_LINK | DND.DROP_MOVE | DND.DROP_TARGET_MOVE; >+ >+ private final String fTransferName; >+ >+ private final int fTransferId; >+ >+ protected ProposalTransfer(String transferName) { >+ this.fTransferName= transferName; >+ this.fTransferId= registerType(transferName); >+ } >+ >+ public abstract int getDefaultOperation(int supportedOperations); >+ >+ public abstract boolean isSupportedOperation(int operation); >+ >+ @Override >+ public void javaToNative(Object object, TransferData transferData) { >+ if (!checkProposalTransferType(object) || !isSupportedType(transferData)) >+ DND.error(DND.ERROR_INVALID_DATA); >+ ProposalTransferType[] props= (ProposalTransferType[]) object; >+ ByteArrayOutputStream out= new ByteArrayOutputStream(); >+ DataOutputStream writeOut= new DataOutputStream(out); >+ try { >+ for (int i= 0, length= props.length; i < length; i++) { >+ if (props[i].getCategoryId() != null) { >+ byte[] buffer= props[i].getCategoryId().getBytes(); >+ writeOut.writeInt(buffer.length); >+ writeOut.write(buffer); >+ } else >+ writeOut.writeInt(0); >+ Integer index= props[i].getListIndex(); >+ writeOut.writeInt(index == null ? -1 : index.intValue()); >+ } >+ byte[] buffer= out.toByteArray(); >+ super.javaToNative(buffer, transferData); >+ } catch (IOException e) { >+ } finally { >+ try { >+ writeOut.close(); >+ } catch (IOException e) { >+ } >+ } >+ } >+ >+ @Override >+ public Object nativeToJava(TransferData transferData) { >+ if (isSupportedType(transferData)) { >+ byte[] buffer= (byte[]) super.nativeToJava(transferData); >+ if (buffer == null) >+ return null; >+ >+ List<ProposalTransferType> props= new ArrayList<ProposalTransferType>(); >+ ByteArrayInputStream in= new ByteArrayInputStream(buffer); >+ DataInputStream readIn= new DataInputStream(in); >+ try { >+ while (readIn.available() > 0) { >+ ProposalTransferType proposal= new ProposalTransferType(); >+ int size= readIn.readInt(); >+ if (size == 0) >+ proposal.setCategoryId(null); >+ else { >+ byte[] id= new byte[size]; >+ readIn.read(id); >+ proposal.setCategoryId(new String(id)); >+ } >+ int index= readIn.readInt(); >+ proposal.setListIndex(index < 0 ? null : Integer.valueOf(index)); >+ props.add(proposal); >+ } >+ } catch (IOException ex) { >+ return null; >+ } finally { >+ try { >+ readIn.close(); >+ } catch (IOException e) { >+ return null; >+ } >+ } >+ return props.toArray(new ProposalTransferType[0]); >+ } >+ return null; >+ } >+ >+ @Override >+ protected int[] getTypeIds() { >+ return new int[] { fTransferId }; >+ } >+ >+ @Override >+ protected String[] getTypeNames() { >+ return new String[] { fTransferName }; >+ } >+ >+ @Override >+ protected boolean validate(Object object) { >+ return checkProposalTransferType(object); >+ } >+ >+ public int getCompatibleOperation(int operation, int supportedOperations, TransferData currentDataType) { >+ if (this.isSupportedType(currentDataType)) { >+ if (operation == DND.DROP_DEFAULT) >+ return this.getDefaultOperation(supportedOperations); >+ if (this.isSupportedOperation(operation) && (supportedOperations & operation) != 0) >+ return operation; >+ return DND.DROP_NONE; >+ } >+ return -1; >+ } >+ >+ private boolean checkProposalTransferType(Object object) { >+ if (object == null || !(object instanceof ProposalTransferType[]) || ((ProposalTransferType[]) object).length == 0) >+ return false; >+ ProposalTransferType[] cats= (ProposalTransferType[]) object; >+ for (ProposalTransferType category : cats) >+ if (category == null || ((category.getCategoryId() == null || category.getCategoryId().length() == 0) && category.getListIndex() == null)) >+ return false; >+ return true; >+ } >+} >Index: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/ProposalTransferType.java >=================================================================== >RCS file: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/ProposalTransferType.java >diff -N ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/ProposalTransferType.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/ProposalTransferType.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,53 @@ >+/** >+ * Copyright (c) 2011 Thomas Schlosser. >+ * 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: >+ * Thomas Schlosser <schlosser@stud.tu-darmstadt.de> - initial API and implementation. >+ */ >+package org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.dnd; >+ >+/** >+ * >+ * @since 3.8 >+ */ >+public final class ProposalTransferType { >+ private Integer fListIndex; >+ >+ private String fCategoryId; >+ >+ public ProposalTransferType() { >+ } >+ >+ public ProposalTransferType(String categoryId) { >+ this.fCategoryId= categoryId; >+ } >+ >+ public ProposalTransferType(Integer listIndex) { >+ this.fListIndex= listIndex; >+ } >+ >+ public ProposalTransferType(String categoryId, Integer listIndex) { >+ this.fCategoryId= categoryId; >+ this.fListIndex= listIndex; >+ } >+ >+ public Integer getListIndex() { >+ return fListIndex; >+ } >+ >+ public void setListIndex(Integer listIndex) { >+ fListIndex= listIndex; >+ } >+ >+ public String getCategoryId() { >+ return fCategoryId; >+ } >+ >+ public void setCategoryId(String categoryId) { >+ fCategoryId= categoryId; >+ } >+} >Index: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/ProvidedCategoryTransfer.java >=================================================================== >RCS file: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/ProvidedCategoryTransfer.java >diff -N ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/ProvidedCategoryTransfer.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/ProvidedCategoryTransfer.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,43 @@ >+/** >+ * Copyright (c) 2011 Thomas Schlosser. >+ * 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: >+ * Thomas Schlosser <schlosser@stud.tu-darmstadt.de> - initial API and implementation. >+ */ >+package org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.dnd; >+ >+import org.eclipse.swt.dnd.DND; >+ >+/** >+ * >+ * @since 3.8 >+ */ >+public final class ProvidedCategoryTransfer extends ProposalTransfer { >+ private static final String TRANSFER_NAME= "ProvidedCategoryTransfer"; //$NON-NLS-1$ >+ >+ private static final ProvidedCategoryTransfer instance= new ProvidedCategoryTransfer(); >+ >+ private ProvidedCategoryTransfer() { >+ super(TRANSFER_NAME); >+ } >+ >+ public static ProvidedCategoryTransfer getInstance() { >+ return instance; >+ } >+ >+ @Override >+ public int getDefaultOperation(int supportedOperations) { >+ if ((supportedOperations & DND.DROP_COPY) != 0) >+ return DND.DROP_COPY; >+ return DND.DROP_NONE; >+ } >+ >+ @Override >+ public boolean isSupportedOperation(int operation) { >+ return operation == DND.DROP_COPY; >+ } >+} >Index: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/model/ModelElement.java >=================================================================== >RCS file: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/model/ModelElement.java >diff -N ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/model/ModelElement.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/model/ModelElement.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,128 @@ >+/** >+ * Copyright (c) 2011 Thomas Schlosser. >+ * 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: >+ * Thomas Schlosser <schlosser@stud.tu-darmstadt.de> - initial API and implementation. >+ */ >+package org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.model; >+ >+import java.util.Comparator; >+import java.util.Set; >+ >+import org.eclipse.swt.graphics.Image; >+ >+import org.eclipse.core.commands.Command; >+import org.eclipse.core.commands.IParameter; >+import org.eclipse.core.commands.Parameterization; >+import org.eclipse.core.commands.ParameterizedCommand; >+import org.eclipse.core.commands.common.NotDefinedException; >+ >+import org.eclipse.core.runtime.Assert; >+ >+import org.eclipse.jface.viewers.Viewer; >+import org.eclipse.jface.viewers.ViewerComparator; >+ >+import org.eclipse.ui.PlatformUI; >+import org.eclipse.ui.commands.ICommandService; >+ >+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.CodeAssistAdvancedUtilitiesProxy; >+import org.eclipse.jdt.internal.ui.text.java.CompletionProposalCategory; >+ >+/** >+ * >+ * @since 3.8 >+ */ >+public final class ModelElement { >+ >+ public static final class ModelElementComparator implements Comparator<ModelElement> { >+ public int compare(ModelElement o1, ModelElement o2) { >+ return o1.getName().compareTo(o2.getName()); >+ } >+ } >+ >+ public static final class ModelElementViewerComparator extends ViewerComparator { >+ @Override >+ public int compare(Viewer viewer, Object e1, Object e2) { >+ ModelElement m1= (ModelElement) e1; >+ ModelElement m2= (ModelElement) e2; >+ return new ModelElementComparator().compare(m1, m2); >+ } >+ } >+ >+ private final CodeAssistAdvancedUtilitiesProxy fUtilitiesProxy; >+ >+ private final CompletionProposalCategory fCategory; >+ >+ private final Command fCommand; >+ >+ private final IParameter fParam; >+ >+ private final PreferenceModel fPreferenceModel; >+ >+ ModelElement(CompletionProposalCategory category, PreferenceModel model, CodeAssistAdvancedUtilitiesProxy utilitiesProxy) { >+ fCategory= category; >+ ICommandService commandSvc= (ICommandService) PlatformUI.getWorkbench().getAdapter(ICommandService.class); >+ fCommand= commandSvc.getCommand("org.eclipse.jdt.ui.specific_content_assist.command"); //$NON-NLS-1$ >+ IParameter type; >+ try { >+ type= fCommand.getParameters()[0]; >+ } catch (NotDefinedException x) { >+ Assert.isTrue(false); >+ type= null; >+ } >+ fParam= type; >+ fPreferenceModel= model; >+ fUtilitiesProxy= utilitiesProxy; >+ } >+ >+ public Image getImage() { >+ return fUtilitiesProxy.getImage(fCategory.getImageDescriptor()); >+ } >+ >+ public String getName() { >+ return fCategory.getDisplayName(); >+ } >+ >+ public String getKeybindingAsString() { >+ final Parameterization[] params= { new Parameterization(fParam, fCategory.getId()) }; >+ final ParameterizedCommand pCmd= new ParameterizedCommand(fCommand, params); >+ String key= fUtilitiesProxy.getKeyboardShortcut(pCmd); >+ return key; >+ } >+ >+ public Set<Integer> getProposalListIndices() { >+ return fCategory.getProposalListIndices(); >+ } >+ >+ public boolean isInProposalList(int index) { >+ return getProposalListIndices().contains(Integer.valueOf(index)); >+ } >+ >+ public void setInProposalList(int index) { >+ if (!isInProposalList(index)) >+ fPreferenceModel.changeSingleCategory(this, Integer.valueOf(index), null); >+ } >+ >+ public void moveToProposalList(int sourceIndex, int targetIndex) { >+ if (!isInProposalList(targetIndex) || isInProposalList(sourceIndex)) >+ fPreferenceModel.changeSingleCategory(this, Integer.valueOf(targetIndex), Integer.valueOf(sourceIndex)); >+ } >+ >+ public void removeInProposalList(int index) { >+ if (isInProposalList(index)) >+ fPreferenceModel.changeSingleCategory(this, null, Integer.valueOf(index)); >+ } >+ >+ public String getId() { >+ return fCategory.getId(); >+ } >+ >+ void updateIndices(Set<Integer> indices) { >+ fCategory.clearProposalListIndices(); >+ fCategory.addAllProposalListIndices(indices); >+ } >+} >Index: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/model/PreferenceModel.java >=================================================================== >RCS file: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/model/PreferenceModel.java >diff -N ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/model/PreferenceModel.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/model/PreferenceModel.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,235 @@ >+/** >+ * Copyright (c) 2011 Thomas Schlosser. >+ * 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: >+ * Thomas Schlosser <schlosser@stud.tu-darmstadt.de> - initial API and implementation. >+ */ >+package org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.model; >+ >+import java.util.ArrayList; >+import java.util.Collections; >+import java.util.HashMap; >+import java.util.HashSet; >+import java.util.List; >+import java.util.Map; >+import java.util.Set; >+import java.util.StringTokenizer; >+import java.util.TreeMap; >+ >+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.CodeAssistAdvancedUtilitiesProxy; >+import org.eclipse.jdt.internal.ui.text.java.CompletionProposalCategory; >+import org.eclipse.jdt.internal.ui.text.java.CompletionProposalComputerRegistry; >+ >+/** >+ * >+ * @since 3.8 >+ */ >+public final class PreferenceModel { >+ private static final String COLON= ":"; //$NON-NLS-1$ >+ >+ private static final String SEPARATOR= "\0"; //$NON-NLS-1$ >+ >+ private final CodeAssistAdvancedUtilitiesProxy fUtilitiesProxy; >+ >+ private final List<ModelElement> fElements; >+ >+ /** >+ * The read-only list of elements. >+ */ >+ public final List<ModelElement> elements; >+ >+ public PreferenceModel(CompletionProposalComputerRegistry registry, CodeAssistAdvancedUtilitiesProxy utilitiesProxy) { >+ fUtilitiesProxy= utilitiesProxy; >+ List<CompletionProposalCategory> categories= registry.getProposalCategories(); >+ fElements= new ArrayList<ModelElement>(); >+ for (CompletionProposalCategory category : categories) >+ if (category.hasComputers()) >+ fElements.add(new ModelElement(category, this, fUtilitiesProxy)); >+ elements= Collections.unmodifiableList(fElements); >+ } >+ >+ public void changeSingleCategory(ModelElement changed, Integer addIndex, Integer removeIndex) { >+ int initialBufferSize= 50 * fElements.size(); >+ Map<Integer, StringBuffer> proposalListsCategories= new TreeMap<Integer, StringBuffer>(); >+ for (ModelElement item : fElements) { >+ Set<Integer> indices= new HashSet<Integer>(item.getProposalListIndices()); >+ if (changed == item) { >+ if (addIndex != null) >+ indices.add(addIndex); >+ if (removeIndex != null) >+ indices.remove(removeIndex); >+ } >+ for (Integer index : indices) { >+ StringBuffer buf= proposalListsCategories.get(index); >+ if (buf == null) { >+ buf= new StringBuffer(initialBufferSize); >+ proposalListsCategories.put(index, buf); >+ } >+ buf.append(item.getId()); >+ buf.append(COLON); >+ } >+ } >+ writeProposalListsPreferences(proposalListsCategories, initialBufferSize); >+ } >+ >+ public void removeList(int listIndex) { >+ int initialBufferSize= 50 * fElements.size(); >+ Map<Integer, StringBuffer> proposalListsCategories= new TreeMap<Integer, StringBuffer>(); >+ for (ModelElement item : fElements) { >+ for (int index : item.getProposalListIndices()) { >+ if (listIndex == index) >+ continue; >+ else if (index > listIndex) >+ index--; >+ StringBuffer buf= proposalListsCategories.get(Integer.valueOf(index)); >+ if (buf == null) { >+ buf= new StringBuffer(initialBufferSize); >+ proposalListsCategories.put(Integer.valueOf(index), buf); >+ } >+ buf.append(item.getId()); >+ buf.append(COLON); >+ } >+ } >+ writeProposalListsPreferences(proposalListsCategories, initialBufferSize); >+ } >+ >+ public void addNewList(int listIndex, List<String> categoryIds) { >+ int initialBufferSize= 50 * fElements.size(); >+ Map<Integer, StringBuffer> proposalListsCategories= new TreeMap<Integer, StringBuffer>(); >+ for (ModelElement item : fElements) { >+ for (int index : item.getProposalListIndices()) { >+ if (index >= listIndex) >+ index++; >+ StringBuffer buf= proposalListsCategories.get(Integer.valueOf(index)); >+ if (buf == null) { >+ buf= new StringBuffer(initialBufferSize); >+ proposalListsCategories.put(Integer.valueOf(index), buf); >+ } >+ buf.append(item.getId()); >+ buf.append(COLON); >+ } >+ } >+ if (categoryIds != null && !categoryIds.isEmpty()) { >+ // add categories to new list >+ StringBuffer newListBuf= new StringBuffer(initialBufferSize); >+ proposalListsCategories.put(Integer.valueOf(listIndex), newListBuf); >+ for (String catId : categoryIds) { >+ newListBuf.append(catId); >+ newListBuf.append(COLON); >+ } >+ } >+ writeProposalListsPreferences(proposalListsCategories, initialBufferSize); >+ } >+ >+ public void moveList(int listIndex, int targetIndex) { >+ int initialBufferSize= 50 * fElements.size(); >+ Map<Integer, StringBuffer> proposalListsCategories= new TreeMap<Integer, StringBuffer>(); >+ for (ModelElement item : fElements) { >+ for (int index : item.getProposalListIndices()) { >+ if (index > listIndex && index < targetIndex) >+ index--; >+ else if (index >= targetIndex && index < listIndex) >+ index++; >+ else if (index == listIndex) >+ index= listIndex < targetIndex ? targetIndex - 1 : targetIndex; >+ StringBuffer buf= proposalListsCategories.get(Integer.valueOf(index)); >+ if (buf == null) { >+ buf= new StringBuffer(initialBufferSize); >+ proposalListsCategories.put(Integer.valueOf(index), buf); >+ } >+ buf.append(item.getId()); >+ buf.append(COLON); >+ } >+ } >+ writeProposalListsPreferences(proposalListsCategories, initialBufferSize); >+ } >+ >+ public void mergeLists(int sourceIndex, int targetIndex, boolean removeSource) { >+ int initialBufferSize= 50 * fElements.size(); >+ Map<Integer, StringBuffer> proposalListsCategories= new TreeMap<Integer, StringBuffer>(); >+ for (ModelElement item : fElements) { >+ Set<Integer> indices= new HashSet<Integer>(item.getProposalListIndices()); >+ if (indices.contains(Integer.valueOf(sourceIndex))) { >+ if (removeSource) >+ indices.remove(Integer.valueOf(sourceIndex)); >+ indices.add(Integer.valueOf(targetIndex)); >+ } >+ for (Integer index : indices) { >+ StringBuffer buf= proposalListsCategories.get(index); >+ if (buf == null) { >+ buf= new StringBuffer(initialBufferSize); >+ proposalListsCategories.put(index, buf); >+ } >+ buf.append(item.getId()); >+ buf.append(COLON); >+ } >+ } >+ writeProposalListsPreferences(proposalListsCategories, initialBufferSize); >+ } >+ >+ private void writeProposalListsPreferences(Map<Integer, StringBuffer> proposalListsCategories, int initialBufferSize) { >+ StringBuffer buf= new StringBuffer(initialBufferSize * proposalListsCategories.size()); >+ for (StringBuffer proposalList : proposalListsCategories.values()) { >+ buf.append(proposalList); >+ buf.append(SEPARATOR); >+ } >+ String newValue= buf.toString(); >+ String oldValue= fUtilitiesProxy.setValue(newValue); >+ fUtilitiesProxy.validateSettings(oldValue, newValue); >+ updatePreferenceModel(); >+ } >+ >+ public void updatePreferenceModel() { >+ Map<String, Set<Integer>> newConfig= new HashMap<String, Set<Integer>>(); >+ StringTokenizer tok= new StringTokenizer(fUtilitiesProxy.getValue(), SEPARATOR); >+ for (int listIndex= 0; tok.hasMoreTokens(); listIndex++) { >+ StringTokenizer inner= new StringTokenizer(tok.nextToken(), COLON); >+ if (inner.countTokens() == 0) >+ listIndex--; >+ while (inner.hasMoreTokens()) { >+ String categoryId= inner.nextToken(); >+ Set<Integer> indices= newConfig.get(categoryId); >+ if (indices == null) { >+ indices= new HashSet<Integer>(); >+ newConfig.put(categoryId, indices); >+ } >+ indices.add(Integer.valueOf(listIndex)); >+ } >+ } >+ for (ModelElement elem : fElements) >+ elem.updateIndices(newConfig.get(elem.getId())); >+ } >+ >+ public ModelElement getElement(String id) { >+ for (ModelElement el : fElements) >+ if (el.getId().equals(id)) >+ return el; >+ return null; >+ } >+ >+ public List<ModelElement> getElements(int index) { >+ List<ModelElement> result= new ArrayList<ModelElement>(); >+ for (ModelElement el : fElements) >+ if (el.getProposalListIndices() != null && el.getProposalListIndices().contains(Integer.valueOf(index))) >+ result.add(el); >+ return result; >+ } >+ >+ public List<String> getCategoryIds(int index) { >+ List<String> result= new ArrayList<String>(); >+ for (ModelElement el : fElements) >+ if (el.getProposalListIndices() != null && el.getProposalListIndices().contains(Integer.valueOf(index))) >+ result.add(el.getId()); >+ return result; >+ } >+ >+ public boolean isValidCategoryId(String id) { >+ if (id != null) >+ return getElement(id) != null; >+ return false; >+ } >+} >Index: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/widgets/NewListDropSection.java >=================================================================== >RCS file: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/widgets/NewListDropSection.java >diff -N ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/widgets/NewListDropSection.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/widgets/NewListDropSection.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,93 @@ >+/** >+ * Copyright (c) 2011 Thomas Schlosser. >+ * 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: >+ * Thomas Schlosser <schlosser@stud.tu-darmstadt.de> - initial API and implementation. >+ */ >+package org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.widgets; >+ >+import org.eclipse.swt.SWT; >+import org.eclipse.swt.dnd.DropTarget; >+import org.eclipse.swt.dnd.Transfer; >+import org.eclipse.swt.layout.GridData; >+import org.eclipse.swt.layout.GridLayout; >+import org.eclipse.swt.widgets.Composite; >+ >+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.CodeAssistAdvancedUtilitiesProxy; >+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.dnd.DropNewProposalListListener; >+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.dnd.ProposalListCategoryTransfer; >+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.dnd.ProposalListTransfer; >+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.dnd.ProposalTransfer; >+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.dnd.ProvidedCategoryTransfer; >+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.model.PreferenceModel; >+ >+/** >+ * >+ * @since 3.8 >+ */ >+public final class NewListDropSection { >+ private final PreferenceModel fModel; >+ >+ private final CodeAssistAdvancedUtilitiesProxy fUtilitiesProxy; >+ >+ private final ProposalListSection fProposalListSection; >+ >+ private final Composite fPaddingComposite; >+ >+ private final Composite fHighlightComposite; >+ >+ public NewListDropSection(Composite wrappingComposite, int listIndex, PreferenceModel model, ProposalListSection proposalListSection, CodeAssistAdvancedUtilitiesProxy utilitiesProxy) { >+ this.fModel= model; >+ this.fUtilitiesProxy= utilitiesProxy; >+ this.fProposalListSection= proposalListSection; >+ >+ fPaddingComposite= createPaddingComposite(wrappingComposite); >+ fHighlightComposite= createHighlightComposite(fPaddingComposite); >+ >+ addDropSupport(fPaddingComposite, fHighlightComposite, listIndex); >+ } >+ >+ public void activateLastPositionSpaceBehavior(boolean last) { >+ GridData gd= new GridData(GridData.FILL, GridData.FILL, true, last); >+ gd.heightHint= 10; >+ fPaddingComposite.setLayoutData(gd); >+ } >+ >+ public void dispose() { >+ fPaddingComposite.dispose(); >+ fHighlightComposite.dispose(); >+ } >+ >+ private Composite createPaddingComposite(Composite wrappingComposite) { >+ Composite paddingComposite= new Composite(wrappingComposite, SWT.NONE); >+ GridData gd= new GridData(GridData.FILL, GridData.BEGINNING, true, false); >+ gd.heightHint= 10; >+ paddingComposite.setLayoutData(gd); >+ GridLayout layout= new GridLayout(); >+ layout.marginHeight= 0; >+ layout.verticalSpacing= 0; >+ layout.marginWidth= 0; >+ paddingComposite.setLayout(layout); >+ return paddingComposite; >+ } >+ >+ private Composite createHighlightComposite(Composite paddingComposite) { >+ Composite highlightComposite= new Composite(paddingComposite, SWT.NONE); >+ GridData gd= new GridData(SWT.FILL, SWT.BEGINNING, true, true); >+ gd.heightHint= 2; >+ gd.verticalIndent= 4; >+ highlightComposite.setLayoutData(gd); >+ return highlightComposite; >+ } >+ >+ private void addDropSupport(Composite paddingComposite, Composite highlightComposite, int listIndex) { >+ Transfer[] transferTypes= new Transfer[] { ProvidedCategoryTransfer.getInstance(), ProposalListCategoryTransfer.getInstance(), ProposalListTransfer.getInstance() }; >+ DropTarget dropTarget= new DropTarget(paddingComposite, ProposalTransfer.ALL_DRAG_OPERATIONS); >+ dropTarget.setTransfer(transferTypes); >+ dropTarget.addDropListener(new DropNewProposalListListener(highlightComposite, listIndex, fModel, fUtilitiesProxy, fProposalListSection)); >+ } >+} >Index: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/widgets/ProposalList.java >=================================================================== >RCS file: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/widgets/ProposalList.java >diff -N ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/widgets/ProposalList.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/widgets/ProposalList.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,421 @@ >+/** >+ * Copyright (c) 2011 Thomas Schlosser. >+ * 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: >+ * Thomas Schlosser <schlosser@stud.tu-darmstadt.de> - initial API and implementation. >+ */ >+package org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.widgets; >+ >+import java.util.ArrayList; >+import java.util.Collections; >+import java.util.List; >+ >+import org.eclipse.swt.SWT; >+import org.eclipse.swt.dnd.DropTarget; >+import org.eclipse.swt.dnd.Transfer; >+import org.eclipse.swt.events.MouseEvent; >+import org.eclipse.swt.events.MouseListener; >+import org.eclipse.swt.events.PaintEvent; >+import org.eclipse.swt.events.PaintListener; >+import org.eclipse.swt.graphics.GC; >+import org.eclipse.swt.graphics.Image; >+import org.eclipse.swt.graphics.ImageData; >+import org.eclipse.swt.graphics.Point; >+import org.eclipse.swt.graphics.Rectangle; >+import org.eclipse.swt.layout.GridData; >+import org.eclipse.swt.layout.GridLayout; >+import org.eclipse.swt.widgets.Composite; >+import org.eclipse.swt.widgets.Event; >+import org.eclipse.swt.widgets.Listener; >+import org.eclipse.swt.widgets.Table; >+import org.eclipse.swt.widgets.TableColumn; >+import org.eclipse.swt.widgets.TableItem; >+ >+import org.eclipse.core.runtime.Assert; >+ >+import org.eclipse.jface.viewers.IStructuredContentProvider; >+import org.eclipse.jface.viewers.ITableLabelProvider; >+import org.eclipse.jface.viewers.LabelProvider; >+import org.eclipse.jface.viewers.TableViewer; >+import org.eclipse.jface.viewers.Viewer; >+ >+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.CodeAssistAdvancedUtilitiesProxy; >+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.dnd.DragProposalListCategoryListener; >+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.dnd.DropIntoProposalListListener; >+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.dnd.ProposalListCategoryTransfer; >+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.dnd.ProposalListTransfer; >+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.dnd.ProposalTransfer; >+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.dnd.ProvidedCategoryTransfer; >+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.model.ModelElement; >+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.model.PreferenceModel; >+ >+/** >+ * >+ * @since 3.8 >+ */ >+public final class ProposalList { >+ >+ private final class ProposalListTableLabelProvider 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 class ProposalListContentProvider implements IStructuredContentProvider { >+ private final int fListIndex; >+ >+ public ProposalListContentProvider(int listIndex) { >+ this.fListIndex= listIndex; >+ } >+ >+ public void dispose() { >+ } >+ >+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { >+ } >+ >+ public Object[] getElements(Object inputElement) { >+ return fModel.getElements(fListIndex).toArray(); >+ } >+ } >+ >+ private final PreferenceModel fModel; >+ >+ private final CodeAssistAdvancedUtilitiesProxy fUtilitiesProxy; >+ >+ private final ProposalListSection fProposalListSection; >+ >+ private final Composite fTableContainer; >+ >+ private final ProposalListHeader fHeader; >+ >+ private final TableViewer fTableViewer; >+ >+ private final NewListDropSection fNewListDropSection; >+ >+ private boolean fSelected; >+ >+ public ProposalList(Composite parent, int listIndex, ProposalListSection proposalListSection, PreferenceModel model, CodeAssistAdvancedUtilitiesProxy utilitiesProxy) { >+ this.fModel= model; >+ this.fUtilitiesProxy= utilitiesProxy; >+ this.fProposalListSection= proposalListSection; >+ >+ fTableContainer= createTableContainer(parent); >+ fHeader= new ProposalListHeader(fTableContainer, listIndex, fModel, fUtilitiesProxy); >+ fTableViewer= createTable(fTableContainer, listIndex); >+ >+ fNewListDropSection= new NewListDropSection(parent, listIndex + 1, fModel, fProposalListSection, fUtilitiesProxy); >+ >+ addDropSupport(fTableContainer, listIndex); >+ addRemoveIconVisibility(); >+ addBorderPainter(fTableContainer); >+ } >+ >+ @SuppressWarnings("unchecked") >+ public List<ModelElement> getContent() { >+ Object obj= fTableViewer.getInput(); >+ if (obj == null) >+ return null; >+ return (List<ModelElement>) obj; >+ } >+ >+ public void clearContent() { >+ fTableViewer.setInput(null); >+ } >+ >+ public void addContent(ModelElement element) { >+ List<ModelElement> content= getContent(); >+ if (content == null) >+ content= new ArrayList<ModelElement>(); >+ content.add(element); >+ setContent(content); >+ } >+ >+ public void setContent(List<ModelElement> elements) { >+ fTableViewer.setInput(elements); >+ } >+ >+ public void activateLastListSpaceBehavior(boolean last) { >+ fNewListDropSection.activateLastPositionSpaceBehavior(last); >+ } >+ >+ public void dispose() { >+ fTableContainer.dispose(); >+ fHeader.dispose(); >+ fTableViewer.getTable().dispose(); >+ fNewListDropSection.dispose(); >+ } >+ >+ public void highlight(boolean highlight) { >+ if (fSelected == highlight) >+ return; >+ fSelected= highlight; >+ fTableContainer.redraw(); >+ >+ fHeader.highlight(highlight); >+ } >+ >+ private Composite createTableContainer(Composite parent) { >+ Composite tableContainer= new Composite(parent, SWT.NONE); >+ tableContainer.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); >+ GridLayout layout= new GridLayout(); >+ layout.marginHeight= 1; >+ layout.marginWidth= 1; >+ layout.verticalSpacing= 0; >+ layout.horizontalSpacing= 0; >+ tableContainer.setLayout(layout); >+ return tableContainer; >+ } >+ >+ private TableViewer createTable(Composite tableContainer, final int listIndex) { >+ TableViewer tableViewer= createInitialTableViewer(tableContainer); >+ TableColumn nameColumn= addFirstColumn(tableViewer); >+ >+ ITableLabelProvider labelProvider= setProviderAndComparator(tableViewer, listIndex); >+ adjustFirstColumnWidth(nameColumn, tableViewer, labelProvider); >+ >+ addDragSupport(tableViewer, listIndex); >+ addFocusOutListener(tableViewer); >+ addProposalListCategoryRemoveIconCreator(tableViewer, listIndex); >+ >+ return tableViewer; >+ } >+ >+ private void addDropSupport(Composite tableContainer, int listIndex) { >+ Transfer[] transferTypes= new Transfer[] { ProvidedCategoryTransfer.getInstance(), ProposalListCategoryTransfer.getInstance(), ProposalListTransfer.getInstance() }; >+ DropTarget dropTarget= new DropTarget(tableContainer, ProposalTransfer.ALL_DRAG_OPERATIONS); >+ dropTarget.setTransfer(transferTypes); >+ dropTarget.addDropListener(new DropIntoProposalListListener(this, listIndex, fModel, fUtilitiesProxy, fProposalListSection)); >+ } >+ >+ private void addRemoveIconVisibility() { >+ Listener l= new Listener() { >+ public void handleEvent(Event e) { >+ fHeader.showRemoveIcon(); >+ } >+ }; >+ this.addListener(SWT.MouseEnter, l); >+ this.addListener(SWT.MouseMove, l); >+ this.addListener(SWT.MouseExit, new Listener() { >+ public void handleEvent(Event e) { >+ fHeader.hideRemoveIcon(); >+ } >+ }); >+ } >+ >+ private void addBorderPainter(final Composite tableContainer) { >+ tableContainer.addPaintListener(new PaintListener() { >+ public void paintControl(PaintEvent e) { >+ if (fSelected) >+ e.gc.setBackground(CodeAssistAdvancedUtilitiesProxy.SELECTED_COLOR); >+ else >+ e.gc.setBackground(CodeAssistAdvancedUtilitiesProxy.UNSELECTED_BORDER_COLOR); >+ Rectangle rect= tableContainer.getClientArea(); >+ e.gc.fillRectangle(rect); >+ } >+ }); >+ } >+ >+ private TableViewer createInitialTableViewer(Composite tableContainer) { >+ TableViewer listViewer= new TableViewer(tableContainer, SWT.SINGLE | SWT.NO_SCROLL); >+ final Table table= listViewer.getTable(); >+ table.setHeaderVisible(false); >+ table.setLinesVisible(false); >+ table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); >+ return listViewer; >+ } >+ >+ private TableColumn addFirstColumn(TableViewer tableViewer) { >+ TableColumn nameColumn= new TableColumn(tableViewer.getTable(), SWT.NONE); >+ nameColumn.setResizable(false); >+ return nameColumn; >+ } >+ >+ private void adjustFirstColumnWidth(TableColumn column, TableViewer tableViewer, ITableLabelProvider labelProvider) { >+ final int ICON_WIDTH= 16; >+ final int HEADER_MARGIN= 20; >+ int minNameWidth= fUtilitiesProxy.computeWidth(tableViewer.getTable(), column.getText()) + HEADER_MARGIN; >+ for (int i= 0; i < fModel.elements.size(); i++) { >+ minNameWidth= Math.max(minNameWidth, fUtilitiesProxy.computeWidth(tableViewer.getTable(), labelProvider.getColumnText(fModel.elements.get(i), 0)) + 2 * ICON_WIDTH); >+ } >+ column.setWidth(minNameWidth); >+ } >+ >+ private ITableLabelProvider setProviderAndComparator(TableViewer tableViewer, int listIndex) { >+ tableViewer.setContentProvider(new ProposalListContentProvider(listIndex)); >+ tableViewer.setComparator(new ModelElement.ModelElementViewerComparator()); >+ ITableLabelProvider labelProvider= new ProposalListTableLabelProvider(); >+ tableViewer.setLabelProvider(labelProvider); >+ return labelProvider; >+ } >+ >+ private void addDragSupport(TableViewer tableViewer, int listIndex) { >+ Transfer[] transferTypes= new Transfer[] { ProposalListCategoryTransfer.getInstance() }; >+ tableViewer.addDragSupport(ProposalTransfer.ALL_DRAG_OPERATIONS, transferTypes, new DragProposalListCategoryListener(tableViewer, listIndex)); >+ } >+ >+ private void addFocusOutListener(TableViewer tableViewer) { >+ final Table table= tableViewer.getTable(); >+ table.addListener(SWT.FocusOut, new Listener() { >+ public void handleEvent(Event event) { >+ table.deselectAll(); >+ } >+ }); >+ } >+ >+ private void addListener(int eventType, Listener listener) { >+ fTableContainer.addListener(eventType, listener); >+ fHeader.addListener(eventType, listener); >+ fTableViewer.getTable().addListener(eventType, listener); >+ } >+ >+ private void addProposalListCategoryRemoveIconCreator(final TableViewer tableViewer, final int listIndex) { >+ Table table= tableViewer.getTable(); >+ Rectangle iconRect= addRemoveIconToItemsPainter(table); >+ addRemoveIconRedrawListener(table, iconRect); >+ addRemoveCategoryOnClickListener(table, iconRect, listIndex); >+ } >+ >+ private Rectangle addRemoveIconToItemsPainter(Table table) { >+ final Rectangle iconRect= new Rectangle(0, 0, 0, 0); >+ Listener paintListener= new Listener() { >+ public void handleEvent(Event event) { >+ Table tab= ((Table) event.widget); >+ Point tabLoc= getTableLocation(tab); >+ Point mouseLoc= getMouseLocation(tab, tabLoc); >+ if (isMouseOverCurrentRow(tab, mouseLoc, (TableItem) event.item)) { >+ updateIconRectangle(tab, event.height, event.y); >+ drawIcon(event.gc, mouseLoc); >+ } >+ } >+ >+ private Point getTableLocation(Table tab) { >+ return tab.toDisplay(tab.getClientArea().x, tab.getClientArea().y); >+ } >+ >+ private Point getMouseLocation(Table tab, Point tabLoc) { >+ Point mouseLoc= tab.getDisplay().getCursorLocation(); >+ mouseLoc= new Point(mouseLoc.x - tabLoc.x, mouseLoc.y - tabLoc.y); >+ return mouseLoc; >+ } >+ >+ private boolean isMouseOverCurrentRow(Table tab, Point mouseLoc, TableItem currentItem) { >+ return tab.getClientArea().contains(mouseLoc) && currentItem == getItem(tab, mouseLoc); >+ } >+ >+ private void updateIconRectangle(Table tab, int eventHeight, int eventY) { >+ ImageData imgData= fUtilitiesProxy.fRemoveProposalListImage.getImageData(); >+ int x= tab.getClientArea().width - imgData.width; >+ int offset= Math.max(0, (eventHeight - imgData.height) / 2); >+ >+ iconRect.height= imgData.height; >+ iconRect.width= imgData.width; >+ iconRect.x= x; >+ iconRect.y= eventY + offset; >+ } >+ >+ private void drawIcon(GC gc, Point mouseLoc) { >+ gc.setClipping(iconRect); >+ if (iconRect.contains(mouseLoc)) >+ gc.drawImage(fUtilitiesProxy.fRemoveProposalListOverImage, iconRect.x, iconRect.y); >+ else >+ gc.drawImage(fUtilitiesProxy.fRemoveProposalListImage, iconRect.x, iconRect.y); >+ } >+ }; >+ table.addListener(SWT.PaintItem, paintListener); >+ return iconRect; >+ } >+ >+ private void addRemoveIconRedrawListener(final Table table, final Rectangle iconRect) { >+ Listener mouseOverTableListener= new Listener() { >+ TableItem lastItem; >+ >+ boolean lastOverImg; >+ >+ public void handleEvent(Event e) { >+ TableItem item= getItem(table, new Point(e.x, e.y)); >+ boolean overImg= iconRect.contains(e.x, e.y); >+ if (lastItem != item || lastOverImg != overImg) { >+ lastItem= item; >+ lastOverImg= overImg; >+ table.redraw(); >+ } >+ } >+ }; >+ table.addListener(SWT.MouseEnter, mouseOverTableListener); >+ table.addListener(SWT.MouseMove, mouseOverTableListener); >+ table.addListener(SWT.MouseExit, mouseOverTableListener); >+ } >+ >+ private void addRemoveCategoryOnClickListener(final Table table, final Rectangle iconRect, final int listIndex) { >+ table.addMouseListener(new MouseListener() { >+ public void mouseUp(MouseEvent e) { >+ if (isSingleClick(e.count) && isUpOverIcon(e.x, e.y)) { >+ int elemIndex= table.indexOf(getItem(table, new Point(e.x, e.y))); >+ List<ModelElement> categories= fModel.getElements(listIndex); >+ Collections.sort(categories, new ModelElement.ModelElementComparator()); >+ categories.get(elemIndex).removeInProposalList(listIndex); >+ fUtilitiesProxy.updateControls(); >+ } >+ } >+ >+ public void mouseDown(MouseEvent e) { >+ } >+ >+ public void mouseDoubleClick(MouseEvent e) { >+ } >+ >+ private boolean isSingleClick(int count) { >+ return count == 1; >+ } >+ >+ private boolean isUpOverIcon(int x, int y) { >+ return iconRect.contains(x, y); >+ } >+ }); >+ } >+ >+ private TableItem getItem(Table tab, Point p) { >+ for (int index= 0; index < tab.getItemCount(); index++) { >+ if (getItemBounds(tab, index).contains(p)) >+ return tab.getItem(index); >+ } >+ return null; >+ } >+ >+ private Rectangle getItemBounds(Table tab, int itemIndex) { >+ Rectangle tableBounds= tab.getBounds(); >+ int height= tab.getItemHeight(); >+ int width= tableBounds.width; >+ int x= tableBounds.x; >+ int y= itemIndex * height; >+ return new Rectangle(x, y, width, height); >+ } >+ >+ public TableViewer getTableViewer() { >+ return fTableViewer; >+ } >+} >Index: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/widgets/ProposalListHeader.java >=================================================================== >RCS file: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/widgets/ProposalListHeader.java >diff -N ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/widgets/ProposalListHeader.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/widgets/ProposalListHeader.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,197 @@ >+/** >+ * Copyright (c) 2011 Thomas Schlosser. >+ * 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: >+ * Thomas Schlosser <schlosser@stud.tu-darmstadt.de> - initial API and implementation. >+ */ >+package org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.widgets; >+ >+import org.eclipse.swt.SWT; >+import org.eclipse.swt.dnd.DragSource; >+import org.eclipse.swt.dnd.DragSourceListener; >+import org.eclipse.swt.dnd.Transfer; >+import org.eclipse.swt.events.MouseEvent; >+import org.eclipse.swt.events.MouseListener; >+import org.eclipse.swt.graphics.Color; >+import org.eclipse.swt.layout.GridData; >+import org.eclipse.swt.layout.GridLayout; >+import org.eclipse.swt.widgets.Composite; >+import org.eclipse.swt.widgets.Control; >+import org.eclipse.swt.widgets.Display; >+import org.eclipse.swt.widgets.Event; >+import org.eclipse.swt.widgets.Label; >+import org.eclipse.swt.widgets.Listener; >+ >+import org.eclipse.jdt.internal.corext.util.Messages; >+ >+import org.eclipse.jdt.internal.ui.preferences.PreferencesMessages; >+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.CodeAssistAdvancedUtilitiesProxy; >+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.dnd.DragProposalListListener; >+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.dnd.ProposalListTransfer; >+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.dnd.ProposalTransfer; >+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.model.PreferenceModel; >+ >+/** >+ * >+ * @since 3.8 >+ */ >+public final class ProposalListHeader { >+ >+ private static final Color SELECTED_COLOR= Display.getCurrent().getSystemColor(SWT.COLOR_LIST_SELECTION); >+ >+ private static final Color SELECTED_TEXT_COLOR= Display.getCurrent().getSystemColor(SWT.COLOR_LIST_SELECTION_TEXT); >+ >+ private static final Color UNSELECTED_COLOR= Display.getCurrent().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND); >+ >+ private static final Color UNSELECTED_TEXT_COLOR= Display.getCurrent().getSystemColor(SWT.COLOR_WIDGET_FOREGROUND); >+ >+ private final PreferenceModel fModel; >+ >+ private final CodeAssistAdvancedUtilitiesProxy fUtilitiesProxy; >+ >+ private final Composite fPaddingComposite; >+ >+ private final Label fTitle; >+ >+ private final Label fRemoveLabel; >+ >+ public ProposalListHeader(Composite tableContainer, int listIndex, PreferenceModel model, CodeAssistAdvancedUtilitiesProxy utilitiesProxy) { >+ this.fModel= model; >+ this.fUtilitiesProxy= utilitiesProxy; >+ >+ fPaddingComposite= createPaddingComposite(tableContainer); >+ fTitle= createTitle(fPaddingComposite, listIndex); >+ fRemoveLabel= createRemoveIcon(fPaddingComposite, listIndex); >+ updateHeaderHeight(); >+ >+ addListDragSupport(fPaddingComposite, listIndex); >+ addListDragSupport(fTitle, listIndex); >+ } >+ >+ public void dispose() { >+ fPaddingComposite.dispose(); >+ fTitle.dispose(); >+ fRemoveLabel.dispose(); >+ } >+ >+ public void highlight(boolean highlight) { >+ Color backgroundColor= highlight ? SELECTED_COLOR : UNSELECTED_COLOR; >+ Color foregroundColor= highlight ? SELECTED_TEXT_COLOR : UNSELECTED_TEXT_COLOR; >+ fPaddingComposite.setBackground(backgroundColor); >+ fTitle.setBackground(backgroundColor); >+ fTitle.setForeground(foregroundColor); >+ fRemoveLabel.setBackground(backgroundColor); >+ } >+ >+ public void showRemoveIcon() { >+ fRemoveLabel.setVisible(true); >+ } >+ >+ public void hideRemoveIcon() { >+ fRemoveLabel.setVisible(false); >+ } >+ >+ public void addListener(int eventType, Listener listener) { >+ fPaddingComposite.addListener(eventType, listener); >+ fTitle.addListener(eventType, listener); >+ fRemoveLabel.addListener(eventType, listener); >+ } >+ >+ private Composite createPaddingComposite(Composite tableContainer) { >+ Composite paddingComposite= new Composite(tableContainer, SWT.NONE); >+ GridLayout layout= new GridLayout(2, false); >+ layout.marginHeight= 0; >+ layout.verticalSpacing= 0; >+ paddingComposite.setLayout(layout); >+ return paddingComposite; >+ } >+ >+ private Label createTitle(Composite paddingComposite, int listIndex) { >+ Label title= new Label(paddingComposite, SWT.NONE); >+ title.setText(getProposalListTitle(listIndex)); >+ title.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true)); >+ return title; >+ } >+ >+ private void updateHeaderHeight() { >+ GridData gd= new GridData(SWT.FILL, SWT.FILL, true, true); >+ gd.heightHint= getHeaderHeight(); >+ fPaddingComposite.setLayoutData(gd); >+ } >+ >+ private Label createRemoveIcon(final Composite paddingComposite, final int listIndex) { >+ final Label removeLabel= createRemoveLabel(paddingComposite); >+ addMouseOverIconListener(removeLabel); >+ addRemoveListOnClickListener(removeLabel, listIndex); >+ return removeLabel; >+ } >+ >+ private void addListDragSupport(Control control, int listIndex) { >+ DragSourceListener tableDragSourceListener= new DragProposalListListener(listIndex); >+ Transfer[] transferTypes= new Transfer[] { ProposalListTransfer.getInstance() }; >+ DragSource dragSource= new DragSource(control, ProposalTransfer.ALL_DRAG_OPERATIONS); >+ dragSource.setTransfer(transferTypes); >+ dragSource.addDragListener(tableDragSourceListener); >+ } >+ >+ private String getProposalListTitle(int index) { >+ return Messages.format(PreferencesMessages.CodeAssistAdvancedConfigurationBlock_proposal_list_table_title, Integer.valueOf(index + 1)); >+ } >+ >+ private int getHeaderHeight() { >+ return fTitle.computeSize(SWT.DEFAULT, SWT.DEFAULT).y + 8; >+ } >+ >+ private Label createRemoveLabel(Composite paddingComposite) { >+ final Label removeLabel= new Label(paddingComposite, SWT.NONE); >+ removeLabel.setVisible(false); >+ removeLabel.setImage(fUtilitiesProxy.fRemoveProposalListImage); >+ GridData gd= new GridData(SWT.RIGHT, SWT.CENTER, true, true); >+ gd.widthHint= fUtilitiesProxy.fRemoveProposalListImage.getImageData().width; >+ gd.minimumWidth= gd.widthHint; >+ removeLabel.setLayoutData(gd); >+ return removeLabel; >+ } >+ >+ private void addMouseOverIconListener(final Label removeLabel) { >+ removeLabel.addListener(SWT.MouseEnter, new Listener() { >+ public void handleEvent(Event e) { >+ removeLabel.setImage(fUtilitiesProxy.fRemoveProposalListOverImage); >+ } >+ }); >+ removeLabel.addListener(SWT.MouseExit, new Listener() { >+ public void handleEvent(Event e) { >+ removeLabel.setImage(fUtilitiesProxy.fRemoveProposalListImage); >+ } >+ }); >+ } >+ >+ private void addRemoveListOnClickListener(final Label removeLabel, final int listIndex) { >+ removeLabel.addMouseListener(new MouseListener() { >+ public void mouseUp(MouseEvent e) { >+ if (isSingleClick(e.count) && isUpOverIcon(e.x, e.y)) { >+ fModel.removeList(listIndex); >+ fUtilitiesProxy.updateControls(); >+ } >+ } >+ >+ public void mouseDown(MouseEvent e) { >+ } >+ >+ public void mouseDoubleClick(MouseEvent e) { >+ } >+ >+ private boolean isSingleClick(int count) { >+ return count == 1; >+ } >+ >+ private boolean isUpOverIcon(int x, int y) { >+ return x >= 0 && x < removeLabel.getBounds().width && y >= 0 && y < removeLabel.getBounds().height; >+ } >+ }); >+ } >+} >Index: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/widgets/ProposalListSection.java >=================================================================== >RCS file: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/widgets/ProposalListSection.java >diff -N ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/widgets/ProposalListSection.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/widgets/ProposalListSection.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,194 @@ >+/** >+ * Copyright (c) 2011 Thomas Schlosser. >+ * 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: >+ * Thomas Schlosser <schlosser@stud.tu-darmstadt.de> - initial API and implementation. >+ */ >+package org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.widgets; >+ >+import java.util.ArrayList; >+import java.util.HashSet; >+import java.util.List; >+import java.util.Set; >+ >+import org.eclipse.swt.SWT; >+import org.eclipse.swt.custom.ScrolledComposite; >+import org.eclipse.swt.dnd.DropTarget; >+import org.eclipse.swt.dnd.DropTargetEvent; >+import org.eclipse.swt.dnd.Transfer; >+import org.eclipse.swt.events.ControlEvent; >+import org.eclipse.swt.events.ControlListener; >+import org.eclipse.swt.graphics.Point; >+import org.eclipse.swt.graphics.Rectangle; >+import org.eclipse.swt.layout.GridData; >+import org.eclipse.swt.layout.GridLayout; >+import org.eclipse.swt.widgets.Composite; >+ >+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.CodeAssistAdvancedUtilitiesProxy; >+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.dnd.AutoscrollDropTargetListener; >+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.dnd.ProposalListCategoryTransfer; >+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.dnd.ProposalListTransfer; >+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.dnd.ProposalTransfer; >+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.dnd.ProvidedCategoryTransfer; >+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.model.ModelElement; >+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.model.PreferenceModel; >+ >+/** >+ * >+ * @since 3.8 >+ */ >+public final class ProposalListSection { >+ private final PreferenceModel fModel; >+ >+ private final CodeAssistAdvancedUtilitiesProxy fUtilitiesProxy; >+ >+ private final ScrolledComposite fScrolledComposite; >+ >+ private final Composite fInnerWrappingComposite; >+ >+ private final List<ProposalList> fProposalLists= new ArrayList<ProposalList>(); >+ >+ public ProposalListSection(Composite parent, PreferenceModel model, CodeAssistAdvancedUtilitiesProxy utilitiesProxy) { >+ this.fModel= model; >+ this.fUtilitiesProxy= utilitiesProxy; >+ >+ fScrolledComposite= createOuterScrolledComposite(parent); >+ addDropAutoScroll(fScrolledComposite); >+ fInnerWrappingComposite= createInnerProposalListWrappingComposite(fScrolledComposite); >+ >+ addOuterSizeUpdater(fScrolledComposite, fInnerWrappingComposite); >+ >+ createFirstNewListDropSection(fInnerWrappingComposite); >+ } >+ >+ public void updateControls() { >+ //FIXME: This fixes the problem of refreshing the first list when first element (category) has been added. >+ // This bug only occurs when the configuration page has been opened indirectly. >+ // If the "Content Assist"->"Advanced" page is opened directly, it behaves as expected. >+ if (fProposalLists.size() == 1 && fProposalLists.get(0).getContent() == null) { >+ fProposalLists.get(0).dispose(); >+ fProposalLists.remove(0); >+ } >+ clearOldListState(); >+ Set<Integer> filledLists= updateListStates(); >+ makeSureFirstListExists(); >+ adjustAndCleanUp(filledLists); >+ reLayoutInnerComposite(); >+ } >+ >+ public void autoScroll(DropTargetEvent event) { >+ Rectangle area= fScrolledComposite.getClientArea(); >+ Point absoluteLocation= fScrolledComposite.toDisplay(1, 1); >+ Point origin= fScrolledComposite.getOrigin(); >+ Rectangle bounds= fInnerWrappingComposite.getBounds(); >+ >+ int scrollDetectRange= 15; >+ int offset= 5; >+ if (absoluteLocation.y + scrollDetectRange > event.y) >+ origin.y= Math.max(0, origin.y - offset); >+ if (absoluteLocation.y + area.height - scrollDetectRange < event.y) >+ origin.y= Math.min(bounds.height - area.height, origin.y + offset); >+ fScrolledComposite.setOrigin(origin); >+ } >+ >+ private ScrolledComposite createOuterScrolledComposite(Composite parent) { >+ ScrolledComposite scrolledComposite= new ScrolledComposite(parent, SWT.V_SCROLL | SWT.BORDER); >+ scrolledComposite.setAlwaysShowScrollBars(true); >+ scrolledComposite.setExpandHorizontal(true); >+ scrolledComposite.setExpandVertical(true); >+ GridData gridData= new GridData(GridData.FILL, GridData.FILL, true, true); >+ gridData.heightHint= 0; >+ scrolledComposite.setLayoutData(gridData); >+ return scrolledComposite; >+ } >+ >+ private void addDropAutoScroll(Composite composite) { >+ Transfer[] transferTypes= new Transfer[] { ProvidedCategoryTransfer.getInstance(), ProposalListCategoryTransfer.getInstance(), ProposalListTransfer.getInstance() }; >+ DropTarget dropTarget= new DropTarget(composite, ProposalTransfer.ALL_DRAG_OPERATIONS); >+ dropTarget.setTransfer(transferTypes); >+ dropTarget.addDropListener(new AutoscrollDropTargetListener(this)); >+ } >+ >+ private Composite createInnerProposalListWrappingComposite(ScrolledComposite scrolledComposite) { >+ Composite wrappingComposite= new Composite(scrolledComposite, SWT.NONE); >+ scrolledComposite.setContent(wrappingComposite); >+ GridLayout layout= new GridLayout(); >+ layout.marginHeight= 0; >+ layout.verticalSpacing= 0; >+ wrappingComposite.setLayout(layout); >+ return wrappingComposite; >+ } >+ >+ private void addOuterSizeUpdater(final ScrolledComposite scrolledComposite, final Composite innerComposite) { >+ innerComposite.addControlListener(new ControlListener() { >+ public void controlResized(ControlEvent e) { >+ innerComposite.update(); >+ scrolledComposite.setMinSize(innerComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT)); >+ scrolledComposite.layout(true, true); >+ } >+ >+ public void controlMoved(ControlEvent e) { >+ } >+ }); >+ } >+ >+ private void createFirstNewListDropSection(Composite innerWrappingComposite) { >+ new NewListDropSection(innerWrappingComposite, 0, fModel, this, fUtilitiesProxy); >+ } >+ >+ private void clearOldListState() { >+ for (ProposalList list : fProposalLists) >+ list.clearContent(); >+ } >+ >+ private Set<Integer> updateListStates() { >+ Set<Integer> filledLists= new HashSet<Integer>(); >+ for (ModelElement element : fModel.elements) { >+ Set<Integer> indices= element.getProposalListIndices(); >+ if (indices != null) { >+ filledLists.addAll(indices); >+ for (int index : indices) { >+ makeSureListExists(index); >+ addElementToList(element, index); >+ } >+ } >+ } >+ return filledLists; >+ } >+ >+ private void makeSureFirstListExists() { >+ if (fProposalLists.size() == 0) >+ makeSureListExists(0); >+ } >+ >+ private void adjustAndCleanUp(Set<Integer> filledLists) { >+ boolean last= true; >+ for (int i= fProposalLists.size() - 1; i >= 0; i--) >+ if (i > 0 && !filledLists.contains(Integer.valueOf(i))) { >+ fProposalLists.get(i).dispose(); >+ fProposalLists.remove(i); >+ } >+ else { >+ fProposalLists.get(i).activateLastListSpaceBehavior(last); >+ last= false; >+ } >+ } >+ >+ private void reLayoutInnerComposite() { >+ fInnerWrappingComposite.pack(true); >+ fInnerWrappingComposite.layout(false); >+ } >+ >+ private void addElementToList(ModelElement element, int listIndex) { >+ fProposalLists.get(listIndex).addContent(element); >+ } >+ >+ private void makeSureListExists(int listIndex) { >+ while (fProposalLists.size() < listIndex + 1) >+ fProposalLists.add(new ProposalList(fInnerWrappingComposite, fProposalLists.size(), this, fModel, fUtilitiesProxy)); >+ } >+} >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 18 Jul 2011 13:26:55 -0000 >@@ -7,13 +7,18 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Thomas Schlosser <schlosser@stud.tu-darmstadt.de> - 340876 [preferences][content assist] Request for more flexible configuration of content assist lists - https://bugs.eclipse.org/bugs/show_bug.cgi?id=340876 > *******************************************************************************/ > package org.eclipse.jdt.internal.ui.text.java; > > import java.net.URL; > import java.util.ArrayList; >+import java.util.Collection; >+import java.util.Collections; >+import java.util.HashSet; > import java.util.Iterator; > import java.util.List; >+import java.util.Set; > > import org.osgi.framework.Bundle; > >@@ -55,12 +60,11 @@ > /** The image descriptor for this category, or <code>null</code> if none specified. */ > private final ImageDescriptor fImage; > >- private boolean fIsSeparateCommand= true; >+ private final Set<Integer> fProposalListIndices = new HashSet<Integer>(); >+ private final Set<Integer> fPublicProposalListIndices= Collections.unmodifiableSet(fProposalListIndices); > private boolean fIsEnabled= true; >- private boolean fIsIncluded= true; > private final CompletionProposalComputerRegistry fRegistry; > >- private int fSortOrder= 0xffff - 1; > private String fLastError= null; > > CompletionProposalCategory(IConfigurationElement element, CompletionProposalComputerRegistry registry) throws CoreException { >@@ -158,35 +162,54 @@ > } > > /** >- * Sets the separate command state of the category. >- * >- * @param enabled the new enabled state. >+ * Adds the given proposal list index to the proposal list indices of this category. >+ * >+ * @param listIndex the index of the proposal list. > */ >- public void setSeparateCommand(boolean enabled) { >- fIsSeparateCommand= enabled; >+ public void addProposalListIndex(Integer listIndex) { >+ fProposalListIndices.add(listIndex); > } > > /** >- * Returns the enablement state of the category. >- * >- * @return the enablement state of the category >+ * Adds all given proposal list indices to the proposal list indices of this category. >+ * >+ * @param listIndices the indices of the proposal lists. > */ >- public boolean isSeparateCommand() { >- return fIsSeparateCommand; >+ public void addAllProposalListIndices(Collection<Integer> listIndices) { >+ if (listIndices == null) >+ return; >+ fProposalListIndices.addAll(listIndices); > } > > /** >- * @param included the included >+ * Removes all given proposal list indices from the proposal list indices of this category. >+ * >+ * @param listIndices the indices of the proposal lists. > */ >- public void setIncluded(boolean included) { >- fIsIncluded= included; >+ public void removeAllProposalListIndices(Collection<Integer> listIndices) { >+ if (listIndices == null) >+ return; >+ fProposalListIndices.removeAll(listIndices); > } > > /** >- * @return included >+ * Clears the list of proposal list indices of this category. >+ * > */ >- public boolean isIncluded() { >- return fIsIncluded; >+ public void clearProposalListIndices() { >+ fProposalListIndices.clear(); >+ } >+ >+ /** >+ * Returns the indices of the proposal lists of this category. >+ * <p> >+ * The returned set is read-only. >+ * </p> >+ * >+ * @return the indices of the proposal lists of this category >+ */ >+ public Set<Integer> getProposalListIndices() { >+ return fPublicProposalListIndices; > } > > public boolean isEnabled() { >@@ -233,20 +256,6 @@ > } > > /** >- * @return sortOrder >- */ >- public int getSortOrder() { >- return fSortOrder; >- } >- >- /** >- * @param sortOrder the sortOrder >- */ >- public void setSortOrder(int sortOrder) { >- fSortOrder= sortOrder; >- } >- >- /** > * Safely computes completion proposals of all computers of this category through their > * extension. If an extension is disabled, throws an exception or otherwise does not adhere to > * the contract described in {@link IJavaCompletionProposalComputer}, it is disabled. >@@ -288,7 +297,7 @@ > List<CompletionProposalComputerDescriptor> descriptors= new ArrayList<CompletionProposalComputerDescriptor>(fRegistry.getProposalComputerDescriptors(partition)); > for (Iterator<CompletionProposalComputerDescriptor> it= descriptors.iterator(); it.hasNext();) { > CompletionProposalComputerDescriptor desc= it.next(); >- if (desc.getCategory() == this && (isIncluded() || isSeparateCommand())) >+ if (desc.getCategory() == this && !fProposalListIndices.isEmpty()) > result.addAll(desc.computeContextInformation(context, monitor)); > if (fLastError == null) > fLastError= desc.getErrorMessage(); >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 18 Jul 2011 13:26:55 -0000 >@@ -7,6 +7,7 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Thomas Schlosser <schlosser@stud.tu-darmstadt.de> - 340876 [preferences][content assist] Request for more flexible configuration of content assist lists - https://bugs.eclipse.org/bugs/show_bug.cgi?id=340876 > *******************************************************************************/ > package org.eclipse.jdt.internal.ui.text.java; > >@@ -21,6 +22,8 @@ > import java.util.Map; > import java.util.Set; > import java.util.StringTokenizer; >+import java.util.TreeMap; >+import java.util.Map.Entry; > > import org.eclipse.swt.SWT; > import org.eclipse.swt.events.SelectionAdapter; >@@ -330,25 +333,28 @@ > > private List<CompletionProposalCategory> getCategories(List<IConfigurationElement> elements) { > IPreferenceStore store= JavaPlugin.getDefault().getPreferenceStore(); >- String preference= store.getString(PreferenceConstants.CODEASSIST_EXCLUDED_CATEGORIES); >- Set<String> disabled= new HashSet<String>(); >- StringTokenizer tok= new StringTokenizer(preference, "\0"); //$NON-NLS-1$ >- while (tok.hasMoreTokens()) >- disabled.add(tok.nextToken()); >- Map<String, Integer> ordered= new HashMap<String, Integer>(); >- preference= store.getString(PreferenceConstants.CODEASSIST_CATEGORY_ORDER); >- tok= new StringTokenizer(preference, "\0"); //$NON-NLS-1$ >- while (tok.hasMoreTokens()) { >+ String preference= store.getString(PreferenceConstants.CODEASSIST_PROPOSAL_LISTS); >+ Map<String, Set<Integer>> proposalLists= new HashMap<String, Set<Integer>>(); >+ StringTokenizer tok= new StringTokenizer(preference, "\0"); //$NON-NLS-1$ >+ for (int i= 0; tok.hasMoreTokens(); i++) { > StringTokenizer inner= new StringTokenizer(tok.nextToken(), ":"); //$NON-NLS-1$ >- String id= inner.nextToken(); >- int rank= Integer.parseInt(inner.nextToken()); >- ordered.put(id, new Integer(rank)); >+ if (inner.countTokens() == 0) >+ i--; >+ while (inner.hasMoreTokens()) { >+ String categoryId= inner.nextToken(); >+ Set<Integer> set= proposalLists.get(categoryId); >+ if (set == null) { >+ set= new HashSet<Integer>(); >+ proposalLists.put(categoryId, set); >+ } >+ set.add(Integer.valueOf(i)); >+ } > } > > CompletionProposalCategory allProposals= null; > CompletionProposalCategory typeProposals= null; > CompletionProposalCategory allButTypeProposals= null; >- >+ > List<CompletionProposalCategory> categories= new ArrayList<CompletionProposalCategory>(); > for (Iterator<IConfigurationElement> iter= elements.iterator(); iter.hasNext();) { > IConfigurationElement element= iter.next(); >@@ -358,17 +364,8 @@ > > CompletionProposalCategory category= new CompletionProposalCategory(element, this); > categories.add(category); >- category.setIncluded(!disabled.contains(category.getId())); >- Integer rank= ordered.get(category.getId()); >- if (rank != null) { >- int r= rank.intValue(); >- boolean separate= r < 0xffff; >- if (!separate) >- r= r - 0xffff; >- category.setSeparateCommand(separate); >- category.setSortOrder(r); >- } >- >+ category.addAllProposalListIndices(proposalLists.get(category.getId())); >+ > String id= category.getId(); > if ("org.eclipse.jdt.ui.javaAllProposalCategory".equals(id)) //$NON-NLS-1$ > allProposals= category; >@@ -383,7 +380,7 @@ > * some other reason. Do not include the extension in the list and inform the user > * about it. > */ >- Object[] args= {element.toString()}; >+ Object[] args= { element.toString() }; > String message= Messages.format(JavaTextMessages.CompletionProposalComputerRegistry_invalid_message, args); > IStatus status= new Status(IStatus.WARNING, JavaPlugin.getPluginId(), IStatus.OK, message, x); > informUser(status); >@@ -391,35 +388,47 @@ > informUser(x.getStatus()); > } > } >- preventDuplicateCategories(store, disabled, allProposals, typeProposals, allButTypeProposals); >+ preventDuplicateCategories(store, proposalLists, allProposals, typeProposals, allButTypeProposals, categories.size()); > return categories; > } > >- private void preventDuplicateCategories(IPreferenceStore store, Set<String> disabled, CompletionProposalCategory allProposals, CompletionProposalCategory typeProposals, >- CompletionProposalCategory allButTypeProposals) { >+ private void preventDuplicateCategories(IPreferenceStore store, Map<String, Set<Integer>> proposalLists, CompletionProposalCategory allProposals, CompletionProposalCategory typeProposals, >+ CompletionProposalCategory allButTypeProposals, int numberOfCategories) { > boolean adjusted= false; >- if (allProposals == null || !allProposals.isIncluded()) >+ if (allProposals == null || allProposals.getProposalListIndices().isEmpty()) > return; > >- if (allButTypeProposals != null && allButTypeProposals.isIncluded()) { >- allButTypeProposals.setIncluded(false); >- disabled.add(allButTypeProposals.getId()); >+ if (allButTypeProposals != null && !allButTypeProposals.getProposalListIndices().isEmpty()) { >+ allButTypeProposals.removeAllProposalListIndices(allProposals.getProposalListIndices()); >+ proposalLists.put(allButTypeProposals.getId(), allButTypeProposals.getProposalListIndices()); > adjusted= true; > } >- if (typeProposals != null && typeProposals.isIncluded()) { >- typeProposals.setIncluded(false); >- disabled.add(typeProposals.getId()); >+ if (typeProposals != null && !typeProposals.getProposalListIndices().isEmpty()) { >+ typeProposals.removeAllProposalListIndices(allProposals.getProposalListIndices()); >+ proposalLists.put(typeProposals.getId(), typeProposals.getProposalListIndices()); > adjusted= true; > } > > if (adjusted) { >- StringBuffer buf= new StringBuffer(50 * disabled.size()); >- Iterator<String> iter= disabled.iterator(); >- while (iter.hasNext()) { >- buf.append(iter.next()); >+ int initialBufferSize= 50 * numberOfCategories; >+ Map<Integer, StringBuffer> proposalListsCategories= new TreeMap<Integer, StringBuffer>(); >+ for (Entry<String, Set<Integer>> category : proposalLists.entrySet()) { >+ for (Integer index : category.getValue()) { >+ StringBuffer buf= proposalListsCategories.get(index); >+ if (buf == null) { >+ buf= new StringBuffer(initialBufferSize); >+ proposalListsCategories.put(index, buf); >+ } >+ buf.append(category.getKey()); >+ buf.append(':'); >+ } >+ } >+ StringBuffer buf= new StringBuffer(initialBufferSize * proposalListsCategories.size()); >+ for (StringBuffer proposalList : proposalListsCategories.values()) { >+ buf.append(proposalList); > buf.append('\0'); > } >- store.putValue(PreferenceConstants.CODEASSIST_EXCLUDED_CATEGORIES, buf.toString()); >+ store.putValue(PreferenceConstants.CODEASSIST_PROPOSAL_LISTS, buf.toString()); > } > } > >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 18 Jul 2011 13:26:56 -0000 >@@ -7,14 +7,15 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Thomas Schlosser <schlosser@stud.tu-darmstadt.de> - 340876 [preferences][content assist] Request for more flexible configuration of content assist lists - https://bugs.eclipse.org/bugs/show_bug.cgi?id=340876 > *******************************************************************************/ > package org.eclipse.jdt.internal.ui.text.java; > > import java.util.ArrayList; >-import java.util.Collections; >-import java.util.Comparator; > import java.util.Iterator; > import java.util.List; >+import java.util.Map; >+import java.util.TreeMap; > > import org.eclipse.swt.SWT; > import org.eclipse.swt.events.SelectionAdapter; >@@ -186,14 +187,6 @@ > */ > private static final String PREF_WARN_ABOUT_EMPTY_ASSIST_CATEGORY= "EmptyDefaultAssistCategory"; //$NON-NLS-1$ > >- private static final Comparator<CompletionProposalCategory> ORDER_COMPARATOR= new Comparator<CompletionProposalCategory>() { >- >- public int compare(CompletionProposalCategory d1, CompletionProposalCategory d2) { >- return d1.getSortOrder() - d2.getSortOrder(); >- } >- >- }; >- > private final List<CompletionProposalCategory> fCategories; > private final String fPartition; > private final ContentAssistant fAssistant; >@@ -444,47 +437,44 @@ > } > > private List<List<CompletionProposalCategory>> getCategoryIteration() { >- List<List<CompletionProposalCategory>> sequence= new ArrayList<List<CompletionProposalCategory>>(); >- sequence.add(getDefaultCategories()); >- for (Iterator<CompletionProposalCategory> it= getSeparateCategories().iterator(); it.hasNext();) { >- CompletionProposalCategory cat= it.next(); >- sequence.add(Collections.singletonList(cat)); >- } >- return sequence; >- } >- >- private List<CompletionProposalCategory> getDefaultCategories() { >- // default mix - enable all included computers >- List<CompletionProposalCategory> included= getDefaultCategoriesUnchecked(); >- >- if (fComputerRegistry.hasUninstalledComputers(fPartition, included)) { >- if (informUserAboutEmptyDefaultCategory()) >- // preferences were restored - recompute the default categories >- included= getDefaultCategoriesUnchecked(); >+ List<List<CompletionProposalCategory>> categories= getProposalCategoriesUnchecked(); >+ if (fComputerRegistry.hasUninstalledComputers(fPartition, categories.get(0))) { >+ if (informUserAboutEmptyFirstProposalCategory()) >+ // preferences were restored - recompute the categories in the first proposal list >+ categories= getProposalCategoriesUnchecked(); > fComputerRegistry.resetUnistalledComputers(); > } >- >- return included; >+ return categories; > } > >- private List<CompletionProposalCategory> getDefaultCategoriesUnchecked() { >- List<CompletionProposalCategory> included= new ArrayList<CompletionProposalCategory>(); >- for (Iterator<CompletionProposalCategory> it= fCategories.iterator(); it.hasNext();) { >- CompletionProposalCategory category= it.next(); >- if (category.isIncluded() && category.hasComputers(fPartition)) >- included.add(category); >+ private List<List<CompletionProposalCategory>> getProposalCategoriesUnchecked() { >+ Map<Integer, List<CompletionProposalCategory>> sorted= new TreeMap<Integer, List<CompletionProposalCategory>>(); >+ for (CompletionProposalCategory category : fCategories) { >+ if (!category.getProposalListIndices().isEmpty() && category.hasComputers(fPartition)) { >+ for (Integer index : category.getProposalListIndices()) { >+ List<CompletionProposalCategory> list= sorted.get(index); >+ if (list == null) { >+ list= new ArrayList<CompletionProposalCategory>(); >+ sorted.put(index, list); >+ } >+ list.add(category); >+ } >+ } > } >- return included; >+ // put at least an empty first list >+ if (sorted.isEmpty()) >+ sorted.put(Integer.valueOf(0), new ArrayList<CompletionProposalCategory>()); >+ return new ArrayList<List<CompletionProposalCategory>>(sorted.values()); > } > > /** >- * Informs the user about the fact that there are no enabled categories in the default content >- * assist set and shows a link to the preferences. >- * >- * @return <code>true</code> if the default should be restored >+ * Informs the user about the fact that there are no enabled categories in the first content >+ * assist proposal list set and shows a link to the preferences. >+ * >+ * @return <code>true</code> if the default should be restored > * @since 3.3 > */ >- private boolean informUserAboutEmptyDefaultCategory() { >+ private boolean informUserAboutEmptyFirstProposalCategory() { > if (OptionalMessageDialog.isDialogEnabled(PREF_WARN_ABOUT_EMPTY_ASSIST_CATEGORY)) { > final Shell shell= JavaPlugin.getActiveWorkbenchShell(); > String title= JavaTextMessages.ContentAssistProcessor_all_disabled_title; >@@ -549,8 +539,7 @@ > if (restoreId == returnValue || settingsId == returnValue) { > if (restoreId == returnValue) { > IPreferenceStore store= JavaPlugin.getDefault().getPreferenceStore(); >- store.setToDefault(PreferenceConstants.CODEASSIST_CATEGORY_ORDER); >- store.setToDefault(PreferenceConstants.CODEASSIST_EXCLUDED_CATEGORIES); >+ store.setToDefault(PreferenceConstants.CODEASSIST_PROPOSAL_LISTS); > } > if (settingsId == returnValue) > PreferencesUtil.createPreferenceDialogOn(shell, "org.eclipse.jdt.ui.preferences.CodeAssistPreferenceAdvanced", null, null).open(); //$NON-NLS-1$ >@@ -561,17 +550,6 @@ > return false; > } > >- private List<CompletionProposalCategory> getSeparateCategories() { >- ArrayList<CompletionProposalCategory> sorted= new ArrayList<CompletionProposalCategory>(); >- for (Iterator<CompletionProposalCategory> it= fCategories.iterator(); it.hasNext();) { >- CompletionProposalCategory category= it.next(); >- if (category.isSeparateCommand() && category.hasComputers(fPartition)) >- sorted.add(category); >- } >- Collections.sort(sorted, ORDER_COMPARATOR); >- return sorted; >- } >- > private String createEmptyMessage() { > return Messages.format(JavaTextMessages.ContentAssistProcessor_empty_message, new String[]{getCategoryLabel(fRepetition)}); > } >@@ -582,13 +560,7 @@ > > private String getCategoryLabel(int repetition) { > int iteration= repetition % fCategoryIteration.size(); >- if (iteration == 0) >- return JavaTextMessages.ContentAssistProcessor_defaultProposalCategory; >- return toString(fCategoryIteration.get(iteration).get(0)); >- } >- >- private String toString(CompletionProposalCategory category) { >- return category.getDisplayName(); >+ return Messages.format(JavaTextMessages.ContentAssistProcessor_proposalList, Integer.valueOf(iteration + 1)); > } > > private String getIterationGesture() { >Index: ui/org/eclipse/jdt/internal/ui/text/java/JavaTextMessages.java >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/JavaTextMessages.java,v >retrieving revision 1.23 >diff -u -r1.23 JavaTextMessages.java >--- ui/org/eclipse/jdt/internal/ui/text/java/JavaTextMessages.java 16 Nov 2009 17:00:10 -0000 1.23 >+++ ui/org/eclipse/jdt/internal/ui/text/java/JavaTextMessages.java 18 Jul 2011 13:26:56 -0000 >@@ -7,6 +7,7 @@ > * > * Contributors: > * IBM Corporation - initial API and implementation >+ * Thomas Schlosser <schlosser@stud.tu-darmstadt.de> - 340876 [preferences][content assist] Request for more flexible configuration of content assist lists - https://bugs.eclipse.org/bugs/show_bug.cgi?id=340876 > *******************************************************************************/ > package org.eclipse.jdt.internal.ui.text.java; > >@@ -59,7 +60,7 @@ > public static String CompletionProposalComputerDescriptor_blame_message; > public static String CompletionProposalComputerRegistry_invalid_message; > public static String CompletionProposalComputerRegistry_error_dialog_title; >- public static String ContentAssistProcessor_defaultProposalCategory; >+ public static String ContentAssistProcessor_proposalList; > public static String ContentAssistProcessor_toggle_affordance_press_gesture; > public static String ContentAssistProcessor_toggle_affordance_click_gesture; > public static String ContentAssistProcessor_toggle_affordance_update_message; >Index: ui/org/eclipse/jdt/internal/ui/text/java/JavaTextMessages.properties >=================================================================== >RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/JavaTextMessages.properties,v >retrieving revision 1.35 >diff -u -r1.35 JavaTextMessages.properties >--- ui/org/eclipse/jdt/internal/ui/text/java/JavaTextMessages.properties 16 Nov 2009 17:00:10 -0000 1.35 >+++ ui/org/eclipse/jdt/internal/ui/text/java/JavaTextMessages.properties 18 Jul 2011 13:26:56 -0000 >@@ -7,6 +7,7 @@ > # > # Contributors: > # IBM Corporation - initial API and implementation >+# Thomas Schlosser <schlosser@stud.tu-darmstadt.de> - 340876 [preferences][content assist] Request for more flexible configuration of content assist lists - https://bugs.eclipse.org/bugs/show_bug.cgi?id=340876 > ############################################################################### > > CompletionProcessor_error_accessing_title=Error Accessing Compilation Unit >@@ -57,14 +58,14 @@ > ContentAssistProcessor_all_disabled_preference_link=Change the settings on the <a>Advanced Content Assist preference page</a> or click ''{0}'' to restore the default behavior. > ContentAssistProcessor_collecting_contexts=Collecting context information > ContentAssistProcessor_sorting_contexts=Sorting >-ContentAssistProcessor_defaultProposalCategory=Default Proposals >+ContentAssistProcessor_proposalList={0}. Proposal List > # {0} will be replaced by a keyboard shortcut (accelerator) > ContentAssistProcessor_toggle_affordance_press_gesture=Press ''{0}'' > ContentAssistProcessor_toggle_affordance_click_gesture=Click > # {0} will be replaced by a title describing the displayed proposal category, {1} by either the press_gesture or click_gesture message above, {2} by the name of the next proposal category > ContentAssistProcessor_toggle_affordance_update_message={1} to show {2} > # {0} will be replaced by a title describing the displayed proposal category >-ContentAssistProcessor_empty_message= No {0} >+ContentAssistProcessor_empty_message= No proposals in {0} > > ContentAssistHistory_serialize_error=Problems writing content assist history to XML > ContentAssistHistory_deserialize_error=Problems reading content assist history from XML >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 18 Jul 2011 13:26:57 -0000 >@@ -8,12 +8,19 @@ > * Contributors: > * IBM Corporation - initial API and implementation > * Guven Demir <guven.internet+eclipse@gmail.com> - [package explorer] Alternative package name shortening: abbreviation - https://bugs.eclipse.org/bugs/show_bug.cgi?id=299514 >+ * Thomas Schlosser <schlosser@stud.tu-darmstadt.de> - 340876 [preferences][content assist] Request for more flexible configuration of content assist lists - https://bugs.eclipse.org/bugs/show_bug.cgi?id=340876 > *******************************************************************************/ > package org.eclipse.jdt.ui; > > import java.util.Arrays; > import java.util.Locale; >+import java.util.HashMap; >+import java.util.HashSet; >+import java.util.Map.Entry; >+import java.util.Map; >+import java.util.Set; > import java.util.StringTokenizer; >+import java.util.TreeMap; > > import org.eclipse.swt.SWT; > import org.eclipse.swt.graphics.RGB; >@@ -3174,9 +3181,8 @@ > * Value is of type <code>String</code>, a "\0"-separated list of identifiers. > * </p> > * >- * @see #getExcludedCompletionProposalCategories() >- * @see #setExcludedCompletionProposalCategories(String[]) > * @since 3.2 >+ * @deprecated As of 3.8, use {@link #CODEASSIST_PROPOSAL_LISTS} instead > */ > public static final String CODEASSIST_EXCLUDED_CATEGORIES= "content_assist_disabled_computers"; //$NON-NLS-1$ > >@@ -3196,8 +3202,25 @@ > * </p> > * > * @since 3.2 >+ * @deprecated As of 3.8, use {@link #CODEASSIST_PROPOSAL_LISTS} instead > */ > public static final String CODEASSIST_CATEGORY_ORDER= "content_assist_category_order"; //$NON-NLS-1$ >+ >+ /** >+ * A named preference that controls which completion proposal category is included in which proposal list. >+ * <p> >+ * Value is of type <code>String</code>, a "\0"-separated list of "\1"-separated lists with categoryId where >+ * <ul> >+ * <li>categoryId is the <code>String</code> holding the category ID</li> >+ * </ul> >+ * >+ * </p> >+ * >+ * @see #getProposalLists() >+ * @see #setProposalLists(Map) >+ * @since 3.8 >+ */ >+ public static final String CODEASSIST_PROPOSAL_LISTS= "content_assist_proposal_lists"; //$NON-NLS-1$ > > /** > * A named preference that controls whether folding is enabled in the Java editor. >@@ -3784,8 +3807,7 @@ > store.setDefault(PreferenceConstants.CODEASSIST_FILL_ARGUMENT_NAMES, true); > store.setDefault(PreferenceConstants.CODEASSIST_GUESS_METHOD_ARGUMENTS, false); > store.setDefault(PreferenceConstants.CODEASSIST_PREFIX_COMPLETION, false); >- store.setDefault(PreferenceConstants.CODEASSIST_EXCLUDED_CATEGORIES, "org.eclipse.jdt.ui.textProposalCategory\0org.eclipse.jdt.ui.javaTypeProposalCategory\0org.eclipse.jdt.ui.javaNoTypeProposalCategory\0"); //$NON-NLS-1$ >- store.setDefault(PreferenceConstants.CODEASSIST_CATEGORY_ORDER, "org.eclipse.jdt.ui.spellingProposalCategory:65545\0org.eclipse.jdt.ui.javaTypeProposalCategory:65540\0org.eclipse.jdt.ui.javaNoTypeProposalCategory:65539\0org.eclipse.jdt.ui.textProposalCategory:65541\0org.eclipse.jdt.ui.javaAllProposalCategory:65542\0org.eclipse.jdt.ui.templateProposalCategory:2\0org.eclipse.jdt.ui.swtProposalCategory:3\0"); //$NON-NLS-1$ >+ store.setDefault(PreferenceConstants.CODEASSIST_PROPOSAL_LISTS, "org.eclipse.jdt.ui.templateProposalCategory:org.eclipse.jdt.ui.swtProposalCategory:org.eclipse.jdt.ui.javaAllProposalCategory:org.eclipse.pde.api.tools.ui.apitools_proposal_category:\0org.eclipse.jdt.ui.templateProposalCategory:\0org.eclipse.jdt.ui.swtProposalCategory:\0org.eclipse.pde.api.tools.ui.apitools_proposal_category:\0"); //$NON-NLS-1$ > store.setDefault(PreferenceConstants.CODEASSIST_LRU_HISTORY, ""); //$NON-NLS-1$ > store.setDefault(PreferenceConstants.CODEASSIST_SORTER, "org.eclipse.jdt.ui.RelevanceSorter"); //$NON-NLS-1$ > store.setDefault(PreferenceConstants.CODEASSIST_FAVORITE_STATIC_MEMBERS, ""); //$NON-NLS-1$ >@@ -4005,38 +4027,61 @@ > } > > /** >- * Returns the completion proposal categories which >- * are excluded from the default proposal list. >- * >- * @return an array with the IDs of the excluded categories >- * @see #CODEASSIST_EXCLUDED_CATEGORIES >- * @since 3.4 >- */ >- public static String[] getExcludedCompletionProposalCategories() { >- String encodedPreference= getPreference(CODEASSIST_EXCLUDED_CATEGORIES, null); >- StringTokenizer tokenizer= new StringTokenizer(encodedPreference, "\0"); //$NON-NLS-1$ >- String[] result= new String[tokenizer.countTokens()]; >- for (int i= 0; i < result.length; i++) >- result[i]= tokenizer.nextToken(); >+ * Returns the completion proposal categories with their corresponding proposal list indices. >+ * >+ * @return a map which maps the category IDs to a set of proposal list indices >+ * @see #CODEASSIST_PROPOSAL_LISTS >+ * @since 3.8 >+ */ >+ public static Map<String, Set<Integer>> getProposalLists() { >+ String encodedPreference= getPreference(CODEASSIST_PROPOSAL_LISTS, null); >+ Map<String, Set<Integer>> result= new HashMap<String, Set<Integer>>(); >+ StringTokenizer tok= new StringTokenizer(encodedPreference, "\0"); //$NON-NLS-1$ >+ for (int i= 0; tok.hasMoreTokens(); i++) { >+ StringTokenizer inner= new StringTokenizer(tok.nextToken(), ":"); //$NON-NLS-1$ >+ if (inner.countTokens() == 0) >+ i--; >+ while (inner.hasMoreTokens()) { >+ String category= inner.nextToken(); >+ Set<Integer> set= result.get(category); >+ if (set == null) { >+ set= new HashSet<Integer>(); >+ result.put(category, set); >+ } >+ set.add(Integer.valueOf(i)); >+ } >+ } > return result; > } > > /** >- * Sets the completion proposal categories which are excluded from the >- * default proposal list and reloads the registry. >- * >- * @param categories the array with the IDs of the excluded categories >- * @see #CODEASSIST_EXCLUDED_CATEGORIES >- * @since 3.4 >- */ >- public static void setExcludedCompletionProposalCategories(String[] categories) { >- Assert.isLegal(categories != null); >- StringBuffer buf= new StringBuffer(50 * categories.length); >- for (int i= 0; i < categories.length; i++) { >- buf.append(categories[i]); >- buf.append('\0'); >+ * Sets the completion proposal categories for each proposal list and reloads the registry. >+ * >+ * @param proposalLists a map which maps the category IDs to a set of proposal list indices >+ * @see #CODEASSIST_PROPOSAL_LISTS >+ * @since 3.8 >+ */ >+ public static void setProposalLists(Map<String, Set<Integer>> proposalLists) { >+ Assert.isLegal(proposalLists != null); >+ int initialBufferSize= 250; >+ Map<Integer, StringBuffer> proposalListsCategories= new TreeMap<Integer, StringBuffer>(); >+ for (Entry<String, Set<Integer>> category : proposalLists.entrySet()) { >+ for (Integer index : category.getValue()) { >+ StringBuffer buf= proposalListsCategories.get(index); >+ if (buf == null) { >+ buf= new StringBuffer(initialBufferSize); >+ proposalListsCategories.put(index, buf); >+ } >+ buf.append(category.getKey()); >+ buf.append(":"); //$NON-NLS-1$ >+ } >+ } >+ StringBuffer buf= new StringBuffer(initialBufferSize * proposalListsCategories.size()); >+ for (StringBuffer proposalList : proposalListsCategories.values()) { >+ buf.append(proposalList); >+ buf.append("\0"); //$NON-NLS-1$ > } >- getPreferenceStore().setValue(CODEASSIST_EXCLUDED_CATEGORIES, buf.toString()); >+ getPreferenceStore().setValue(CODEASSIST_PROPOSAL_LISTS, buf.toString()); > CompletionProposalComputerRegistry.getDefault().reload(); > } >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 340876
:
191835
|
191838
|
199831
|
199833
|
199834
|
201347
|
202831