net.sf.smbt.ui.btc.views.MTGoxView.java Source code

Java tutorial

Introduction

Here is the source code for net.sf.smbt.ui.btc.views.MTGoxView.java

Source

/***********************************************************************************
 * Ubiquisense - A smart ambient utilities framework 
 * 
 * Copyright (c) 2013, Lucas Bigeardel
 * 
 * The library is released under:
 * 
 * A) LGPL
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General
 * Public License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301 USA
 * 
 * B) EPL
 * 
 * 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:
 *     Lucas Bigeardel <lucas.bigeardel@gmail.com> - Initial API and implementation
 ***********************************************************************************/

package net.sf.smbt.ui.btc.views;

import net.sf.smbt.btc.BtcCurrency;
import net.sf.smbt.btc.mtgox.MTGoxCmd;
import net.sf.smbt.btc.mtgox.MTGoxController;
import net.sf.smbt.btc.mtgox.MTGoxUtils;
import net.sf.smbt.btc.mtgox.Order;
import net.sf.smbt.btc.mtgox.Wallet;
import net.sf.smbt.btc.mtgox.WalletRecord;
import net.sf.smbt.fmodex.core.AudioUtils;
import net.sf.smbt.fmodex.core.SystemSound;
import net.sf.smbt.quantic.warp.QuanticMojo;
import net.sf.smbt.ui.btc.Activator;
import net.sf.smbt.ui.btc.prefs.MtGoxWalletPreferenceConstants;
import net.sf.smbt.ui.hmi.GUIToolkit;
import net.sf.smbt.ui.hmi.UbiJob;
import net.sf.xqz.model.engine.EVENT_KIND;
import net.sf.xqz.model.engine.impl.AbstractQxEventHandlerImpl;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.draw2d.ColorConstants;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
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.dialogs.MessageDialog;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ColumnViewerEditor;
import org.eclipse.jface.viewers.ColumnViewerEditorActivationEvent;
import org.eclipse.jface.viewers.ColumnViewerEditorActivationStrategy;
import org.eclipse.jface.viewers.ComboViewer;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.FocusCellOwnerDrawHighlighter;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.StyledCellLabelProvider;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.TreeViewerColumn;
import org.eclipse.jface.viewers.TreeViewerEditor;
import org.eclipse.jface.viewers.TreeViewerFocusCellManager;
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.mylyn.commons.ui.dialogs.AbstractNotificationPopup;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.part.ViewPart;

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;

public class MTGoxView extends ViewPart {
    private Color lightBlue = new Color(Display.getDefault(), new RGB(0, 191, 255));
    private Font medFont = new Font(Display.getDefault(), "tahoma", 12, SWT.NORMAL);

    private TreeViewer transactionTreeViewer, hitoryTreeViewer;
    private ComboViewer currencyComboViewer;
    private RefreshJob refreshJob;
    private MTGoxController mtgoxController;
    private Image alarmIcon = Activator.imageDescriptorFromPlugin(Activator.PLUGIN_ID, "icons/alarm.png")
            .createImage();
    private Action cancelOrderAction;
    private Label wallInfoLabel;

    public MTGoxView() {
        String apiKey = Activator.getDefault().getPreferenceStore()
                .getString(MtGoxWalletPreferenceConstants.P_MTGOX_API_KEY);
        String secretKey = Activator.getDefault().getPreferenceStore()
                .getString(MtGoxWalletPreferenceConstants.P_MTGOX_SECRET_KEY);

        if (apiKey == null || secretKey == null || "".equals(apiKey) || "".equals(secretKey)) {
            MessageDialog.openInformation(Display.getDefault().getActiveShell(), "BitMinter Key Information",
                    "BitMinter Authentication Key is missing in preferences. \nPlease grab a key from BitMinter.com and update the eclipse preferences page accordingly.");
        }

        mtgoxController = MTGoxUtils.INSTANCE.getMTGoxControl(apiKey, secretKey);

        if (mtgoxController != null) {
            mtgoxController.getMtgoxPipe().addQxEventHandler(new AbstractQxEventHandlerImpl() {
                public synchronized void handleQxEvent(net.sf.xqz.model.engine.Event event) {
                    if (event.getKind().equals(EVENT_KIND.RX_DONE)) {
                        if (event.getCmd() instanceof MTGoxCmd) {
                            MTGoxCmd cmd = (MTGoxCmd) event.getCmd();
                            String jsonRcv = cmd.getJsonRcv();
                            JsonElement o = MTGoxUtils.INSTANCE.loadDataFromJson(jsonRcv);
                            if (o instanceof JsonObject) {
                                try {
                                    String mtgoxTag = o.getAsJsonObject().get("mtgox").getAsString();
                                    if (mtgoxTag != null) {
                                        if (mtgoxTag.endsWith("/private/order/cancel")
                                                || mtgoxTag.endsWith("/private/order/add")) {
                                            JsonObject json = (JsonObject) o;
                                            refreshJob.cancel();
                                            refreshJob.schedule();
                                            notifyOrderStatus(json);
                                        }
                                    }
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                            }
                        }
                    }
                };
            });
        }

        Activator.getDefault().getPreferenceStore().addPropertyChangeListener(new IPropertyChangeListener() {
            @Override
            public void propertyChange(org.eclipse.jface.util.PropertyChangeEvent event) {
                if (event.getProperty().equals(MtGoxWalletPreferenceConstants.P_MTGOX_API_KEY)) {
                    refreshJob.cancel();
                    refreshJob.schedule();
                } else if (event.getProperty().equals(MtGoxWalletPreferenceConstants.P_MTGOX_SECRET_KEY)) {
                    refreshJob.cancel();
                    refreshJob.schedule();
                }
            }
        });

        refreshJob = new RefreshJob();
        mtgoxController.getMoneyOrders(BtcCurrency.BTC, mtgoxController.getMTGox().getMarket().getCurrency());
        mtgoxController.getWalletHistory(mtgoxController.getMTGox().getMarket().getCurrency());
    }

    private void notifyOrderStatus(JsonObject o) {
        final JsonObject json = o;
        final AbstractNotificationPopup notification = new AbstractNotificationPopup(Display.getDefault()) {
            @Override
            protected void createContentArea(Composite composite) {
                composite.setLayout(new GridLayout(1, true));
                Label label = new Label(composite, SWT.NONE);
                String tag = json.getAsJsonObject().get("mtgox").getAsString();
                if (tag.endsWith("/cancel")) {
                    JsonObject returnv = (JsonObject) json.getAsJsonObject().get("return");
                    String oid = returnv.get("oid").getAsString();
                    String success = json.getAsJsonObject().get("result").getAsString();

                    label.setText("Cancelling " + oid + " : " + success);
                } else if (tag.endsWith("/add")) {
                    String qid = json.getAsJsonObject().get("return").getAsString();
                    String success = json.getAsJsonObject().get("result").getAsString();

                    label.setText("Adding " + qid + " : " + success);
                }
            }

            @Override
            protected String getPopupShellTitle() {
                return "MtGOX Order Status";
            }

            @Override
            protected Image getPopupShellImage(int maximumHeight) {
                return alarmIcon;
            }
        };
        Runnable runnable = new Runnable() {
            public void run() {
                refreshJob.cancel();
                refreshJob.schedule(50);
                notification.open();
            }
        };
        Display.getDefault().syncExec(runnable);
    }

    class RefreshJob extends UbiJob {
        public RefreshJob() {
            super("MtGox View Refresh Job");
        }

        @Override
        public IStatus runInUIThread(IProgressMonitor monitor) {
            String apiKey = Activator.getDefault().getPreferenceStore()
                    .getString(MtGoxWalletPreferenceConstants.P_MTGOX_API_KEY);
            String secretKey = Activator.getDefault().getPreferenceStore()
                    .getString(MtGoxWalletPreferenceConstants.P_MTGOX_SECRET_KEY);
            mtgoxController = MTGoxUtils.INSTANCE.getMTGoxControl(apiKey, secretKey);

            if (mtgoxController != null) {
                if (mtgoxController.getMTGox().getWallet() != null) {
                    Wallet wallet = mtgoxController.getMTGox().getWallet();
                    if (wallInfoLabel != null && wallet.getBtcInfo() != null && wallet.getEurInfo() != null) {
                        wallInfoLabel.setText("Balance : " + wallet.getBtcInfo().getBalance().getDisplay() + " / "
                                + wallet.getEurInfo().getBalance().getDisplay() + " (" + wallet.getTradeFee()
                                + "% fee)");
                    }
                    mtgoxController.getMoneyOrders(BtcCurrency.BTC,
                            mtgoxController.getMTGox().getMarket().getCurrency());
                    mtgoxController.getWalletHistory(BtcCurrency.BTC);

                    transactionTreeViewer.setInput(mtgoxController.getMTGox());
                    hitoryTreeViewer.setInput(mtgoxController.getMTGox());

                    transactionTreeViewer.refresh();
                    hitoryTreeViewer.refresh();
                }
            }
            schedule(1500);
            return Status.OK_STATUS;
        }
    }

    @Override
    public void createPartControl(Composite parent) {
        Composite container = GUIToolkit.INSTANCE.createComposite(parent);
        container.setBackground(GUIToolkit.BG);
        container.setForeground(GUIToolkit.FG);
        container.setLayout(GridLayoutFactory.fillDefaults().numColumns(2).create());
        container.setLayoutData(GridDataFactory.fillDefaults().create());

        currencyComboViewer = new ComboViewer(container);
        currencyComboViewer.setContentProvider(new ArrayContentProvider());
        currencyComboViewer.setLabelProvider(new LabelProvider());
        currencyComboViewer.setInput(BtcCurrency.VALUES);
        currencyComboViewer.setSelection(new StructuredSelection(BtcCurrency.EUR));
        currencyComboViewer.addSelectionChangedListener(new ISelectionChangedListener() {
            @Override
            public void selectionChanged(SelectionChangedEvent event) {
                ISelection s = event.getSelection();
                if (s instanceof StructuredSelection) {
                    BtcCurrency currency = (BtcCurrency) ((StructuredSelection) s).getFirstElement();
                    mtgoxController.getMTGox().getMarket().setCurrency(currency);
                    mtgoxController.getMTGox().getTrend().clear();
                }
            }
        });
        currencyComboViewer.getCombo().setEnabled(false);

        wallInfoLabel = new Label(container, SWT.NONE);
        wallInfoLabel.setLayoutData(GridDataFactory.fillDefaults().create());
        wallInfoLabel.setFont(medFont);
        wallInfoLabel.setForeground(lightBlue);

        wallInfoLabel.setText("Balance : " + "???" + " (0.6% fee)");

        SashForm sash = new SashForm(container, SWT.BORDER | SWT.VERTICAL);
        sash.setLayout(GridLayoutFactory.fillDefaults().create());
        sash.setLayoutData(GridDataFactory.fillDefaults().span(2, 1).grab(true, true).create());
        sash.setBackground(GUIToolkit.FG);

        transactionTreeViewer = new TreeViewer(sash);

        transactionTreeViewer.getControl().setLayoutData(GridDataFactory.fillDefaults().grab(true, true).create());
        transactionTreeViewer.getControl().setFont(medFont);
        transactionTreeViewer.getControl().setBackground(ColorConstants.darkGray);
        transactionTreeViewer.getControl().setForeground(ColorConstants.lightBlue);

        transactionTreeViewer
                .setLabelProvider(new AdapterFactoryLabelProvider(new MTGoxCompseableAdapterFactory()) {
                    @Override
                    public String getText(Object object) {
                        return super.getText(object);
                    }
                });
        transactionTreeViewer.setContentProvider(new WalletOrdersContentProvider());
        transactionTreeViewer.getTree().setHeaderVisible(true);
        transactionTreeViewer.getTree().setLinesVisible(true);

        transactionTreeViewer.setInput(mtgoxController.getMTGox());

        createTableViewerColumn("Order", 100);
        createTableViewerColumn("type", 100);
        createTableViewerColumn("BTC", 100);
        createTableViewerColumn("Value", 100);
        createTableViewerColumn("Status", 100);
        createTableViewerColumn("Date", 100);

        TreeViewerFocusCellManager focusCellManager = new TreeViewerFocusCellManager(transactionTreeViewer,
                new FocusCellOwnerDrawHighlighter(transactionTreeViewer) {
                    @Override
                    public ViewerCell getFocusCell() {
                        ViewerCell cell = super.getFocusCell();
                        //handleClipDetails(cell.getElement(), cell.getColumnIndex());
                        return cell;
                    }
                });

        ColumnViewerEditorActivationStrategy actSupport = new ColumnViewerEditorActivationStrategy(
                transactionTreeViewer) {
            protected boolean isEditorActivationEvent(ColumnViewerEditorActivationEvent event) {
                return false;
            }
        };

        TreeViewerEditor.create(transactionTreeViewer, focusCellManager, actSupport,
                ColumnViewerEditor.KEYBOARD_ACTIVATION);

        cancelOrderAction = new Action("Cancel Order",
                Activator.imageDescriptorFromPlugin(Activator.PLUGIN_ID, "icons/cancel.png")) {
            public void run() {
                ISelection sel = transactionTreeViewer.getSelection();
                for (Object o : ((IStructuredSelection) sel).toArray()) {
                    if (o instanceof Order) {
                        Order order = (Order) o;
                        String oid = order.getOid();
                        if (mtgoxController != null) {
                            mtgoxController.cancelOrder(BtcCurrency.BTC, mtgoxController.getMTGox().getCurrency(),
                                    oid);
                            refreshJob.schedule(250);
                        }
                    }
                }
            };
        };

        hookContextMenu();

        hitoryTreeViewer = new TreeViewer(sash);

        hitoryTreeViewer.getControl().setLayoutData(GridDataFactory.fillDefaults().grab(true, true).create());
        hitoryTreeViewer.getControl().setFont(medFont);
        hitoryTreeViewer.getControl().setBackground(ColorConstants.darkGray);
        hitoryTreeViewer.getControl().setForeground(ColorConstants.lightBlue);

        hitoryTreeViewer.setLabelProvider(new AdapterFactoryLabelProvider(new MTGoxCompseableAdapterFactory()) {
            @Override
            public String getText(Object object) {
                return super.getText(object);
            }
        });
        hitoryTreeViewer.setContentProvider(new WalletHistoryContentProvider());
        hitoryTreeViewer.getTree().setHeaderVisible(true);
        hitoryTreeViewer.getTree().setLinesVisible(true);

        hitoryTreeViewer.setInput(mtgoxController.getMTGox());

        createHistoryTableViewerColumn("Index", 100);
        createHistoryTableViewerColumn("Info", 100);
        createHistoryTableViewerColumn("type", 100);
        createHistoryTableViewerColumn("Balance", 100);
        createHistoryTableViewerColumn("Date", 100);
        createHistoryTableViewerColumn("Value", 100);

        sash.setWeights(new int[] { 50, 50 });

        init();
    }

    private void fillContextMenu(IMenuManager manager) {
        ISelection sel = transactionTreeViewer.getSelection();
        if (sel instanceof IStructuredSelection) {
            cancelOrderAction.setEnabled(true);
            manager.add(cancelOrderAction);

            // drillDownAdapter.addNavigationActions(manager);
            // Other plug-ins can contribute there actions here
            manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
        }
    }

    private void hookContextMenu() {
        MenuManager menuMgr = new MenuManager("#PopupMenu");
        menuMgr.setRemoveAllWhenShown(true);
        menuMgr.addMenuListener(new IMenuListener() {
            public void menuAboutToShow(IMenuManager manager) {
                fillContextMenu(manager);
            }
        });
        Menu menu = menuMgr.createContextMenu(transactionTreeViewer.getControl());
        transactionTreeViewer.getControl().setMenu(menu);
        transactionTreeViewer.addSelectionChangedListener(new ISelectionChangedListener() {
            @Override
            public void selectionChanged(SelectionChangedEvent event) {
                ISelection sel = event.getSelection();
                if (sel instanceof IStructuredSelection) {
                    cancelOrderAction.setEnabled(true);
                }
            }
        });
        transactionTreeViewer.setSelection(new StructuredSelection());
        transactionTreeViewer.addDoubleClickListener(new IDoubleClickListener() {
            @Override
            public void doubleClick(DoubleClickEvent event) {
                if (event.getSelection() instanceof StructuredSelection) {
                    cancelOrderAction.run();
                    AudioUtils.INSTANCE.playSystemSound(SystemSound.BEEP_24);
                }
            }
        });
    }

    private TreeViewerColumn createHistoryTableViewerColumn(String title, int bound) {
        final TreeViewerColumn viewerColumn = new TreeViewerColumn(hitoryTreeViewer, SWT.NONE);
        final TreeColumn column = viewerColumn.getColumn();
        column.setText(title);
        column.setWidth(bound);
        column.setResizable(true);
        column.setMoveable(true);
        viewerColumn.setLabelProvider(new StyledCellLabelProvider() {
            @Override
            protected void paint(Event event, Object element) {
                super.paint(event, element);
            }

            @Override
            public void update(ViewerCell cell) {
                super.update(cell);
                if (cell.getElement() instanceof WalletRecord) {
                    WalletRecord v = (WalletRecord) cell.getElement();
                    String cellText = "???";
                    switch (cell.getColumnIndex()) {
                    case 0:
                        cellText = "" + v.getIndex();
                        break;
                    case 1:
                        cellText = "" + v.getInfo();
                        break;
                    case 2:
                        cellText = "" + v.getType();
                        break;
                    case 3:
                        cellText = "" + v.getBalance().getDisplay_short();
                        break;
                    case 4:
                        cellText = "" + v.getDate();
                        break;
                    case 5:
                        cellText = "" + v.getValue().getDisplay_short();
                        break;
                    }
                    cell.setText(cellText);
                    cell.setForeground(GUIToolkit.FG);
                    cell.setBackground(GUIToolkit.BG);
                }
            }
        });
        return viewerColumn;
    }

    private TreeViewerColumn createTableViewerColumn(String title, int bound) {
        final TreeViewerColumn viewerColumn = new TreeViewerColumn(transactionTreeViewer, SWT.NONE);
        final TreeColumn column = viewerColumn.getColumn();
        column.setText(title);
        column.setWidth(bound);
        column.setResizable(true);
        column.setMoveable(true);
        viewerColumn.setLabelProvider(new StyledCellLabelProvider() {
            @Override
            protected void paint(Event event, Object element) {
                super.paint(event, element);
            }

            @Override
            public void update(ViewerCell cell) {
                super.update(cell);
                if (cell.getElement() instanceof Order) {
                    Order v = (Order) cell.getElement();
                    String cellText = "???";
                    switch (cell.getColumnIndex()) {
                    case 0:
                        cellText = "" + v.getOid();
                        break;
                    case 1:
                        cellText = "" + v.getType();
                        break;
                    case 2:
                        cellText = "" + v.getAmount().getDisplay_short();
                        break;
                    case 3:
                        cellText = "" + v.getPrice().getDisplay_short();
                        break;
                    case 4:
                        cellText = "" + v.getStatus();
                        break;
                    case 5:
                        cellText = "" + v.getDate();
                        break;
                    }
                    cell.setText(cellText);
                    cell.setForeground(GUIToolkit.FG);
                    cell.setBackground(GUIToolkit.BG);
                }
            }
        });
        return viewerColumn;
    }

    private void init() {
        refreshJob.schedule();
    }

    @Override
    public void setFocus() {
    }

    @Override
    public void dispose() {
        if (mtgoxController != null) {
            if (mtgoxController.getMtgoxPipe() != null) {
                QuanticMojo.INSTANCE.closePipe(mtgoxController.getMtgoxPipe(), true);
            }
        }
        super.dispose();
    }
}