package org.nightlabs.jfire.personrelation.issuetracking.trade.ui; import javax.jdo.FetchPlan; import javax.jdo.JDOHelper; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.ListenerList; import org.eclipse.core.runtime.Status; import org.eclipse.swt.SWT; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.nightlabs.base.ui.composite.XComposite; import org.nightlabs.base.ui.job.Job; import org.nightlabs.base.ui.notification.NotificationAdapterJob; import org.nightlabs.base.ui.notification.SelectionManager; import org.nightlabs.jdo.NLJDOHelper; import org.nightlabs.jfire.base.jdo.notification.JDOLifecycleManager; import org.nightlabs.jfire.base.ui.prop.edit.ValidationResultHandler; import org.nightlabs.jfire.base.ui.prop.edit.blockbased.BlockBasedEditor; import org.nightlabs.jfire.base.ui.prop.edit.blockbased.DataBlockEditorChangedEvent; import org.nightlabs.jfire.base.ui.prop.edit.blockbased.DataBlockEditorChangedListener; import org.nightlabs.jfire.base.ui.prop.edit.blockbased.FullDataBlockCoverageComposite; import org.nightlabs.jfire.jdo.notification.DirtyObjectID; import org.nightlabs.jfire.person.Person; import org.nightlabs.jfire.prop.PropertySet; import org.nightlabs.jfire.prop.StructLocal; import org.nightlabs.jfire.prop.dao.PropertySetDAO; import org.nightlabs.jfire.prop.dao.StructLocalDAO; import org.nightlabs.jfire.prop.id.PropertySetID; import org.nightlabs.jfire.prop.validation.ValidationResult; import org.nightlabs.jfire.trade.LegalEntity; import org.nightlabs.jfire.trade.dao.LegalEntityDAO; import org.nightlabs.jfire.trade.ui.TradePlugin; import org.nightlabs.jfire.transfer.id.AnchorID; import org.nightlabs.notification.NotificationEvent; import org.nightlabs.notification.NotificationListener; import org.nightlabs.progress.ProgressMonitor; import org.nightlabs.progress.SubProgressMonitor; import org.nightlabs.util.Util; /** * Contains the widgets to display the synchronised details for the selected Person-Relation * currently on the Person-relation tree. * * @author khaireel */ public class PersonRelationDetailsComposite extends XComposite { private PropertySet selectedPerson; private Display display; private FullDataBlockCoverageComposite fullDataBlockCoverageComposite; /** * Creates a new instance of the PersonRelationDetailsComposite. */ public PersonRelationDetailsComposite(Composite parent) { super(parent, SWT.NONE, LayoutMode.TIGHT_WRAPPER); display = parent.getDisplay(); GridLayout layout = new GridLayout(1, true); this.setLayout(layout); // Listeners (and disposers). JDOLifecycleManager.sharedInstance().addNotificationListener(Person.class, notificationListenerPersonChanged); this.addDisposeListener(new DisposeListener() { public void widgetDisposed(DisposeEvent e) { JDOLifecycleManager.sharedInstance().removeNotificationListener(Person.class, notificationListenerPersonChanged); } }); } /** * Updates this composite with details of the currently selected Person. */ private void createOrUpdateFullDataBlockCoverageComposite() { if (fullDataBlockCoverageComposite == null) { ValidationResultHandler resultManager = new ValidationResultHandler() { @Override public void handleValidationResult(ValidationResult validationResult) { } }; fullDataBlockCoverageComposite = new FullDataBlockCoverageComposite(this, SWT.NONE, selectedPerson, null, resultManager) { @Override protected BlockBasedEditor createBlockBasedEditor() { return new BlockBasedEditor(false); } }; fullDataBlockCoverageComposite.setLayoutData(new GridData(GridData.FILL_BOTH)); // Check to see if contents of the view is modified. fullDataBlockCoverageComposite.addChangeListener(new DataBlockEditorChangedListener() { @Override public void dataBlockEditorChanged(DataBlockEditorChangedEvent dataBlockEditorChangedEvent) { for (Object l : dataBlockEditorChangedListeners.getListeners()) ((DataBlockEditorChangedListener)l).dataBlockEditorChanged(dataBlockEditorChangedEvent); } }); } else fullDataBlockCoverageComposite.refresh(selectedPerson); this.layout(true); } // |--------------------->> Managing the Person details ---------------------------------------------------------->> /** * Sets up and prepares the Composite to display the detailed information of the selected Person-relation. * @param personID indicate the PropertySetID of the Person to display. */ public void setPersonID(PropertySetID personID, ProgressMonitor monitor) { // These steps are similar to the ones found in ContactDetailsComposite.setPersonID(xxx). if (Display.getCurrent() != null) throw new IllegalStateException("This method must be called in a Job!"); //$NON-NLS-1$ monitor.beginTask("Loading details...", 100); try { // step 1 PropertySet p = personID == null ? null : PropertySetDAO.sharedInstance().getPropertySet( personID, new String[] { FetchPlan.DEFAULT, PropertySet.FETCH_GROUP_FULL_DATA }, NLJDOHelper.MAX_FETCH_DEPTH_NO_LIMIT, new SubProgressMonitor(monitor, 70) ); // step 2 p = Util.cloneSerializable(p); // This cloning is essential, because we would otherwise edit the object that is right now in the cache (and shared)! monitor.worked(5); // step 3 StructLocal personStruct = p == null ? null : StructLocalDAO.sharedInstance().getStructLocal(p.getStructLocalObjectID(), new SubProgressMonitor(monitor, 20)); // step 4 if (p != null) p.inflate(personStruct); monitor.worked(5); // update UI on SWT thread final PropertySet person = p; display.asyncExec( new Runnable() { @Override public void run() { selectedPerson = person; createOrUpdateFullDataBlockCoverageComposite(); SelectionManager.sharedInstance().notify(new NotificationEvent(this, TradePlugin.ZONE_SALE, person, Person.class)); } } ); } finally { monitor.done(); } } /** * Sets up and prepares the Composite to display the detailed information of the selected Person-relation. * @param personID indicate the PropertySetID of the Person to be displayed. */ public void setPersonID(final PropertySetID personID) { Job job = new Job("Loading details...") { @Override protected IStatus run(ProgressMonitor monitor) throws Exception { setPersonID(personID, monitor); return Status.OK_STATUS; } }; job.setPriority(Job.SHORT); job.schedule(); } /** * Sets up and prepares the Composite to display the detailed information of the selected Person. * @param legalEntityID indicate the AnchorID of the Person to be displayed. */ public void setLegalEntityID(final AnchorID legalEntityID) { Job job = new Job("Loading details...") { @Override protected IStatus run(ProgressMonitor monitor) throws Exception { LegalEntity legalEntity = LegalEntityDAO.sharedInstance().getLegalEntity( legalEntityID, new String[] { FetchPlan.DEFAULT, LegalEntity.FETCH_GROUP_PERSON }, NLJDOHelper.MAX_FETCH_DEPTH_NO_LIMIT, monitor ); if (legalEntity != null) setPersonID((PropertySetID)JDOHelper.getObjectId(legalEntity.getPerson()), monitor); return Status.OK_STATUS; } }; job.setPriority(Job.SHORT); job.schedule(); } /** * @return the Person currently on display. */ public PropertySet getPerson() { if (Display.getCurrent() != display) throw new IllegalStateException("Thread mismatch! This method must be called on the SWT UI thread!"); //$NON-NLS-1$ if (fullDataBlockCoverageComposite != null && !fullDataBlockCoverageComposite.isDisposed()) fullDataBlockCoverageComposite.updatePropertySet(); return selectedPerson; } // |--------------------->> Managing listeners ------------------------------------------------------------------->> private ListenerList dataBlockEditorChangedListeners = new ListenerList(); private NotificationListener notificationListenerPersonChanged = new NotificationAdapterJob("Notifying...") { @Override public void notify(NotificationEvent notificationEvent) { PropertySetID selectedPersonID = (PropertySetID) JDOHelper.getObjectId(selectedPerson); if (selectedPersonID == null) return; DirtyObjectID dirtyObjectID = (DirtyObjectID) notificationEvent.getFirstSubject(); Object objectID = dirtyObjectID.getObjectID(); if (selectedPersonID.equals(objectID)) { setPersonID(selectedPersonID, getProgressMonitor()); } } }; }