package org.nightlabs.jfire.trade.admin.ui.moneyflow;
import java.util.Iterator;
import javax.jdo.FetchPlan;
import javax.jdo.JDOHelper;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StackLayout;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
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.Label;
import org.eclipse.swt.widgets.Shell;
import org.nightlabs.base.ui.composite.FadeableComposite;
import org.nightlabs.base.ui.composite.XComposite;
import org.nightlabs.base.ui.job.FadeableCompositeJob;
import org.nightlabs.base.ui.job.Job;
import org.nightlabs.base.ui.notification.IDirtyStateManager;
import org.nightlabs.base.ui.notification.NotificationAdapterJob;
import org.nightlabs.base.ui.wizard.DynamicPathWizardDialog;
import org.nightlabs.jdo.NLJDOHelper;
import org.nightlabs.jfire.accounting.book.LocalAccountantDelegate;
import org.nightlabs.jfire.accounting.book.id.LocalAccountantDelegateID;
import org.nightlabs.jfire.accounting.book.mappingbased.MappingBasedAccountantDelegate;
import org.nightlabs.jfire.accounting.book.mappingbased.MoneyFlowMapping;
import org.nightlabs.jfire.store.ProductType;
import org.nightlabs.jfire.store.ProductTypeLocal;
import org.nightlabs.jfire.store.dao.ProductTypeDAO;
import org.nightlabs.jfire.store.id.ProductTypeID;
import org.nightlabs.jfire.trade.admin.ui.moneyflow.edit.AddMoneyFlowMappingWizard;
import org.nightlabs.jfire.trade.admin.ui.moneyflow.edit.SelectCreateAccountantDelegateWizard;
import org.nightlabs.jfire.trade.admin.ui.resource.Messages;
import org.nightlabs.notification.NotificationEvent;
import org.nightlabs.notification.NotificationListener;
import org.nightlabs.progress.ProgressMonitor;
/**
* @author Daniel.Mazurek [at] NightLabs [dot] de
*
*/
public class MoneyFlowConfigComposite
extends XComposite
{
private boolean showButtons = true;
public MoneyFlowConfigComposite(Composite parent, int style,
IDirtyStateManager dirtyStateManager, boolean showButtons)
{
super(parent, style);
this.dirtyStateManager = dirtyStateManager;
this.showButtons = showButtons;
createPartContents(this);
}
public MoneyFlowConfigComposite(Composite parent, int style,
LayoutMode layoutMode, LayoutDataMode layoutDataMode,
IDirtyStateManager dirtyStateManager, boolean showButtons)
{
super(parent, style, layoutMode, layoutDataMode);
this.dirtyStateManager = dirtyStateManager;
this.showButtons = showButtons;
createPartContents(this);
}
private IDirtyStateManager dirtyStateManager;
private MoneyFlowMappingTree productTypeMappingTree;
public MoneyFlowMappingTree getProductTypeMappingTree() {
return productTypeMappingTree;
}
private ResolvedMappingTree resolvedMappingTree;
private ProductTypeID currProductTypeID;
private FadeableComposite fadeableComposite;
private Composite stackWrapper;
private StackLayout stackLayout;
private XComposite treeWrapper;
private XComposite noDelegateComp;
private NotificationListener notificationListenerProductTypeSelected = new NotificationAdapterJob(Messages.getString("org.nightlabs.jfire.trade.admin.ui.moneyflow.MoneyFlowConfigComposite.loadMoneyFlowConfigJob.name")) { //$NON-NLS-1$
public void notify(NotificationEvent event) {
boolean doRefresh = false;
ProductTypeID productTypeID = null;
if (event.getSubjects().isEmpty()) {
doRefresh = currProductTypeID != null;
currProductTypeID = null;
}
else {
for (Iterator it = event.getSubjects().iterator(); it.hasNext(); ) {
Object subject = it.next();
if (subject instanceof ProductTypeID) {
productTypeID = (ProductTypeID)subject;
doRefresh = (productTypeID != null) && (!productTypeID.equals(currProductTypeID));
currProductTypeID = productTypeID;
}
else {
doRefresh = currProductTypeID != null;
currProductTypeID = null;
}
}
}
if (doRefresh) {
setProductTypeID(currProductTypeID);
}
}
};
public NotificationListener getNotificationListener() {
return notificationListenerProductTypeSelected;
}
private ProductType productType;
public ProductType getProductType() {
return productType;
}
/**
* @deprecated use {@link #setProductType(ProductType)} instead
*
* sets the id of the {@link ProductType} to load
* @param productTypeID the id of the {@link ProductType} to set
*/
@Deprecated
public void setProductTypeID(final ProductTypeID productTypeID)
{
currProductTypeID = productTypeID;
Job updateJob = new FadeableCompositeJob(Messages.getString("org.nightlabs.jfire.trade.admin.ui.moneyflow.MoneyFlowConfigComposite.updateMoneyFlowConfigJob.name"), fadeableComposite, this) { //$NON-NLS-1$
@Override
protected IStatus run(ProgressMonitor monitor, Object source) throws Exception {
if (productTypeID != null)
productType = ProductTypeDAO.sharedInstance().getProductType(
productTypeID, MoneyFlowMappingTree.DEFAULT_PTYPE_FETCH_GROUPS, NLJDOHelper.MAX_FETCH_DEPTH_NO_LIMIT,
monitor);
if ((productType == null) || (productType.getProductTypeLocal().getLocalAccountantDelegate() == null)) {
Display.getDefault().asyncExec(new Runnable() {
public void run() {
stackLayout.topControl = noDelegateComp;
stackWrapper.layout(true);
}
});
}
else {
Display.getDefault().asyncExec(new Runnable() {
public void run() {
stackLayout.topControl = treeWrapper;
stackWrapper.layout(true);
}
});
}
productTypeMappingTree.setProductTypeID(productTypeID, monitor);
ProductType pType = ProductTypeDAO.sharedInstance().getProductType(
productTypeID, new String[] {FetchPlan.DEFAULT}, NLJDOHelper.MAX_FETCH_DEPTH_NO_LIMIT,
monitor);
if (pType != null && pType.isSaleable())
resolvedMappingTree.setProductTypeID(productTypeID, monitor);
else
resolvedMappingTree.clear();
return Status.OK_STATUS;
}
};
updateJob.schedule();
}
/**
* sets the {@link ProductType} to display the MoneyFlowConfiguration for
* @param productType the proudctType to set
*/
public void setProductType(final ProductType productType)
{
this.productType = productType;
currProductTypeID = (ProductTypeID) JDOHelper.getObjectId(productType);
Job updateJob = new FadeableCompositeJob(Messages.getString("org.nightlabs.jfire.trade.admin.ui.moneyflow.MoneyFlowConfigComposite.updateMoneyFlowConfigJob.name"), fadeableComposite, this) { //$NON-NLS-1$
@Override
protected IStatus run(ProgressMonitor monitor, Object source) throws Exception {
if ((productType == null) || (productType.getProductTypeLocal().getLocalAccountantDelegate() == null)) {
Display.getDefault().asyncExec(new Runnable() {
public void run() {
if (stackWrapper.isDisposed())
return;
stackLayout.topControl = noDelegateComp;
stackWrapper.layout(true);
}
});
}
else {
Display.getDefault().asyncExec(new Runnable() {
public void run() {
if (stackWrapper.isDisposed())
return;
stackLayout.topControl = treeWrapper;
stackWrapper.layout(true);
}
});
}
productTypeMappingTree.setProductType(productType);
resolvedMappingTree.setProductType(productType);
return Status.OK_STATUS;
}
};
updateJob.schedule();
}
protected void updateDelegate(final LocalAccountantDelegate delegate) {
if (currProductTypeID != null) {
Display.getDefault().asyncExec(new Runnable() {
public void run() {
stackLayout.topControl = treeWrapper;
stackWrapper.layout(true);
productTypeMappingTree.setDelegateID((LocalAccountantDelegateID)JDOHelper.getObjectId(delegate));
}
});
}
}
/**
* @see org.nightlabs.base.ui.part.ControllablePart#createPartContents(org.eclipse.swt.widgets.Composite)
*/
public void createPartContents(Composite parent)
{
fadeableComposite = new FadeableComposite(parent, SWT.NONE, LayoutMode.TIGHT_WRAPPER);
stackWrapper = new Composite(fadeableComposite, SWT.NONE);
stackLayout = new StackLayout();
stackWrapper.setLayout(stackLayout);
stackWrapper.setLayoutData(new GridData(GridData.FILL_BOTH));
treeWrapper = new XComposite(stackWrapper, SWT.NONE);
treeWrapper.getGridLayout().makeColumnsEqualWidth = true;
treeWrapper.setLayout(new GridLayout(2, false));
// XComposite comp = new XComposite(treeWrapper, SWT.BORDER, LayoutMode.TIGHT_WRAPPER);
XComposite comp = new XComposite(treeWrapper, getBorderStyle(), LayoutMode.TIGHT_WRAPPER);
comp.setLayoutData(new GridData(GridData.FILL_BOTH));
productTypeMappingTree = new MoneyFlowMappingTree(comp, null);
resolvedMappingTree = new ResolvedMappingTree(comp);
if (showButtons) {
Composite buttonParent = new XComposite(treeWrapper, SWT.NONE);
buttonParent.setLayoutData(new GridData(GridData.FILL_VERTICAL));
Button addDelegateButton = new Button(buttonParent, SWT.NONE);
addDelegateButton.setText(Messages.getString("org.nightlabs.jfire.trade.admin.ui.moneyflow.MoneyFlowConfigComposite.addDelegateButton.text")); //$NON-NLS-1$
addDelegateButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
addDelegateButton.addSelectionListener(addDelegateListener);
Button removeDelegateButton = new Button(buttonParent, SWT.NONE);
removeDelegateButton.setText(Messages.getString("org.nightlabs.jfire.trade.admin.ui.moneyflow.MoneyFlowConfigComposite.removeDelegateButton.text")); //$NON-NLS-1$
removeDelegateButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
removeDelegateButton.addSelectionListener(removeDelegateListener);
}
noDelegateComp = new XComposite(stackWrapper, SWT.NONE);
Label label = new Label(noDelegateComp, SWT.WRAP);
label.setText(Messages.getString("org.nightlabs.jfire.trade.admin.ui.moneyflow.MoneyFlowConfigComposite.noDelegateLabel.text")); //$NON-NLS-1$
Button button = new Button(noDelegateComp, SWT.FLAT);
button.setText(Messages.getString("org.nightlabs.jfire.trade.admin.ui.moneyflow.MoneyFlowConfigComposite.assignDelegateButton.text")); //$NON-NLS-1$
button.addSelectionListener(new SelectionListener(){
public void widgetSelected(SelectionEvent e) {
openSelectedAccountDelegateWizard();
}
public void widgetDefaultSelected(SelectionEvent e) {
}
});
stackLayout.topControl = treeWrapper;
}
public void addDelegate()
{
if (getCurrProductTypeID() == null || getCurrDelegate() == null)
return;
AddMoneyFlowMappingWizard wiz = new AddMoneyFlowMappingWizard(
getCurrDelegate(),
getCurrProductTypeID()
);
DynamicPathWizardDialog wizardDialog = new DynamicPathWizardDialog(wiz) {
@Override
protected void configureShell(Shell newShell) {
super.configureShell(newShell);
newShell.setSize(500, 450);
}
};
if (wizardDialog.open() == Window.OK) {
setNextRefreshSelectMapping(wiz.getCreatedMapping());
refresh(true);
if (dirtyStateManager != null)
dirtyStateManager.markDirty();
}
}
private SelectionListener addDelegateListener = new SelectionListener(){
public void widgetSelected(SelectionEvent e) {
addDelegate();
}
public void widgetDefaultSelected(SelectionEvent e) {
widgetSelected(e);
}
};
public void removeDelegate()
{
if (getCurrProductTypeID() == null)
return;
MoneyFlowMapping mapping = getSelectedMoneyFlowMapping();
if (mapping == null)
return;
LocalAccountantDelegate _delegate = getSelectedLocalAccountantDelegate();
if (_delegate == null)
return;
if (!(_delegate instanceof MappingBasedAccountantDelegate))
return;
MappingBasedAccountantDelegate delegate = (MappingBasedAccountantDelegate) _delegate;
// TODO: Popup confirmation dialog
delegate.removeMoneyFlowMapping(mapping);
refresh(true);
if (dirtyStateManager != null)
dirtyStateManager.markDirty();
}
private SelectionListener removeDelegateListener = new SelectionListener(){
public void widgetSelected(SelectionEvent e) {
removeDelegate();
}
public void widgetDefaultSelected(SelectionEvent e) {
widgetSelected(e);
}
};
public ProductTypeID getCurrProductTypeID() {
return currProductTypeID;
}
public MappingBasedAccountantDelegate getCurrDelegate() {
return productTypeMappingTree.getCurrentDelegate();
}
public void refresh(boolean refreshInput) {
productTypeMappingTree.refresh(refreshInput);
}
/**
* @see org.nightlabs.jfire.trade.admin.ui.moneyflow.MoneyFlowMappingTree#setLastAddedMapping(org.nightlabs.jfire.accounting.book.MoneyFlowMapping)
*/
public void setNextRefreshSelectMapping(MoneyFlowMapping nextRefreshSelectMapping) {
productTypeMappingTree.setLastAddedMapping(nextRefreshSelectMapping);
}
/**
* @see org.nightlabs.jfire.trade.admin.ui.moneyflow.MoneyFlowMappingTree#getSelectedLocalAccountantDelegate()
*/
public LocalAccountantDelegate getSelectedLocalAccountantDelegate() {
return productTypeMappingTree.getSelectedLocalAccountantDelegate();
}
/**
* @see org.nightlabs.jfire.trade.admin.ui.moneyflow.MoneyFlowMappingTree#getSelectedMoneyFlowMapping()
*/
public MoneyFlowMapping getSelectedMoneyFlowMapping() {
return productTypeMappingTree.getSelectedMoneyFlowMapping();
}
// public void openSelectedAccountDelegateWizard()
// {
// final SelectCreateAccountantDelegateWizard wiz = new SelectCreateAccountantDelegateWizard();
// DynamicPathWizardDialog dlg = new DynamicPathWizardDialog(wiz);
// dlg.open();
// if (wiz.getSelectedDelegate() != null) {
// Job assignJob = new Job("Assigning delegate") {
// @Override
// protected IStatus run(ProgressMonitor monitor) {
// if (currProductTypeID != null) {
// try {
// // selected delegate is assigned
// getProductType().setLocalAccountantDelegate(wiz.getSelectedDelegate());
// if (dirtyStateManager != null) {
// Display.getDefault().syncExec(new Runnable(){
// public void run() {
// dirtyStateManager.markDirty();
// }
// });
// }
// } catch (Exception t) {
// throw new RuntimeException(t);
// }
// }
// updateDelegate(wiz.getSelectedDelegate());
// resolvedMappingTree.setProductType(getProductType());
// return Status.OK_STATUS;
// }
// };
// assignJob.setUser(true);
// assignJob.schedule();
// }
// }
public void openSelectedAccountDelegateWizard()
{
final SelectCreateAccountantDelegateWizard wiz = new SelectCreateAccountantDelegateWizard();
DynamicPathWizardDialog dlg = new DynamicPathWizardDialog(wiz);
dlg.open();
if (wiz.getSelectedDelegate() != null) {
if (currProductTypeID != null) {
try {
// selected delegate is assigned
// TODO what about the inheritance? The meta-data is not set - I'll set it here, but I'm not sure whether it's set already somewhere else. IMHO here, it makes sense - otherwise our setting would be overwritten...
getProductType().getProductTypeLocal().getFieldMetaData(ProductTypeLocal.FieldName.localAccountantDelegate).setValueInherited(wiz.isLocalAccountantDelegateInherited());
getProductType().getProductTypeLocal().setLocalAccountantDelegate(wiz.getSelectedDelegate());
if (dirtyStateManager != null)
dirtyStateManager.markDirty();
} catch (Exception t) {
throw new RuntimeException(t);
}
}
updateDelegate(wiz.getSelectedDelegate());
resolvedMappingTree.setProductType(getProductType());
}
}
}