package org.nightlabs.jfire.contact.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.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.contact.ui.resource.Messages; 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.notification.NotificationEvent; import org.nightlabs.notification.NotificationListener; import org.nightlabs.progress.ProgressMonitor; import org.nightlabs.progress.SubProgressMonitor; import org.nightlabs.util.Util; public class ContactDetailComposite extends XComposite { private Display display; private PropertySet selectedPerson; private FullDataBlockCoverageComposite fullDataBlockCoverageComposite; private NotificationListener notificationListenerPersonChanged = new NotificationAdapterJob(Messages.getString("org.nightlabs.jfire.contact.ui.ContactDetailComposite.notificationListenerPersonChanged.jobName")) { //$NON-NLS-1$ @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()); } } }; public ContactDetailComposite(Composite parent) { super(parent, SWT.NONE, LayoutMode.TIGHT_WRAPPER); display = parent.getDisplay(); GridLayout layout = new GridLayout(1, true); this.setLayout(layout); JDOLifecycleManager.sharedInstance().addNotificationListener(Person.class, notificationListenerPersonChanged); this.addDisposeListener(new DisposeListener() { public void widgetDisposed(DisposeEvent e) { JDOLifecycleManager.sharedInstance().removeNotificationListener(Person.class, notificationListenerPersonChanged); } }); } 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); } private ListenerList dataBlockEditorChangedListeners = new ListenerList(); public void addChangeListener(DataBlockEditorChangedListener listener) { dataBlockEditorChangedListeners.add(listener); } public void removeChangeListener(DataBlockEditorChangedListener listener) { dataBlockEditorChangedListeners.remove(listener); } public void setPersonID(final PropertySetID personID) { Job job = new Job(Messages.getString("org.nightlabs.jfire.contact.ui.ContactDetailComposite.loadSelectedPersonJob.name")) { //$NON-NLS-1$ @Override protected IStatus run(ProgressMonitor monitor) throws Exception { setPersonID(personID, monitor); return Status.OK_STATUS; } }; job.setPriority(Job.SHORT); job.schedule(); } public void setPersonID(PropertySetID personID, ProgressMonitor monitor) { if (Display.getCurrent() != null) throw new IllegalStateException("This method must be called in a Job!"); //$NON-NLS-1$ monitor.beginTask(Messages.getString("org.nightlabs.jfire.contact.ui.ContactDetailComposite.loadSelectedPersonJob.name"), 100); //$NON-NLS-1$ 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 essentially necessary, because we 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(); } } ); } finally { monitor.done(); } } 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; } // public void setPerson(PropertySet person) { // if (Display.getCurrent() != display) // throw new IllegalStateException("Thread mismatch! This method must be called on the SWT UI thread!"); // // this.selectedPerson = person; // // if (fullDataBlockCoverageComposite != null && !fullDataBlockCoverageComposite.isDisposed()) // fullDataBlockCoverageComposite.refresh(person); // } }