/***************************************************************************** * Copyright (c) 2012 CEA LIST. * * 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: * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Initial API and implementation *****************************************************************************/ package org.eclipse.papyrus.infra.gmfdiag.dnd.preferences; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.eclipse.core.databinding.observable.list.WritableList; import org.eclipse.jface.viewers.ColumnViewerToolTipSupport; import org.eclipse.jface.viewers.ColumnWeightData; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.TableLayout; import org.eclipse.jface.window.ToolTip; import org.eclipse.papyrus.infra.gmfdiag.dnd.policy.DropStrategyManager; import org.eclipse.papyrus.infra.gmfdiag.dnd.strategy.DropStrategy; import org.eclipse.papyrus.infra.widgets.editors.MultipleReferenceEditor; import org.eclipse.papyrus.infra.widgets.providers.IStaticContentProvider; import org.eclipse.papyrus.infra.widgets.providers.StaticContentProvider; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.TreeEditor; import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.events.KeyListener; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.TreeColumn; import org.eclipse.swt.widgets.TreeItem; public class DropStrategyEditor extends MultipleReferenceEditor { // protected Button toggle; public static final int ACTIVATION_COLUMN = 0; public static final int LABEL_COLUMN = 1; private final Map<DropStrategy, Button> checkboxes; public DropStrategyEditor(Composite parent, int style) { super(parent, style, true, true, "Strategies"); List<DropStrategy> values = DropStrategyManager.instance.getAllStrategies(); IStaticContentProvider provider = new StaticContentProvider(values.toArray()); ColumnViewerToolTipSupport.enableFor(treeViewer, ToolTip.NO_RECREATE); setProviders(provider, new DropStrategyLabelProvider()); setModelObservable(new DropStrategyObservableList(values)); TableLayout layout = new TableLayout(); new TreeColumn(tree, SWT.LEFT); layout.addColumnData(new ColumnWeightData(10, 25, false)); new TreeColumn(tree, SWT.LEFT); layout.addColumnData(new ColumnWeightData(100, 250, true)); tree.setLayout(layout); tree.setHeaderVisible(false); setToolTipText("Strategies"); treeViewer.refresh(); //Adds a checkbox for each DropStrategy, to toggle it checkboxes = new HashMap<DropStrategy, Button>(); for(TreeItem item : tree.getItems()) { if(item.getData() instanceof DropStrategy) { TreeEditor editor = new TreeEditor(tree); final Button button = new Button(tree, SWT.CHECK); final TreeItem currentItem = item; final DropStrategy strategy = (DropStrategy)currentItem.getData(); button.addSelectionListener(new SelectionListener() { public void widgetSelected(SelectionEvent e) { updateStrategy(strategy, button); treeViewer.refresh(); } public void widgetDefaultSelected(SelectionEvent e) { //Nothing } }); checkboxes.put(strategy, button); button.setSelection(DropStrategyManager.instance.isActive(strategy)); editor.setEditor(button, item, ACTIVATION_COLUMN); editor.horizontalAlignment = SWT.CENTER; editor.grabHorizontal = true; } } //Adds a space-key listener to edit a list of selected checkboxes tree.addKeyListener(new KeyListener() { public void keyReleased(KeyEvent e) { if(e.keyCode == SWT.SPACE) { ISelection selection = treeViewer.getSelection(); if(selection instanceof IStructuredSelection && !selection.isEmpty()) { IStructuredSelection structuredSelection = (IStructuredSelection)selection; Boolean isActive = findIsActive(structuredSelection); Iterator<?> iterator = structuredSelection.iterator(); while(iterator.hasNext()) { Object element = iterator.next(); if(element instanceof DropStrategy) { DropStrategy strategy = (DropStrategy)element; Button button = checkboxes.get(strategy); updateStrategy(strategy, button, isActive); } } treeViewer.refresh(); } } } public void keyPressed(KeyEvent e) { //Nothing } }); } //Returns the new status of the first DropStrategy in the selection. //Returns null if the selection doesn't contain any DropStrategy private Boolean findIsActive(IStructuredSelection selection) { Iterator<?> iterator = selection.iterator(); while(iterator.hasNext()) { Object element = iterator.next(); if(element instanceof DropStrategy) { boolean isActive = DropStrategyManager.instance.isActive((DropStrategy)element); //Current status return !isActive; //New status (Toggle) } } return null; //No DropStrategy found in the selection } private void updateStrategy(DropStrategy strategy, Button button, boolean isActive) { DropStrategyManager.instance.setActive(strategy, isActive); button.setSelection(isActive); } private void updateStrategy(DropStrategy strategy, Button button) { boolean isActive = DropStrategyManager.instance.isActive(strategy); updateStrategy(strategy, button, !isActive); } @Override public void createListControls() { super.createListControls(); edit.dispose(); remove.dispose(); add.dispose(); up.dispose(); down.dispose(); // toggle = new Button(controlsSection, SWT.TOGGLE); // toggle.setImage(org.eclipse.papyrus.infra.widgets.Activator.getDefault().getImage("/icons/Add_12x12.gif")); // toggle.addSelectionListener(this); // toggle.setToolTipText("Toggle the selected strategies"); treeViewer.addSelectionChangedListener(new ISelectionChangedListener() { public void selectionChanged(SelectionChangedEvent event) { updateControls(); } }); } protected Object[] getSelectedElements() { IStructuredSelection selection = (IStructuredSelection)treeViewer.getSelection(); return selection.toArray(); } @Override public void widgetSelected(SelectionEvent event) { // if(event.widget == toggle) { // toggleAction(toggle.getSelection()); // } else { super.widgetSelected(event); // } } protected void toggleAction(boolean activate) { Object[] selectedElements = getSelectedElements(); for(Object selected : selectedElements) { if(selected instanceof DropStrategy) { DropStrategyManager.instance.setActive((DropStrategy)selected, activate); } } treeViewer.refresh(); } @Override protected void updateControls() { //Skip super.updateControls ; this is not configurable. Avoids a widget disposed exception // boolean activate = false; // // Object[] selectedElements = getSelectedElements(); // for(Object selected : selectedElements) { // if(selected instanceof DropStrategy) { // if(DropStrategyManager.instance.isActive((DropStrategy)selected)) { // activate = true; // break; // } // } // } // toggle.setSelection(activate); } private class DropStrategyObservableList extends WritableList { public DropStrategyObservableList(List<DropStrategy> values) { super(); addAll(values); } @Override public Object move(int oldIndex, int newIndex) { Object objectToMove = get(oldIndex); Object other = get(newIndex); if(objectToMove instanceof DropStrategy && other instanceof DropStrategy) { DropStrategy strategyToMove = (DropStrategy)objectToMove; DropStrategy otherStrategy = (DropStrategy)other; int priority = DropStrategyManager.instance.findPriority(otherStrategy); int newPriority = (newIndex > oldIndex) ? priority + 1 : priority - 1; DropStrategyManager.instance.setPriority(strategyToMove, newPriority); } return super.move(oldIndex, newIndex); } } /** * Refreshes the widget's contents, based on the DropStrategyManager's current values */ public void refresh() { for(Map.Entry<DropStrategy, Button> entry : checkboxes.entrySet()) { boolean isActive = DropStrategyManager.instance.isActive(entry.getKey()); updateStrategy(entry.getKey(), entry.getValue(), isActive); } treeViewer.refresh(); } }