/* ****************************************************************************** * Copyright (c) 2006-2012 XMind Ltd. and others. * * This file is a part of XMind 3. XMind releases 3 and * above are dual-licensed under the Eclipse Public License (EPL), * which is available at http://www.eclipse.org/legal/epl-v10.html * and the GNU Lesser General Public License (LGPL), * which is available at http://www.gnu.org/licenses/lgpl.html * See http://www.xmind.net/license.html for details. * * Contributors: * XMind Ltd. - initial API and implementation *******************************************************************************/ package org.xmind.ui.viewers; import java.util.HashMap; import java.util.Map; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.ISelectionProvider; import org.eclipse.jface.viewers.SelectionChangedEvent; /** * @author Frank Shaka * */ public class SelectionSynchronizer { private class SelectionMonitor implements ISelectionChangedListener { private ISelectionProvider source; /** * */ public SelectionMonitor(ISelectionProvider source) { this.source = source; this.source.addSelectionChangedListener(this); } /* * (non-Javadoc) * * @see * org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged * (org.eclipse.jface.viewers.SelectionChangedEvent) */ public void selectionChanged(SelectionChangedEvent event) { syncSelection(source, event); } /** * @return the source */ public ISelectionProvider getSource() { return source; } public void dispose() { this.source.removeSelectionChangedListener(this); } } private Map<ISelectionProvider, SelectionMonitor> monitors = new HashMap<ISelectionProvider, SelectionMonitor>(); private boolean syncing = false; public void addPrimary(ISelectionProvider source) { add(source, true); } public void add(ISelectionProvider source) { add(source, false); } private void add(ISelectionProvider source, boolean primary) { if (monitors.containsKey(source)) return; monitors.put(source, new SelectionMonitor(source)); if (!monitors.isEmpty()) { if (primary) { ISelection selection = source.getSelection(); for (ISelectionProvider target : monitors.keySet()) { target.setSelection(selection); } } else { source.setSelection(monitors.keySet().iterator().next() .getSelection()); } } } public void remove(ISelectionProvider source) { SelectionMonitor monitor = monitors.remove(source); if (monitor != null) { monitor.dispose(); } } private void syncSelection(ISelectionProvider source, SelectionChangedEvent event) { if (syncing) return; syncing = true; ISelection selection = event.getSelection(); for (Object monitor : monitors.values().toArray()) { syncSelection(source, selection, (SelectionMonitor) monitor); } syncing = false; } /** * @param source * @param event * @param selectionMonitor */ private void syncSelection(ISelectionProvider source, ISelection selection, SelectionMonitor monitor) { if (monitor.getSource() == source) return; monitor.getSource().setSelection(selection); } /** * */ public void clear() { for (Object source : monitors.keySet().toArray()) { remove((ISelectionProvider) source); } } }