at.spardat.xma.mdl.list.ListUIDelegateClient Maven / Gradle / Ivy
/*******************************************************************************
* Copyright (c) 2003, 2007 s IT Solutions AT Spardat 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:
* s IT Solutions AT Spardat GmbH - initial API and implementation
*******************************************************************************/
/*
* Created on 04.11.2003
*
*
*
*/
package at.spardat.xma.mdl.list;
import java.util.ArrayList;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.TypedEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.List;
import at.spardat.enterprise.fmt.AParseException;
import at.spardat.enterprise.fmt.IFmt;
import at.spardat.xma.mdl.Atom;
import at.spardat.xma.mdl.AttachmentExceptionClient;
import at.spardat.xma.mdl.ModelChangeEvent;
import at.spardat.xma.mdl.UIDelegateClient;
import at.spardat.xma.mdl.ValidationErrorClient;
import at.spardat.xma.mdl.WModel;
import at.spardat.xma.page.EventAdapter;
import at.spardat.xma.page.PageClient;
/**
* This class is the UIDelegate for a {@link ListWMClient} widget model. It
* manages the interaction between an SWT-combo or an SWT-list and the widget model.
* If a Combo is to be attached, the model must not have the style {@link ListWM#S_MULTI_SELECT}.
* If a List is to be attached, the model must not have the style {@link ListWM#S_NOT_STRICT}.
*
* @author s2877
*/
public class ListUIDelegateClient extends UIDelegateClient {
/**
* The attached SWT-control. A List or a Combo
*/
private Control control_;
/**
* The opional label usually positioned at the left hand side of the list or combo.
*/
private Label label_;
/**
* The widget model.
*/
private ListWMClient wModel_;
/**
* Keep track of whether we are updating the UI.
*/
private boolean updatingUI_ = false;
/**
* The editable-property
*/
private boolean editable_ = true;
/**
* The enabled-property
*/
private boolean enabled_ = true;
/** Do prefixsearch or not */
private boolean doPrefixSearch_ = true;
/** Do a case sensitive or case insensitive prefix search */
private boolean prefixSearchCaseSensitive_ = true;
private String oldPrefix_ = "";
/**
* Is non null if the first entry in the control is a key that is
* not in the domain of values itself. This may happen, if the
* selection in the model is out of range. This variable
* then holds the key of this out of domain selection.
*/
private String outOfDomainKey_;
/**
* Stores the drop down lists visibleItemCount.
* If a combo model is set to setEditable(false) then the widgets.setVisibleItemCount() is set to 0
* and the old value is stored in this property for resetting the widget's value at setEditable(true).
*/
private int visibleItemCount_;
/**
* Constructor
* @param wModel the widget model to use this UIDelegate with.
*/
public ListUIDelegateClient (ListWMClient wModel) {
wModel_ = wModel;
}
/**
* Adds/removes the outOfDomainKey to the list of the combo
*/
private void outOfDomain2Combo() {
Combo combo = (Combo)control_;
if(outOfDomainKey_!=null && combo.getItemCount()>0) {
combo.remove(0);
}
String selection = wModel_.getSelected();
if(selection!=null && !wModel_.table_.containsKey(selection)) {
outOfDomainKey_=selection;
IFmt fmt = wModel_.getFmt();
if(fmt!=null) {
combo.add(fmt.format(selection),0);
} else {
combo.add(selection,0);
}
} else {
outOfDomainKey_=null;
}
}
/**
* Adds/removes the outOfDomainKey to the list
* If the model is strict it does nothing.
*
*/
private void outOfDomain2List() {
if(!wModel_.isStrict()) {
List list = (List)control_;
if(outOfDomainKey_!=null && list.getItemCount()>0) {
list.remove(0);
}
String selection = wModel_.getSelected();
if(selection!=null && !wModel_.table_.containsKey(selection)) {
outOfDomainKey_=selection;
IFmt fmt = wModel_.getFmt();
if(fmt!=null) {
list.add(fmt.format(selection),0);
} else {
list.add(selection,0);
}
} else {
outOfDomainKey_=null;
}
}
}
/**
* Transfers the entries of the model to the attached widget.
* It fills the list of coices of the Combo or List.
*/
private void list2UI() {
if(control_ instanceof Combo) {
Combo combo = (Combo) control_;
combo.removeAll();
outOfDomain2Combo();
for(int i=0;i0) {
String selected = wModel_.getSelected();
if(selected != null && wModel_.isUserStrict() && wModel_.table_.containsKey(selected)){
Atom value = wModel_.table_.get(selected, 0); //get the value to the key, needed if key value pairs were added //KWF
selected = value.toString();
}
IFmt fmt = wModel_.getFmt();
if(fmt!=null) {
combo.setText(fmt.format(selected));
} else {
combo.setText(selected);
}
}
} else if(control_ instanceof List) {
List list = (List) control_;
list.deselectAll();
if(wModel_.getSelectionCount()>0) {
if(outOfDomainKey_!=null) {
list.select(0);
} else {
String[] selection = wModel_.getSelection();
for(int i=0;i0) {
combo.setSelection(new Point(oldPrefix_.length(),selected.length()));
prefix=oldPrefix_;
} else {
prefix="";
}
} else {
combo2selection();
}
}
}
oldPrefix_=prefix;
}
/**
* return true if string starts with prefix
* prefixSearchCaseSensitive_ determines if this check is case sensitive or not.
*/
private boolean startsWith(String string, String prefix) {
if(prefixSearchCaseSensitive_) {
return string.startsWith(prefix);
} else {
if(prefix.length()>string.length()) return false;
for (int i=0; i0){
visibleItemCount_ = count;
}
if(!editable_){
((Combo)control_).setVisibleItemCount(0);
}else {
((Combo)control_).setVisibleItemCount(visibleItemCount_);
}
}
}
}
/* (non-Javadoc)
* @see at.spardat.xma.mdl.UIDelegateClient#isEnabled()
*/
public boolean isEnabled () {
if (isUIAttached()) {
//always take the state from the widget (if it was set directly on it) as this is the old behavior
enabled_ = control_.isEnabled();
}
return enabled_;
}
/* (non-Javadoc)
* @see at.spardat.xma.mdl.UIDelegateClient#setEnabled(boolean)
*/
public void setEnabled(boolean what) {
enabled_ = what;
if (isUIAttached()) control_.setEnabled(what);
}
/**
* @return if prefix search will be done case sensitive
* @since 1.7.3
*/
public boolean isPrefixSearchCaseSensitive() {
return prefixSearchCaseSensitive_;
}
/**
* determine if prefix seach has to be done case sensitive or not
* @param prefixSearchCaseSensitive
* @since 1.7.3
*/
public void setPrefixSearchCaseSensitive(boolean prefixSearchCaseSensitive) {
prefixSearchCaseSensitive_ = prefixSearchCaseSensitive;
}
/**
* @return if prefix search will be done on this list model
* @since 1.8.1
*/
public boolean isDoPrefixSearch() {
return doPrefixSearch_;
}
/**
* determine if prefix search has to be done on this model
* @since 1.8.1
*/
public void setDoPrefixSearch(boolean doPrefixSearch) {
if(isUIAttached()&&control_ instanceof Combo) {
boolean readonly = (control_.getStyle()&SWT.READ_ONLY)!=0;
if(!readonly&&wModel_.isUserStrict()&&doPrefixSearch==false) {
throw new IllegalStateException("userstrict combos which are not readonly must have prefix search activated");
}
}
this.doPrefixSearch_ = doPrefixSearch;
}
/**
* This method must be called after every change in an SWT Text control to update
* the error state information. What must be done here is to check the mandatory
* property of the widget model.
*/
void updateErrorState () {
if(control_ instanceof Combo) {
Combo combo_ = (Combo) control_;
PageClient pageModel = wModel_.getPageModelC();
if (editable_) {
boolean ok = true;
String text = combo_.getText();
IFmt validator = wModel_.getFmt();
if(validator!=null&&!validator.isOneWay()) {
try {
// pass the text through the formatter to check if it is legitimate external
// input for the widget model
validator.parse(text);
} catch (AParseException ex) {
// construct a ValidationErrorClient object and register it with the Page
pageModel.setValidationErrorImpl(new ValidationErrorClient (wModel_, control_, getLabelText(), ex));
ok = false;
}
}
if(ok) {
// clear a previous error state
pageModel.clearValidationErrorImpl(combo_);
}
} else {
pageModel.clearValidationErrorImpl(combo_);
}
}
}
/**
* If inError, this method sets the background of the corresponding Control c
* to the error color defined in ComponentClient. If inError is false,
* the background is reset to the default color.
*/
public void setErrorColor (boolean inError) {
wModel_.getPageModelC().getPageEffects().errorStateChanged(control_,editable_,inError);
}
/**
* Returns the text of the label which may be null, if the label is unknown.
*/
private String getLabelText () {
return label_ != null ? label_.getText() : null;
}
}