blob: 708a3711d772ebd18bb02cdc761385c0aa4412b8 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2010 BSI Business Systems Integration AG.
* 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:
* BSI Business Systems Integration AG - initial API and implementation
******************************************************************************/
package org.eclipse.scout.rt.ui.swt.form.fields.numberfield;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import org.eclipse.scout.commons.StringUtility;
import org.eclipse.scout.commons.exception.ProcessingException;
import org.eclipse.scout.rt.client.ui.action.menu.IMenu;
import org.eclipse.scout.rt.client.ui.form.fields.IFormField;
import org.eclipse.scout.rt.client.ui.form.fields.numberfield.AbstractNumberField;
import org.eclipse.scout.rt.client.ui.form.fields.numberfield.INumberField;
import org.eclipse.scout.rt.ui.swt.LogicalGridLayout;
import org.eclipse.scout.rt.ui.swt.action.menu.SwtContextMenuMarkerComposite;
import org.eclipse.scout.rt.ui.swt.action.menu.SwtScoutContextMenu;
import org.eclipse.scout.rt.ui.swt.action.menu.text.StyledTextAccess;
import org.eclipse.scout.rt.ui.swt.ext.StatusLabelEx;
import org.eclipse.scout.rt.ui.swt.form.fields.LogicalGridDataBuilder;
import org.eclipse.scout.rt.ui.swt.form.fields.SwtScoutBasicFieldComposite;
import org.eclipse.scout.rt.ui.swt.internal.TextFieldEditableSupport;
import org.eclipse.scout.rt.ui.swt.util.SwtUtility;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.VerifyEvent;
import org.eclipse.swt.events.VerifyListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.MessageBox;
/**
* <h3>SwtScoutNumberField</h3>
*
* @since 1.0.0 14.04.2008
*/
public class SwtScoutNumberField extends SwtScoutBasicFieldComposite<INumberField<?>> implements ISwtScoutNumberField {
private SwtContextMenuMarkerComposite m_menuMarkerComposite;
private SwtScoutContextMenu m_contextMenu;
private PropertyChangeListener m_contextMenuVisibilityListener;
@Override
protected void initializeSwt(Composite parent) {
Composite container = getEnvironment().getFormToolkit().createComposite(parent);
StatusLabelEx label = getEnvironment().getFormToolkit().createStatusLabel(container, getEnvironment(), getScoutObject());
m_menuMarkerComposite = new SwtContextMenuMarkerComposite(container, getEnvironment());
getEnvironment().getFormToolkit().adapt(m_menuMarkerComposite);
m_menuMarkerComposite.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
getSwtField().setFocus();
m_contextMenu.getSwtMenu().setVisible(true);
}
});
int style = SWT.SINGLE;
StyledText textField = getEnvironment().getFormToolkit().createStyledText(m_menuMarkerComposite, style);
textField.setAlignment(SwtUtility.getHorizontalAlignment(getScoutObject().getGridData().horizontalAlignment));
textField.setMargins(2, 2, 2, 2);
textField.setWrapIndent(textField.getIndent());
textField.addVerifyListener(new P_VerifyListener());
setSwtContainer(container);
setSwtLabel(label);
setSwtField(textField);
//listeners
addModifyListenerForBasicField(textField);
// layout
getSwtContainer().setLayout(new LogicalGridLayout(1, 0));
m_menuMarkerComposite.setLayoutData(LogicalGridDataBuilder.createField(((IFormField) getScoutObject()).getGridData()));
}
protected void installContextMenu() {
m_menuMarkerComposite.setMarkerVisible(getScoutObject().getContextMenu().isVisible());
m_contextMenuVisibilityListener = new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (IMenu.PROP_VISIBLE.equals(evt.getPropertyName())) {
final boolean markerVisible = getScoutObject().getContextMenu().isVisible();
getEnvironment().invokeSwtLater(new Runnable() {
@Override
public void run() {
m_menuMarkerComposite.setMarkerVisible(markerVisible);
}
});
}
}
};
getScoutObject().getContextMenu().addPropertyChangeListener(m_contextMenuVisibilityListener);
m_contextMenu = new SwtScoutContextMenu(getSwtField().getShell(), getScoutObject().getContextMenu(), getEnvironment());
SwtScoutContextMenu fieldMenu = new SwtScoutContextMenu(getSwtField().getShell(), getScoutObject().getContextMenu(), getEnvironment(),
getScoutObject().isAutoAddDefaultMenus() ? new StyledTextAccess(getSwtField()) : null, getScoutObject().isAutoAddDefaultMenus() ? getSwtField() : null);
getSwtField().setMenu(fieldMenu.getSwtMenu());
}
protected void uninstallContextMenu() {
if (m_contextMenuVisibilityListener != null) {
getScoutObject().getContextMenu().removePropertyChangeListener(m_contextMenuVisibilityListener);
m_contextMenuVisibilityListener = null;
}
}
@Override
protected void attachScout() {
super.attachScout();
installContextMenu();
}
@Override
protected void detachScout() {
uninstallContextMenu();
super.detachScout();
}
@Override
public StyledText getSwtField() {
return (StyledText) super.getSwtField();
}
@Override
protected String getText() {
return getSwtField().getText();
}
@Override
protected void setText(String text) {
getSwtField().setText(text);
}
@Override
protected Point getSelection() {
return getSwtField().getSelection();
}
@Override
protected void setSelection(int startIndex, int endIndex) {
getSwtField().setSelection(startIndex, endIndex);
}
@Override
protected TextFieldEditableSupport createEditableSupport() {
return new TextFieldEditableSupport(getSwtField());
}
@Override
protected int getCaretOffset() {
return getSwtField().getCaretOffset();
}
@Override
protected void setCaretOffset(int caretPosition) {
//nothing to do: SWT sets the caret itself. If startIndex > endIndex it is placed at the beginning.
}
private final class P_VerifyListener implements VerifyListener {
@Override
public void verifyText(VerifyEvent e) {
String curText = ((StyledText) e.widget).getText();
e.doit = AbstractNumberField.isWithinNumberFormatLimits(getScoutObject().getFormat(), curText, e.start, e.end - e.start, e.text);
if (!e.doit && textWasPasted(e)) {
try {
String newText = AbstractNumberField.createNumberWithinFormatLimits(getScoutObject().getFormat(), curText, e.start, e.end - e.start, e.text);
if (!curText.equals(newText)) {
((StyledText) e.widget).setText(newText);
((StyledText) e.widget).setSelection(newText.length());
}
}
catch (ProcessingException exception) {
MessageBox box = new MessageBox(e.display.getActiveShell(), SWT.OK);
box.setText(SwtUtility.getNlsText(e.display, "Paste"));
box.setMessage(SwtUtility.getNlsText(e.display, "PasteTextNotApplicableForNumberField", String.valueOf(getScoutObject().getFormat().getMaximumIntegerDigits())));
box.open();
}
}
}
/**
* returns true if the text was pasted.
*/
private boolean textWasPasted(VerifyEvent e) {
return StringUtility.length(e.text) > 1;
}
}
}