001: /*
002: *
003: * JMoney - A Personal Finance Manager
004: * Copyright (c) 2004 Nigel Westbury <westbury@users.sourceforge.net>
005: *
006: *
007: * This program is free software; you can redistribute it and/or modify
008: * it under the terms of the GNU General Public License as published by
009: * the Free Software Foundation; either version 2 of the License, or
010: * (at your option) any later version.
011: *
012: * This program is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015: * GNU General Public License for more details.
016: *
017: * You should have received a copy of the GNU General Public License
018: * along with this program; if not, write to the Free Software
019: * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
020: *
021: */
022:
023: package net.sf.jmoney.fields;
024:
025: import net.sf.jmoney.JMoneyPlugin;
026: import net.sf.jmoney.model2.Commodity;
027: import net.sf.jmoney.model2.Currency;
028: import net.sf.jmoney.model2.CurrencyAccount;
029: import net.sf.jmoney.model2.CurrencyAccountInfo;
030: import net.sf.jmoney.model2.ExtendableObject;
031: import net.sf.jmoney.model2.IPropertyControl;
032: import net.sf.jmoney.model2.ScalarPropertyAccessor;
033: import net.sf.jmoney.model2.Session;
034:
035: import org.eclipse.swt.custom.CCombo;
036: import org.eclipse.swt.events.SelectionEvent;
037: import org.eclipse.swt.events.SelectionListener;
038: import org.eclipse.swt.widgets.Composite;
039: import org.eclipse.swt.widgets.Control;
040:
041: /**
042: * Note that this class has neither get/set methods for the value being edited
043: * and no support for property change listeners. This is
044: * because objects of this class are tied to an CapitalAccount object.
045: * Changes to this
046: * object are reflected by this object in the CapitalAccount class objects.
047: * Consumers who are interested in changes to the CapitalAccount class objects should
048: * add themselves as listeners to the appropriate PropertyAccessor object.
049: *
050: * @author Nigel Westbury
051: * @author Johann Gyger
052: */
053: public class CurrencyEditor implements IPropertyControl {
054:
055: private ExtendableObject extendableObject;
056:
057: private ScalarPropertyAccessor<Currency> currencyPropertyAccessor;
058:
059: private CCombo propertyControl;
060:
061: /**
062: * @param propertyAccessor the accessor for the property to be edited
063: * by this control. The property must be of type Currency.
064: */
065: public CurrencyEditor(Composite parent,
066: ScalarPropertyAccessor<Currency> propertyAccessor) {
067: propertyControl = new CCombo(parent, 0);
068: this .currencyPropertyAccessor = propertyAccessor;
069:
070: Session session = JMoneyPlugin.getDefault().getSession();
071:
072: for (Commodity commodity : session.getCommodityCollection()) {
073: if (commodity instanceof Currency) {
074: propertyControl.add(commodity.getName());
075: }
076: }
077:
078: // Selection changes are reflected immediately in the
079: // mutable account object. This allows other properties
080: // such as money amounts to listen for changes to the
081: // currency and change their format to be correct for
082: // the newly selected currency.
083:
084: propertyControl.addSelectionListener(new SelectionListener() {
085: public void widgetSelected(SelectionEvent e) {
086: save();
087: }
088:
089: public void widgetDefaultSelected(SelectionEvent e) {
090: // Should this be here?
091: save();
092: }
093: });
094: }
095:
096: /**
097: * Load the control with the value from the given model object.
098: */
099: public void load(ExtendableObject extendableObject) {
100: this .extendableObject = extendableObject;
101:
102: if (extendableObject == null) {
103: propertyControl.setText("");
104: } else {
105: Currency currency = extendableObject
106: .getPropertyValue(currencyPropertyAccessor);
107: // Currency should not be null, but check in case of incomplete data.
108: // TODO: clean this up when we know the policy on invalid data in the
109: // datastore.
110: if (currency == null) {
111: propertyControl.setText("");
112: } else {
113: propertyControl.setText(currency.getName() == null ? ""
114: : currency.getName());
115: }
116:
117: // If the currency property being edited is the currency
118: // for a CurrencyAccount and the account has entries then the currency cannot
119: // be changed. We therefore disable the control.
120: // It might be that at some future time we implement
121: // an extension point that allows plug-ins to veto
122: // changes. If so then this may be better implemented
123: // using such an extension point.
124: if (currencyPropertyAccessor == CurrencyAccountInfo
125: .getCurrencyAccessor()) {
126: CurrencyAccount currencyAccount = (CurrencyAccount) extendableObject;
127: propertyControl.setEnabled(!currencyAccount
128: .hasEntries());
129: }
130: }
131: propertyControl.setEnabled(extendableObject != null);
132: }
133:
134: /**
135: * Save the value from the control back into the account object.
136: *
137: * Editors may update the property on a regular basis, not just when
138: * the framework calls the <code>save</code> method. However, the only time
139: * that editors must update the property is when the framework calls this method.
140: *
141: * In this implementation we save the value back into the entry when the selection
142: * is changed. This causes the change to be seen in other views as soon as the
143: * user changes the selection.
144: *
145: * The framework should never call this method when no account is selected
146: * so we can assume that <code>account</code> is not null.
147: */
148: public void save() {
149: String currencyName = propertyControl.getText();
150: for (Commodity commodity : extendableObject.getSession()
151: .getCommodityCollection()) {
152: if (commodity instanceof Currency
153: && commodity.getName().equals(currencyName)) {
154: extendableObject.setPropertyValue(
155: currencyPropertyAccessor, (Currency) commodity);
156: }
157: }
158: }
159:
160: /* (non-Javadoc)
161: * @see net.sf.jmoney.model2.IPropertyControl#getControl()
162: */
163: public Control getControl() {
164: return propertyControl;
165: }
166:
167: }
|