net.sourceforge.eclipsetrader.trading.portfolio.PortfolioView.java Source code

Java tutorial

Introduction

Here is the source code for net.sourceforge.eclipsetrader.trading.portfolio.PortfolioView.java

Source

/*
 * Copyright (c) 2004-2007 Marco Maccaferri and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Marco Maccaferri - initial API and implementation
 */

package net.sourceforge.eclipsetrader.trading.portfolio;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import net.sourceforge.eclipsetrader.core.db.Account;
import net.sourceforge.eclipsetrader.core.db.PortfolioPosition;
import net.sourceforge.eclipsetrader.core.db.Security;
import net.sourceforge.eclipsetrader.core.transfers.SecurityTransfer;
import net.sourceforge.eclipsetrader.core.ui.AccountGroupSelection;
import net.sourceforge.eclipsetrader.core.ui.AccountSelection;
import net.sourceforge.eclipsetrader.core.ui.NullSelection;
import net.sourceforge.eclipsetrader.core.ui.PortfolioPositionSelection;
import net.sourceforge.eclipsetrader.core.ui.SelectionProvider;
import net.sourceforge.eclipsetrader.trading.TradingPlugin;
import net.sourceforge.eclipsetrader.trading.dialogs.TransactionDialog;
import net.sourceforge.eclipsetrader.trading.internal.ClosePositionAction;
import net.sourceforge.eclipsetrader.trading.internal.TransactionAction;

import org.apache.commons.logging.LogFactory;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.preference.PreferenceStore;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeViewerListener;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TreeExpansionEvent;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTException;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DropTargetAdapter;
import org.eclipse.swt.dnd.DropTargetEvent;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.part.ViewPart;

public class PortfolioView extends ViewPart {
    public static final String VIEW_ID = "net.sourceforge.eclipsetrader.views.portfolio";
    public static final String PREFS_COLUMN_SIZE = "COLUMN_SIZE";
    public static final String PREFS_EXPANDED_GROUPS = "EXPANDED_GROUPS";
    public static final String PREFS_EXPANDED_ACCOUNTS = "EXPANDED_ACCOUNTS";
    PreferenceStore preferences;
    Set expandedGroups = new HashSet();
    Set expandedAccounts = new HashSet();
    Tree tree;
    TreeViewer viewer;
    Color negativeForeground = new Color(null, 240, 0, 0);
    Color positiveForeground = new Color(null, 0, 192, 0);
    Font boldFont;
    Action closePositionAction = new ClosePositionAction(this);
    Action newTransactionAction = new TransactionAction(this);
    SelectionProvider selectionProvider = new SelectionProvider();
    ControlListener columnControlListener = new ControlAdapter() {
        public void controlResized(ControlEvent e) {
            StringBuffer sizes = new StringBuffer();
            for (int i = 0; i < tree.getColumnCount(); i++)
                sizes.append(String.valueOf(tree.getColumn(i).getWidth()) + ";");
            preferences.setValue(PREFS_COLUMN_SIZE, sizes.toString());
        }
    };
    Job updateJob = new Job("Portfolio Build") {
        protected IStatus run(IProgressMonitor monitor) {
            final PortfolioInput input = new PortfolioInput();
            try {
                tree.getDisplay().asyncExec(new Runnable() {
                    public void run() {
                        if (!tree.isDisposed()) {
                            viewer.setInput(input);
                            restoreExpandedStatus();
                            updateSelection();
                        }
                    }
                });
            } catch (SWTException e) {
                if (e.code != SWT.ERROR_WIDGET_DISPOSED)
                    throw e;
            }
            return Status.OK_STATUS;
        }
    };
    DropTargetAdapter dropTargetListener = new DropTargetAdapter() {
        public void dragEnter(DropTargetEvent event) {
            event.detail = DND.DROP_COPY;
        }

        public void drop(DropTargetEvent event) {
            event.detail = DND.DROP_COPY;

            Account account = null;
            if (event.item instanceof TreeItem) {
                Object node = event.item.getData();
                if (node instanceof PositionTreeNode)
                    account = ((PositionTreeNode) node).getParent().value;
                if (node instanceof AccountTreeNode)
                    account = ((AccountTreeNode) node).value;
            }

            if (account != null && SecurityTransfer.getInstance().isSupportedType(event.currentDataType)) {
                Security[] securities = (Security[]) event.data;
                for (int i = 0; i < securities.length; i++) {
                    TransactionDialog dlg = new TransactionDialog(account, getViewSite().getShell());
                    dlg.open(securities[i]);
                }
            }
        }
    };

    public PortfolioView() {
    }

    /* (non-Javadoc)
     * @see org.eclipse.ui.part.ViewPart#init(org.eclipse.ui.IViewSite)
     */
    public void init(IViewSite site) throws PartInitException {
        preferences = new PreferenceStore(
                TradingPlugin.getDefault().getStateLocation().append("portfolio.prefs").toOSString());
        try {
            preferences.load();
        } catch (Exception e) {
        }

        IMenuManager menuManager = site.getActionBars().getMenuManager();
        menuManager.add(new Separator("top")); //$NON-NLS-1$
        menuManager.add(closePositionAction);
        menuManager.add(newTransactionAction);
        menuManager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
        menuManager.add(new Separator("bottom")); //$NON-NLS-1$

        site.getActionBars().updateActionBars();
        site.setSelectionProvider(selectionProvider);

        super.init(site);
    }

    /* (non-Javadoc)
     * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
     */
    public void createPartControl(Composite parent) {
        tree = new Tree(parent, SWT.FULL_SELECTION | SWT.MULTI);
        tree.setHeaderVisible(true);
        tree.setLinesVisible(false);
        TreeColumn column = new TreeColumn(tree, SWT.NONE);
        column.addControlListener(columnControlListener);
        column = new TreeColumn(tree, SWT.RIGHT);
        column.setText("Position");
        column.addControlListener(columnControlListener);
        column = new TreeColumn(tree, SWT.RIGHT);
        column.setText("Price");
        column.addControlListener(columnControlListener);
        column = new TreeColumn(tree, SWT.RIGHT);
        column.setText("Last");
        column.addControlListener(columnControlListener);
        column = new TreeColumn(tree, SWT.RIGHT);
        column.setText("Value");
        column.addControlListener(columnControlListener);
        column = new TreeColumn(tree, SWT.RIGHT);
        column.setText("Gain / Loss");
        column.addControlListener(columnControlListener);

        FontData fd = tree.getFont().getFontData()[0];
        boldFont = new Font(null, fd.getName(), fd.getHeight(), SWT.BOLD);

        viewer = new TreeViewer(tree);
        viewer.setUseHashlookup(true);
        viewer.setContentProvider(new PortfolioContentProvider());
        PortfolioLabelProvider labelProvider = new PortfolioLabelProvider();
        labelProvider.boldFont = boldFont;
        labelProvider.negativeForeground = negativeForeground;
        labelProvider.positiveForeground = positiveForeground;
        viewer.setLabelProvider(labelProvider);
        viewer.addSelectionChangedListener(new ISelectionChangedListener() {
            public void selectionChanged(SelectionChangedEvent event) {
                updateSelection();
            }
        });
        viewer.addTreeListener(new ITreeViewerListener() {

            public void treeCollapsed(TreeExpansionEvent event) {
                Object element = event.getElement();
                if (element instanceof AccountGroupTreeNode)
                    expandedGroups.remove(((AccountGroupTreeNode) element).value.getId());
                if (element instanceof AccountTreeNode)
                    expandedAccounts.remove(((AccountTreeNode) element).value.getId());
                saveExpandedStatus();
            }

            public void treeExpanded(TreeExpansionEvent event) {
                Object element = event.getElement();
                if (element instanceof AccountGroupTreeNode)
                    expandedGroups.add(((AccountGroupTreeNode) element).value.getId());
                if (element instanceof AccountTreeNode)
                    expandedAccounts.add(((AccountTreeNode) element).value.getId());
                saveExpandedStatus();
            }
        });
        viewer.addDropSupport(DND.DROP_COPY, new Transfer[] { SecurityTransfer.getInstance() }, dropTargetListener);

        MenuManager menuMgr = new MenuManager("#popupMenu", "popupMenu"); //$NON-NLS-1$ //$NON-NLS-2$
        menuMgr.setRemoveAllWhenShown(true);
        menuMgr.addMenuListener(new IMenuListener() {
            public void menuAboutToShow(IMenuManager menuManager) {
                menuManager.add(new Separator("top")); //$NON-NLS-1$
                menuManager.add(closePositionAction);
                menuManager.add(newTransactionAction);
                menuManager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
                menuManager.add(new Separator("bottom")); //$NON-NLS-1$
            }
        });
        tree.setMenu(menuMgr.createContextMenu(tree));
        getSite().registerContextMenu(menuMgr, getSite().getSelectionProvider());

        String[] sizes = preferences.getString(PREFS_COLUMN_SIZE).split(";");
        for (int i = 0; i < tree.getColumnCount(); i++) {
            if (i < sizes.length && sizes[i].length() != 0)
                tree.getColumn(i).setWidth(Integer.parseInt(sizes[i]));
            else
                tree.getColumn(i).setWidth(i == 0 ? 100 : 75);
        }
        if ("gtk".equals(SWT.getPlatform()))
            tree.getColumn(tree.getColumnCount() - 1).pack();

        updateJob.setUser(false);
        updateJob.schedule();

    }

    /* (non-Javadoc)
     * @see org.eclipse.ui.part.WorkbenchPart#setFocus()
     */
    public void setFocus() {
        tree.setFocus();
    }

    /* (non-Javadoc)
     * @see org.eclipse.ui.part.WorkbenchPart#dispose()
     */
    public void dispose() {
        boldFont.dispose();

        try {
            preferences.save();
        } catch (Exception e) {
            LogFactory.getLog(getClass()).warn(e);
        }

        super.dispose();
    }

    void updateSelection() {
        IStructuredSelection selection = (IStructuredSelection) viewer.getSelection();
        if (selection != null && !selection.isEmpty()) {
            Object obj = selection.getFirstElement();
            if (obj instanceof AccountTreeNode)
                selectionProvider.setSelection(new AccountSelection(((AccountTreeNode) obj).value));
            else if (obj instanceof AccountGroupTreeNode)
                selectionProvider.setSelection(new AccountGroupSelection(((AccountGroupTreeNode) obj).value));
            else if (obj instanceof PositionTreeNode) {
                Account account = ((PositionTreeNode) obj).parent.value;
                PortfolioPosition position = ((PositionTreeNode) obj).value;
                selectionProvider.setSelection(new PortfolioPositionSelection(account, position));
            } else
                selectionProvider.setSelection(new NullSelection());

            closePositionAction.setEnabled(obj instanceof PositionTreeNode);
            newTransactionAction.setEnabled((obj instanceof AccountTreeNode) || (obj instanceof PositionTreeNode));
        } else {
            selectionProvider.setSelection(new NullSelection());
            closePositionAction.setEnabled(false);
            newTransactionAction.setEnabled(false);
        }
    }

    void saveExpandedStatus() {
        StringBuffer sb = new StringBuffer();
        for (Iterator iter = expandedGroups.iterator(); iter.hasNext();) {
            if (sb.length() != 0)
                sb.append(";");
            sb.append(String.valueOf(iter.next()));
        }
        preferences.setValue(PREFS_EXPANDED_GROUPS, sb.toString());

        sb = new StringBuffer();
        for (Iterator iter = expandedAccounts.iterator(); iter.hasNext();) {
            if (sb.length() != 0)
                sb.append(";");
            sb.append(String.valueOf(iter.next()));
        }
        preferences.setValue(PREFS_EXPANDED_ACCOUNTS, sb.toString());
    }

    void restoreExpandedStatus() {
        PortfolioInput input = (PortfolioInput) viewer.getInput();

        String[] values = preferences.getString(PREFS_EXPANDED_GROUPS).split(";");
        for (int i = 0; i < values.length; i++) {
            try {
                Integer id = new Integer(values[i]);
                Object element = input.getAccountGroupNode(id);
                if (element != null) {
                    expandedGroups.add(id);
                    viewer.setExpandedState(element, true);
                }
            } catch (Exception e) {
            }
        }

        values = preferences.getString(PREFS_EXPANDED_ACCOUNTS).split(";");
        for (int i = 0; i < values.length; i++) {
            try {
                Integer id = new Integer(values[i]);
                Object element = input.getAccountNode(id);
                if (element != null) {
                    expandedAccounts.add(id);
                    viewer.setExpandedState(element, true);
                }
            } catch (Exception e) {
            }
        }
    }
}