/** * */ package org.nightlabs.jfire.trade.ui.producttype.quicklist; import java.text.Collator; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Set; import javax.jdo.FetchPlan; import org.eclipse.jface.viewers.ColumnWeightData; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.TableLayout; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.ViewerSorter; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.TreeColumn; import org.nightlabs.base.ui.table.TableLabelProvider; import org.nightlabs.base.ui.tree.AbstractTreeComposite; import org.nightlabs.base.ui.tree.TreeContentProvider; import org.nightlabs.jfire.store.ProductType; import org.nightlabs.jfire.store.ProductTypeGroup; import org.nightlabs.jfire.store.ProductTypeGroupSearchResult; import org.nightlabs.jfire.store.ProductTypeGroupSearchResult.Entry; import org.nightlabs.jfire.store.id.ProductTypeGroupID; import org.nightlabs.jfire.store.id.ProductTypeID; import org.nightlabs.jfire.trade.ui.producttype.quicklist.SelectionUtil.SelectionContainment; import org.nightlabs.jfire.trade.ui.resource.Messages; import org.nightlabs.util.NLLocale; /** * Abstract base implementation for trees which display {@link ProductTypeGroup}s. * * @author Daniel Mazurek - daniel [at] nightlabs [dot] de * */ public abstract class AbstractProductTypeGroupTree extends AbstractTreeComposite<AbstractProductTypeGroupTree.ProductTypeGroupNode> implements ISelectionHandler { public static String[] FETCH_GROUPS_PRODUCT_TYPE_GROUP = new String[] { FetchPlan.DEFAULT, ProductTypeGroup.FETCH_GROUP_NAME }; public static String[] FETCH_GROUPS_PRODUCT_TYPE = new String[] { FetchPlan.DEFAULT, ProductType.FETCH_GROUP_NAME }; /** * ContentProvider which holds the ProductTypeGroupIDSearchResult * which was set as input for the viewer. * * @author Daniel Mazurek - daniel [at] nightlabs [dot] de * */ public static class ContentProvider extends TreeContentProvider { private ProductTypeGroupSearchResult searchResult; public Object[] getElements(Object inputElement) { if (inputElement instanceof ProductTypeGroupSearchResult) { searchResult = (ProductTypeGroupSearchResult) inputElement; return getRootElements(searchResult).toArray(); } else if (inputElement instanceof String[]) { return (String[]) inputElement; } return null; } private Collection<ProductTypeGroupNode> getRootElements(ProductTypeGroupSearchResult input) { List<ProductTypeGroupNode> result = new LinkedList<ProductTypeGroupNode>(); for (Iterator<ProductTypeGroupSearchResult.Entry> it = input.getEntries().iterator(); it.hasNext();) { ProductTypeGroupSearchResult.Entry entry = it.next(); result.add(new ProductTypeGroupNode(entry)); } return result; } /** * @see org.nightlabs.base.ui.tree.TreeContentProvider#getChildren(java.lang.Object) */ @Override public Object[] getChildren(Object parentElement) { if (parentElement instanceof ProductTypeGroupNode) return ((ProductTypeGroupNode)parentElement).getChildren(); return super.getChildren(parentElement); } /** * @see org.nightlabs.base.ui.tree.TreeContentProvider#getParent(java.lang.Object) */ @Override public Object getParent(Object element) { if (element instanceof ProductTypeGroupNode) return ((ProductTypeGroupNode)element).getChildren(); return super.getParent(element); } /** * @see org.nightlabs.base.ui.tree.TreeContentProvider#hasChildren(java.lang.Object) */ @Override public boolean hasChildren(Object element) { if (element instanceof ProductTypeGroupNode) return ((ProductTypeGroupNode)element).hasChildren(); return super.hasChildren(element); } @Override public void dispose() { } @Override public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { super.inputChanged(viewer, oldInput, newInput); searchResult = null; } public ProductTypeGroupSearchResult getSearchResult() { return searchResult; } } /** * Simple LabelProvider which returns just the name for * {@link ProductTypeGroup}s, as well as for the contained * {@link ProductType}s * @author Daniel Mazurek - daniel [at] nightlabs [dot] de */ public static class LabelProvider extends TableLabelProvider { public String getColumnText(Object element, int columnIndex) { if (element instanceof String) { if (columnIndex == 0) return (String) element; return ""; //$NON-NLS-1$ } if (!(element instanceof ProductTypeGroupNode)) throw new IllegalArgumentException("Expected ProductTypeGroupNode as element found "+element.getClass().getName()); //$NON-NLS-1$ ProductTypeGroupNode node = (ProductTypeGroupNode)element; if (node.getType() == ProductTypeGroupNode.NODE_TYPE_GROUP) { if (columnIndex == 0) { ProductTypeGroup group = ((ProductTypeGroup) node.getNodeObject()); // ProductTypeGroup group = ProductTypeGroupDAO.sharedInstance().getProductTypeGroup( // (ProductTypeGroupID)node.getNodeObject(), // FETCH_GROUPS_PRODUCT_TYPE_GROUP, // NLJDOHelper.MAX_FETCH_DEPTH_NO_LIMIT, // new NullProgressMonitor() // ); return group.getName().getText(NLLocale.getDefault().getLanguage()); } return ""; //$NON-NLS-1$ } else { ProductType productType = (ProductType) node.getNodeObject(); // ProductType productType = ProductTypeDAO.sharedInstance().getProductType( // (ProductTypeID)node.getNodeObject(), // FETCH_GROUPS_PRODUCT_TYPE, // NLJDOHelper.MAX_FETCH_DEPTH_NO_LIMIT, // new NullProgressMonitor() // ); switch (columnIndex) { case 0: return productType.getName().getText(); } return ""; //$NON-NLS-1$ } } } /** * Node object for {@link AbstractProductTypeGroupTree} * @author Daniel Mazurek - daniel [at] nightlabs [dot] de */ // public class ProductTypeGroupNode public static class ProductTypeGroupNode { public static final int NODE_TYPE_GROUP = 1; public static final int NODE_TYPE_SINGLE = 2; private int type; private ProductTypeGroup productTypeGroup; private ProductType productType; private ProductTypeGroupNode parent; private Object[] children; public ProductTypeGroupNode(ProductTypeGroupSearchResult.Entry entry) { if (entry.getProductTypes().size() > 1) { this.productType = null; this.productTypeGroup = entry.getProductTypeGroup(); this.type = NODE_TYPE_GROUP; List<ProductTypeGroupNode> c = new LinkedList<ProductTypeGroupNode>(); for (Iterator<ProductType> iter = entry.getProductTypes().iterator(); iter.hasNext();) { ProductType pType = iter.next(); ProductTypeGroupNode node = new ProductTypeGroupNode(pType); node.setParent(this); c.add(node); } children = c.toArray(); } else { if (entry.getProductTypes().size() <= 0) { this.productType = null; this.productTypeGroup = entry.getProductTypeGroup(); this.type = NODE_TYPE_GROUP; return; } this.productType = (ProductType)entry.getProductTypes().toArray()[0]; this.productTypeGroup = null; this.type = NODE_TYPE_SINGLE; } } public ProductTypeGroupNode(ProductType productType) { this.productType = productType; this.productTypeGroup = null; this.type = NODE_TYPE_SINGLE; } public ProductType getProductType() { return productType; } public boolean hasChildren() { return (type != NODE_TYPE_SINGLE) && ((children == null) ? false: children.length > 0 ); } public Object[] getChildren() { return children; } public ProductTypeGroupNode getParent() { return parent; } public void setParent(ProductTypeGroupNode parent) { this.parent = parent; } public Object getNodeObject() { if (type == NODE_TYPE_GROUP) return productTypeGroup; else return productType; } public int getType() { return type; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((productTypeGroup == null) ? 0 : productTypeGroup.hashCode()); result = prime * result + ((productType == null) ? 0 : productType.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; final ProductTypeGroupNode other = (ProductTypeGroupNode) obj; if (productTypeGroup == null) { if (other.productTypeGroup != null) return false; } else if (!productTypeGroup.equals(other.productTypeGroup)) return false; if (productType == null) { if (other.productType != null) return false; } else if (!productType.equals(other.productType)) return false; return true; } } private ContentProvider contentProvider; /** * @param parent the parent composite */ public AbstractProductTypeGroupTree(Composite parent) { this(parent, AbstractTreeComposite.DEFAULT_STYLE_SINGLE); } /** * @param parent the parent composite * @param style the SWT style flag */ public AbstractProductTypeGroupTree(Composite parent, int style) { super(parent, style, true, true, true); } /* (non-Javadoc) * @see org.nightlabs.base.ui.tree.AbstractTreeComposite#createTreeColumns(org.eclipse.swt.widgets.Tree) */ @Override public void createTreeColumns(Tree tree) { TreeColumn col = new TreeColumn(tree, SWT.LEFT); col.setText(Messages.getString("org.nightlabs.jfire.trade.ui.producttype.quicklist.AbstractProductTypeGroupTree.column.name")); //$NON-NLS-1$ TableLayout tableLayout = new TableLayout(); tableLayout.addColumnData(new ColumnWeightData(1)); tree.setLayout(tableLayout); } /* (non-Javadoc) * @see org.nightlabs.base.ui.tree.AbstractTreeComposite#setTreeProvider(org.eclipse.jface.viewers.TreeViewer) */ @Override public void setTreeProvider(TreeViewer treeViewer) { contentProvider = new ContentProvider(); treeViewer.setContentProvider(contentProvider); treeViewer.setLabelProvider(new LabelProvider()); treeViewer.setComparator(new ViewerSorter(Collator.getInstance(NLLocale.getDefault()))); } @Override public boolean canHandleSelection(ISelection selection) { SelectionContainment selectionContainment = SelectionUtil.getSelectionContainment(selection); Set<ProductTypeGroupID> productTypeGroupsIDs = selectionContainment.getProductTypeGroupIDs(); Set<ProductTypeID> productTypeIDs = selectionContainment.getProductTypeIDs(); if (!selectionContainment.isEmpty()) { if (contentProvider != null && getSearchResult() != null) { // first check for contained productTypeGroupIDs for (ProductTypeGroupID productTypeGroupID : productTypeGroupsIDs) { Entry entry = getSearchResult().getEntry(productTypeGroupID); if (entry != null) { return true; } } // if nothing found yet, check for contained productTypeIDs in the productTypeGroups Collection<ProductTypeID> searchResultProductTypeIDs = getSearchResult().getAllProductTypeIDs(); for (ProductTypeID pTypeID : productTypeIDs) { if (searchResultProductTypeIDs.contains(pTypeID)) { return true; } } } } return false; } @Override public void setSelection(ISelection selection) { SelectionContainment selectionContainment = SelectionUtil.getSelectionContainment(selection); if (!selectionContainment.isEmpty()) { Set<ProductTypeGroupID> productTypeGroupsIDs = selectionContainment.getProductTypeGroupIDs(); Set<ProductTypeID> productTypeIDs = selectionContainment.getProductTypeIDs(); List<ProductTypeGroupNode> selectedNodes = new ArrayList<ProductTypeGroupNode>(); // first create nodes for productTypeGroupIDs for (ProductTypeGroupID productTypeGroupID : productTypeGroupsIDs) { Entry entry = getSearchResult().getEntry(productTypeGroupID); selectedNodes.add(new ProductTypeGroupNode(entry)); } // then create nodes for productTypeIDs for (ProductTypeID productTypeID : productTypeIDs) { ProductType productType = getSearchResult().getProductType(productTypeID); selectedNodes.add(new ProductTypeGroupNode(productType)); } // TODO: ARRGH, reveal does not work for trees super.setSelection(selectedNodes, true); } else { super.setSelection(selection); } } // TODO: maybe this should not come from the contentProvider protected ProductTypeGroupSearchResult getSearchResult() { return contentProvider.getSearchResult(); } public void setLoadingMessage(String message) { if (getTreeViewer().getContentProvider() != null) setInput(new String[] {message}); } }