/** * */ package org.nightlabs.jfire.trade.ui.reserve; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import javax.jdo.JDOHelper; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IAction; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.viewers.DoubleClickEvent; import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; 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.eclipse.swt.widgets.Menu; import org.eclipse.ui.forms.widgets.Form; import org.eclipse.ui.forms.widgets.FormToolkit; import org.nightlabs.base.ui.action.ISelectionAction; import org.nightlabs.base.ui.composite.XComposite; import org.nightlabs.base.ui.notification.NotificationAdapterJob; import org.nightlabs.base.ui.resource.SharedImages; import org.nightlabs.base.ui.resource.SharedImages.ImageFormat; import org.nightlabs.base.ui.table.AbstractTableComposite; import org.nightlabs.jdo.NLJDOHelper; import org.nightlabs.jfire.base.ui.jdo.notification.JDOLifecycleManagerRCP; import org.nightlabs.jfire.jdo.notification.DirtyObjectID; import org.nightlabs.jfire.store.id.ProductTypeID; import org.nightlabs.jfire.trade.Offer; import org.nightlabs.jfire.trade.dao.OfferDAO; import org.nightlabs.jfire.trade.id.OfferID; import org.nightlabs.jfire.trade.ui.TradePlugin; import org.nightlabs.jfire.trade.ui.overview.offer.action.EditOfferAction; import org.nightlabs.jfire.trade.ui.resource.Messages; import org.nightlabs.notification.NotificationEvent; import org.nightlabs.notification.NotificationListener; import org.nightlabs.progress.NullProgressMonitor; /** * @author daniel [AT] nightlabs [DOT] de */ public class ReservationComposite extends XComposite { class RefreshAction extends Action { private final String ID = RefreshAction.class.getName(); public RefreshAction() { super(); setId(ID); setText(Messages.getString("org.nightlabs.jfire.trade.ui.reserve.ReservationComposite.action.refresh.text")); //$NON-NLS-1$ setToolTipText(Messages.getString("org.nightlabs.jfire.trade.ui.reserve.ReservationComposite.action.refresh.tooltip")); //$NON-NLS-1$ setImageDescriptor(SharedImages.getSharedImageDescriptor(TradePlugin.getDefault(), RefreshAction.class, "", ImageFormat.gif)); //$NON-NLS-1$ } @Override public void run() { refresh(); } } private ReservationTable reservationTable = null; private Form form; private EditOfferAction editAction; private ProductTypeID productTypeID; private Map<OfferID, Offer> offerIDToReservationOffer; /** * @param parent * @param style */ public ReservationComposite(Composite parent, int style) { super(parent, style); createComposite(this); } /** * @param parent * @param style * @param layoutMode * @param layoutDataMode */ public ReservationComposite(Composite parent, int style, LayoutMode layoutMode, LayoutDataMode layoutDataMode) { super(parent, style, layoutMode, layoutDataMode); createComposite(this); } protected void createComposite(Composite parent) { offerIDToReservationOffer = new HashMap<OfferID, Offer>(); form = getToolkit(true).createForm(parent); if (getToolkit() instanceof FormToolkit) { ((FormToolkit)getToolkit()).decorateFormHeading(form); } form.setLayoutData(new GridData(GridData.FILL_BOTH)); form.getBody().setLayoutData(new GridData(GridData.FILL_BOTH)); form.getBody().setLayout(new GridLayout()); reservationTable = new ReservationTable(form.getBody(), getBorderStyle(), true, AbstractTableComposite.DEFAULT_STYLE_SINGLE_BORDER); reservationTable.setLayoutData(new GridData(GridData.FILL_BOTH)); form.getToolBarManager().add(new RefreshAction()); // add actions to context menu MenuManager menuManager = new MenuManager(); final List<IAction> actions = createActions(); for (IAction action : actions) { menuManager.add(action); form.getToolBarManager().add(action); } form.getToolBarManager().update(true); Menu contextMenu = menuManager.createContextMenu(reservationTable.getControl()); reservationTable.getControl().setMenu(contextMenu); reservationTable.addSelectionChangedListener(new ISelectionChangedListener(){ @Override public void selectionChanged(SelectionChangedEvent event) { updateActions(actions, event.getSelection()); } }); // double click is edit reservationTable.addDoubleClickListener(new IDoubleClickListener(){ @Override public void doubleClick(DoubleClickEvent event) { if (editAction != null) editAction.run(); } }); addNotficationListener(); updateActions(actions, StructuredSelection.EMPTY); } protected List<IAction> createActions() { final List<IAction> actions = new ArrayList<IAction>(); editAction = new EditOfferAction(); actions.add(editAction); // TODO XXX FIXME have been refactored to org.nightlabs.jfire.reporting.trade.ui use extension point here // actions.add(new PrintOfferAction()); // actions.add(new ShowOfferAction()); actions.add(new PayAndDeliverReservationAction()); actions.add(new RejectReservationAction()); return actions; } protected void updateActions(Collection<IAction> actions, ISelection selection) { for (IAction action : actions) { if (action instanceof ISelectionAction) { ISelectionAction selectionAction = (ISelectionAction) action; selectionAction.setSelection(selection); action.setEnabled(selectionAction.calculateEnabled()); } } } protected void addNotficationListener() { JDOLifecycleManagerRCP.sharedInstance().addNotificationListener(Offer.class, offerListener); addDisposeListener(new DisposeListener(){ @Override public void widgetDisposed(DisposeEvent e) { JDOLifecycleManagerRCP.sharedInstance().removeNotificationListener(Offer.class, offerListener); } }); } public void setInput(ProductTypeID productTypeID, String title) { this.productTypeID = productTypeID; loadReservations(); refreshGUI(); form.setText(Messages.getString("org.nightlabs.jfire.trade.ui.reserve.ReservationComposite.form.text.reservationList")); //$NON-NLS-1$ form.setMessage(title); } protected Map<OfferID, Offer> buildMap(Collection<Offer> offers) { Map<OfferID, Offer> offerIDToOffer = new HashMap<OfferID, Offer>(); for (Offer offer : offers) { offerIDToOffer.put((OfferID) JDOHelper.getObjectId(offer), offer); } return offerIDToOffer; } protected void loadReservations() { if (productTypeID != null) { Collection<Offer> reservations = OfferDAO.sharedInstance().getReservations(productTypeID, ReservationTable.FETCH_GROUP_RESERVATIONS, NLJDOHelper.MAX_FETCH_DEPTH_NO_LIMIT, new NullProgressMonitor()); offerIDToReservationOffer = buildMap(reservations); } } protected void refreshGUI() { if (productTypeID != null && !reservationTable.isDisposed()) { reservationTable.setInput(offerIDToReservationOffer.values()); } } public void refresh() { loadReservations(); refreshGUI(); } private NotificationListener offerListener = new NotificationAdapterJob(){ @Override public void notify(NotificationEvent notificationEvent) { for (Iterator<DirtyObjectID> it = notificationEvent.getSubjects().iterator(); it.hasNext(); ) { DirtyObjectID dirtyObjectID = it.next(); Set<OfferID> dirtyOfferIDs = new HashSet<OfferID>(); if (offerIDToReservationOffer.containsKey(dirtyObjectID.getObjectID())) { switch (dirtyObjectID.getLifecycleState()) { case DIRTY: dirtyOfferIDs.add((OfferID)dirtyObjectID.getObjectID()); break; } } if (!dirtyOfferIDs.isEmpty()) { List<Offer> dirtyOffers = OfferDAO.sharedInstance().getOffers(dirtyOfferIDs, ReservationTable.FETCH_GROUP_RESERVATIONS, NLJDOHelper.MAX_FETCH_DEPTH_NO_LIMIT, new NullProgressMonitor()); for (Offer offer : dirtyOffers) { offerIDToReservationOffer.put((OfferID) JDOHelper.getObjectId(offer), offer); } Display display = getDisplay(); if (!display.isDisposed()) { display.asyncExec(new Runnable(){ @Override public void run() { refreshGUI(); } }); } } } } }; }