Index: META-INF/MANIFEST.MF
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/META-INF/MANIFEST.MF,v
retrieving revision 1.91
diff -u -r1.91 MANIFEST.MF
--- META-INF/MANIFEST.MF 28 Jul 2011 19:53:25 -0000 1.91
+++ META-INF/MANIFEST.MF 11 Aug 2011 19:11:59 -0000
@@ -66,6 +66,11 @@
org.eclipse.jdt.internal.ui.packageview;x-internal:=true,
org.eclipse.jdt.internal.ui.preferences;x-friends:="org.eclipse.jdt.apt.ui",
org.eclipse.jdt.internal.ui.preferences.cleanup;x-internal:=true,
+ org.eclipse.jdt.internal.ui.preferences.codeassist.advanced;x-internal:=true,
+ org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.dnd;x-internal:=true,
+ org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.model;x-internal:=true,
+ org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.widgets;x-internal:=true,
+ org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.widgets.util;x-internal:=true,
org.eclipse.jdt.internal.ui.preferences.formatter;x-internal:=true,
org.eclipse.jdt.internal.ui.propertiesfileeditor;x-internal:=true,
org.eclipse.jdt.internal.ui.refactoring;x-internal:=true,
Index: ui/org/eclipse/jdt/internal/ui/javaeditor/JavaEditorMessages.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/javaeditor/JavaEditorMessages.java,v
retrieving revision 1.42
diff -u -r1.42 JavaEditorMessages.java
--- ui/org/eclipse/jdt/internal/ui/javaeditor/JavaEditorMessages.java 28 Jul 2011 17:39:58 -0000 1.42
+++ ui/org/eclipse/jdt/internal/ui/javaeditor/JavaEditorMessages.java 11 Aug 2011 19:12:00 -0000
@@ -8,7 +8,7 @@
* Contributors:
* IBM Corporation - initial API and implementation
* Andre Soereng - [syntax highlighting] highlight numbers - https://bugs.eclipse.org/bugs/show_bug.cgi?id=63573
- * Bj�rn Michael - [syntax highlighting] Syntax coloring for abstract classes - https://bugs.eclipse.org/331311
+ * Bj�rn Michael - [syntax highlighting] Syntax coloring for abstract classes - https://bugs.eclipse.org/331311
*******************************************************************************/
package org.eclipse.jdt.internal.ui.javaeditor;
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 11 Aug 2011 19:12:00 -0000
@@ -7,11 +7,15 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Thomas Schlosser - 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 editor
, showing only proposals computed by the
* CompletionProposalCategory
with the given categoryId
.
- *
+ *
* @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 categories= fRegistry.getProposalCategories();
- boolean[] inclusionState= new boolean[categories.size()];
- boolean[] separateState= new boolean[categories.size()];
- int i= 0;
- for (Iterator 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> categoriesState= new ArrayList>(categories.size());
+ for (CompletionProposalCategory cat : categories) {
+ categoriesState.add(new HashSet(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 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 fCategoryComparator= new Comparator() {
- 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 fElements;
- /**
- * The read-only list of elements.
- */
- final List elements;
-
- public PreferenceModel(CompletionProposalComputerRegistry registry) {
- List categories= registry.getProposalCategories();
- fElements= new ArrayList();
- for (Iterator 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 it= fElements.iterator(); it.hasNext();) {
- ModelElement item= it.next();
- boolean included= changed == item ? isInDefaultCategory : item.isInDefaultCategory();
- if (!included)
- buf.append(item.getId() + SEPARATOR);
- }
-
- String newValue= buf.toString();
- String oldValue= setValue(PREF_EXCLUDED_CATEGORIES, newValue);
- validateSettings(PREF_EXCLUDED_CATEGORIES, oldValue, newValue);
- }
-
- private void writeOrderPreference(ModelElement changed, boolean isSeparate) {
- StringBuffer buf= new StringBuffer();
- int i= 0;
- for (Iterator it= fElements.iterator(); it.hasNext(); i++) {
- ModelElement item= it.next();
- boolean separate= changed == item ? isSeparate : item.isSeparateCommand();
- int rank= separate ? i : i + LIMIT;
- buf.append(item.getId() + COLON + rank + SEPARATOR);
- }
-
- String newValue= buf.toString();
- String oldValue= setValue(PREF_CATEGORY_ORDER, newValue);
- validateSettings(PREF_CATEGORY_ORDER, oldValue, newValue);
- }
-
-
- private boolean readInclusionPreference(CompletionProposalCategory cat) {
- String[] ids= getTokens(getValue(PREF_EXCLUDED_CATEGORIES), SEPARATOR);
- for (int i= 0; i < ids.length; i++) {
- if (ids[i].equals(cat.getId()))
- return false;
- }
- return true;
- }
-
- private int readOrderPreference(CompletionProposalCategory cat) {
- String[] sortOrderIds= getTokens(getValue(PREF_CATEGORY_ORDER), SEPARATOR);
- for (int i= 0; i < sortOrderIds.length; i++) {
- String[] idAndRank= getTokens(sortOrderIds[i], COLON);
- if (idAndRank[0].equals(cat.getId()))
- return Integer.parseInt(idAndRank[1]);
- }
- 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 fImages= new HashMap();
-
- 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 defaultChecked= new ArrayList(size);
- List separateChecked= new ArrayList(size);
-
- for (Iterator 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 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 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 11 Aug 2011 19:12:00 -0000
@@ -7,6 +7,7 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Thomas Schlosser - 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.144
diff -u -r1.144 PreferencesMessages.java
--- ui/org/eclipse/jdt/internal/ui/preferences/PreferencesMessages.java 28 Jul 2011 17:39:58 -0000 1.144
+++ ui/org/eclipse/jdt/internal/ui/preferences/PreferencesMessages.java 11 Aug 2011 19:12:00 -0000
@@ -11,6 +11,7 @@
* Sebastian Davids, sdavids@gmx.de - 187316 [preferences] Mark Occurences Pref Page; Link to
* Benjamin Muskalla - [preferences] Add preference for new compiler warning: MissingSynchronizedModifierInInheritedMethod - https://bugs.eclipse.org/bugs/show_bug.cgi?id=245240
* Guven Demir - [package explorer] Alternative package name shortening: abbreviation - https://bugs.eclipse.org/bugs/show_bug.cgi?id=299514
+ * Thomas Schlosser - 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.531
diff -u -r1.531 PreferencesMessages.properties
--- ui/org/eclipse/jdt/internal/ui/preferences/PreferencesMessages.properties 28 Jul 2011 17:39:58 -0000 1.531
+++ ui/org/eclipse/jdt/internal/ui/preferences/PreferencesMessages.properties 11 Aug 2011 19:12:01 -0000
@@ -11,6 +11,7 @@
# Sebastian Davids, sdavids@gmx.de - 187316 [preferences] Mark Occurrences Pref Page; Link to
# Benjamin Muskalla - [preferences] Add preference for new compiler warning: MissingSynchronizedModifierInInheritedMethod - https://bugs.eclipse.org/bugs/show_bug.cgi?id=245240
# Guven Demir - [package explorer] Alternative package name shortening: abbreviation - https://bugs.eclipse.org/bugs/show_bug.cgi?id=299514
+# Thomas Schlosser - 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.
@@ -849,15 +850,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 'Keys' 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,423 @@
+/*******************************************************************************
+ * 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 - 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.Observable;
+import java.util.Observer;
+
+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.ParameterizedCommand;
+
+import org.eclipse.core.runtime.Assert;
+
+import org.eclipse.jface.layout.PixelConverter;
+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.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.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.DragProvidedCategoriesListener;
+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.dnd.DragState;
+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.ImageHandler;
+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.model.KeyboardBindings;
+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 implements Observer {
+
+ 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 ImageHandler fImageHandler;
+
+ private TableViewer fProvidedViewer;
+
+ private ProposalListSection fProposalListSection;
+
+ public CodeAssistAdvancedConfigurationBlock(IStatusChangeListener statusListener, IWorkbenchPreferenceContainer container) {
+ super(statusListener, null, getAllKeys(), container);
+ fImageHandler= new ImageHandler();
+ fModel= new PreferenceModel(CompletionProposalComputerRegistry.getDefault(), fImageHandler);
+ }
+
+ /*
+ * @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, fImageHandler);
+
+ createFiller(composite);
+
+ createParameterTimeoutControl(composite);
+
+ updateControls();
+ selectFirstProvidedCategory();
+
+ addToObservable();
+
+ 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= KeyboardBindings.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.MULTI | 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() };
+ DragProvidedCategoriesListener dragListener= new DragProvidedCategoriesListener(fProvidedViewer);
+ DragState.addToObservable(dragListener);
+ fProvidedViewer.addDragSupport(ProposalTransfer.ALL_DRAG_OPERATIONS, transferTypes, dragListener);
+
+ // add drop support for proposal lists and proposal list categories
+ transferTypes= new Transfer[] { ProposalListTransfer.getInstance(), ProposalListCategoryTransfer.getInstance() };
+ DropIntoProvidedListener dropListener= new DropIntoProvidedListener(fModel);
+ dropListener.addUpdateObserver(this);
+ fProvidedViewer.addDropSupport(ProposalTransfer.ALL_DRAG_OPERATIONS, transferTypes, dropListener);
+ }
+
+ 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);
+ }
+
+ private void addToObservable() {
+ fModel.addObserver(this);
+ fProposalListSection.addUpdateObserver(this);
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.ui.preferences.OptionsConfigurationBlock#settingsUpdated()
+ */
+ @Override
+ protected void settingsUpdated() {
+ 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) {
+ updatePreferenceModel();
+ 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() {
+ fImageHandler.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();
+ }
+ }
+
+ public void update(Observable o, Object arg) {
+ if (arg == null) {
+ updateControls();
+ } else {
+ String newValue= (String) arg;
+ updatePreferenceModel(newValue);
+ }
+ }
+
+ private void updatePreferenceModel(String newValue) {
+ String oldValue= setProposalListsPrefsValue(newValue);
+ validateProposalListsPrefsSettings(oldValue, newValue);
+ updatePreferenceModel();
+ }
+
+ private void updatePreferenceModel() {
+ if (fModel != null)
+ fModel.updatePreferenceModel(getProposalListsPrefsValue());
+ }
+
+ protected String setProposalListsPrefsValue(String value) {
+ return setValue(CodeAssistAdvancedConfigurationBlock.PREF_PROPOSAL_LISTS, value);
+ }
+
+ protected String getProposalListsPrefsValue() {
+ return getValue(CodeAssistAdvancedConfigurationBlock.PREF_PROPOSAL_LISTS);
+ }
+
+ protected void validateProposalListsPrefsSettings(String oldValue, String newValue) {
+ validateSettings(CodeAssistAdvancedConfigurationBlock.PREF_PROPOSAL_LISTS, oldValue, newValue);
+ }
+}
Index: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/AutoscrollDropTargetAdapter.java
===================================================================
RCS file: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/AutoscrollDropTargetAdapter.java
diff -N ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/AutoscrollDropTargetAdapter.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/AutoscrollDropTargetAdapter.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,76 @@
+/**
+ * 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 - initial API and implementation.
+ */
+package org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.dnd;
+
+import java.util.Observable;
+import java.util.Observer;
+import java.util.Vector;
+
+import org.eclipse.swt.dnd.DropTargetEvent;
+import org.eclipse.swt.dnd.DropTargetListener;
+import org.eclipse.swt.graphics.Point;
+
+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.widgets.util.AutoscrollObservable;
+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.widgets.util.AutoscrollObserver;
+
+/**
+ *
+ * @since 3.8
+ */
+public class AutoscrollDropTargetAdapter extends Observable implements DropTargetListener, AutoscrollObservable {
+
+ private Vector fDragOverObservers;
+
+ public AutoscrollDropTargetAdapter() {
+ this.fDragOverObservers= new Vector();
+ }
+
+ public void dragEnter(DropTargetEvent event) {
+ }
+
+ public void dragLeave(DropTargetEvent event) {
+ }
+
+ public void dragOperationChanged(DropTargetEvent event) {
+ }
+
+ public void dragOver(DropTargetEvent event) {
+ notifyAutoscrollObservers(new Point(event.x, event.y));
+ }
+
+ public void drop(DropTargetEvent event) {
+ }
+
+ public void dropAccept(DropTargetEvent event) {
+ }
+
+ public synchronized void addUpdateObserver(Observer o) {
+ super.addObserver(o);
+ }
+
+ protected void notifyUpdateObservers() {
+ setChanged();
+ notifyObservers();
+ }
+
+ public synchronized void addAutoscrollObserver(AutoscrollObserver o) {
+ if (o == null)
+ throw new NullPointerException();
+ if (!fDragOverObservers.contains(o)) {
+ fDragOverObservers.addElement(o);
+ }
+ }
+
+ protected synchronized void notifyAutoscrollObservers(Point p) {
+ for (AutoscrollObserver o : fDragOverObservers)
+ o.autoScroll(p);
+ }
+}
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,42 @@
+/**
+ * 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 - 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;
+
+/**
+ *
+ * @since 3.8
+ */
+public class AutoscrollDropTargetListener extends AutoscrollDropTargetAdapter {
+
+ @Override
+ public void dragEnter(DropTargetEvent event) {
+ event.detail= DND.DROP_NONE;
+ }
+
+ @Override
+ public void dragOperationChanged(DropTargetEvent event) {
+ event.detail= DND.DROP_NONE;
+ }
+
+ @Override
+ public void drop(DropTargetEvent event) {
+ event.detail= DND.DROP_NONE;
+ }
+
+ @Override
+ public void dropAccept(DropTargetEvent event) {
+ event.detail= DND.DROP_NONE;
+ }
+}
Index: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/BaseDropTargetAdapter.java
===================================================================
RCS file: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/BaseDropTargetAdapter.java
diff -N ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/BaseDropTargetAdapter.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/BaseDropTargetAdapter.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,95 @@
+/**
+ * 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 - 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.jdt.internal.ui.preferences.codeassist.advanced.model.PreferenceModel;
+
+/**
+ *
+ * @since 3.8
+ */
+public abstract class BaseDropTargetAdapter extends AutoscrollDropTargetAdapter {
+
+ protected final PreferenceModel fModel;
+
+ public BaseDropTargetAdapter(PreferenceModel model) {
+ this.fModel= model;
+ }
+
+ @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) {
+ super.dragOver(event);
+ event.feedback= DND.FEEDBACK_NONE;
+ }
+
+ @Override
+ public void drop(DropTargetEvent event) {
+ if (!isValidProposalTransferTypeArray(event.data)) {
+ event.detail= DND.DROP_NONE;
+ return;
+ }
+ ProposalTransferType[] data= (ProposalTransferType[]) event.data;
+ boolean successfulTransfer= dropProposalTransfers(data, event.detail);
+ if (successfulTransfer)
+ notifyUpdateObservers();
+ else
+ event.detail= DND.DROP_NONE;
+ }
+
+ private boolean isValidProposalTransferTypeArray(Object data) {
+ if (data == null || !(data instanceof ProposalTransferType[]))
+ return false;
+ return true;
+ }
+
+ protected abstract boolean dropProposalTransfers(ProposalTransferType[] data, int detail);
+
+ protected final boolean isProvidedListCategory(ProposalTransferType data) {
+ return data.getListIndex() == null && fModel.isValidCategoryId(data.getCategoryId());
+ }
+
+ protected final boolean isProposalList(ProposalTransferType data) {
+ return data.getListIndex() != null && data.getCategoryId() == null;
+ }
+
+ protected final boolean isProposalListCategory(ProposalTransferType data) {
+ return data.getListIndex() != null && fModel.isValidCategoryId(data.getCategoryId());
+ }
+
+ protected 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/DragCategoriesListener.java
===================================================================
RCS file: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/DragCategoriesListener.java
diff -N ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/DragCategoriesListener.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/DragCategoriesListener.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,72 @@
+/**
+ * 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 - initial API and implementation.
+ */
+package org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.dnd;
+
+import java.util.Iterator;
+import java.util.Observable;
+
+import org.eclipse.swt.dnd.DragSourceEvent;
+import org.eclipse.swt.dnd.DragSourceListener;
+import org.eclipse.swt.dnd.TransferData;
+
+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 abstract class DragCategoriesListener extends Observable implements DragSourceListener {
+ private final TableViewer fViewer;
+
+ public DragCategoriesListener(TableViewer viewer) {
+ this.fViewer= viewer;
+ }
+
+ public void dragSetData(DragSourceEvent event) {
+ if (isSupportedDataType(event.dataType)) {
+ IStructuredSelection selection= (IStructuredSelection) fViewer.getSelection();
+ if (selection != null && !selection.isEmpty())
+ event.data= getTransferData(selection);
+ }
+ }
+
+ protected abstract boolean isSupportedDataType(TransferData dataType);
+
+ private ProposalTransferType[] getTransferData(IStructuredSelection selection) {
+ ProposalTransferType[] transferData= new ProposalTransferType[selection.size()];
+ int i= 0;
+ for (Iterator meIt= selection.iterator(); meIt.hasNext();) {
+ ModelElement me= meIt.next();
+ if (me != null)
+ transferData[i++]= createProposalTransferElement(me);
+ }
+ return transferData;
+ }
+
+ protected abstract ProposalTransferType createProposalTransferElement(ModelElement me);
+
+ public void dragStart(DragSourceEvent event) {
+ if (fViewer.getSelection() == null || fViewer.getSelection().isEmpty())
+ event.doit= false;
+ else {
+ setChanged();
+ notifyObservers(Boolean.TRUE);
+ }
+ }
+
+ public void dragFinished(DragSourceEvent event) {
+ setChanged();
+ notifyObservers(Boolean.FALSE);
+ }
+}
Index: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/DragProposalListCategoriesListener.java
===================================================================
RCS file: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/DragProposalListCategoriesListener.java
diff -N ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/DragProposalListCategoriesListener.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/DragProposalListCategoriesListener.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,40 @@
+/**
+ * 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 - initial API and implementation.
+ */
+package org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.dnd;
+
+import org.eclipse.swt.dnd.TransferData;
+
+import org.eclipse.jface.viewers.TableViewer;
+
+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.model.ModelElement;
+
+/**
+ *
+ * @since 3.8
+ */
+public final class DragProposalListCategoriesListener extends DragCategoriesListener {
+ private final Integer fListIndex;
+
+ public DragProposalListCategoriesListener(TableViewer viewer, int listIndex) {
+ super(viewer);
+ this.fListIndex= Integer.valueOf(listIndex);
+ }
+
+ @Override
+ protected boolean isSupportedDataType(TransferData dataType) {
+ return ProposalListCategoryTransfer.getInstance().isSupportedType(dataType);
+ }
+
+ @Override
+ protected ProposalTransferType createProposalTransferElement(ModelElement me) {
+ return new ProposalTransferType(me.getId(), fListIndex);
+ }
+}
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,44 @@
+/**
+ * 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 - initial API and implementation.
+ */
+package org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.dnd;
+
+import java.util.Observable;
+
+import org.eclipse.swt.dnd.DragSourceEvent;
+import org.eclipse.swt.dnd.DragSourceListener;
+
+/**
+ *
+ * @since 3.8
+ */
+public final class DragProposalListListener extends Observable 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) {
+ setChanged();
+ notifyObservers(Boolean.TRUE);
+ }
+
+ public void dragFinished(DragSourceEvent event) {
+ setChanged();
+ notifyObservers(Boolean.FALSE);
+ }
+}
Index: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/DragProvidedCategoriesListener.java
===================================================================
RCS file: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/DragProvidedCategoriesListener.java
diff -N ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/DragProvidedCategoriesListener.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/DragProvidedCategoriesListener.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 - initial API and implementation.
+ */
+package org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.dnd;
+
+import org.eclipse.swt.dnd.TransferData;
+
+import org.eclipse.jface.viewers.TableViewer;
+
+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.model.ModelElement;
+
+/**
+ *
+ * @since 3.8
+ */
+public final class DragProvidedCategoriesListener extends DragCategoriesListener {
+
+ public DragProvidedCategoriesListener(TableViewer viewer) {
+ super(viewer);
+ }
+
+ @Override
+ protected boolean isSupportedDataType(TransferData dataType) {
+ return ProvidedCategoryTransfer.getInstance().isSupportedType(dataType);
+ }
+
+ @Override
+ protected ProposalTransferType createProposalTransferElement(ModelElement me) {
+ return new ProposalTransferType(me.getId());
+ }
+}
Index: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/DragState.java
===================================================================
RCS file: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/DragState.java
diff -N ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/DragState.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/DragState.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,50 @@
+/**
+ * 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 - initial API and implementation.
+ */
+package org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.dnd;
+
+import java.util.Observable;
+import java.util.Observer;
+
+/**
+ *
+ * @since 3.8
+ */
+public class DragState implements Observer {
+
+ private boolean dragged;
+
+ private static DragState instance= new DragState();
+
+ private DragState() {
+ }
+
+ public static DragState getInstance() {
+ return instance;
+ }
+
+ public void update(Observable o, Object arg) {
+ if (arg != null && arg instanceof Boolean)
+ dragged= (((Boolean) arg).booleanValue());
+ }
+
+ public static boolean isDragged() {
+ return getInstance().dragged;
+ }
+
+ public static boolean isNotDragged() {
+ return !getInstance().dragged;
+ }
+
+ public static void addToObservable(Observable o) {
+ o.addObserver(getInstance());
+ }
+
+}
Index: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/DropHighlightListener.java
===================================================================
RCS file: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/DropHighlightListener.java
diff -N ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/DropHighlightListener.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/dnd/DropHighlightListener.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,73 @@
+/**
+ * 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 - initial API and implementation.
+ */
+package org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.dnd;
+
+import java.util.Vector;
+
+import org.eclipse.swt.dnd.DND;
+import org.eclipse.swt.dnd.DropTargetEvent;
+
+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.model.PreferenceModel;
+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.widgets.util.HighlightObservable;
+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.widgets.util.HighlightObserver;
+
+/**
+ *
+ * @since 3.8
+ */
+public abstract class DropHighlightListener extends BaseDropTargetAdapter implements HighlightObservable {
+
+ private Vector fHighlightObservers;
+
+ public DropHighlightListener(PreferenceModel model) {
+ super(model);
+ this.fHighlightObservers= new Vector();
+ }
+
+ @Override
+ public void dragLeave(DropTargetEvent event) {
+ notifyHighlightObservers(false);
+ }
+
+ @Override
+ public void dragOperationChanged(DropTargetEvent event) {
+ super.dragOperationChanged(event);
+ if (event.detail == DND.DROP_NONE)
+ notifyHighlightObservers(false);
+ }
+
+ @Override
+ public void dragOver(DropTargetEvent event) {
+ super.dragOver(event);
+ if (event.detail != DND.DROP_NONE)
+ notifyHighlightObservers(true);
+ }
+
+ @Override
+ public void dropAccept(DropTargetEvent event) {
+ if (!(ProvidedCategoryTransfer.getInstance().isSupportedType(event.currentDataType) ||
+ ProposalListCategoryTransfer.getInstance().isSupportedType(event.currentDataType) || ProposalListTransfer.getInstance().isSupportedType(event.currentDataType)))
+ event.detail= DND.DROP_NONE;
+ }
+
+ public synchronized void addHighlightObserver(HighlightObserver o) {
+ if (o == null)
+ throw new NullPointerException();
+ if (!fHighlightObservers.contains(o)) {
+ fHighlightObservers.addElement(o);
+ }
+ }
+
+ protected synchronized void notifyHighlightObservers(boolean highlight) {
+ for (HighlightObserver o : fHighlightObservers)
+ o.highlight(highlight);
+ }
+}
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,110 @@
+/**
+ * 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 - initial API and implementation.
+ */
+package org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.dnd;
+
+import org.eclipse.swt.dnd.DND;
+
+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.model.PreferenceModel;
+
+/**
+ *
+ * @since 3.8
+ */
+public final class DropIntoProposalListListener extends DropHighlightListener {
+
+ private final int fListIndex;
+
+ public DropIntoProposalListListener(int listIndex, PreferenceModel model) {
+ super(model);
+ this.fListIndex= listIndex;
+ }
+
+ @Override
+ protected boolean dropProposalTransfers(ProposalTransferType[] data, int detail) {
+ boolean successfulTransfer= false;
+ for (ProposalTransferType ptt : data)
+ successfulTransfer|= drop(ptt, detail);
+ return successfulTransfer;
+ }
+
+ private boolean drop(ProposalTransferType data, int detail) {
+ if (data == null || isSourceEqualTarget(data.getListIndex()))
+ return false;
+
+ if (isProvidedListCategory(data))
+ return dropProvidedListCategory(data, detail);
+ if (isProposalList(data))
+ return dropProposalList(data.getListIndex(), detail);
+ if (isProposalListCategory(data))
+ return dropProposalListCategory(data, data.getListIndex(), detail);
+
+ return false;
+ }
+
+ private boolean isSourceEqualTarget(Integer sourceListIndex) {
+ return sourceListIndex != null && sourceListIndex.intValue() == fListIndex;
+ }
+
+ private boolean dropProvidedListCategory(ProposalTransferType data, int detail) {
+ switch (detail) {
+ case DND.DROP_COPY:
+ copyElementToList(data.getCategoryId());
+ break;
+ default:
+ return false;
+ }
+ return true;
+ }
+
+ private boolean dropProposalList(Integer sourceListIndex, int detail) {
+ switch (detail) {
+ case DND.DROP_COPY:
+ copyAllElementsToList(sourceListIndex.intValue());
+ break;
+ case DND.DROP_MOVE:
+ moveAllElementsToList(sourceListIndex.intValue());
+ break;
+ default:
+ return false;
+ }
+ return true;
+ }
+
+ private boolean dropProposalListCategory(ProposalTransferType data, Integer sourceListIndex, int detail) {
+ switch (detail) {
+ case DND.DROP_COPY:
+ copyElementToList(data.getCategoryId());
+ break;
+ case DND.DROP_MOVE:
+ moveElementToList(data.getCategoryId(), sourceListIndex.intValue());
+ break;
+ default:
+ return false;
+ }
+ return true;
+ }
+
+ private void copyAllElementsToList(int sourceListIndex) {
+ fModel.mergeLists(sourceListIndex, fListIndex, false);
+ }
+
+ private void moveAllElementsToList(int sourceListIndex) {
+ fModel.mergeLists(sourceListIndex, fListIndex, true);
+ }
+
+ private void copyElementToList(String categoryId) {
+ fModel.getElement(categoryId).setInProposalList(fListIndex);
+ }
+
+ private void moveElementToList(String categoryId, int sourceListIndex) {
+ fModel.getElement(categoryId).moveToProposalList(sourceListIndex, fListIndex);
+ }
+}
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,72 @@
+/**
+ * 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 - 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.jdt.internal.ui.preferences.codeassist.advanced.model.PreferenceModel;
+
+/**
+ *
+ * @since 3.8
+ */
+public final class DropIntoProvidedListener extends BaseDropTargetAdapter {
+
+ public DropIntoProvidedListener(PreferenceModel model) {
+ super(model);
+ }
+
+ @Override
+ protected boolean dropProposalTransfers(ProposalTransferType[] data, int detail) {
+ boolean successfulTransfer= false;
+ for (ProposalTransferType ptt : data)
+ successfulTransfer|= drop(ptt);
+ return successfulTransfer;
+ }
+
+ private boolean drop(ProposalTransferType data) {
+ if (data == null)
+ return false;
+
+ if (isProposalList(data))
+ return dropProposalList(data.getListIndex());
+ if (isProposalListCategory(data))
+ return dropProposalListCategory(data, data.getListIndex());
+
+ return false;
+ }
+
+ private boolean dropProposalList(Integer sourceListIndex) {
+ fModel.removeList(sourceListIndex.intValue());
+ return true;
+ }
+
+ private boolean dropProposalListCategory(ProposalTransferType data, Integer sourceListIndex) {
+ fModel.getElement(data.getCategoryId()).removeInProposalList(sourceListIndex.intValue());
+ return true;
+ }
+
+ @Override
+ public void dropAccept(DropTargetEvent event) {
+ if (!(ProposalListCategoryTransfer.getInstance().isSupportedType(event.currentDataType) || ProposalListTransfer.getInstance().isSupportedType(event.currentDataType)))
+ event.detail= DND.DROP_NONE;
+ }
+
+ @Override
+ protected int getCompatibleOperation(int detail, int operations, TransferData currentDataType) {
+ int operation= super.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,156 @@
+/**
+ * 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 - initial API and implementation.
+ */
+package org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.dnd;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.swt.dnd.DND;
+
+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.model.PreferenceModel;
+
+/**
+ *
+ * @since 3.8
+ */
+public final class DropNewProposalListListener extends DropHighlightListener {
+
+ private final int fListIndex;
+
+ private final class RemoveCategoryEntry implements Comparable {
+ final String fCategoryId;
+
+ final Integer fIndex;
+
+ private RemoveCategoryEntry(String categoryId, Integer index) {
+ this.fCategoryId= categoryId;
+ this.fIndex= index;
+ }
+
+ public int compareTo(RemoveCategoryEntry o) {
+ return o.fIndex.compareTo(this.fIndex); // reverse order
+ }
+ }
+
+ public DropNewProposalListListener(int listIndex, PreferenceModel model) {
+ super(model);
+ this.fListIndex= listIndex;
+ }
+
+ @Override
+ protected boolean dropProposalTransfers(ProposalTransferType[] data, int detail) {
+ if (data == null || data.length == 0)
+ return false;
+
+ if (isProvidedListCategory(data[0]))
+ return dropProvidedListCategories(data, detail);
+ if (isProposalList(data[0]))
+ return dropProposalList(data[0].getListIndex(), detail);
+ if (isProposalListCategory(data[0]))
+ return dropProposalListCategories(data, detail);
+
+ return false;
+ }
+
+ private boolean dropProvidedListCategories(ProposalTransferType[] data, int detail) {
+ switch (detail) {
+ case DND.DROP_COPY:
+ copyCategoriesToNewList(getCategoryIds(data));
+ break;
+ default:
+ return false;
+ }
+ return true;
+ }
+
+ private boolean dropProposalList(Integer sourceListIndex, int detail) {
+ int sourceIndex= sourceListIndex.intValue();
+ switch (detail) {
+ case DND.DROP_COPY:
+ copyCategoriesToNewList(getCategoryIdsFromModel(sourceIndex));
+ break;
+ case DND.DROP_MOVE:
+ if (isSourceUnequalTarget(sourceIndex))
+ moveList(sourceIndex);
+ else
+ return false;
+ break;
+ default:
+ return false;
+ }
+ return true;
+ }
+
+ private boolean dropProposalListCategories(ProposalTransferType[] data, int detail) {
+ switch (detail) {
+ case DND.DROP_MOVE:
+ copyCategoriesToNewList(getCategoryIds(data));
+ removeCategories(data);
+ break;
+ case DND.DROP_COPY:
+ copyCategoriesToNewList(getCategoryIds(data));
+ break;
+ default:
+ return false;
+ }
+ return true;
+ }
+
+ private void copyCategoriesToNewList(List categoryIds) {
+ fModel.addNewList(fListIndex, categoryIds);
+ }
+
+ private boolean isSourceUnequalTarget(int sourceIndex) {
+ return sourceIndex != fListIndex && sourceIndex + 1 != fListIndex;
+ }
+
+ private void moveList(int sourceIndex) {
+ fModel.moveList(sourceIndex, fListIndex);
+ }
+
+ private List getCategoryIds(ProposalTransferType[] data) {
+ List ids= new ArrayList(data.length);
+ for (ProposalTransferType ptt : data)
+ ids.add(ptt.getCategoryId());
+ return ids;
+ }
+
+ private List getCategoryIdsFromModel(int listIndex) {
+ return fModel.getCategoryIds(listIndex);
+ }
+
+ private void removeCategories(ProposalTransferType[] data) {
+ removeCategories(getSortedRemoveCategories(data));
+ }
+
+ private List getSortedRemoveCategories(ProposalTransferType[] data) {
+ List indices= new ArrayList(data.length);
+ for (ProposalTransferType ptt : data) {
+ if (ptt.getListIndex() == null)
+ continue;
+ int sourceIndex= ptt.getListIndex().intValue();
+ int removeIndex= fListIndex > sourceIndex ? sourceIndex : sourceIndex + 1;
+ indices.add(new RemoveCategoryEntry(ptt.getCategoryId(), Integer.valueOf(removeIndex)));
+ }
+ Collections.sort(indices);
+ return indices;
+ }
+
+ private void removeCategories(List categories) {
+ for (RemoveCategoryEntry cat : categories)
+ removeCategory(cat);
+ }
+
+ private void removeCategory(RemoveCategoryEntry category) {
+ fModel.getElement(category.fCategoryId).removeInProposalList(category.fIndex.intValue());
+ }
+}
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 - 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 - 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 - 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 props= new ArrayList();
+ 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 - 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 - 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/ImageHandler.java
===================================================================
RCS file: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/model/ImageHandler.java
diff -N ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/model/ImageHandler.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/model/ImageHandler.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,47 @@
+/**
+ * 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 - initial API and implementation.
+ */
+package org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.model;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.eclipse.swt.graphics.Image;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+
+/**
+ *
+ * @since 3.8
+ */
+public class ImageHandler {
+
+ private final Map fImages= new HashMap();
+
+ public 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;
+ }
+
+ public void dispose() {
+ for (Iterator it= fImages.values().iterator(); it.hasNext();) {
+ Image image= it.next();
+ image.dispose();
+ }
+ }
+}
Index: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/model/KeyboardBindings.java
===================================================================
RCS file: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/model/KeyboardBindings.java
diff -N ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/model/KeyboardBindings.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/model/KeyboardBindings.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,68 @@
+/**
+ * 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 - initial API and implementation.
+ */
+package org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.model;
+
+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.jface.bindings.BindingManager;
+import org.eclipse.jface.bindings.Scheme;
+import org.eclipse.jface.bindings.TriggerSequence;
+
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.keys.IBindingService;
+
+import org.eclipse.jdt.internal.ui.JavaPlugin;
+
+/**
+ *
+ * @since 3.8
+ */
+public class KeyboardBindings {
+ 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());
+ }
+
+ public 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/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,127 @@
+/**
+ * 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 - 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.text.java.CompletionProposalCategory;
+
+/**
+ *
+ * @since 3.8
+ */
+public final class ModelElement {
+
+ public static final class ModelElementComparator implements Comparator {
+ 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 ImageHandler fImageHandler;
+
+ private final CompletionProposalCategory fCategory;
+
+ private final Command fCommand;
+
+ private final IParameter fParam;
+
+ private final PreferenceModel fPreferenceModel;
+
+ ModelElement(CompletionProposalCategory category, PreferenceModel model, ImageHandler imageHandler) {
+ 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;
+ fImageHandler= imageHandler;
+ }
+
+ public Image getImage() {
+ return fImageHandler.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= KeyboardBindings.getKeyboardShortcut(pCmd);
+ return key;
+ }
+
+ public Set 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 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,231 @@
+/**
+ * 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 - 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.Observable;
+import java.util.Set;
+import java.util.StringTokenizer;
+import java.util.TreeMap;
+
+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 extends Observable {
+ private static final String COLON= ":"; //$NON-NLS-1$
+
+ private static final String SEPARATOR= "\0"; //$NON-NLS-1$
+
+ private final List fElements;
+
+ /**
+ * The read-only list of elements.
+ */
+ public final List elements;
+
+ public PreferenceModel(CompletionProposalComputerRegistry registry, ImageHandler imageHandler) {
+ List categories= registry.getProposalCategories();
+ fElements= new ArrayList();
+ for (CompletionProposalCategory category : categories)
+ if (category.hasComputers())
+ fElements.add(new ModelElement(category, this, imageHandler));
+ elements= Collections.unmodifiableList(fElements);
+ }
+
+ public void changeSingleCategory(ModelElement changed, Integer addIndex, Integer removeIndex) {
+ int initialBufferSize= 50 * fElements.size();
+ Map proposalListsCategories= new TreeMap();
+ for (ModelElement item : fElements) {
+ Set indices= new HashSet(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 proposalListsCategories= new TreeMap();
+ 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 categoryIds) {
+ int initialBufferSize= 50 * fElements.size();
+ Map proposalListsCategories= new TreeMap();
+ 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 proposalListsCategories= new TreeMap();
+ 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 proposalListsCategories= new TreeMap();
+ for (ModelElement item : fElements) {
+ Set indices= new HashSet(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 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();
+ setChanged();
+ notifyObservers(newValue);
+ }
+
+ public void updatePreferenceModel(String newValue) {
+ Map> newConfig= new HashMap>();
+ StringTokenizer tok= new StringTokenizer(newValue, 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 indices= newConfig.get(categoryId);
+ if (indices == null) {
+ indices= new HashSet();
+ 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 getElements(int index) {
+ List result= new ArrayList();
+ for (ModelElement el : fElements)
+ if (el.getProposalListIndices() != null && el.getProposalListIndices().contains(Integer.valueOf(index)))
+ result.add(el);
+ return result;
+ }
+
+ public List getCategoryIds(int index) {
+ List result= new ArrayList();
+ 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,113 @@
+/**
+ * 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 - initial API and implementation.
+ */
+package org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.widgets;
+
+import java.util.Observer;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.dnd.DropTarget;
+import org.eclipse.swt.dnd.Transfer;
+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.Display;
+
+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;
+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.widgets.util.HighlightObserver;
+
+/**
+ *
+ * @since 3.8
+ */
+public final class NewListDropSection implements HighlightObserver {
+ private static final Color SELECTED_COLOR= Display.getCurrent().getSystemColor(SWT.COLOR_LIST_SELECTION);
+
+ private static final Color UNSELECTED_COLOR= Display.getCurrent().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND);
+
+ private final PreferenceModel fModel;
+
+ private final ProposalListSection fProposalListSection;
+
+ private DropNewProposalListListener fDropListener;
+
+ private Composite fPaddingComposite;
+
+ private Composite fHighlightComposite;
+
+ public NewListDropSection(Composite wrappingComposite, int listIndex, PreferenceModel model, ProposalListSection proposalListSection) {
+ this.fModel= model;
+ this.fProposalListSection= proposalListSection;
+
+ createPaddingComposite(wrappingComposite);
+ createHighlightComposite();
+
+ addDropSupport(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();
+ }
+
+ public void highlight(boolean selected) {
+ if (selected)
+ fHighlightComposite.setBackground(SELECTED_COLOR);
+ else
+ fHighlightComposite.setBackground(UNSELECTED_COLOR);
+ fHighlightComposite.update();
+ }
+
+ public void addUpdateObserver(Observer o) {
+ fDropListener.addUpdateObserver(o);
+ }
+
+ private void createPaddingComposite(Composite wrappingComposite) {
+ fPaddingComposite= new Composite(wrappingComposite, SWT.NONE);
+ GridData gd= new GridData(GridData.FILL, GridData.BEGINNING, true, false);
+ gd.heightHint= 10;
+ fPaddingComposite.setLayoutData(gd);
+ GridLayout layout= new GridLayout();
+ layout.marginHeight= 0;
+ layout.verticalSpacing= 0;
+ layout.marginWidth= 0;
+ fPaddingComposite.setLayout(layout);
+ }
+
+ private void createHighlightComposite() {
+ fHighlightComposite= new Composite(fPaddingComposite, SWT.NONE);
+ GridData gd= new GridData(SWT.FILL, SWT.BEGINNING, true, true);
+ gd.heightHint= 2;
+ gd.verticalIndent= 4;
+ fHighlightComposite.setLayoutData(gd);
+ }
+
+ private void addDropSupport(int listIndex) {
+ Transfer[] transferTypes= new Transfer[] { ProvidedCategoryTransfer.getInstance(), ProposalListCategoryTransfer.getInstance(), ProposalListTransfer.getInstance() };
+ DropTarget dropTarget= new DropTarget(fPaddingComposite, ProposalTransfer.ALL_DRAG_OPERATIONS);
+ dropTarget.setTransfer(transferTypes);
+ fDropListener= new DropNewProposalListListener(listIndex, fModel);
+ fProposalListSection.addToAutoscrollObserver(fDropListener);
+ fDropListener.addHighlightObserver(this);
+ dropTarget.addDropListener(fDropListener);
+ }
+}
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,500 @@
+/**
+ * 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 - 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 java.util.Observable;
+import java.util.Observer;
+
+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.Color;
+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.Control;
+import org.eclipse.swt.widgets.Display;
+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.resource.ImageDescriptor;
+import org.eclipse.jface.resource.JFaceResources;
+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.ui.plugin.AbstractUIPlugin;
+
+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.dnd.DragProposalListCategoriesListener;
+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.dnd.DragState;
+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.ImageHandler;
+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.util.HighlightObserver;
+
+/**
+ *
+ * @since 3.8
+ */
+public final class ProposalList extends Observable implements HighlightObserver {
+
+ 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 static final Color SELECTED_COLOR= Display.getCurrent().getSystemColor(SWT.COLOR_LIST_SELECTION);
+
+ private static final Color UNSELECTED_BORDER_COLOR= Display.getCurrent().getSystemColor(SWT.COLOR_GRAY);
+
+ 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 class RemoveIconPaintListener implements Listener {
+ final Rectangle iconRect= new Rectangle(0, 0, 0, 0);
+
+ public void handleEvent(Event event) {
+ Table tab= ((Table) event.widget);
+ Point tabLoc= getTableLocation(tab);
+ Point absMouseLoc= getAbsoluteMouseLocation(tab.getDisplay());
+ Point relMouseLoc= getRelativeMouseLocation(absMouseLoc, tabLoc);
+ if (DragState.isNotDragged() && isMouseOverScrolledComposite(absMouseLoc) && isMouseOverCurrentRow(tab, relMouseLoc, (TableItem) event.item)) {
+ updateIconRectangle(tab, event.height, event.y);
+ drawIcon(event.gc, relMouseLoc);
+ }
+ }
+
+ private Point getTableLocation(Table tab) {
+ return tab.toDisplay(tab.getClientArea().x, tab.getClientArea().y);
+ }
+
+ private Point getAbsoluteMouseLocation(Display disp) {
+ return disp.getCursorLocation();
+ }
+
+ private Point getRelativeMouseLocation(Point mouseLoc, Point tabLoc) {
+ return new Point(mouseLoc.x - tabLoc.x, mouseLoc.y - tabLoc.y);
+ }
+
+ private boolean isMouseOverScrolledComposite(Point absMouseLoc) {
+ return fProposalListSection.isPointInScrolledComposite(absMouseLoc);
+ }
+
+ 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= fRemoveProposalListImage.getImageData();
+
+ int x= calculateNewX(tab, imgData);
+ int y= calculateNewY(imgData, eventHeight, eventY);
+ int width= calculateNewWidth(imgData);
+ int height= calculateNewHeight(imgData);
+
+ updateRectangle(iconRect, x, y, width, height);
+ }
+
+ private void drawIcon(GC gc, Point mouseLoc) {
+ gc.setClipping(iconRect);
+ if (iconRect.contains(mouseLoc))
+ gc.drawImage(fRemoveProposalListOverImage, iconRect.x, iconRect.y);
+ else
+ gc.drawImage(fRemoveProposalListImage, iconRect.x, iconRect.y);
+ }
+
+ private int calculateNewX(Table tab, ImageData imgData) {
+ return tab.getClientArea().width - imgData.width;
+ }
+
+ private int calculateNewY(ImageData imgData, int eventHeight, int eventY) {
+ int offset= Math.max(0, (eventHeight - imgData.height) / 2);
+ return eventY + offset;
+ }
+
+ private int calculateNewWidth(ImageData imgData) {
+ return imgData.width;
+ }
+
+ private int calculateNewHeight(ImageData imgData) {
+ return imgData.height;
+ }
+
+ private void updateRectangle(Rectangle rect, int x, int y, int width, int height) {
+ rect.x= x;
+ rect.y= y;
+ rect.width= width;
+ rect.height= height;
+ }
+ }
+
+ private final PreferenceModel fModel;
+
+ private final ProposalListSection fProposalListSection;
+
+ private final Image fRemoveProposalListImage;
+
+ private final Image fRemoveProposalListOverImage;
+
+ private Composite fTableContainer;
+
+ private final ProposalListHeader fHeader;
+
+ private TableViewer fTableViewer;
+
+ private final NewListDropSection fNewListDropSection;
+
+ private DropIntoProposalListListener fDropListener;
+
+ private boolean fHighlighted;
+
+ public ProposalList(Composite parent, int listIndex, ProposalListSection proposalListSection, PreferenceModel model, ImageHandler imageHandler) {
+ this.fModel= model;
+ this.fProposalListSection= proposalListSection;
+
+ this.fRemoveProposalListImage= imageHandler.getImage(REMOVE_PROPOSAL_LIST_ICON_DESCRIPTOR);
+ this.fRemoveProposalListOverImage= imageHandler.getImage(REMOVE_PROPOSAL_LIST_OVER_ICON_DESCRIPTOR);
+
+ createTableContainer(parent);
+ this.fHeader= new ProposalListHeader(fTableContainer, listIndex, fModel, imageHandler);
+ createTable(listIndex);
+
+ this.fNewListDropSection= new NewListDropSection(parent, listIndex + 1, fModel, fProposalListSection);
+
+ addDropSupportToTableContainer(listIndex);
+ addRemoveIconVisibility();
+ addBorderPainterToTableContainer();
+ }
+
+ public List getContent() {
+ return (List) fTableViewer.getInput();
+ }
+
+ public void clearContent() {
+ fTableViewer.setInput(null);
+ }
+
+ public void addContent(ModelElement element) {
+ List content= getContent();
+ if (content == null)
+ content= new ArrayList();
+ content.add(element);
+ setContent(content);
+ }
+
+ public void setContent(List 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 (fHighlighted == highlight)
+ return;
+ fHighlighted= highlight;
+ fTableContainer.redraw();
+
+ fHeader.highlight(highlight);
+ }
+
+ @Override
+ public synchronized void addObserver(Observer o) {
+ super.addObserver(o);
+ fDropListener.addUpdateObserver(o);
+ fHeader.addObserver(o);
+ fNewListDropSection.addUpdateObserver(o);
+ }
+
+
+ public TableViewer getTableViewer() {
+ return fTableViewer;
+ }
+
+ private void createTableContainer(Composite parent) {
+ fTableContainer= new Composite(parent, SWT.NONE);
+ fTableContainer.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;
+ fTableContainer.setLayout(layout);
+ }
+
+ private void createTable(int listIndex) {
+ createInitialTableViewer();
+ TableColumn nameColumn= addFirstTableColumn();
+
+ ITableLabelProvider labelProvider= setTableProviderAndComparator(listIndex);
+ adjustFirstTableColumnWidth(nameColumn, labelProvider);
+
+ addDragSupportToTable(listIndex);
+ addFocusOutListenerToTable();
+ addProposalListCategoryRemoveIconCreatorToTable(listIndex);
+ }
+
+ private void addDropSupportToTableContainer(int listIndex) {
+ Transfer[] transferTypes= new Transfer[] { ProvidedCategoryTransfer.getInstance(), ProposalListCategoryTransfer.getInstance(), ProposalListTransfer.getInstance() };
+ DropTarget dropTarget= new DropTarget(fTableContainer, ProposalTransfer.ALL_DRAG_OPERATIONS);
+ dropTarget.setTransfer(transferTypes);
+ fDropListener= new DropIntoProposalListListener(listIndex, fModel);
+ fProposalListSection.addToAutoscrollObserver(fDropListener);
+ fDropListener.addHighlightObserver(this);
+ dropTarget.addDropListener(fDropListener);
+ }
+
+ 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 addBorderPainterToTableContainer() {
+ fTableContainer.addPaintListener(new PaintListener() {
+ public void paintControl(PaintEvent e) {
+ if (fHighlighted)
+ e.gc.setBackground(SELECTED_COLOR);
+ else
+ e.gc.setBackground(UNSELECTED_BORDER_COLOR);
+ Rectangle rect= fTableContainer.getClientArea();
+ e.gc.fillRectangle(rect);
+ }
+ });
+ }
+
+ private void createInitialTableViewer() {
+ fTableViewer= new TableViewer(fTableContainer, SWT.MULTI | SWT.NO_SCROLL);
+ final Table table= fTableViewer.getTable();
+ table.setHeaderVisible(false);
+ table.setLinesVisible(false);
+ table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ }
+
+ private TableColumn addFirstTableColumn() {
+ TableColumn nameColumn= new TableColumn(fTableViewer.getTable(), SWT.NONE);
+ nameColumn.setResizable(false);
+ return nameColumn;
+ }
+
+ private void adjustFirstTableColumnWidth(TableColumn column, ITableLabelProvider labelProvider) {
+ final int ICON_WIDTH= 16;
+ final int HEADER_MARGIN= 20;
+ int minNameWidth= computeWidth(fTableViewer.getTable(), column.getText()) + HEADER_MARGIN;
+ for (int i= 0; i < fModel.elements.size(); i++)
+ minNameWidth= Math.max(minNameWidth, computeWidth(fTableViewer.getTable(), labelProvider.getColumnText(fModel.elements.get(i), 0)) + 2 * ICON_WIDTH);
+ column.setWidth(minNameWidth);
+ }
+
+ private ITableLabelProvider setTableProviderAndComparator(int listIndex) {
+ fTableViewer.setContentProvider(new ProposalListContentProvider(listIndex));
+ fTableViewer.setComparator(new ModelElement.ModelElementViewerComparator());
+ ITableLabelProvider labelProvider= new ProposalListTableLabelProvider();
+ fTableViewer.setLabelProvider(labelProvider);
+ return labelProvider;
+ }
+
+ private void addDragSupportToTable(int listIndex) {
+ Transfer[] transferTypes= new Transfer[] { ProposalListCategoryTransfer.getInstance() };
+ DragProposalListCategoriesListener dragListener= new DragProposalListCategoriesListener(fTableViewer, listIndex);
+ DragState.addToObservable(dragListener);
+ fTableViewer.addDragSupport(ProposalTransfer.ALL_DRAG_OPERATIONS, transferTypes, dragListener);
+ }
+
+ private void addFocusOutListenerToTable() {
+ final Table table= fTableViewer.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 addProposalListCategoryRemoveIconCreatorToTable(int listIndex) {
+ Rectangle iconRect= addRemoveIconToTableItemsPainter();
+ addRemoveIconRedrawListenerToTable(iconRect);
+ addRemoveCategoryOnClickListenerToTable(iconRect, listIndex);
+ }
+
+ private Rectangle addRemoveIconToTableItemsPainter() {
+ RemoveIconPaintListener paintListener= new RemoveIconPaintListener();
+ fTableViewer.getTable().addListener(SWT.PaintItem, paintListener);
+ return paintListener.iconRect;
+ }
+
+ private void addRemoveIconRedrawListenerToTable(final Rectangle iconRect) {
+ final Table table= fTableViewer.getTable();
+ 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 addRemoveCategoryOnClickListenerToTable(final Rectangle iconRect, final int listIndex) {
+ final Table table= fTableViewer.getTable();
+ 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 categories= fModel.getElements(listIndex);
+ Collections.sort(categories, new ModelElement.ModelElementComparator());
+ categories.get(elemIndex).removeInProposalList(listIndex);
+ setChanged();
+ notifyObservers();
+ }
+ }
+
+ 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);
+ }
+
+ 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();
+ }
+ }
+}
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,212 @@
+/**
+ * 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 - initial API and implementation.
+ */
+package org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.widgets;
+
+import java.util.Observable;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.dnd.DragSource;
+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.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.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+
+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.dnd.DragProposalListListener;
+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.dnd.DragState;
+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.ImageHandler;
+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.model.PreferenceModel;
+
+/**
+ *
+ * @since 3.8
+ */
+public final class ProposalListHeader extends Observable {
+
+ 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 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 Image fRemoveProposalListImage;
+
+ private final Image fRemoveProposalListOverImage;
+
+ private Composite fPaddingComposite;
+
+ private Label fTitle;
+
+ private Label fRemoveLabel;
+
+ public ProposalListHeader(Composite tableContainer, int listIndex, PreferenceModel model, ImageHandler imageHandler) {
+ this.fModel= model;
+
+ this.fRemoveProposalListImage= imageHandler.getImage(REMOVE_PROPOSAL_LIST_ICON_DESCRIPTOR);
+ this.fRemoveProposalListOverImage= imageHandler.getImage(REMOVE_PROPOSAL_LIST_OVER_ICON_DESCRIPTOR);
+
+ createPaddingComposite(tableContainer);
+ createTitle(listIndex);
+ createRemoveIcon(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 void createPaddingComposite(Composite tableContainer) {
+ fPaddingComposite= new Composite(tableContainer, SWT.NONE);
+ GridLayout layout= new GridLayout(2, false);
+ layout.marginHeight= 0;
+ layout.verticalSpacing= 0;
+ fPaddingComposite.setLayout(layout);
+ }
+
+ private void createTitle(int listIndex) {
+ fTitle= new Label(fPaddingComposite, SWT.NONE);
+ fTitle.setText(getProposalListTitle(listIndex));
+ fTitle.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true));
+ }
+
+ private void updateHeaderHeight() {
+ GridData gd= new GridData(SWT.FILL, SWT.FILL, true, true);
+ gd.heightHint= getHeaderHeight();
+ fPaddingComposite.setLayoutData(gd);
+ }
+
+ private void createRemoveIcon(int listIndex) {
+ fRemoveLabel= createRemoveLabel();
+ addMouseOverRemoveIconListener();
+ addRemoveListOnClickListener(listIndex);
+ }
+
+ private void addListDragSupport(Control control, int listIndex) {
+ DragProposalListListener tableDragSourceListener= new DragProposalListListener(listIndex);
+ Transfer[] transferTypes= new Transfer[] { ProposalListTransfer.getInstance() };
+ DragSource dragSource= new DragSource(control, ProposalTransfer.ALL_DRAG_OPERATIONS);
+ dragSource.setTransfer(transferTypes);
+ DragState.addToObservable(tableDragSourceListener);
+ 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() {
+ final Label removeLabel= new Label(fPaddingComposite, SWT.NONE);
+ removeLabel.setVisible(false);
+ removeLabel.setImage(fRemoveProposalListImage);
+ GridData gd= new GridData(SWT.RIGHT, SWT.CENTER, true, true);
+ gd.widthHint= fRemoveProposalListImage.getImageData().width;
+ gd.minimumWidth= gd.widthHint;
+ removeLabel.setLayoutData(gd);
+ return removeLabel;
+ }
+
+ private void addMouseOverRemoveIconListener() {
+ fRemoveLabel.addListener(SWT.MouseEnter, new Listener() {
+ public void handleEvent(Event e) {
+ fRemoveLabel.setImage(fRemoveProposalListOverImage);
+ }
+ });
+ fRemoveLabel.addListener(SWT.MouseExit, new Listener() {
+ public void handleEvent(Event e) {
+ fRemoveLabel.setImage(fRemoveProposalListImage);
+ }
+ });
+ }
+
+ private void addRemoveListOnClickListener(final int listIndex) {
+ fRemoveLabel.addMouseListener(new MouseListener() {
+ public void mouseUp(MouseEvent e) {
+ if (isSingleClick(e.count) && isUpOverIcon(e.x, e.y)) {
+ fModel.removeList(listIndex);
+ setChanged();
+ notifyObservers();
+ }
+ }
+
+ 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 < fRemoveLabel.getBounds().width && y >= 0 && y < fRemoveLabel.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,222 @@
+/**
+ * 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 - 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.Observable;
+import java.util.Observer;
+import java.util.Set;
+import java.util.Vector;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.ScrolledComposite;
+import org.eclipse.swt.dnd.DropTarget;
+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.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Listener;
+
+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.ImageHandler;
+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.util.AutoscrollEngine;
+import org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.widgets.util.AutoscrollObservable;
+
+/**
+ *
+ * @since 3.8
+ */
+public final class ProposalListSection {
+ private final PreferenceModel fModel;
+
+ private final Vector fUpdateObservers;
+
+ private final ImageHandler fImageHandler;
+
+ private final List fProposalLists= new ArrayList();
+
+ private ScrolledComposite fScrolledComposite;
+
+ private AutoscrollEngine fAutoScrollEngine;
+
+ private Composite fInnerWrappingComposite;
+
+ private NewListDropSection fFirstNewListDropSection;
+
+ public ProposalListSection(Composite parent, PreferenceModel model, ImageHandler imageHandler) {
+ this.fModel= model;
+ this.fUpdateObservers= new Vector();
+ this.fImageHandler= imageHandler;
+
+ createOuterScrolledComposite(parent);
+ createInnerProposalListWrappingComposite();
+
+ createAutoScrollEnginge();
+ addDropAutoScroll();
+
+ addOuterSizeUpdater();
+
+ createFirstNewListDropSection();
+ }
+
+ public void updateControls() {
+ clearOldListState();
+ Set filledLists= updateListStates();
+ makeSureFirstListExists();
+ adjustAndCleanUp(filledLists);
+ reLayoutInnerComposite();
+ }
+
+ public void addUpdateObserver(Observer observer) {
+ fUpdateObservers.add(observer);
+ fFirstNewListDropSection.addUpdateObserver(observer);
+ for (Observable o : fProposalLists) {
+ o.addObserver(observer);
+ }
+ }
+
+ public void addToAutoscrollObserver(AutoscrollObservable o) {
+ o.addAutoscrollObserver(fAutoScrollEngine);
+ }
+
+ public void addListener(int eventType, Listener listener) {
+ fScrolledComposite.addListener(eventType, listener);
+ fInnerWrappingComposite.addListener(eventType, listener);
+ }
+
+ public boolean isPointInScrolledComposite(Point p) {
+ Point relativePoint= fScrolledComposite.toControl(p);
+ return fScrolledComposite.getClientArea().contains(relativePoint);
+ }
+
+ private void createOuterScrolledComposite(Composite parent) {
+ fScrolledComposite= new ScrolledComposite(parent, SWT.V_SCROLL | SWT.BORDER);
+ fScrolledComposite.setAlwaysShowScrollBars(true);
+ fScrolledComposite.setExpandHorizontal(true);
+ fScrolledComposite.setExpandVertical(true);
+ GridData gridData= new GridData(GridData.FILL, GridData.FILL, true, true);
+ gridData.heightHint= 0;
+ fScrolledComposite.setLayoutData(gridData);
+ }
+
+ private void createAutoScrollEnginge() {
+ fAutoScrollEngine= new AutoscrollEngine(fScrolledComposite);
+ }
+
+ private void addDropAutoScroll() {
+ Transfer[] transferTypes= new Transfer[] { ProvidedCategoryTransfer.getInstance(), ProposalListCategoryTransfer.getInstance(), ProposalListTransfer.getInstance() };
+ DropTarget dropTarget= new DropTarget(fScrolledComposite, ProposalTransfer.ALL_DRAG_OPERATIONS);
+ dropTarget.setTransfer(transferTypes);
+ AutoscrollDropTargetListener dropListener= new AutoscrollDropTargetListener();
+ dropListener.addAutoscrollObserver(fAutoScrollEngine);
+ dropTarget.addDropListener(dropListener);
+ }
+
+ private void createInnerProposalListWrappingComposite() {
+ fInnerWrappingComposite= new Composite(fScrolledComposite, SWT.NONE);
+ fScrolledComposite.setContent(fInnerWrappingComposite);
+ GridLayout layout= new GridLayout();
+ layout.marginHeight= 0;
+ layout.verticalSpacing= 0;
+ fInnerWrappingComposite.setLayout(layout);
+ }
+
+ private void addOuterSizeUpdater() {
+ fInnerWrappingComposite.addControlListener(new ControlListener() {
+ public void controlResized(ControlEvent e) {
+ fInnerWrappingComposite.update();
+ fScrolledComposite.setMinSize(fInnerWrappingComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT));
+ fScrolledComposite.layout(true, true);
+ }
+
+ public void controlMoved(ControlEvent e) {
+ }
+ });
+ }
+
+ private void createFirstNewListDropSection() {
+ fFirstNewListDropSection= new NewListDropSection(fInnerWrappingComposite, 0, fModel, this);
+ }
+
+ private void clearOldListState() {
+ for (ProposalList list : fProposalLists)
+ list.clearContent();
+ }
+
+ private Set updateListStates() {
+ Set filledLists= new HashSet();
+ for (ModelElement element : fModel.elements) {
+ Set indices= element.getProposalListIndices();
+ if (indices != null) {
+ filledLists.addAll(indices);
+ addElementToLists(element, indices);
+ }
+ }
+ return filledLists;
+ }
+
+ private void makeSureFirstListExists() {
+ if (fProposalLists.size() == 0)
+ makeSureListExists(0);
+ }
+
+ private void adjustAndCleanUp(Set 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 addElementToLists(ModelElement element, Set indices) {
+ for (int index : indices) {
+ makeSureListExists(index);
+ addElementToList(element, index);
+ }
+ }
+
+ private void makeSureListExists(int listIndex) {
+ while (fProposalLists.size() < listIndex + 1) {
+ ProposalList proposalList= new ProposalList(fInnerWrappingComposite, fProposalLists.size(), this, fModel, fImageHandler);
+ addAllUpdateObservers(proposalList);
+ fProposalLists.add(proposalList);
+ }
+ }
+
+ private void addElementToList(ModelElement element, int listIndex) {
+ fProposalLists.get(listIndex).addContent(element);
+ }
+
+ private void addAllUpdateObservers(Observable o) {
+ for (Observer observer : fUpdateObservers)
+ o.addObserver(observer);
+ }
+}
Index: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/widgets/util/AutoscrollEngine.java
===================================================================
RCS file: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/widgets/util/AutoscrollEngine.java
diff -N ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/widgets/util/AutoscrollEngine.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/widgets/util/AutoscrollEngine.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,96 @@
+/**
+ * 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 - initial API and implementation.
+ */
+package org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.widgets.util;
+
+import org.eclipse.swt.custom.ScrolledComposite;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Control;
+
+/**
+ *
+ * @since 3.8
+ */
+public class AutoscrollEngine implements AutoscrollObserver {
+ private final ScrolledComposite fScrolledComposite;
+
+ private final int fScrollDetectRange;
+
+ private final int fScrollOffset;
+
+ public AutoscrollEngine(ScrolledComposite scrolledComposite) {
+ this(scrolledComposite, 15, 5);
+ }
+
+ public AutoscrollEngine(ScrolledComposite scrolledComposite, int scrollDetectRange, int scrollOffset) {
+ fScrolledComposite= scrolledComposite;
+ fScrollDetectRange= scrollDetectRange;
+ fScrollOffset= scrollOffset;
+ }
+
+ public void autoScroll(Point mouseLocation) {
+ assert mouseLocation != null : "Mouse location can't be NULL"; //$NON-NLS-1$
+
+ Point scrolledCompPosition= getScrolledCompositePosition();
+ Rectangle scrollArea= getScrollArea();
+ Point origin= getScrolledOrigin();
+ Rectangle childrenBounds= getChildrenBounds();
+
+ if (isMouseInTopDetectRange(scrolledCompPosition, mouseLocation))
+ updateOriginTopDetected(origin);
+ if (isMouseInBottomDetectRange(scrolledCompPosition, mouseLocation, scrollArea))
+ updateOriginBottomDetected(origin, scrollArea, childrenBounds);
+
+ setUpdatedOrigin(origin);
+ }
+
+ private Rectangle getScrollArea() {
+ return fScrolledComposite.getClientArea();
+ }
+
+ private Point getScrolledCompositePosition() {
+ return fScrolledComposite.toDisplay(1, 1);
+ }
+
+ private Point getScrolledOrigin() {
+ return fScrolledComposite.getOrigin();
+ }
+
+ private Rectangle getChildrenBounds() {
+ Control[] children= fScrolledComposite.getChildren();
+ if (children == null || children.length == 0)
+ return new Rectangle(0, 0, 0, 0);
+ Rectangle childrenBounds= children[0].getBounds();
+ for (Control c : children)
+ childrenBounds.union(c.getBounds());
+ return childrenBounds;
+ }
+
+ private boolean isMouseInTopDetectRange(Point scrolledCompositePosition, Point mouseLocation) {
+ return scrolledCompositePosition.y + fScrollDetectRange > mouseLocation.y;
+ }
+
+ private boolean isMouseInBottomDetectRange(Point scrolledCompositePosition, Point mouseLocation, Rectangle scrollArea) {
+ return scrolledCompositePosition.y + scrollArea.height - fScrollDetectRange < mouseLocation.y;
+ }
+
+ private void updateOriginTopDetected(Point origin) {
+ origin.y= Math.max(0, origin.y - fScrollOffset);
+ }
+
+ private void updateOriginBottomDetected(Point origin, Rectangle scrollArea, Rectangle childrenBounds) {
+ origin.y= Math.min(childrenBounds.height - scrollArea.height, origin.y + fScrollOffset);
+ }
+
+ private void setUpdatedOrigin(Point origin) {
+ fScrolledComposite.setOrigin(origin);
+ }
+}
Index: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/widgets/util/AutoscrollObservable.java
===================================================================
RCS file: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/widgets/util/AutoscrollObservable.java
diff -N ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/widgets/util/AutoscrollObservable.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/widgets/util/AutoscrollObservable.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,19 @@
+/**
+ * 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 - initial API and implementation.
+ */
+package org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.widgets.util;
+
+/**
+ *
+ * @since 3.8
+ */
+public interface AutoscrollObservable {
+ public void addAutoscrollObserver(AutoscrollObserver o);
+}
Index: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/widgets/util/AutoscrollObserver.java
===================================================================
RCS file: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/widgets/util/AutoscrollObserver.java
diff -N ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/widgets/util/AutoscrollObserver.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/widgets/util/AutoscrollObserver.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,21 @@
+/**
+ * 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 - initial API and implementation.
+ */
+package org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.widgets.util;
+
+import org.eclipse.swt.graphics.Point;
+
+/**
+ *
+ * @since 3.8
+ */
+public interface AutoscrollObserver {
+ public void autoScroll(Point mouseLocation);
+}
Index: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/widgets/util/HighlightObservable.java
===================================================================
RCS file: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/widgets/util/HighlightObservable.java
diff -N ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/widgets/util/HighlightObservable.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/widgets/util/HighlightObservable.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,19 @@
+/**
+ * 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 - initial API and implementation.
+ */
+package org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.widgets.util;
+
+/**
+ *
+ * @since 3.8
+ */
+public interface HighlightObservable {
+ public void addHighlightObserver(HighlightObserver o);
+}
Index: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/widgets/util/HighlightObserver.java
===================================================================
RCS file: ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/widgets/util/HighlightObserver.java
diff -N ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/widgets/util/HighlightObserver.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ui/org/eclipse/jdt/internal/ui/preferences/codeassist/advanced/widgets/util/HighlightObserver.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,19 @@
+/**
+ * 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 - initial API and implementation.
+ */
+package org.eclipse.jdt.internal.ui.preferences.codeassist.advanced.widgets.util;
+
+/**
+ *
+ * @since 3.8
+ */
+public interface HighlightObserver {
+ public void highlight(boolean highlight);
+}
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 11 Aug 2011 19:12:02 -0000
@@ -7,13 +7,18 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Thomas Schlosser - 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 null
if none specified. */
private final ImageDescriptor fImage;
- private boolean fIsSeparateCommand= true;
+ private final Set fProposalListIndices = new HashSet();
+ private final Set 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 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 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.
+ *
+ * The returned set is read-only.
+ *
+ *
+ * @return the indices of the proposal lists of this category
+ */
+ public Set 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 descriptors= new ArrayList(fRegistry.getProposalComputerDescriptors(partition));
for (Iterator 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 11 Aug 2011 19:12:03 -0000
@@ -7,6 +7,7 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Thomas Schlosser - 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 getCategories(List elements) {
IPreferenceStore store= JavaPlugin.getDefault().getPreferenceStore();
- String preference= store.getString(PreferenceConstants.CODEASSIST_EXCLUDED_CATEGORIES);
- Set disabled= new HashSet();
- StringTokenizer tok= new StringTokenizer(preference, "\0"); //$NON-NLS-1$
- while (tok.hasMoreTokens())
- disabled.add(tok.nextToken());
- Map ordered= new HashMap();
- 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> proposalLists= new HashMap>();
+ 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 set= proposalLists.get(categoryId);
+ if (set == null) {
+ set= new HashSet();
+ proposalLists.put(categoryId, set);
+ }
+ set.add(Integer.valueOf(i));
+ }
}
CompletionProposalCategory allProposals= null;
CompletionProposalCategory typeProposals= null;
CompletionProposalCategory allButTypeProposals= null;
-
+
List categories= new ArrayList();
for (Iterator 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 disabled, CompletionProposalCategory allProposals, CompletionProposalCategory typeProposals,
- CompletionProposalCategory allButTypeProposals) {
+ private void preventDuplicateCategories(IPreferenceStore store, Map> 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 iter= disabled.iterator();
- while (iter.hasNext()) {
- buf.append(iter.next());
+ int initialBufferSize= 50 * numberOfCategories;
+ Map proposalListsCategories= new TreeMap();
+ for (Entry> 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 11 Aug 2011 19:12:03 -0000
@@ -7,14 +7,15 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Thomas Schlosser - 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 ORDER_COMPARATOR= new Comparator() {
-
- public int compare(CompletionProposalCategory d1, CompletionProposalCategory d2) {
- return d1.getSortOrder() - d2.getSortOrder();
- }
-
- };
-
private final List fCategories;
private final String fPartition;
private final ContentAssistant fAssistant;
@@ -444,47 +437,44 @@
}
private List> getCategoryIteration() {
- List> sequence= new ArrayList>();
- sequence.add(getDefaultCategories());
- for (Iterator it= getSeparateCategories().iterator(); it.hasNext();) {
- CompletionProposalCategory cat= it.next();
- sequence.add(Collections.singletonList(cat));
- }
- return sequence;
- }
-
- private List getDefaultCategories() {
- // default mix - enable all included computers
- List included= getDefaultCategoriesUnchecked();
-
- if (fComputerRegistry.hasUninstalledComputers(fPartition, included)) {
- if (informUserAboutEmptyDefaultCategory())
- // preferences were restored - recompute the default categories
- included= getDefaultCategoriesUnchecked();
+ List> 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 getDefaultCategoriesUnchecked() {
- List included= new ArrayList();
- for (Iterator it= fCategories.iterator(); it.hasNext();) {
- CompletionProposalCategory category= it.next();
- if (category.isIncluded() && category.hasComputers(fPartition))
- included.add(category);
+ private List> getProposalCategoriesUnchecked() {
+ Map> sorted= new TreeMap>();
+ for (CompletionProposalCategory category : fCategories) {
+ if (!category.getProposalListIndices().isEmpty() && category.hasComputers(fPartition)) {
+ for (Integer index : category.getProposalListIndices()) {
+ List list= sorted.get(index);
+ if (list == null) {
+ list= new ArrayList();
+ 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());
+ return new ArrayList>(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 true
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 true
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 getSeparateCategories() {
- ArrayList sorted= new ArrayList();
- for (Iterator 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 11 Aug 2011 19:12:03 -0000
@@ -7,6 +7,7 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Thomas Schlosser - 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 11 Aug 2011 19:12:03 -0000
@@ -7,6 +7,7 @@
#
# Contributors:
# IBM Corporation - initial API and implementation
+# Thomas Schlosser - 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 Advanced Content Assist preference page 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 11 Aug 2011 19:12:04 -0000
@@ -8,12 +8,19 @@
* Contributors:
* IBM Corporation - initial API and implementation
* Guven Demir - [package explorer] Alternative package name shortening: abbreviation - https://bugs.eclipse.org/bugs/show_bug.cgi?id=299514
+ * Thomas Schlosser - 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 String
, a "\0"-separated list of identifiers.
*
*
- * @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 @@
*
*
* @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.
+ *
+ * Value is of type String
, a "\0"-separated list of "\1"-separated lists with categoryId where
+ *
+ * - categoryId is the
String
holding the category ID
+ *
+ *
+ *
+ *
+ * @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> getProposalLists() {
+ String encodedPreference= getPreference(CODEASSIST_PROPOSAL_LISTS, null);
+ Map> result= new HashMap>();
+ 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 set= result.get(category);
+ if (set == null) {
+ set= new HashSet();
+ 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> proposalLists) {
+ Assert.isLegal(proposalLists != null);
+ int initialBufferSize= 250;
+ Map proposalListsCategories= new TreeMap();
+ for (Entry> 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();
}