/*******************************************************************************
* Copyright (c) 2012, 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.actions;
import com.google.common.collect.Sets;
import java.util.Set;
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.FiltersPreferencePage;
import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.actions.ui.SynchronizerDialog;
import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.filters.StructureMergeViewerFilter;
import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.filters.impl.DifferenceFilterManager;
import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.filters.IDifferenceFilter;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialogWithToggle;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Shell;
/**
* These will be the actual actions displayed in the filter menu. Their sole purpose is to provide a Predicate
* to the structure viewer's filter.
* <p>
* Do note that each distinct {@link FilterAction} in the {@link FilterActionMenu filter menu} is considered
* as an "exclude" filter, and that they are OR'ed together (thus, any element must <b>not</b> meet the
* selected filters' criteria in order to be displayed).
* </p>
*
* @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
* @since 4.0
*/
public class FilterAction extends Action {
/** The filter associated with this action. */
private final IDifferenceFilter filter;
/** The Filter that will be modified by the action. */
private final StructureMergeViewerFilter structureMergeViewerFilter;
/** Preferences holding the value of the synchronization behavior of filters. */
private final IPreferenceStore preferences;
/** {@link DifferenceFilterManager}. */
private final DifferenceFilterManager filterManager;
/**
* The "default" constructor for this action.
*
* @param text
* Will be used as the action's tooltip.
* @param structureMergeViewerFilter
* The viewer filter that this action will need to update.
* @param filter
* The filter associated with this action.
*/
public FilterAction(String text, StructureMergeViewerFilter structureMergeViewerFilter,
IDifferenceFilter filter) {
super(text, IAction.AS_CHECK_BOX);
this.structureMergeViewerFilter = structureMergeViewerFilter;
this.filter = filter;
this.preferences = EMFCompareRCPUIPlugin.getDefault().getPreferenceStore();
this.filterManager = EMFCompareRCPUIPlugin.getDefault().getDifferenceFilterManager();
}
/**
* {@inheritDoc}
*/
@Override
public void runWithEvent(Event event) {
if (isChecked()) {
structureMergeViewerFilter.addFilter(filter);
} else {
structureMergeViewerFilter.removeFilter(filter);
}
handleSynchronization(event);
}
/**
* Handle synchronization with {@link DifferenceFilterManager}.
*
* @param event
* Event.
*/
private void handleSynchronization(Event event) {
String sync = preferences.getString(FiltersPreferencePage.SYNCHRONIZATION_BEHAVIOR);
if ("".equals(sync)) { //$NON-NLS-1$
sync = MessageDialogWithToggle.PROMPT;
}
final Shell shell = event.display.getActiveShell();
if (MessageDialogWithToggle.PROMPT.equals(sync) && shell != null) {
shell.getDisplay().asyncExec(new SynchronizationBehaviorRunnable(shell));
} else if (MessageDialogWithToggle.ALWAYS.equals(sync)) {
synchonizeFilters();
}
}
/**
* Synchronizes UI filter selection with the preferences.
*/
private void synchonizeFilters() {
Set<IDifferenceFilter> byDefaultFilters = Sets
.newLinkedHashSet(filterManager.getCurrentByDefaultFilters());
// Add newly activated filters
for (IDifferenceFilter activeFilter : structureMergeViewerFilter.getSelectedDifferenceFilters()) {
byDefaultFilters.add(activeFilter);
}
// Remove deactivated filters
for (IDifferenceFilter toDeactivateFilter : structureMergeViewerFilter
.getUnSelectedDifferenceFilters()) {
byDefaultFilters.remove(toDeactivateFilter);
}
filterManager.setCurrentByDefaultFilters(byDefaultFilters);
}
/**
* Runnable in charge of synchronizing selection in UI with the {@link DifferenceFilterManager}.
*
* @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a>
*/
private final class SynchronizationBehaviorRunnable implements Runnable {
/** Shell of this runnable. */
private final Shell shell;
/**
* Constructor.
*
* @param shell
* Shell for this runnable.
*/
private SynchronizationBehaviorRunnable(Shell shell) {
this.shell = shell;
}
/**
* {@inheritDoc}
*/
public void run() {
MessageDialogWithToggle dialog = new SynchronizerDialog(shell,
EMFCompareRCPUIMessages.getString("FilterAction.synchronization.dialog.title"), //$NON-NLS-1$
EMFCompareRCPUIMessages.getString("FilterAction.synchronization.dialog.message"), //$NON-NLS-1$
FiltersPreferencePage.PAGE_ID);
dialog.setPrefKey(FiltersPreferencePage.SYNCHRONIZATION_BEHAVIOR);
dialog.setPrefStore(EMFCompareRCPUIPlugin.getDefault().getPreferenceStore());
if (dialog.open() == IDialogConstants.YES_ID) {
synchonizeFilters();
}
}
}
}