package org.nightlabs.jfire.contact.ui;
import javax.jdo.JDOHelper;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.nightlabs.base.ui.job.Job;
import org.nightlabs.base.ui.notification.NotificationAdapterSWTThreadAsync;
import org.nightlabs.base.ui.notification.SelectionManager;
import org.nightlabs.base.ui.resource.SharedImages;
import org.nightlabs.base.ui.util.RCPUtil;
import org.nightlabs.jfire.base.login.ui.part.LSDViewPart;
import org.nightlabs.jfire.base.ui.prop.edit.blockbased.DataBlockEditorChangedEvent;
import org.nightlabs.jfire.base.ui.prop.edit.blockbased.DataBlockEditorChangedListener;
import org.nightlabs.jfire.contact.ui.resource.Messages;
import org.nightlabs.jfire.person.Person;
import org.nightlabs.jfire.prop.PropertySet;
import org.nightlabs.jfire.prop.dao.PropertySetDAO;
import org.nightlabs.jfire.prop.id.PropertySetID;
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;
/**
* @author Chairat Kongarayawetchakun <!-- chairat [AT] nightlabs [DOT] de -->
*
*/
public class ContactDetailView
extends LSDViewPart
{
public static final String VIEW_ID = ContactDetailView.class.getName();
private SaveAction saveAction;
private Display display;
private ContactDetailComposite contactDetailComposite;
private NotificationListener contactSelectionListener;
/* (non-Javadoc)
* @see org.nightlabs.base.ui.part.ControllablePart#createPartContents(org.eclipse.swt.widgets.Composite)
*/
@Override
public void createPartContents(Composite parent)
{
display = parent.getDisplay();
contactDetailComposite = new ContactDetailComposite(parent);
contributeToActionBars();
contactDetailComposite.addChangeListener(new DataBlockEditorChangedListener() {
@Override
public void dataBlockEditorChanged(DataBlockEditorChangedEvent dataBlockEditorChangedEvent) {
if (saveAction != null && !saveAction.isEnabled())
saveAction.setEnabled(true);
}
});
contactSelectionListener = new NotificationAdapterSWTThreadAsync() {
@Override
public void notify(NotificationEvent notificationEvent) {
final PropertySet selectedPerson = contactDetailComposite.getPerson();
final Object firstSelection = notificationEvent.getFirstSubject();
if (firstSelection instanceof PropertySetID) {
if (firstSelection != null) {
// Check to see if the Person record has been modified before allowing uset to navigate to another
// record. If so prompt to save changes.
if (selectedPerson != null && saveAction != null && saveAction.isEnabled()) {
boolean isSaveChanges = MessageDialog.openQuestion(
RCPUtil.getActiveShell(),
Messages.getString("org.nightlabs.jfire.contact.ui.ContactDetailView.askUserSaveChangesDialog.title"), //$NON-NLS-1$
String.format(Messages.getString("org.nightlabs.jfire.contact.ui.ContactDetailView.askUserSaveChangesDialog.text"), selectedPerson.getDisplayName()) //$NON-NLS-1$
);
if (isSaveChanges) {
final PropertySet person = Util.cloneSerializable(selectedPerson);
Job job = new Job(Messages.getString("org.nightlabs.jfire.contact.ui.ContactDetailView.savePersonJob.name")) { //$NON-NLS-1$
@Override
protected IStatus run(ProgressMonitor monitor) throws Exception {
person.deflate();
PropertySetDAO.sharedInstance().storeJDOObject(
person, false, null, 1,
monitor
);
return Status.OK_STATUS;
}
};
job.setPriority(Job.LONG);
job.schedule();
}
// @Kai: The problem you described in the following is solved by Util.cloneSerializable(...)
// Something is still not correct here.
// Problem symptom: (1) User decides NOT to save Record_A. (2) Navigates to other records.
// (3) Some time later comes back to (unsaved) Record_A.
// ==> The modified-unsaved Record_A is displayed, instead of the original Record_A.
// So: Restore previous (clean) data? Clear changes from cache? Or what??
// @Kai: No! We need to clone the object! Marco.
// @Marco: Ok. Kapish.
saveAction.setEnabled(false);
}
contactDetailComposite.setPersonID((PropertySetID)firstSelection);
}
}
}
};
SelectionManager.sharedInstance().addNotificationListener(ContactPlugin.ZONE_PROPERTY, Person.class, contactSelectionListener);
contactDetailComposite.addDisposeListener(new DisposeListener() {
public void widgetDisposed(DisposeEvent e) {
SelectionManager.sharedInstance().removeNotificationListener(ContactPlugin.ZONE_PROPERTY, Person.class, contactSelectionListener);
}
});
}
/* (non-Javadoc)
* @see org.nightlabs.jfire.base.ui.login.part.LSDViewPart#setFocus()
*/
@Override
public void setFocus() {
if (contactDetailComposite != null)
contactDetailComposite.setFocus();
}
/**
* Prepares the ActionBar.
*/
private void contributeToActionBars() {
if (saveAction != null)
return;
IToolBarManager toolBarManager = getViewSite().getActionBars().getToolBarManager();
saveAction = new SaveAction();
toolBarManager.add(saveAction);
toolBarManager.update(true);
}
/**
* Allows to click on Action to save changes.
*/
private class SaveAction extends Action {
public SaveAction() {
setId(SaveAction.class.getName());
setImageDescriptor(SharedImages.SAVE_16x16);
setToolTipText(Messages.getString("org.nightlabs.jfire.contact.ui.ContactDetailView.SaveAction.toolTipText")); //$NON-NLS-1$
setText(Messages.getString("org.nightlabs.jfire.contact.ui.ContactDetailView.SaveAction.text")); //$NON-NLS-1$
// By default, this button should always be disabled.
setEnabled(false);
}
@Override
public void run() {
final PropertySet selectedPerson = contactDetailComposite.getPerson();
if (selectedPerson == null)
return;
final PropertySet person = Util.cloneSerializable(selectedPerson);
final PropertySetID personID = (PropertySetID) JDOHelper.getObjectId(person);
Job job = new Job(Messages.getString("org.nightlabs.jfire.contact.ui.ContactDetailView.savePersonJob.name")) { //$NON-NLS-1$
@Override
protected IStatus run(ProgressMonitor _monitor) throws Exception {
_monitor.beginTask(Messages.getString("org.nightlabs.jfire.contact.ui.ContactDetailView.savePersonJob.name"), 100); //$NON-NLS-1$
try {
person.deflate();
PropertySetDAO.sharedInstance().storeJDOObject(
person, false, null, 1,
new SubProgressMonitor(_monitor, 50)
);
contactDetailComposite.setPersonID(personID, new SubProgressMonitor(_monitor, 50));
} finally {
_monitor.done();
}
return Status.OK_STATUS;
}
};
job.setPriority(Job.SHORT);
job.setUser(true);
setEnabled(false);
job.schedule();
}
}
public PropertySet getPerson() {
return contactDetailComposite.getPerson();
}
}