diff options
author | Arthur Daussy | 2014-03-10 14:02:09 +0000 |
---|---|---|
committer | Axel Richard | 2014-03-31 17:03:06 +0000 |
commit | fc3f44bc4a7dd71909a16eb2cca15629e985eb2e (patch) | |
tree | 36e3c6f7b82f64246e7ab047fc4d4bdd4f48ad2b /plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal | |
parent | b90eb542179909786520502d6586451fa88dc2a7 (diff) | |
download | org.eclipse.emf.compare-fc3f44bc4a7dd71909a16eb2cca15629e985eb2e.tar.gz org.eclipse.emf.compare-fc3f44bc4a7dd71909a16eb2cca15629e985eb2e.tar.xz org.eclipse.emf.compare-fc3f44bc4a7dd71909a16eb2cca15629e985eb2e.zip |
[429636] Create preference page for groups
Create preference page to rank groups in order define which one will be
used by default.
Bug: 429636
Change-Id: If763cf54cef1f9f26c2714aca97b66e185f77270
Signed-off-by: Arthur Daussy <arthur.daussy@obeo.fr>
Diffstat (limited to 'plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal')
9 files changed, 984 insertions, 177 deletions
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/emfcomparercpuimessages.properties b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/emfcomparercpuimessages.properties index 7669af241..ebce98807 100644 --- a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/emfcomparercpuimessages.properties +++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/emfcomparercpuimessages.properties @@ -39,8 +39,15 @@ InteractiveUIContent.DESCRIPTION_COMPOSITE_LABEL = Description InteractiveUIContent.INCORRECT_SELECTION_TITLE = Incorrect selection InteractiveUIContent.INCORRECT_SELECTION_MESSAGE = At least one item has to be selected. +GroupsInteractiveContent.AUTOMATIC_BEHAVIOR_GROUP_LABEL = Automatic behavior +GroupsInteractiveContent.AUTOMATIC_BEHAVIOR_LABEL = Synchronize current group selection: + + PostProcessorPreferencePage.PREFERENCE_PAGE_DESCRIPTION = Select active post processors: +GroupsPreferencePage.VIEWER_DESCRIPTION_LABEL = Rank each group by priority (Highest ranked enabled element will be use as default): +GroupsPreferencePage.TWO_WAY_COMPARISON_TAB_LABEL = 2 way comparison +GroupsPreferencePage.THREE_WAY_COMPARISON_TAB_LABEL = 3 way comparison EditorPreferencePage.mainTab.label = Main EditorPreferencePage.mainTab.colorHyperLink.label = See <a>''Color and Fonts''</a> preferences for EMF Compare colors. diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/EnginesPreferencePage.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/EnginesPreferencePage.java index 1021746b9..4ae568128 100644 --- a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/EnginesPreferencePage.java +++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/EnginesPreferencePage.java @@ -40,7 +40,8 @@ import org.eclipse.emf.compare.rcp.ui.EMFCompareRCPUIPlugin; import org.eclipse.emf.compare.rcp.ui.internal.EMFCompareRCPUIMessages; import org.eclipse.emf.compare.rcp.ui.internal.configuration.ui.AbstractConfigurationUI; import org.eclipse.emf.compare.rcp.ui.internal.configuration.ui.IConfigurationUIFactory; -import org.eclipse.emf.compare.rcp.ui.internal.preferences.InteractiveUIContent.InteractiveUIBuilder; +import org.eclipse.emf.compare.rcp.ui.internal.preferences.impl.InteractiveUIContent; +import org.eclipse.emf.compare.rcp.ui.internal.preferences.impl.InteractiveUIContent.InteractiveUIBuilder; import org.eclipse.emf.compare.req.IReqEngine; import org.eclipse.jface.preference.PreferencePage; import org.eclipse.jface.resource.ImageDescriptor; @@ -137,7 +138,7 @@ public class EnginesPreferencePage extends PreferencePage implements IWorkbenchP * @param tabComposite * Holding composite. * @param dataHolder - * Data that will be synchronoze with the UI. + * Data that will be synchronized with the UI. * @param <T> * type of engine. * @return {@link InteractiveUIContent} for a specific type of engine. diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/GroupsPreferencePage.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/GroupsPreferencePage.java new file mode 100644 index 000000000..f6e7e9b73 --- /dev/null +++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/GroupsPreferencePage.java @@ -0,0 +1,198 @@ +/******************************************************************************* + * Copyright (c) 2014 Obeo. + * 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: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.emf.compare.rcp.ui.internal.preferences; + +import java.util.List; + +import org.eclipse.core.runtime.preferences.InstanceScope; +import org.eclipse.emf.compare.rcp.internal.extension.IItemDescriptor; +import org.eclipse.emf.compare.rcp.ui.EMFCompareRCPUIPlugin; +import org.eclipse.emf.compare.rcp.ui.internal.EMFCompareRCPUIMessages; +import org.eclipse.emf.compare.rcp.ui.internal.preferences.impl.GroupsInteractiveContent; +import org.eclipse.emf.compare.rcp.ui.internal.preferences.impl.ItemDescriptorLabelProvider; +import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.groups.impl.DifferenceGroupManager; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider.Descriptor; +import org.eclipse.jface.preference.PreferencePage; +import org.eclipse.jface.viewers.ArrayContentProvider; +import org.eclipse.jface.viewers.ListViewer; +import org.eclipse.swt.SWT; +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.TabFolder; +import org.eclipse.swt.widgets.TabItem; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPreferencePage; +import org.eclipse.ui.preferences.ScopedPreferenceStore; + +/** + * Preference page for group providers. + * + * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a> + */ +public class GroupsPreferencePage extends PreferencePage implements IWorkbenchPreferencePage { + + /** UI content for two way comparison tab. */ + private GroupsInteractiveContent twoWayComparisonContent; + + /** UI content for three way comparison tab. */ + private GroupsInteractiveContent threeWayComparisonContent; + + /** {@link DifferenceGroupManager}. */ + private DifferenceGroupManager groupManager = new DifferenceGroupManager(EMFCompareRCPUIPlugin + .getDefault().getEMFCompareUIPreferences(), EMFCompareRCPUIPlugin.getDefault() + .getItemDifferenceGroupProviderRegistry()); + + /** + * {@inheritDoc} + */ + public void init(IWorkbench workbench) { + // Do not use InstanceScope.Instance to be compatible with Helios. + @SuppressWarnings("deprecation") + ScopedPreferenceStore store = new ScopedPreferenceStore(new InstanceScope(), + EMFCompareRCPUIPlugin.PLUGIN_ID); + setPreferenceStore(store); + + } + + @Override + protected Control createContents(Composite parent) { + parent.setLayout(new GridLayout(1, true)); + Composite container = new Composite(parent, SWT.NONE); + container.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + container.setLayout(new GridLayout(1, true)); + + TabFolder tabFolder = new TabFolder(container, SWT.NONE); + tabFolder.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + fillTwoWayComparisonTab(tabFolder); + fillThreeWayComparisonTab(tabFolder); + return container; + } + + /** + * Fills the tab for two way comparison. + * + * @param tabFolder + * Holding tab folder. + */ + private void fillTwoWayComparisonTab(TabFolder tabFolder) { + Composite tabSkeletonComposite = createTabSkeleton(tabFolder, EMFCompareRCPUIMessages + .getString("GroupsPreferencePage.TWO_WAY_COMPARISON_TAB_LABEL"), //$NON-NLS-1$ + EMFCompareRCPUIMessages.getString("GroupsPreferencePage.VIEWER_DESCRIPTION_LABEL")); //$NON-NLS-1$ + + List<IItemDescriptor<Descriptor>> currentGroupRanking = groupManager.getCurrentGroupRanking(false); + + twoWayComparisonContent = createInteractiveContent(tabSkeletonComposite, currentGroupRanking, + currentGroupRanking.get(0)); + } + + /** + * Fills the tab for three way comparison. + * + * @param tabFolder + * Holding tab folder. + */ + private void fillThreeWayComparisonTab(TabFolder tabFolder) { + Composite tabSkeletonComposite = createTabSkeleton(tabFolder, EMFCompareRCPUIMessages + .getString("GroupsPreferencePage.THREE_WAY_COMPARISON_TAB_LABEL"), //$NON-NLS-1$ + EMFCompareRCPUIMessages.getString("GroupsPreferencePage.VIEWER_DESCRIPTION_LABEL")); //$NON-NLS-1$ + + List<IItemDescriptor<Descriptor>> currentGroupRanking = groupManager.getCurrentGroupRanking(true); + threeWayComparisonContent = createInteractiveContent(tabSkeletonComposite, currentGroupRanking, + currentGroupRanking.get(0)); + } + + /** + * Creates an interactive content. + * <p> + * Interactive content aims at handling all ui that is modified with user interaction. + * </p> + * + * @param parent + * Parent Composite. + * @param input + * Input of the viewer. + * @param defaultSelection + * Default element that need to be selected. + * @return A {@link GroupsInteractiveContent} + */ + private GroupsInteractiveContent createInteractiveContent(Composite parent, + List<IItemDescriptor<IDifferenceGroupProvider.Descriptor>> input, + IItemDescriptor<IDifferenceGroupProvider.Descriptor> defaultSelection) { + + final GroupsInteractiveContent interactiveUI = new GroupsInteractiveContent(parent); + createViewer(interactiveUI); + interactiveUI.setViewerInput(input); + interactiveUI.select(defaultSelection); + + return interactiveUI; + } + + /** + * Creates skeleton of a tab. + * + * @param tabFolder + * Holding tab folder. + * @param tabLabel + * Label of the tab. + * @param introText + * Text use as description a tab + * @return Main composite of the tab + */ + private Composite createTabSkeleton(TabFolder tabFolder, String tabLabel, String introText) { + TabItem tbtmMain = new TabItem(tabFolder, SWT.NONE); + tbtmMain.setText(tabLabel); + Composite tabComposite = new Composite(tabFolder, SWT.NONE); + tbtmMain.setControl(tabComposite); + tabComposite.setLayout(new GridLayout(1, true)); + GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1); + tabComposite.setLayoutData(layoutData); + // Description text + Label introductionText = new Label(tabComposite, SWT.WRAP); + introductionText.setText(introText); + return tabComposite; + } + + /** + * Creates the list viewer holding items. + * + * @param interactiveUI + * {@link GroupsInteractiveContent} in which the viewer need to be set up. + */ + private void createViewer(final GroupsInteractiveContent interactiveUI) { + int style = SWT.BORDER | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.SINGLE; + ListViewer descriptorViewer = new ListViewer(interactiveUI.getViewerComposite(), style); + interactiveUI.setViewer(descriptorViewer); + descriptorViewer.setContentProvider(ArrayContentProvider.getInstance()); + descriptorViewer.setLabelProvider(new ItemDescriptorLabelProvider()); + GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1); + descriptorViewer.getControl().setLayoutData(gd); + } + + @Override + public boolean performOk() { + groupManager.setCurrentGroupRanking(twoWayComparisonContent.getItems(), false); + groupManager.setCurrentGroupRanking(threeWayComparisonContent.getItems(), true); + return super.performOk(); + } + + @Override + protected void performDefaults() { + twoWayComparisonContent.setViewerInput(groupManager.getDefaultRankingConfiguration(false)); + threeWayComparisonContent.setViewerInput(groupManager.getDefaultRankingConfiguration(true)); + super.performDefaults(); + } + +} diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/PostProcessorPreferencePage.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/PostProcessorPreferencePage.java index 878a81848..00a0efc56 100644 --- a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/PostProcessorPreferencePage.java +++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/PostProcessorPreferencePage.java @@ -29,7 +29,8 @@ import org.eclipse.emf.compare.rcp.internal.extension.impl.ItemUtil; import org.eclipse.emf.compare.rcp.internal.preferences.EMFComparePreferences; import org.eclipse.emf.compare.rcp.internal.tracer.TracingConstant; import org.eclipse.emf.compare.rcp.ui.internal.EMFCompareRCPUIMessages; -import org.eclipse.emf.compare.rcp.ui.internal.preferences.InteractiveUIContent.InteractiveUIBuilder; +import org.eclipse.emf.compare.rcp.ui.internal.preferences.impl.InteractiveUIContent; +import org.eclipse.emf.compare.rcp.ui.internal.preferences.impl.InteractiveUIContent.InteractiveUIBuilder; import org.eclipse.jface.preference.PreferencePage; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.swt.SWT; @@ -51,21 +52,41 @@ public class PostProcessorPreferencePage extends PreferencePage implements IWork /** Data holder. */ private DataHolder<IPostProcessor.Descriptor> dataHolder = new DataHolder<IPostProcessor.Descriptor>(); - /** {@link InteractiveUIContent} */ - private InteractiveUIContent interactiveUI = null; + /** {@link InteractiveUIContent}. */ + private InteractiveUIContent interactiveUI; + /** + * Constructor. + */ public PostProcessorPreferencePage() { super(); } + /** + * Constructor. + * + * @param title + * . + * @param image + * . + */ public PostProcessorPreferencePage(String title, ImageDescriptor image) { super(title, image); } + /** + * Constructor. + * + * @param title + * . + */ public PostProcessorPreferencePage(String title) { super(title); } + /** + * {@inheritDoc} + */ public void init(IWorkbench workbench) { // Do not use InstanceScope.Instance to be compatible with Helios. @SuppressWarnings("deprecation") @@ -110,10 +131,10 @@ public class PostProcessorPreferencePage extends PreferencePage implements IWork if (TracingConstant.CONFIGURATION_TRACING_ACTIVATED) { StringBuilder traceMessage = new StringBuilder("Post processor preference serialization:\n"); //$NON-NLS-1$ String prefDelimiter = " :\n"; //$NON-NLS-1$ - String new_line = "\n"; //$NON-NLS-1$ + String newLine = "\n"; //$NON-NLS-1$ traceMessage.append(EMFComparePreferences.DISABLED_POST_PROCESSOR).append(prefDelimiter).append( getPreferenceStore().getString(EMFComparePreferences.DISABLED_POST_PROCESSOR)).append( - new_line); + newLine); EMFCompareRCPPlugin.getDefault().log(IStatus.INFO, traceMessage.toString()); } @@ -136,10 +157,9 @@ public class PostProcessorPreferencePage extends PreferencePage implements IWork * Key used in the preference store. * @param currentSelectedEngines * Engines to store. - * @param defaultConf - * Default configuration for this type of engines. */ - private <T> void setEnginePreferences(String preferenceKey, Set<IItemDescriptor<T>> currentSelectedEngines) { + private void setEnginePreferences(String preferenceKey, + Set<IItemDescriptor<IPostProcessor.Descriptor>> currentSelectedEngines) { if (currentSelectedEngines != null && currentSelectedEngines.size() > 0) { Iterable<String> identifiers = Iterables.transform(currentSelectedEngines, new Function<IItemDescriptor<?>, String>() { diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/impl/GroupsInteractiveContent.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/impl/GroupsInteractiveContent.java new file mode 100644 index 000000000..9cf489815 --- /dev/null +++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/impl/GroupsInteractiveContent.java @@ -0,0 +1,292 @@ +/******************************************************************************* + * Copyright (c) 2014 Obeo. + * 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: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.emf.compare.rcp.ui.internal.preferences.impl; + +import com.google.common.collect.Lists; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.emf.compare.rcp.internal.extension.IItemDescriptor; +import org.eclipse.emf.compare.rcp.ui.EMFCompareRCPUIPlugin; +import org.eclipse.emf.compare.rcp.ui.internal.EMFCompareRCPUIMessages; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider; +import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider.Descriptor; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ListViewer; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.StructuredViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.layout.RowLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Text; + +/** + * Interactive content used for {@link IDifferenceGroupProvider} preferences. + * + * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a> + */ +public class GroupsInteractiveContent { + + /** + * Listener to update description text + * + * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a> + */ + private final class DescriptionListener implements ISelectionChangedListener { + + public void selectionChanged(SelectionChangedEvent event) { + ISelection selection = event.getSelection(); + if (selection instanceof IStructuredSelection) { + IStructuredSelection structSelection = (IStructuredSelection)selection; + Object selected = structSelection.getFirstElement(); + if (selected instanceof IItemDescriptor<?>) { + IItemDescriptor<?> desc = (IItemDescriptor<?>)selected; + String description = desc.getDescription(); + descriptionText.setText(description); + } + } + + } + } + + /** Down icon picture. */ + private static final String ENABLE_DOWN_IMG = "icons/full/pref16/down.gif"; //$NON-NLS-1$ + + /** Up icon picture. */ + private static final String ENABLE_UP_IMG = "icons/full/pref16/up.gif"; //$NON-NLS-1$ + + /** Text that shall be updated with the description of the viewer. */ + private final Text descriptionText; + + private ArrayList<IItemDescriptor<IDifferenceGroupProvider.Descriptor>> descriptors; + + private Button downButton; + + private Button upButton; + + /** Viewer of {@link IItemDescriptor}. */ + private ListViewer viewer; + + /** Composite holding the viewer. */ + private final Composite viewerCompsite; + + public GroupsInteractiveContent(Composite parent) { + super(); + Composite containerComposite = new Composite(parent, SWT.NONE); + containerComposite.setLayout(new GridLayout(1, false)); + containerComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); + + Composite interactiveComposite = new Composite(containerComposite, SWT.BORDER); + interactiveComposite.setLayout(new GridLayout(2, false)); + interactiveComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); + + // Engine chooser composite + this.viewerCompsite = new Composite(interactiveComposite, SWT.NONE); + viewerCompsite.setLayout(new GridLayout(1, true)); + viewerCompsite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); + // Descriptor engine Text + createButtonComposite(interactiveComposite); + this.descriptionText = createDescriptionComposite(interactiveComposite); + } + + /** + * Creates the composite for up and down button. + * + * @param parent + */ + private void createButtonComposite(Composite parent) { + Composite buttonComposite = new Composite(parent, SWT.NONE); + GridData layoutData = new GridData(SWT.LEFT, SWT.CENTER, false, true, 1, 1); + buttonComposite.setLayoutData(layoutData); + buttonComposite.setLayout(new RowLayout(SWT.VERTICAL)); + upButton = new Button(buttonComposite, SWT.NONE); + upButton.setImage(EMFCompareRCPUIPlugin.getImage(ENABLE_UP_IMG)); + upButton.addSelectionListener(new SelectionListener() { + + public void widgetDefaultSelected(SelectionEvent e) { + + } + + public void widgetSelected(SelectionEvent e) { + if (upButton.equals(e.getSource())) { + IItemDescriptor<Descriptor> selection = getCurrentSelection(); + int index = descriptors.indexOf(selection); + descriptors.remove(selection); + int newIndex = index - 1; + if (newIndex <= descriptors.size()) { + descriptors.add(newIndex, selection); + setViewerInput(descriptors); + select(selection); + } + } + } + }); + downButton = new Button(buttonComposite, SWT.NONE); + downButton.addSelectionListener(new SelectionListener() { + + public void widgetDefaultSelected(SelectionEvent e) { + + } + + public void widgetSelected(SelectionEvent e) { + if (downButton.equals(e.getSource())) { + IItemDescriptor<Descriptor> selection = getCurrentSelection(); + int index = descriptors.indexOf(selection); + descriptors.remove(selection); + int newIndex = index + 1; + if (newIndex <= descriptors.size()) { + descriptors.add(newIndex, selection); + setViewerInput(descriptors); + select(selection); + } + } + } + }); + + downButton.setImage(EMFCompareRCPUIPlugin.getImage(ENABLE_DOWN_IMG)); + + } + + /** + * Composite for description. This composite holds the text widget that will update with the current + * selection + * + * @param composite + * @return + */ + private Text createDescriptionComposite(Composite composite) { + Group descriptionComposite = new Group(composite, SWT.BORDER); + descriptionComposite.setText(EMFCompareRCPUIMessages + .getString("InteractiveUIContent.DESCRIPTION_COMPOSITE_LABEL")); //$NON-NLS-1$ + descriptionComposite.setLayout(new GridLayout(1, false)); + descriptionComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1)); + Text engineDescriptionText = new Text(descriptionComposite, SWT.WRAP | SWT.MULTI); + engineDescriptionText.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND)); + GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1); + layoutData.heightHint = 50; + engineDescriptionText.setLayoutData(layoutData); + engineDescriptionText.setEditable(false); + return engineDescriptionText; + } + + @SuppressWarnings("unchecked") + private IItemDescriptor<IDifferenceGroupProvider.Descriptor> getCurrentSelection() { + final ISelection selection = viewer.getSelection(); + if (selection instanceof IStructuredSelection) { + final IStructuredSelection structSelection = (IStructuredSelection)selection; + final Object first = structSelection.getFirstElement(); + if (first instanceof IItemDescriptor<?>) { + // secure due to Object structure. + return (IItemDescriptor<IDifferenceGroupProvider.Descriptor>)first; + } + } + return null; + } + + /** + * @return The ordered list of {@link IItemDescriptor}. + */ + public List<IItemDescriptor<IDifferenceGroupProvider.Descriptor>> getItems() { + return descriptors; + } + + /** + * @return The composite holding the viewer. + */ + public Composite getViewerComposite() { + return viewerCompsite; + } + + private boolean isFirst(Object o) { + if (descriptors != null && !descriptors.isEmpty()) { + return descriptors.get(0).equals(o); + } + return false; + } + + private boolean isLast(Object o) { + if (descriptors != null && !descriptors.isEmpty()) { + return descriptors.get(descriptors.size() - 1).equals(o); + } + return false; + } + + /** + * Handles a selection in the viewer. Updates related components. + * + * @param descriptor + */ + public void select(IItemDescriptor<IDifferenceGroupProvider.Descriptor> descriptor) { + // Update viewer + viewer.setSelection(new StructuredSelection(descriptor), true); + updateLinkedElements(descriptor); + } + + /** + * Sets the input for interactive content. + * + * @param input + */ + public void setViewerInput(List<IItemDescriptor<IDifferenceGroupProvider.Descriptor>> input) { + if (viewer != null) { + this.descriptors = Lists.newArrayList(input); + viewer.setInput(descriptors); + } else { + EMFCompareRCPUIPlugin.getDefault().log(IStatus.ERROR, + "Please initialize the viewer before setting input"); //$NON-NLS-1$ + } + } + + /** + * @param viewer + * A {@link StructuredViewer} of {@link IItemDescriptor} + */ + public void setViewer(ListViewer inputViewer) { + this.viewer = inputViewer; + viewer.addSelectionChangedListener(new DescriptionListener()); + viewer.addSelectionChangedListener(new ISelectionChangedListener() { + + public void selectionChanged(SelectionChangedEvent event) { + IItemDescriptor<?> selection = getCurrentSelection(); + if (selection == null) { + upButton.setEnabled(false); + downButton.setEnabled(false); + } else { + upButton.setEnabled(!isFirst(selection)); + downButton.setEnabled(!isLast(selection)); + } + } + + }); + } + + /** + * Updates linked element in + * + * @param descriptor + */ + private void updateLinkedElements(IItemDescriptor<IDifferenceGroupProvider.Descriptor> descriptor) { + // Update description + descriptionText.setText(descriptor.getDescription()); + } +} diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/InteractiveUIContent.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/impl/InteractiveUIContent.java index ad0cb168b..a26a31014 100644 --- a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/InteractiveUIContent.java +++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/impl/InteractiveUIContent.java @@ -8,7 +8,7 @@ * Contributors: * Obeo - initial API and implementation *******************************************************************************/ -package org.eclipse.emf.compare.rcp.ui.internal.preferences; +package org.eclipse.emf.compare.rcp.ui.internal.preferences.impl; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableMap; @@ -28,6 +28,7 @@ import org.eclipse.emf.compare.rcp.internal.extension.impl.ItemUtil; import org.eclipse.emf.compare.rcp.ui.internal.EMFCompareRCPUIMessages; import org.eclipse.emf.compare.rcp.ui.internal.configuration.ui.AbstractConfigurationUI; import org.eclipse.emf.compare.rcp.ui.internal.configuration.ui.IConfigurationUIFactory; +import org.eclipse.emf.compare.rcp.ui.internal.preferences.DataHolder; import org.eclipse.jface.databinding.viewers.IViewerObservableSet; import org.eclipse.jface.databinding.viewers.ViewersObservables; import org.eclipse.jface.dialogs.MessageDialog; @@ -38,7 +39,6 @@ import org.eclipse.jface.viewers.ICheckStateListener; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.StructuredViewer; @@ -73,7 +73,10 @@ import org.osgi.service.prefs.Preferences; * * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a> */ -public class InteractiveUIContent { +public final class InteractiveUIContent { + + /** Height hint for description composite. */ + private static final int DESCRIPTION_COMPOSITE_HEIGHT_HINT = 50; /** Text that will be updated with the description of the viewer. */ private final Text descriptionText; @@ -93,6 +96,16 @@ public class InteractiveUIContent { /** List of all {@link AbstractConfigurationUI} that are linked to this viewer. */ private final Map<String, AbstractConfigurationUI> configurators = new HashMap<String, AbstractConfigurationUI>(); + /** + * Constructor. + * + * @param parent + * Composite parent holding this interactive content. + * @param hasDescription + * Set to true if this has a description label that react to viewer selection. + * @param hasConfiguration + * set to true if this has a configuration composite that react to viewer selection. + */ private InteractiveUIContent(Composite parent, boolean hasDescription, boolean hasConfiguration) { super(); Composite contentComposite = new Composite(parent, SWT.NONE); @@ -131,12 +144,14 @@ public class InteractiveUIContent { } /** - * Add a configuration to this Interactive content. + * Adds a configuration to this Interactive content. * * @param id * Id of the item to configure * @param configuratorfactory * Factory for the configuration + * @param pref + * Preference store that will hold this {@link IConfigurationUIFactory} value. */ public void addConfigurator(String id, IConfigurationUIFactory configuratorfactory, Preferences pref) { AbstractConfigurationUI configurator = configuratorfactory.createUI(configurationComposite, SWT.NONE, @@ -145,31 +160,34 @@ public class InteractiveUIContent { } /** - * Check one element in the viewer + * Checks one element in the viewer. * * @param descriptor + * element to check. */ public void checkElement(IItemDescriptor<?> descriptor) { viewer.setCheckedElements(new Object[] {descriptor }); } /** - * Check multiple element in the viewer. (Only use if multiple selection is allowed) + * Checks multiple element in the viewer. (Only use if multiple selection is allowed) * * @param descriptors + * elements to check. */ public void checkElements(IItemDescriptor<?>[] descriptors) { viewer.setCheckedElements(descriptors); } /** - * Create the composite that will hold all configurations for a tab. + * Creates the composite that will hold all configurations for a tab. * * @param composite - * @return + * Main composite + * @return Group that will hold configurations in a stack layout. */ private Group createConfigComposite(Composite composite) { - Group confComposite = new Group(composite, SWT.NONE); + Group confComposite = new Group(composite, SWT.BORDER); confComposite.setText(EMFCompareRCPUIMessages .getString("InteractiveUIContent.CONFIGURATION_COMPOSITE_LABEL")); //$NON-NLS-1$ StackLayout layout = new StackLayout(); @@ -182,14 +200,15 @@ public class InteractiveUIContent { } /** - * Composite for description. This composite hold the text widget that will update with the current - * selection + * Composite for description. This composite holds the text widget that will be updated with the current + * selection. * * @param composite - * @return + * Main composite. + * @return Text that will hold viewer selection description. */ private Text createDescriptionComposite(Composite composite) { - Group descriptionComposite = new Group(composite, SWT.NONE); + Group descriptionComposite = new Group(composite, SWT.BORDER); descriptionComposite.setText(EMFCompareRCPUIMessages .getString("InteractiveUIContent.DESCRIPTION_COMPOSITE_LABEL")); //$NON-NLS-1$ descriptionComposite.setLayout(new GridLayout(1, false)); @@ -197,7 +216,7 @@ public class InteractiveUIContent { Text engineDescriptionText = new Text(descriptionComposite, SWT.WRAP | SWT.MULTI); engineDescriptionText.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND)); GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1); - layoutData.heightHint = 50; + layoutData.heightHint = DESCRIPTION_COMPOSITE_HEIGHT_HINT; engineDescriptionText.setLayoutData(layoutData); engineDescriptionText.setEditable(false); return engineDescriptionText; @@ -211,6 +230,8 @@ public class InteractiveUIContent { } /** + * Gets the viewer. + * * @return The viewer. */ private CheckboxTableViewer getViewer() { @@ -218,6 +239,8 @@ public class InteractiveUIContent { } /** + * Returns the composite that will hold the viewer. + * * @return The composite holding the viewer. */ private Composite getViewerComposite() { @@ -225,9 +248,10 @@ public class InteractiveUIContent { } /** - * Handle a selection in the viewer. Update related components. + * Handles a selection in the viewer. Update related components. * * @param descriptor + * Item to select. */ public void select(IItemDescriptor<?> descriptor) { // Update viewer @@ -236,7 +260,9 @@ public class InteractiveUIContent { } /** - * @param viewer + * Sets the viewer in the interactive content. + * + * @param inputViewer * A {@link StructuredViewer} of {@link IItemDescriptor} */ public void setViewer(CheckboxTableViewer inputViewer) { @@ -248,9 +274,10 @@ public class InteractiveUIContent { } /** - * Update linked element in + * Updates the linked element in this interactive content. * * @param descriptor + * Item used as input to get information for satellite elements. */ private void updateLinkedElements(IItemDescriptor<?> descriptor) { // Update description @@ -260,6 +287,12 @@ public class InteractiveUIContent { } } + /** + * Updates the configuration composite. + * + * @param descriptor + * New descriptor. + */ private void updateConfigurationComposite(IItemDescriptor<?> descriptor) { StackLayout stackLayout = (StackLayout)configurationComposite.getLayout(); if (configurators.containsKey(descriptor.getID())) { @@ -271,18 +304,35 @@ public class InteractiveUIContent { } /** - * This listener updates the Data Holder and for that only one element can be checked at a time. + * This listener updates the Data Holder. + * <p> + * With this listener, only one element can be checked at a time + * </p> * * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a> * @param <T> + * Type of item. */ private static final class SingleCheckListener<T> implements ICheckStateListener { + /** Data holder. */ private final DataHolder<T> dataObject; + /** Viewer. */ private final CheckboxTableViewer descriptorViewer; + /** Shell. */ private final Shell shell; + /** + * Constructor. + * + * @param dataObject + * Data holder. + * @param descriptorViewer + * Viewer + * @param shell + * Shell. + */ private SingleCheckListener(DataHolder<T> dataObject, CheckboxTableViewer descriptorViewer, Shell shell) { this.dataObject = dataObject; @@ -290,6 +340,9 @@ public class InteractiveUIContent { this.shell = shell; } + /** + * {@inheritDoc} + */ public void checkStateChanged(CheckStateChangedEvent event) { Object element = event.getElement(); if (event.getChecked()) { @@ -319,25 +372,31 @@ public class InteractiveUIContent { * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a> */ private final class ConfigurationListener implements ISelectionChangedListener { + /** + * {@inheritDoc} + */ public void selectionChanged(SelectionChangedEvent event) { ISelection selection = event.getSelection(); if (selection instanceof IStructuredSelection) { IStructuredSelection structSelection = (IStructuredSelection)selection; Object selected = structSelection.getFirstElement(); if (selected instanceof IItemDescriptor<?>) { - updateLinkedElements(((IItemDescriptor<?>)selected)); + updateLinkedElements((IItemDescriptor<?>)selected); } } } } /** - * Listener to update description text + * Listener used to update description text. * * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a> */ private final class DescriptionListener implements ISelectionChangedListener { + /** + * {@inheritDoc} + */ public void selectionChanged(SelectionChangedEvent event) { ISelection selection = event.getSelection(); if (selection instanceof IStructuredSelection) { @@ -354,25 +413,6 @@ public class InteractiveUIContent { } /** - * Label provider for {@link ILabeledItemDescriptor} - * - * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a> - */ - private static final class EngineDescriptorLabelProvider extends LabelProvider { - /** - * {@inheritDoc} - */ - @Override - public String getText(Object element) { - if (element instanceof IItemDescriptor<?>) { - IItemDescriptor<?> desc = (IItemDescriptor<?>)element; - return desc.getLabel(); - } - return super.getText(element); - } - } - - /** * Builder for an Interactive UI. * * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a> @@ -394,10 +434,10 @@ public class InteractiveUIContent { private Map<String, IConfigurationUIFactory> configurationUIRegistry; /** Set of elements to check by default. */ - private Set<IItemDescriptor<T>> defaultCheck = null; + private Set<IItemDescriptor<T>> defaultCheck; /** Element to select by default. */ - private IItemDescriptor<T> defaultSelection = null; + private IItemDescriptor<T> defaultSelection; /** Object holding data representing the current status of the interactive content. */ private DataHolder<T> dataHolder; @@ -415,8 +455,6 @@ public class InteractiveUIContent { * Holding composite of all the structure. * @param registry * Item registry holding input of the viewer. - * @param dataHolder - * Object holding data representing the current status of the interactive content. */ public InteractiveUIBuilder(Composite parent, IItemRegistry<T> registry) { super(); @@ -425,24 +463,25 @@ public class InteractiveUIContent { } /** - * Set a dataHolder that will be synchronized with the checked element. If this isSimple then - * {@link DataHolder#simpleData} is filled. else {@link DataHolder#data} is filled + * Sets a dataHolder that will be synchronized with the checked element. * - * @param dataHolder - * @return + * @param newDataHolder + * DataHolder. + * @return {@link InteractiveUIBuilder} */ - public InteractiveUIBuilder<T> setHoldingData(DataHolder<T> dataHolder) { - this.dataHolder = dataHolder; + public InteractiveUIBuilder<T> setHoldingData(DataHolder<T> newDataHolder) { + this.dataHolder = newDataHolder; return this; } /** - * Key of the node to get the {@link Preferences} to retrieve {@link IConfigurationUIFactory}. See - * {@link ItemUtil#getConfigurationPreferenceNode(String, String)} (needed is ConfigurationUIRegistry - * is provided) + * Node key used to get the {@link Preferences} to retrieve {@link IConfigurationUIFactory}. See + * {@link ItemUtil#getConfigurationPreferenceNode(String, String)} (needed if a + * ConfigurationUIRegistry has been provided) * * @param key - * @return + * . + * @return {@link InteractiveUIBuilder} */ public InteractiveUIBuilder<T> setConfigurationNodeKey(String key) { this.configurationNodeKey = key; @@ -450,10 +489,11 @@ public class InteractiveUIContent { } /** - * Registry of of {@link IConfigurationUIFactory} to filled the configuraiton composite. + * Registry of {@link IConfigurationUIFactory} used to fill the configuration composite. * * @param configuratorUIRegistry - * @return + * . + * @return {@link InteractiveUIBuilder} */ public InteractiveUIBuilder<T> setConfiguratorUIRegistry( Map<String, IConfigurationUIFactory> configuratorUIRegistry) { @@ -462,54 +502,58 @@ public class InteractiveUIContent { } /** - * Set the default element to check. (A singleton is this is set to simple + * Sets the default element to check. (A singleton if "this" is set to simple * {@link InteractiveUIBuilder#setSimple(boolean)} * - * @param defaultCheck - * @return + * @param newDefaultCheck + * . + * @return InteractiveUIBuilder */ - public InteractiveUIBuilder<T> setDefaultCheck(Set<IItemDescriptor<T>> defaultCheck) { - this.defaultCheck = defaultCheck; + public InteractiveUIBuilder<T> setDefaultCheck(Set<IItemDescriptor<T>> newDefaultCheck) { + this.defaultCheck = newDefaultCheck; return this; } /** * Set the default element to select. * - * @param defaultSelection - * @return + * @param newDefaultSelection + * . + * @return InteractiveUIBuilder */ - public InteractiveUIBuilder<T> setDefaultSelection(IItemDescriptor<T> defaultSelection) { - this.defaultSelection = defaultSelection; + public InteractiveUIBuilder<T> setDefaultSelection(IItemDescriptor<T> newDefaultSelection) { + this.defaultSelection = newDefaultSelection; return this; } /** - * Set to true if this need to create a description field. + * Set to true if "this" needs to create a description field. * - * @param hasDescription - * @return + * @param newHasDescription + * . + * @return {@link InteractiveUIBuilder} */ - public InteractiveUIBuilder<T> setHasDescription(boolean hasDescription) { - this.hasDescription = hasDescription; + public InteractiveUIBuilder<T> setHasDescription(boolean newHasDescription) { + this.hasDescription = newHasDescription; return this; } /** - * Set to true if the viewer can only have only one element check at a time. + * Set to true if the viewer can only have only one element checked at a time. * - * @param isSimple - * @return + * @param newIsSimple + * . + * @return {@link InteractiveUIBuilder} */ - public InteractiveUIBuilder<T> setSimple(boolean isSimple) { - this.isSimple = isSimple; + public InteractiveUIBuilder<T> setSimple(boolean newIsSimple) { + this.isSimple = newIsSimple; return this; } /** - * Build a new {@link InteractiveUI} + * Build a new {@link InteractiveUI}. * - * @return + * @return InteractiveUIContent */ public InteractiveUIContent build() { // If simple only one element check at a time @@ -533,6 +577,13 @@ public class InteractiveUIContent { return interactiveUI; } + /** + * Initializes the viewer. + * + * @param interactiveUI + * . + * @return CheckboxTableViewer + */ private CheckboxTableViewer createViewer(final InteractiveUIContent interactiveUI) { int style = SWT.BORDER | SWT.V_SCROLL | SWT.FULL_SELECTION; if (isSimple) { @@ -542,12 +593,18 @@ public class InteractiveUIContent { .getViewerComposite(), style); interactiveUI.setViewer(descriptorViewer); descriptorViewer.setContentProvider(ArrayContentProvider.getInstance()); - descriptorViewer.setLabelProvider(new EngineDescriptorLabelProvider()); + descriptorViewer.setLabelProvider(new ItemDescriptorLabelProvider()); GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1); descriptorViewer.getControl().setLayoutData(gd); return descriptorViewer; } + /** + * Creates the configuration composite. + * + * @param interactiveUI + * . + */ private void createConfigurationComposite(final InteractiveUIContent interactiveUI) { // Init configuration elements for (IItemDescriptor<T> item : registry.getItemDescriptors()) { @@ -560,6 +617,14 @@ public class InteractiveUIContent { } } + /** + * Initializes and binds interactive content with the data holder value. + * + * @param interactiveUI + * . + * @param descriptorViewer + * . + */ private void bindAndInit(final InteractiveUIContent interactiveUI, CheckboxTableViewer descriptorViewer) { if (defaultSelection != null) { @@ -581,11 +646,17 @@ public class InteractiveUIContent { dataHolder.setData(defaultCheck); } // Bind data - bindMultipleData(DataHolder.DATA_FIELD_NAME, interactiveUI.getViewer(), dataHolder); + bindMultipleData(interactiveUI.getViewer(), dataHolder); } } } + /** + * Sets the viewer input. + * + * @param descriptorViewer + * . + */ private void setViewerInput(CheckboxTableViewer descriptorViewer) { List<IItemDescriptor<T>> itemDescriptors = registry.getItemDescriptors(); Collections.sort(itemDescriptors); @@ -593,19 +664,19 @@ public class InteractiveUIContent { } /** - * Bind UI to data object. + * Binds UI to data object. * - * @param engineBindingProperty * @param descriptorViewer + * . * @param dataObject + * The data holder. */ - private void bindMultipleData(String engineBindingProperty, CheckboxTableViewer descriptorViewer, - final DataHolder<T> dataObject) { + private void bindMultipleData(CheckboxTableViewer descriptorViewer, final DataHolder<T> dataObject) { DataBindingContext ctx = new DataBindingContext(); // Bind the button with the corresponding field in data IViewerObservableSet target = ViewersObservables.observeCheckedElements(descriptorViewer, IItemDescriptor.class); - IObservableSet model = PojoProperties.set(DataHolder.class, engineBindingProperty).observe( + IObservableSet model = PojoProperties.set(DataHolder.class, DataHolder.DATA_FIELD_NAME).observe( dataObject); ctx.bindSet(target, model); diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/impl/ItemDescriptorLabelProvider.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/impl/ItemDescriptorLabelProvider.java new file mode 100644 index 000000000..84d5c57cd --- /dev/null +++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/preferences/impl/ItemDescriptorLabelProvider.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2014 Obeo. + * 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: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.emf.compare.rcp.ui.internal.preferences.impl; + +import org.eclipse.emf.compare.rcp.internal.extension.IItemDescriptor; +import org.eclipse.jface.viewers.LabelProvider; + +/** + * Label provider for {@link IItemDescriptor}. + * + * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a> + */ +public class ItemDescriptorLabelProvider extends LabelProvider { + /** + * {@inheritDoc} + */ + @Override + public String getText(Object element) { + if (element instanceof IItemDescriptor<?>) { + IItemDescriptor<?> desc = (IItemDescriptor<?>)element; + return desc.getLabel(); + } + return super.getText(element); + } +} diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/impl/DifferenceGroupManager.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/impl/DifferenceGroupManager.java new file mode 100644 index 000000000..e6ea2a338 --- /dev/null +++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/impl/DifferenceGroupManager.java @@ -0,0 +1,258 @@ +/******************************************************************************
+ * Copyright (c) 2014 Obeo.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.groups.impl;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import com.google.common.collect.Sets.SetView;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.emf.compare.rcp.internal.extension.IItemDescriptor;
+import org.eclipse.emf.compare.rcp.internal.extension.IItemRegistry;
+import org.eclipse.emf.compare.rcp.internal.extension.impl.ItemUtil;
+import org.eclipse.emf.compare.rcp.internal.tracer.TracingConstant;
+import org.eclipse.emf.compare.rcp.ui.EMFCompareRCPUIPlugin;
+import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider;
+import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider.ComparisonType;
+import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider.Descriptor;
+import org.osgi.service.prefs.Preferences;
+
+/**
+ * This manager can be used to modify EMF Compare UI behavior regarding groups.
+ * <p>
+ * This manager can override the rank of groups. For example, it can be used to define a default group that
+ * will be used by EMF Compare UI.
+ * </p>
+ *
+ * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a>
+ */
+public class DifferenceGroupManager {
+
+ /** Prefix for preferences. */
+ private static final String EMFCOMPARE_RCP_UI_PREFIX = "org.eclipse.emf.compare.rcp.ui."; //$NON-NLS-1$
+
+ /** Ordered list of groups for two way comparison. */
+ private static final String TWO_WAY_GROUP_RANKING = EMFCOMPARE_RCP_UI_PREFIX + "groups.2way.ranking"; //$NON-NLS-1$
+
+ /** Ordered list of groups for three way comparison. */
+ private static final String THREE_WAY_GROUP_RANKING = EMFCOMPARE_RCP_UI_PREFIX + "groups.3way.ranking"; //$NON-NLS-1$
+
+ /** Preferences holding preference values. */
+ private final Preferences preferences;
+
+ /** Registry of {@link IDifferenceGroupProvider.Descriptor}. */
+ private final IItemRegistry<IDifferenceGroupProvider.Descriptor> registry;
+
+ private static final Predicate<IItemDescriptor<Descriptor>> TWO_WAY_FILTER = new Predicate<IItemDescriptor<Descriptor>>() {
+
+ public boolean apply(IItemDescriptor<Descriptor> descriptor) {
+ if (descriptor == null) {
+ return false;
+ }
+ ComparisonType type = descriptor.getItem().getType();
+ return type == ComparisonType.BOTH || type == ComparisonType.TWO_WAY;
+ }
+ };
+
+ private static final Predicate<IItemDescriptor<Descriptor>> THREE_WAY_FILTER = new Predicate<IItemDescriptor<Descriptor>>() {
+
+ public boolean apply(IItemDescriptor<Descriptor> descriptor) {
+ if (descriptor == null) {
+ return false;
+ }
+ ComparisonType type = descriptor.getItem().getType();
+ return type == ComparisonType.BOTH || type == ComparisonType.THREE_WAY;
+ }
+ };
+
+ /**
+ * Constructor.
+ *
+ * @param preferences
+ * Preferences holding preference values.
+ * @param registry
+ * Registry of {@link IDifferenceGroupProvider.Descriptor}.
+ */
+ public DifferenceGroupManager(Preferences preferences,
+ IItemRegistry<IDifferenceGroupProvider.Descriptor> registry) {
+ super();
+ this.preferences = preferences;
+ this.registry = registry;
+ }
+
+ /**
+ * Gets the current value of the group ranking.
+ *
+ * @param preferenceKey
+ * Preference key use to retrieve the value in preferences.
+ * @param defaultOrder
+ * The default ranking.
+ * @return A ordered {@link List} of {@link IItemDescriptor}.
+ */
+ private List<IItemDescriptor<IDifferenceGroupProvider.Descriptor>> getCurrent(String preferenceKey,
+ List<IItemDescriptor<Descriptor>> defaultOrder) {
+ return getOrderedItems(defaultOrder, registry, preferenceKey);
+ }
+
+ /**
+ * Gets the current group order.
+ *
+ * @param isThreeWay
+ * True if three way comparison, false otherwise.
+ * @return Ordered {@link List} of {@link IDifferenceGroupProvider.Descriptor}.
+ */
+ public List<IItemDescriptor<Descriptor>> getCurrentGroupRanking(boolean isThreeWay) {
+ return getCurrent(getGroupPreferenceKey(isThreeWay), getDefaultRankingConfiguration(isThreeWay));
+ }
+
+ /**
+ * Gets the default groups order.
+ *
+ * @param isThreeWay
+ * True if three way comparison, false otherwise.
+ * @return Ordered {@link List} of {@link IDifferenceGroupProvider.Descriptor}.
+ */
+ public List<IItemDescriptor<IDifferenceGroupProvider.Descriptor>> getDefaultRankingConfiguration(
+ boolean isThreeWay) {
+ final Iterable<IItemDescriptor<Descriptor>> groups;
+ if (isThreeWay) {
+ groups = Iterables.filter(registry.getItemDescriptors(), THREE_WAY_FILTER);
+ } else {
+
+ groups = Iterables.filter(registry.getItemDescriptors(), TWO_WAY_FILTER);
+ }
+ List<IItemDescriptor<Descriptor>> result = Lists.newArrayList(groups);
+ Collections.sort(result);
+ return result;
+ }
+
+ /**
+ * Gets the preference key for group ranking.
+ *
+ * @param isThreeWay
+ * True if three way comparison.
+ * @return They key of the group ranking preference for this type of comparison.
+ */
+ private String getGroupPreferenceKey(boolean isThreeWay) {
+ if (isThreeWay) {
+ return THREE_WAY_GROUP_RANKING;
+ } else {
+ return TWO_WAY_GROUP_RANKING;
+ }
+ }
+
+ /**
+ * Returns an ordered list of {@link IItemDescriptor}. The order of the list is either defined by the rank
+ * in the registry or from preference if the rank has been overloaded. If any descriptor has been added or
+ * removed since last modification of the preference, this method will merge the modification.
+ *
+ * @param orderedDefaultDescriptor
+ * List of ordered default {@link IItemDescriptor}.
+ * @param descriptorRegistry
+ * Registry of descriptor.
+ * @param orderedItemPreferenceKey
+ * Key in preferences where are stored the new order of descriptor
+ * @return Ordered list of descriptor.
+ * @param <T>
+ * Descriptor type.
+ */
+ private <T> List<IItemDescriptor<T>> getOrderedItems(List<IItemDescriptor<T>> orderedDefaultDescriptor,
+ IItemRegistry<T> descriptorRegistry, String orderedItemPreferenceKey) {
+ List<IItemDescriptor<T>> itemsDescriptor = ItemUtil.getItemsDescriptor(descriptorRegistry,
+ orderedItemPreferenceKey, preferences);
+
+ if (itemsDescriptor == null) {
+ itemsDescriptor = orderedDefaultDescriptor;
+ } else {
+ HashSet<IItemDescriptor<T>> descriptorFromPrefSet = Sets.newLinkedHashSet(itemsDescriptor);
+ HashSet<IItemDescriptor<T>> defaultDescriptorSet = Sets
+ .newLinkedHashSet(orderedDefaultDescriptor);
+
+ // Remove descriptor
+ SetView<IItemDescriptor<T>> descriptorToRemove = Sets.difference(descriptorFromPrefSet,
+ defaultDescriptorSet);
+ Iterables.removeAll(itemsDescriptor, descriptorToRemove);
+
+ // Add new descriptor
+ SetView<IItemDescriptor<T>> descriptorToAdd = Sets.difference(defaultDescriptorSet,
+ descriptorFromPrefSet);
+ Iterables.addAll(itemsDescriptor, descriptorToAdd);
+
+ }
+ return itemsDescriptor;
+ }
+
+ /**
+ * Sets the ranking of Difference group provider.
+ *
+ * @param descriptors
+ * An ordered list of {@link IItemDescriptor}.
+ * @param isThreeWay
+ * True if three way comparison.
+ */
+ public void setCurrentGroupRanking(List<IItemDescriptor<Descriptor>> descriptors, boolean isThreeWay) {
+ storeInPreferences(getGroupPreferenceKey(isThreeWay), descriptors,
+ getDefaultRankingConfiguration(isThreeWay));
+
+ // Trace preferences values
+ if (TracingConstant.CONFIGURATION_TRACING_ACTIVATED) {
+ StringBuilder builder = new StringBuilder();
+ // Print each preferences
+ builder.append("Preference ").append(getGroupPreferenceKey(isThreeWay)).append(":\n"); //$NON-NLS-1$ //$NON-NLS-2$
+ String preferenceValue = preferences.get(getGroupPreferenceKey(isThreeWay), ""); //$NON-NLS-1$
+ if (!"".equals(preferences)) { //$NON-NLS-1$
+ String[] groups = preferenceValue.split(ItemUtil.PREFERENCE_DELIMITER);
+ for (int rank = 0; rank < groups.length; rank++) {
+ builder.append(rank).append(". ").append(groups[rank]).append("\n"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+ builder.append("\n\n"); //$NON-NLS-1$
+ EMFCompareRCPUIPlugin.getDefault().log(IStatus.INFO, builder.toString());
+ }
+ }
+
+ /**
+ * Stores the value into preferences.
+ *
+ * @param preferenceKey
+ * Key of the preference
+ * @param currentValue
+ * Current value to store
+ * @param defaultConf
+ * Default value
+ */
+ private void storeInPreferences(String preferenceKey,
+ List<IItemDescriptor<IDifferenceGroupProvider.Descriptor>> currentValue,
+ List<IItemDescriptor<IDifferenceGroupProvider.Descriptor>> defaultConf) {
+ if (currentValue != null && !currentValue.equals(defaultConf)) {
+ StringBuilder descriptorsKey = new StringBuilder();
+ for (Iterator<IItemDescriptor<IDifferenceGroupProvider.Descriptor>> iterator = currentValue
+ .iterator(); iterator.hasNext();) {
+ IItemDescriptor<IDifferenceGroupProvider.Descriptor> iItemDescriptor = iterator.next();
+ descriptorsKey.append(iItemDescriptor.getID());
+ if (iterator.hasNext()) {
+ descriptorsKey.append(ItemUtil.PREFERENCE_DELIMITER);
+ }
+ }
+ preferences.put(preferenceKey, descriptorsKey.toString());
+ } else {
+ preferences.remove(preferenceKey);
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/impl/DifferenceGroupRegistryImpl.java b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/impl/DifferenceGroupRegistryImpl.java index ad757210d..e5f263b61 100644 --- a/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/impl/DifferenceGroupRegistryImpl.java +++ b/plugins/org.eclipse.emf.compare.rcp.ui/src/org/eclipse/emf/compare/rcp/ui/internal/structuremergeviewer/groups/impl/DifferenceGroupRegistryImpl.java @@ -13,10 +13,7 @@ package org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.groups.impl import static com.google.common.collect.Lists.newArrayList;
import com.google.common.base.Preconditions;
-import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
import java.util.Collections;
import java.util.List;
@@ -25,13 +22,10 @@ import java.util.ListIterator; import org.eclipse.emf.compare.Comparison;
import org.eclipse.emf.compare.rcp.internal.extension.IItemDescriptor;
import org.eclipse.emf.compare.rcp.internal.extension.IItemRegistry;
-import org.eclipse.emf.compare.rcp.internal.extension.impl.ItemUtil;
import org.eclipse.emf.compare.rcp.internal.extension.impl.WrapperItemDescriptor;
import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider;
-import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider.ComparisonType;
import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider.Descriptor;
import org.eclipse.emf.compare.scope.IComparisonScope;
-import org.osgi.service.prefs.Preferences;
/**
* Implementation of the {@link IDifferenceGroupProvider.Descriptor.Registry}. This implementation allow user
@@ -45,44 +39,21 @@ public class DifferenceGroupRegistryImpl implements IDifferenceGroupProvider.Des /** A map that associates the class name to theirs {@link IDifferenceGroupProvider.Descriptor}s. */
private final IItemRegistry<IDifferenceGroupProvider.Descriptor> registry;
- /** Preference key for two way comparison group ranking. */
- private final String twoWayPreferenceKey;
-
- /** Preference key for three way comparison group ranking. */
- private final String threeWayPrefenceKey;
-
- /** Preferences holding ranked descriptors. */
- private Preferences preferences;
+ /** Group manager. */
+ private DifferenceGroupManager groupManager;
/**
* Constructs the registry.
*
- * @param twoWaygroupProviderDescriptors
+ * @param groupManager
+ * {@link DifferenceGroupManager} use to handle groups.
+ * @param registry
+ * Item registry where are stored all registered group.
*/
- public DifferenceGroupRegistryImpl(IItemRegistry<IDifferenceGroupProvider.Descriptor> registry,
- Preferences preferences, String twoWayPreferenceKey, String threeWayPrefenceKey) {
+ public DifferenceGroupRegistryImpl(DifferenceGroupManager groupManager,
+ IItemRegistry<IDifferenceGroupProvider.Descriptor> registry) {
+ this.groupManager = groupManager;
this.registry = registry;
- this.twoWayPreferenceKey = twoWayPreferenceKey;
- this.threeWayPrefenceKey = threeWayPrefenceKey;
- this.preferences = preferences;
- }
-
- /**
- * Return an ordered list of IItemDescriptor<IDifferenceGroupProvider.Descriptor>.
- *
- * @return Ordered list of IItemDescriptor<IDifferenceGroupProvider.Descriptor>.
- */
- private List<IItemDescriptor<IDifferenceGroupProvider.Descriptor>> getOrderedGroupProviderDescriptors(
- final Comparison comparison) {
- final List<IItemDescriptor<Descriptor>> items;
- if (comparison.isThreeWay()) {
- items = ItemUtil.getOrderedItems(getDefaultThreeWayDescriptors(), registry, threeWayPrefenceKey,
- preferences);
- } else {
- items = ItemUtil.getOrderedItems(getDefaultTwoWayDescriptors(), registry, twoWayPreferenceKey,
- preferences);
- }
- return items;
}
/**
@@ -95,7 +66,8 @@ public class DifferenceGroupRegistryImpl implements IDifferenceGroupProvider.Des Comparison comparison) {
if (comparison != null) {
List<IDifferenceGroupProvider.Descriptor> providers = newArrayList();
- List<IItemDescriptor<Descriptor>> groupProviderDescriptors = getOrderedGroupProviderDescriptors(comparison);
+ List<IItemDescriptor<Descriptor>> groupProviderDescriptors = groupManager
+ .getCurrentGroupRanking(comparison.isThreeWay());
ListIterator<IItemDescriptor<Descriptor>> groupIterator = groupProviderDescriptors.listIterator();
while (groupIterator.hasNext()) {
IItemDescriptor<Descriptor> desc = groupIterator.next();
@@ -183,49 +155,4 @@ public class DifferenceGroupRegistryImpl implements IDifferenceGroupProvider.Des public void clear() {
registry.clear();
}
-
- /**
- * Get an ordered list of default descriptors for a three way comparison.
- *
- * @return
- */
- private List<IItemDescriptor<Descriptor>> getDefaultTwoWayDescriptors() {
- Iterable<IItemDescriptor<Descriptor>> threeWayGroups = Iterables.filter(
- registry.getItemDescriptors(), new Predicate<IItemDescriptor<Descriptor>>() {
-
- public boolean apply(IItemDescriptor<Descriptor> descriptor) {
- if (descriptor == null) {
- return false;
- }
- ComparisonType type = descriptor.getItem().getType();
- return type == ComparisonType.BOTH || type == ComparisonType.TWO_WAY;
- }
- });
- List<IItemDescriptor<Descriptor>> result = Lists.newArrayList(threeWayGroups);
- Collections.sort(result, Collections.reverseOrder());
- return result;
- }
-
- /**
- * Get an ordered list of default descriptors for a three way comparison.
- *
- * @return
- */
- private List<IItemDescriptor<Descriptor>> getDefaultThreeWayDescriptors() {
- Iterable<IItemDescriptor<Descriptor>> twoWayComparison = Iterables.filter(registry
- .getItemDescriptors(), new Predicate<IItemDescriptor<Descriptor>>() {
-
- public boolean apply(IItemDescriptor<Descriptor> descriptor) {
- if (descriptor == null) {
- return false;
- }
- ComparisonType type = descriptor.getItem().getType();
- return type == ComparisonType.BOTH || type == ComparisonType.THREE_WAY;
- }
- });
- List<IItemDescriptor<Descriptor>> result = Lists.newArrayList(twoWayComparison);
- Collections.sort(result, Collections.reverseOrder());
- return result;
- }
-
}
|