/******************************************************************************* * Copyright (c) 2014, 2016 Obeo 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: * Obeo - initial API and implementation * Simon Delisle - bug 495753 *******************************************************************************/ package org.eclipse.emf.compare.rcp.ui.internal.preferences; import static org.eclipse.jface.dialogs.MessageDialogWithToggle.ALWAYS; import static org.eclipse.jface.dialogs.MessageDialogWithToggle.NEVER; import static org.eclipse.jface.dialogs.MessageDialogWithToggle.PROMPT; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; 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.tracer.TracingConstant; 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.dialogs.MessageDialogWithToggle; import org.eclipse.jface.layout.GridLayoutFactory; 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.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Combo; 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; /** * Preference page for group providers. * * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a> */ public class GroupsPreferencePage extends PreferencePage implements IWorkbenchPreferencePage { /** Id of the preference page. */ public static final String PAGE_ID = "org.eclipse.emf.compare.rcp.ui.preferencePage.groups"; //$NON-NLS-1$ /** Default value for the synchronization behavior for 2-way and 3-way comparison. */ private static final String SYNC_DEFAULT_VALUE = MessageDialogWithToggle.PROMPT; /** List of all available values possible for synchronization behavior. */ private static final List<String> SYNC_VALUES = ImmutableList.of(ALWAYS, NEVER, PROMPT); /** Synchronization behavior for group 2 way comparison capable. */ private static final String TWO_WAY_COMPARISON_SYNC_BEHAVIOR = "org.eclipse.emf.compare.rcp.ui.groups.2way.syncbehavior"; //$NON-NLS-1$ /** Synchronization behavior for group 3 way comparison capable. */ private static final String THREE_WAY_COMPARISON_SYNC_BEHAVIOR = "org.eclipse.emf.compare.rcp.ui.groups.3ways.syncbehavior"; //$NON-NLS-1$ /** Combo holding syncrhonization behavior preferences. */ private Combo combo; /** Field holding the synchronization behavior chosen by the user. */ private String synchronizationBehaviorValue; /** 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().getItemDifferenceGroupProviderRegistry(), EMFCompareRCPUIPlugin.getDefault().getPreferenceStore()); /** * Gets the preference key for synchronization behavior. * * @param isThreeWay * True if three way comparison. * @return The key of the synchronization behavior for this type of comparison. */ public static String getGroupSynchronizationPreferenceKey(boolean isThreeWay) { if (isThreeWay) { return THREE_WAY_COMPARISON_SYNC_BEHAVIOR; } else { return TWO_WAY_COMPARISON_SYNC_BEHAVIOR; } } public void init(IWorkbench workbench) { setPreferenceStore(EMFCompareRCPUIPlugin.getDefault().getPreferenceStore()); } @Override protected Control createContents(Composite parent) { Composite container = new Composite(parent, SWT.NULL); GridLayoutFactory.fillDefaults().applyTo(container); container.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); createSynchronizationBehaviorContent(container); 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.twoWayComparisonTab.label"), //$NON-NLS-1$ EMFCompareRCPUIMessages.getString("GroupsPreferencePage.viewerDescription.label")); //$NON-NLS-1$ List<IItemDescriptor<Descriptor>> currentGroupRanking = groupManager.getCurrentGroupRanking(false); twoWayComparisonContent = createInteractiveContent(tabSkeletonComposite, currentGroupRanking, currentGroupRanking.get(0)); setComboInput(getCurrentSynchronizationBehavior(false)); } /** * Fills the tab for three way comparison. * * @param tabFolder * Holding tab folder. */ private void fillThreeWayComparisonTab(TabFolder tabFolder) { Composite tabSkeletonComposite = createTabSkeleton(tabFolder, EMFCompareRCPUIMessages.getString("GroupsPreferencePage.threeWayComparisonTab.label"), //$NON-NLS-1$ EMFCompareRCPUIMessages.getString("GroupsPreferencePage.viewerDescription.label")); //$NON-NLS-1$ List<IItemDescriptor<Descriptor>> currentGroupRanking = groupManager.getCurrentGroupRanking(true); threeWayComparisonContent = createInteractiveContent(tabSkeletonComposite, currentGroupRanking, currentGroupRanking.get(0)); setComboInput(getCurrentSynchronizationBehavior(true)); } /** * 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); 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); } /** * Content for synchronization behavior preferences. * * @param parent * Main composite. */ private void createSynchronizationBehaviorContent(Composite parent) { Composite synchronizationComposite = new Composite(parent, SWT.NONE); GridLayoutFactory.fillDefaults().numColumns(2).applyTo(synchronizationComposite); Label label = new Label(synchronizationComposite, SWT.WRAP); label.setText(EMFCompareRCPUIMessages.getString("GroupsInteractiveContent.SYNC_BEHAVIOR_LABEL")); //$NON-NLS-1$ label.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false)); combo = new Combo(synchronizationComposite, SWT.DROP_DOWN | SWT.READ_ONLY); for (String comboLabel : SYNC_VALUES) { combo.add(comboLabel); } combo.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, true)); combo.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { if (combo.equals(e.getSource())) { synchronizationBehaviorValue = SYNC_VALUES.get(combo.getSelectionIndex()); } } }); } /** * Sets the combo to the given synchronization behavior. * * @param behavior * Input. */ public void setComboInput(String behavior) { int index = SYNC_VALUES.indexOf(behavior); if (index != -1) { combo.select(index); synchronizationBehaviorValue = behavior; } } @Override public boolean performOk() { groupManager.setCurrentGroupRanking(twoWayComparisonContent.getOrderedItems(), false); setCurrentSynchronizationBehavior(synchronizationBehaviorValue, false); groupManager.setCurrentGroupRanking(threeWayComparisonContent.getOrderedItems(), true); setCurrentSynchronizationBehavior(synchronizationBehaviorValue, true); return super.performOk(); } @Override protected void performDefaults() { resetGroupPreference(false, twoWayComparisonContent); resetGroupPreference(true, threeWayComparisonContent); super.performDefaults(); } /** * Resets preferences for group. * <p> * Resets group ranking to default. * </p> * <p> * Resets synchronization behavior to its default value. * </p> * * @param isThreeWay * Type of comparison. * @param interactiveContent * {@link GroupsInteractiveContent} */ private void resetGroupPreference(boolean isThreeWay, GroupsInteractiveContent interactiveContent) { interactiveContent.setViewerInput(groupManager.getDefaultRankingConfiguration(isThreeWay)); setComboInput(SYNC_DEFAULT_VALUE); } /** * Sets the current synchronization behavior value. * * @param newBehavior * <p> * Should be one of the following value. * </p> * <ul> * <li>{@link MessageDialogWithToggle#PROMPT}</li> * <li>{@link MessageDialogWithToggle#ALWAYS}</li> * <li>{@link MessageDialogWithToggle#NEVER}</li> * </ul> * @param isThreeWay * True if three way comparison. */ public void setCurrentSynchronizationBehavior(String newBehavior, boolean isThreeWay) { Preconditions.checkArgument(SYNC_VALUES.contains(newBehavior)); if (!SYNC_DEFAULT_VALUE.equals(newBehavior)) { getPreferenceStore().putValue(getGroupSynchronizationPreferenceKey(isThreeWay), newBehavior); } else { getPreferenceStore().setToDefault(getGroupSynchronizationPreferenceKey(isThreeWay)); } // Trace preferences values if (TracingConstant.CONFIGURATION_TRACING_ACTIVATED) { StringBuilder builder = new StringBuilder(); // Print each preferences builder.append("Preference ").append(getGroupSynchronizationPreferenceKey(isThreeWay)) //$NON-NLS-1$ .append(":\n"); //$NON-NLS-1$ String preferenceValue = getPreferenceStore() .getString(getGroupSynchronizationPreferenceKey(isThreeWay)); builder.append(preferenceValue); EMFCompareRCPUIPlugin.getDefault().log(IStatus.INFO, builder.toString()); } } /** * Gets the state of the the group synchronization behavior. * * @param isThreeWay * True if three way comparison. * @return Returns one of the following value. * <ul> * <li>{@link MessageDialogWithToggle#PROMPT}</li> * <li>{@link MessageDialogWithToggle#ALWAYS}</li> * <li>{@link MessageDialogWithToggle#NEVER}</li> * </ul> */ public String getCurrentSynchronizationBehavior(boolean isThreeWay) { String prefValue = getPreferenceStore().getString(getGroupSynchronizationPreferenceKey(isThreeWay)); if (SYNC_VALUES.contains(prefValue)) { return prefValue; } else { return SYNC_DEFAULT_VALUE; } } }