package org.nightlabs.jfire.trade.ui.overview.account; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import javax.jdo.FetchPlan; import javax.jdo.JDOHelper; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Text; import org.nightlabs.base.ui.composite.NumberSpinnerComposite; import org.nightlabs.base.ui.composite.XComboComposite; import org.nightlabs.base.ui.composite.XComposite; import org.nightlabs.base.ui.job.Job; import org.nightlabs.jdo.NLJDOHelper; import org.nightlabs.jdo.query.QueryEvent; import org.nightlabs.jdo.query.QueryProvider; import org.nightlabs.jdo.query.AbstractSearchQuery.FieldChangeCarrier; import org.nightlabs.jfire.accounting.AccountType; import org.nightlabs.jfire.accounting.dao.AccountTypeDAO; import org.nightlabs.jfire.accounting.id.AccountTypeID; import org.nightlabs.jfire.accounting.id.CurrencyID; import org.nightlabs.jfire.accounting.query.AccountQuery; import org.nightlabs.jfire.base.ui.search.AbstractQueryFilterComposite; import org.nightlabs.jfire.base.ui.search.SpinnerSearchEntry; import org.nightlabs.jfire.trade.LegalEntity; import org.nightlabs.jfire.trade.dao.LegalEntityDAO; import org.nightlabs.jfire.trade.ui.currency.CurrencyCombo; import org.nightlabs.jfire.trade.ui.legalentity.edit.LegalEntitySearchCreateWizard; import org.nightlabs.jfire.trade.ui.resource.Messages; import org.nightlabs.jfire.transfer.id.AnchorID; import org.nightlabs.progress.NullProgressMonitor; import org.nightlabs.progress.ProgressMonitor; import org.nightlabs.util.NLLocale; /** * @author Daniel.Mazurek [at] NightLabs [dot] de * @author Marius Heinzmann - marius[at]nightlabs[dot]com */ public class AccountFilterComposite extends AbstractQueryFilterComposite<AccountQuery> { /** * @param parent * The parent to instantiate this filter into. * @param style * The style to apply. * @param layoutMode * The layout mode to use. See {@link XComposite.LayoutMode}. * @param layoutDataMode * The layout data mode to use. See {@link XComposite.LayoutDataMode}. * @param queryProvider * The queryProvider to use. It may be <code>null</code>, but the caller has to * ensure, that it is set before {@link #getQuery()} is called! */ public AccountFilterComposite(Composite parent, int style, LayoutMode layoutMode, LayoutDataMode layoutDataMode, QueryProvider<? super AccountQuery> queryProvider) { super(parent, style, layoutMode, layoutDataMode, queryProvider); createComposite(); } /** * @param parent * The parent to instantiate this filter into. * @param style * The style to apply. * @param queryProvider * The queryProvider to use. It may be <code>null</code>, but the caller has to * ensure, that it is set before {@link #getQuery()} is called! */ public AccountFilterComposite(Composite parent, int style, QueryProvider<? super AccountQuery> queryProvider) { super(parent, style, queryProvider); createComposite(); } @Override public Class<AccountQuery> getQueryClass() { return AccountQuery.class; } private SpinnerSearchEntry minBalanceEntry; private SpinnerSearchEntry maxBalanceEntry; private Button activeCurrencyButton; private CurrencyCombo currencyCombo; protected CurrencyID selectedCurrencyID; private Button ownerActiveButton; private Text ownerText; private Button ownerBrowseButton; private Button accountTypeActiveButton; private XComboComposite<AccountType> accountTypeList; private static final String[] ACCOUNT_TYPE_FETCH_GROUPS = new String[] { FetchPlan.DEFAULT, AccountType.FETCH_GROUP_NAME }; protected AccountTypeID selectedAccountTypeID; @Override protected void createComposite() { setLayout(new GridLayout(3, false)); minBalanceEntry = new SpinnerSearchEntry(this, SWT.NONE, LayoutMode.TIGHT_WRAPPER, LayoutDataMode.GRID_DATA_HORIZONTAL, Messages.getString("org.nightlabs.jfire.trade.ui.overview.account.AccountSearchComposite.minBalanceEntry.caption")); //$NON-NLS-1$ minBalanceEntry.getSpinnerComposite().setMinimum(Integer.MIN_VALUE); minBalanceEntry.getSpinnerComposite().addModifyListener(new ModifyListener() { @Override public void modifyText(ModifyEvent e) { final Long minBalance = computeValue(minBalanceEntry.getSpinnerComposite()); getQuery().setMinBalance(minBalance); } }); minBalanceEntry.addActiveStateChangeListener(new ButtonSelectionListener() { @Override protected void handleSelection(boolean active) { getQuery().setFieldEnabled(AccountQuery.FieldName.minBalance, active); if (getQuery().getMinBalance() == null) getQuery().setMinBalance( computeValue(minBalanceEntry.getSpinnerComposite()) ); } }); maxBalanceEntry = new SpinnerSearchEntry(this, SWT.NONE, LayoutMode.TIGHT_WRAPPER, LayoutDataMode.GRID_DATA_HORIZONTAL, Messages.getString("org.nightlabs.jfire.trade.ui.overview.account.AccountSearchComposite.maxBalanceEntry.caption")); //$NON-NLS-1$ maxBalanceEntry.getSpinnerComposite().setMinimum(Integer.MIN_VALUE); maxBalanceEntry.getSpinnerComposite().addModifyListener(new ModifyListener() { @Override public void modifyText(ModifyEvent arg0) { final Long maxBalance = computeValue(maxBalanceEntry.getSpinnerComposite()); getQuery().setMaxBalance(maxBalance); } }); maxBalanceEntry.addActiveStateChangeListener(new ButtonSelectionListener() { @Override protected void handleSelection(boolean active) { getQuery().setFieldEnabled(AccountQuery.FieldName.maxBalance, active); if (getQuery().getMaxBalance() == null) getQuery().setMaxBalance( computeValue(maxBalanceEntry.getSpinnerComposite()) ); } }); Group currencyGroup = new Group(this, SWT.NONE); currencyGroup.setText(Messages.getString("org.nightlabs.jfire.trade.ui.overview.account.AccountSearchComposite.currencyGroup.text")); //$NON-NLS-1$ currencyGroup.setLayout(new GridLayout()); XComposite.setLayoutDataMode(LayoutDataMode.GRID_DATA_HORIZONTAL, currencyGroup); activeCurrencyButton = new Button(currencyGroup, SWT.CHECK); activeCurrencyButton.setText(Messages.getString("org.nightlabs.jfire.trade.ui.overview.account.AccountSearchComposite.activeCurrencyButton.text")); //$NON-NLS-1$ activeCurrencyButton.addSelectionListener(new ButtonSelectionListener() { @Override protected void handleSelection(boolean active) { getQuery().setFieldEnabled(AccountQuery.FieldName.currencyID, active); } }); activeCurrencyButton.setSelection(false); currencyCombo = new CurrencyCombo(currencyGroup, SWT.NONE); currencyCombo.setEnabled(false); currencyCombo.addSelectionChangedListener(new ISelectionChangedListener() { @Override public void selectionChanged(SelectionChangedEvent e) { final CurrencyID selectedCurrencyID = (CurrencyID) JDOHelper.getObjectId(currencyCombo.getSelectedCurrency()); getQuery().setCurrencyID(selectedCurrencyID); } }); final Group ownerGroup = new Group(this, SWT.NONE); ownerGroup.setText(Messages.getString("org.nightlabs.jfire.trade.ui.overview.account.AccountListComposite.AccountSearchComposite.ownerGroup.text")); //$NON-NLS-1$ ownerGroup.setLayout(new GridLayout(2, false)); XComposite.setLayoutDataMode(LayoutDataMode.GRID_DATA_HORIZONTAL, ownerGroup); ownerActiveButton = new Button(ownerGroup, SWT.CHECK); ownerActiveButton.setText(Messages.getString("org.nightlabs.jfire.trade.ui.overview.account.AccountListComposite.AccountSearchComposite.ownerActiveButton.text")); //$NON-NLS-1$ GridData vendorLabelData = new GridData(GridData.FILL_HORIZONTAL); vendorLabelData.horizontalSpan = 2; ownerActiveButton.setLayoutData(vendorLabelData); ownerActiveButton.addSelectionListener(new ButtonSelectionListener() { @Override protected void handleSelection(boolean active) { getQuery().setFieldEnabled(AccountQuery.FieldName.ownerID, active); } }); ownerText = new Text(ownerGroup, XComposite.getBorderStyle(ownerGroup)); ownerText.setEnabled(false); ownerText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); ownerBrowseButton = new Button(ownerGroup, SWT.NONE); ownerBrowseButton.setText(Messages.getString("org.nightlabs.jfire.trade.ui.overview.account.AccountListComposite.AccountSearchComposite.ownerBrowseButton.text")); //$NON-NLS-1$ ownerBrowseButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { LegalEntity _legalEntity = LegalEntitySearchCreateWizard.open(ownerText.getText(), false); if (_legalEntity != null) { final AnchorID selectedOwnerID = (AnchorID) JDOHelper.getObjectId(_legalEntity); getQuery().setOwnerID(selectedOwnerID); // TODO perform this expensive code asynchronously LegalEntity legalEntity = LegalEntityDAO.sharedInstance().getLegalEntity(selectedOwnerID, new String[] {LegalEntity.FETCH_GROUP_PERSON, FetchPlan.DEFAULT}, NLJDOHelper.MAX_FETCH_DEPTH_NO_LIMIT, new NullProgressMonitor()); ownerText.setText(legalEntity.getPerson().getDisplayName()); } } }); ownerBrowseButton.setEnabled(false); final Group accountTypeGroup = new Group(this, SWT.NONE); accountTypeGroup.setText(Messages.getString("org.nightlabs.jfire.trade.ui.overview.account.AccountListComposite.AccountSearchComposite.accountTypeGroup.text")); //$NON-NLS-1$ accountTypeGroup.setLayout(new GridLayout()); XComposite.setLayoutDataMode(LayoutDataMode.GRID_DATA_HORIZONTAL, accountTypeGroup); accountTypeActiveButton = new Button(accountTypeGroup, SWT.CHECK); accountTypeActiveButton.setText(Messages.getString("org.nightlabs.jfire.trade.ui.overview.account.AccountListComposite.AccountSearchComposite.accountTypeActiveButton.text")); //$NON-NLS-1$ accountTypeActiveButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); accountTypeActiveButton.addSelectionListener(new ButtonSelectionListener() { @Override protected void handleSelection(boolean active) { getQuery().setFieldEnabled(AccountQuery.FieldName.accountTypeID, active); } }); accountTypeList = new XComboComposite<AccountType>( accountTypeGroup, XComposite.getBorderStyle(accountTypeGroup) | SWT.READ_ONLY, new LabelProvider() { @Override public String getText(Object element) { if (element instanceof AccountType) return ((AccountType)element).getName().getText(); return ""; //$NON-NLS-1$ } } ); accountTypeList.setEnabled(false); AccountType dummyAccountType = new AccountType("dummy.b.c", "dummy", false); //$NON-NLS-1$ //$NON-NLS-2$ dummyAccountType.getName().setText(NLLocale.getDefault().getLanguage(), Messages.getString("org.nightlabs.jfire.trade.ui.overview.account.AccountSearchComposite.loadingAccountTypes")); //$NON-NLS-1$ accountTypeList.setInput(Collections.singletonList(dummyAccountType)); accountTypeList.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { final AccountTypeID selectedAccountTypeID = (AccountTypeID) JDOHelper.getObjectId(accountTypeList.getSelectedElement()); getQuery().setAccountTypeID(selectedAccountTypeID); } }); Job job = new Job(Messages.getString("org.nightlabs.jfire.trade.ui.overview.account.AccountSearchComposite.job.loadingAccountTypes")) { //$NON-NLS-1$ @Override protected IStatus run(ProgressMonitor monitor) throws Exception { final List<AccountType> accountTypes = AccountTypeDAO.sharedInstance().getAccountTypes( ACCOUNT_TYPE_FETCH_GROUPS, NLJDOHelper.MAX_FETCH_DEPTH_NO_LIMIT, monitor ); Display.getDefault().asyncExec(new Runnable() { @Override public void run() { accountTypeList.setInput(accountTypes); } }); return Status.OK_STATUS; } }; job.schedule(); } private static final String ACCOUNT_GROUP_ID = "AccountFilterComposite"; //$NON-NLS-1$ private static Set<String> fieldNames; static { fieldNames = new HashSet<String>(); fieldNames.add(AccountQuery.FieldName.accountTypeID); fieldNames.add(AccountQuery.FieldName.currencyID); fieldNames.add(AccountQuery.FieldName.minBalance); fieldNames.add(AccountQuery.FieldName.maxBalance); fieldNames.add(AccountQuery.FieldName.ownerID); } /* * (non-Javadoc) * @see org.nightlabs.jfire.base.ui.search.AbstractQueryFilterComposite#getFieldNames() */ @Override protected Set<String> getFieldNames() { return fieldNames; } /* * (non-Javadoc) * @see org.nightlabs.jfire.base.ui.search.AbstractQueryFilterComposite#getGroupID() */ @Override protected String getGroupID() { return ACCOUNT_GROUP_ID; } private long computeValue(NumberSpinnerComposite spinner) { int numDigits = spinner.getNumDigits(); double multiplier = Math.pow(10, numDigits); Number number = spinner.getValue(); double val = number.doubleValue() * multiplier; return new Double(val).longValue(); } private double computeDoubleFromQueryValue(long value, NumberSpinnerComposite spinner) { int numDigits = spinner.getNumDigits(); double divider = Math.pow(10, numDigits); return value / divider; } @Override protected void updateUI(QueryEvent event, List<FieldChangeCarrier> changedFields) { // apply changes. for (FieldChangeCarrier changedField : changedFields) { if (AccountQuery.FieldName.maxBalance.equals(changedField.getPropertyName())) { Long tmpMaxBalance = (Long) changedField.getNewValue(); double tmpSpinnerValue = computeDoubleFromQueryValue( tmpMaxBalance == null ? 0 : tmpMaxBalance, maxBalanceEntry.getSpinnerComposite()); maxBalanceEntry.getSpinnerComposite().setValue(tmpSpinnerValue); } else if (getEnableFieldName(AccountQuery.FieldName.maxBalance).equals( changedField.getPropertyName())) { final boolean active = (Boolean) changedField.getNewValue(); maxBalanceEntry.setActive(active); setSearchSectionActive(active); } else if (AccountQuery.FieldName.minBalance.equals(changedField.getPropertyName())) { Long tmpMinBalance = (Long) changedField.getNewValue(); double tmpSpinnerValue = computeDoubleFromQueryValue( tmpMinBalance == null ? 0 : tmpMinBalance, minBalanceEntry.getSpinnerComposite()); minBalanceEntry.getSpinnerComposite().setValue(tmpSpinnerValue); } else if (getEnableFieldName(AccountQuery.FieldName.minBalance).equals( changedField.getPropertyName())) { boolean active = (Boolean) changedField.getNewValue(); minBalanceEntry.setActive(active); setSearchSectionActive(active); } else if (AccountQuery.FieldName.currencyID.equals(changedField.getPropertyName())) { CurrencyID currencyID = (CurrencyID) changedField.getNewValue(); currencyCombo.setSelectedCurrency(currencyID); } else if (getEnableFieldName(AccountQuery.FieldName.currencyID).equals( changedField.getPropertyName())) { Boolean active = (Boolean) changedField.getNewValue(); currencyCombo.setEnabled(active); setSearchSectionActive(activeCurrencyButton, active); } else if (AccountQuery.FieldName.accountTypeID.equals(changedField.getPropertyName())) { AccountTypeID accountTypeID = (AccountTypeID) changedField.getNewValue(); if (accountTypeID == null) { accountTypeList.setSelection((AccountType) null); } else { final AccountType newAccountType = AccountTypeDAO.sharedInstance().getAccountType( accountTypeID, ACCOUNT_TYPE_FETCH_GROUPS, NLJDOHelper.MAX_FETCH_DEPTH_NO_LIMIT, new NullProgressMonitor() ); accountTypeList.setSelection(newAccountType); } } else if (getEnableFieldName(AccountQuery.FieldName.accountTypeID).equals( changedField.getPropertyName())) { Boolean active = (Boolean) changedField.getNewValue(); accountTypeList.setEnabled(active); setSearchSectionActive(accountTypeActiveButton, active); } else if (AccountQuery.FieldName.ownerID.equals(changedField.getPropertyName())) { AnchorID ownerID = (AnchorID) changedField.getNewValue(); if (ownerID == null) { ownerText.setText(""); //$NON-NLS-1$ } else { final LegalEntity legalEntity = LegalEntityDAO.sharedInstance().getLegalEntity( ownerID, new String[] {LegalEntity.FETCH_GROUP_PERSON, FetchPlan.DEFAULT}, NLJDOHelper.MAX_FETCH_DEPTH_NO_LIMIT, new NullProgressMonitor() ); ownerText.setText(legalEntity.getPerson().getDisplayName()); } } else if (getEnableFieldName(AccountQuery.FieldName.ownerID).equals( changedField.getPropertyName())) { Boolean active = (Boolean) changedField.getNewValue(); ownerText.setEnabled(active); ownerBrowseButton.setEnabled(active); setSearchSectionActive(ownerActiveButton, active); } } // for (FieldChangeCarrier changedField : event.getChangedFields()) } }