blob: 332b6b95f063413a665787058c2d99b898233487 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2014 Formal Mind GmbH.
* 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:
* Michael Jastram - initial API and implementation
******************************************************************************/
package org.eclipse.rmf.reqif10.search.filter.ui;
import java.math.BigInteger;
import java.util.List;
import org.eclipse.rmf.reqif10.AttributeDefinition;
import org.eclipse.rmf.reqif10.AttributeDefinitionReal;
import org.eclipse.rmf.reqif10.search.filter.IFilter;
import org.eclipse.rmf.reqif10.search.filter.IFilter.Operator;
import org.eclipse.rmf.reqif10.search.filter.NumberFilter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.VerifyEvent;
import org.eclipse.swt.events.VerifyListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Spinner;
import org.eclipse.swt.widgets.Text;
/**
* This control handles Integers and Reals.
* @author jastram
*/
public class FilterControlNumber extends FilterControl {
private NumberControl control[];
public FilterControlNumber(FilterPanel parent,
AttributeDefinition attribute) {
super(parent, attribute);
}
public FilterControlNumber(FilterPanel parent, NumberFilter template) {
super(parent, template);
}
@Override
protected List<Operator> getOperators() {
return NumberFilter.SUPPORTED_OPERATORS.asList(); }
@Override
protected void updateValueControls(boolean initialize) {
if (getOperator() == Operator.IS_SET
|| getOperator() == Operator.IS_NOT_SET) {
showControl(0, false);
showControl(1, false);
}
else if (getOperator() == Operator.BETWEEN) {
showControl(0, true);
showControl(1, true);
} else {
showControl(0, true);
showControl(1, false);
}
if (initialize) {
if (templateFilter.getFilterValue1() != null) {
control[0].setValue((Number) templateFilter.getFilterValue1());
}
if (templateFilter.getFilterValue2() != null) {
control[1].setValue((Number) templateFilter.getFilterValue2());
}
}
layout();
}
private void showControl(int controlId, boolean show) {
if (control == null) control = new NumberControl[2];
if (show && control[controlId] == null) {
control[controlId] = new NumberControl(this, attribute instanceof AttributeDefinitionReal);
GridData layoutData = new GridData(SWT.FILL, SWT.CENTER, true, false);
control[controlId].getControl().setLayoutData(layoutData);
}
if (! show && control[controlId] != null) {
control[controlId].getControl().dispose();
control[controlId] = null;
}
}
@Override
public IFilter getFilter() {
Number value1 = control[0] == null ? null : control[0].getNumber();
Number value2 = control[1] == null ? null : control[1].getNumber();
return new NumberFilter(getOperator(), value1, value2, (AttributeDefinition)attribute);
}
}
/**
* We need to build our own control, rather than using {@link Spinner}, because
* Spinner is a total hack with far too many limitations :-(
*
* @author jastram
*/
class NumberControl {
private boolean isReal;
private Text text;
public NumberControl(Composite parent, boolean isReal) {
text = new Text(parent, SWT.BORDER | SWT.FILL);
this.isReal = isReal;
text.setText("0");
addValidator();
}
public Text getControl() {
return text;
}
private void addValidator() {
text.addVerifyListener(new VerifyListener() {
@Override
public void verifyText(VerifyEvent e) {
final String oldS = text.getText();
final String newS = oldS.substring(0, e.start) + e.text
+ oldS.substring(e.end);
// We allow an empty String
if (newS.length() == 0) return;
try {
if (isReal) {
new Double(newS);
} else {
new BigInteger(newS);
}
} catch (final NumberFormatException numberFormatException) {
// value is not decimal
e.doit = false;
}
}
});
}
public Number getNumber() {
if (text.getText().length() == 0 ) text.setText("0");
return isReal ? new Double(text.getText()) : new BigInteger(text.getText());
}
public void setValue(Number value) {
text.setText(value.toString());
}
}