/*****************************************************************************
* Copyright (c) 2011 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.widgets.editors;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import org.eclipse.core.databinding.observable.ChangeEvent;
import org.eclipse.core.databinding.observable.IChangeListener;
import org.eclipse.papyrus.infra.widgets.Activator;
import org.eclipse.papyrus.infra.widgets.messages.Messages;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
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.widgets.Button;
import org.eclipse.swt.widgets.Composite;
public class IntegerMask extends AbstractValueEditor implements SelectionListener, IChangeListener, DisposeListener {
private Button[] checkboxes;
private int currentValue;
private final Composite checkboxContainer;
private boolean refreshCheckboxes = true;
public IntegerMask(final Composite parent, final int style) {
super(parent, style);
checkboxContainer = new Composite(this, style);
checkboxContainer.setLayoutData(getDefaultLayoutData());
checkboxContainer.setLayout(new GridLayout(2, true));
checkboxContainer.addDisposeListener(this);
}
@Override
protected GridData getLabelLayoutData() {
GridData data = super.getLabelLayoutData();
data.verticalAlignment = SWT.BEGINNING;
return data;
}
@Override
public Object getValue() {
int totalValue = 0;
for(Button button : checkboxes) {
int value = (Integer)button.getData("IntValue"); //$NON-NLS-1$
if(button.getSelection()) {
totalValue |= value;
}
}
return totalValue;
}
@Override
public void dispose() {
if(modelProperty != null) {
modelProperty.removeChangeListener(this);
}
super.dispose();
}
@Override
public Object getEditableType() {
return Integer.class;
}
@Override
public void setReadOnly(final boolean readOnly) {
// TODO Auto-generated method stub
}
@Override
public boolean isReadOnly() {
// TODO Auto-generated method stub
return false;
}
public void setMasks(final String[] values) {
Map<Integer, String> masks = new HashMap<Integer, String>();
int intValue = 1;
for(String value : values) {
masks.put(intValue, value);
intValue <<= 1;
}
setMasks(masks);
}
public void setMasks(final Map<Integer, String> values) {
if(values.size() > 32) {
StringLabel label = new StringLabel(checkboxContainer, SWT.NONE);
label.getValueLabel().setImage(Activator.getDefault().getImage("/icons/error.gif")); //$NON-NLS-1$
label.getValueLabel().setText(Messages.IntegerMask_ErrorTooManyValues);
checkboxes = new Button[0];
} else {
if(checkboxes != null) {
disposeCheckboxes();
}
checkboxes = new Button[values.size()];
int i = 0;
for(Entry<Integer, String> mask : values.entrySet()) {
int intValue = mask.getKey();
String value = mask.getValue();
checkboxes[i] = new Button(checkboxContainer, SWT.CHECK);
checkboxes[i].setText(value);
checkboxes[i].setData("IntValue", intValue); //$NON-NLS-1$
checkboxes[i].addSelectionListener(this);
i++;
}
}
}
protected void disposeCheckboxes() {
for(Button button : checkboxes) {
button.removeSelectionListener(this);
button.dispose();
}
}
public void setNumColumns(final int numColumns) {
((GridLayout)checkboxContainer.getLayout()).numColumns = numColumns;
checkboxContainer.layout();
layout();
}
@Override
public void doBinding() {
// We don't do a real databinding here
modelProperty.addChangeListener(this);
refreshCheckboxes();
}
protected void refreshCheckboxes() {
if(!refreshCheckboxes) {
return;
}
int totalValue = getCurrentValue();
for(Button button : checkboxes) {
int value = (Integer)button.getData("IntValue"); //$NON-NLS-1$
button.setSelection((totalValue & value) != 0);
}
}
@Override
public void setToolTipText(final String text) {
super.setLabelToolTipText(text);
}
public void widgetSelected(final SelectionEvent e) {
Button button = (Button)e.widget;
int value = (Integer)button.getData("IntValue"); //$NON-NLS-1$
int totalValue = getCurrentValue();
if(button.getSelection()) {
totalValue |= value;
} else {
totalValue &= ~value;
}
setCurrentValue(totalValue);
}
protected void setCurrentValue(final int value) {
if(modelProperty != null) {
refreshCheckboxes = false;
modelProperty.setValue(value);
refreshCheckboxes = true;
}
currentValue = value;
commit();
}
protected Integer getCurrentValue() {
if(modelProperty != null) {
Object value = modelProperty.getValue();
return value == null ? 0 : (Integer)value;
} else {
return currentValue;
}
}
public void widgetDefaultSelected(final SelectionEvent e) {
// Nothing
}
public int getNumColumns() {
return ((GridLayout)checkboxContainer.getLayout()).numColumns;
}
public void handleChange(final ChangeEvent event) {
refreshCheckboxes();
}
public void widgetDisposed(final DisposeEvent e) {
dispose();
}
}