/* * Copyright (c) 2004-2011 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 org.eclipsetrader.ui.internal.charts.views; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.net.URI; import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.GroupMarker; import org.eclipse.jface.action.IMenuListener; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.IToolBarManager; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.action.Separator; import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.viewers.IOpenListener; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.OpenEvent; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.BusyIndicator; import org.eclipse.swt.custom.StackLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.IActionBars; import org.eclipse.ui.IMemento; import org.eclipse.ui.ISaveablePart; import org.eclipse.ui.IViewSite; import org.eclipse.ui.IWorkbenchActionConstants; import org.eclipse.ui.PartInitException; import org.eclipse.ui.part.ViewPart; import org.eclipsetrader.core.feed.History; import org.eclipsetrader.core.feed.HistoryDay; import org.eclipsetrader.core.feed.IHistory; import org.eclipsetrader.core.feed.TimeSpan; import org.eclipsetrader.core.instruments.ISecurity; import org.eclipsetrader.core.repositories.IRepositoryRunnable; import org.eclipsetrader.core.repositories.IRepositoryService; import org.eclipsetrader.ui.Util; import org.eclipsetrader.ui.internal.UIActivator; import org.eclipsetrader.ui.internal.charts.DataImportJob; public class HistoryDataEditorPart extends ViewPart implements ISaveablePart { public static final String VIEW_ID = "org.eclipsetrader.ui.editors.history"; public static final String K_VIEWS = "Views"; //$NON-NLS-1$ public static final String K_URI = "uri"; //$NON-NLS-1$ private URI uri; private ISecurity security; private Composite stackContainer; private StackLayout stackLayout; private MenuManager contextMenuManager; private HistoryDataEditor editor; private final Map<Date, HistoryDataDetailEditor> editorMap = new HashMap<Date, HistoryDataDetailEditor>(); private Action updateAction; private Action editAction; private Action goIntoAction; private Action backUpAction; private IDialogSettings dialogSettings; private boolean dirty; private final PropertyChangeListener dirtyChangeListener = new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { if (!dirty) { dirty = true; firePropertyChange(PROP_DIRTY); } } }; public HistoryDataEditorPart() { } /* (non-Javadoc) * @see org.eclipse.ui.part.ViewPart#init(org.eclipse.ui.IViewSite, org.eclipse.ui.IMemento) */ @Override public void init(IViewSite site, IMemento memento) throws PartInitException { super.init(site, memento); try { dialogSettings = UIActivator.getDefault().getDialogSettings().getSection(K_VIEWS).getSection(site.getSecondaryId()); uri = new URI(dialogSettings.get(K_URI)); IRepositoryService repositoryService = UIActivator.getDefault().getRepositoryService(); security = repositoryService.getSecurityFromURI(uri); } catch (Exception e) { Status status = new Status(IStatus.ERROR, UIActivator.PLUGIN_ID, Messages.ChartViewPart_LoadingErrorMessage + site.getSecondaryId(), e); UIActivator.log(status); } createActions(); IActionBars actionBars = site.getActionBars(); IToolBarManager toolBarManager = actionBars.getToolBarManager(); toolBarManager.add(goIntoAction); toolBarManager.add(backUpAction); toolBarManager.add(new Separator("additions")); //$NON-NLS-1$ toolBarManager.add(updateAction); } protected void createActions() { updateAction = new Action(Messages.ChartViewPart_UpdateAction) { @Override public void run() { DataImportJob job = new DataImportJob(security, DataImportJob.INCREMENTAL, null, null, new TimeSpan[] { TimeSpan.days(1), TimeSpan.minutes(1), TimeSpan.minutes(2), TimeSpan.minutes(3), TimeSpan.minutes(5), TimeSpan.minutes(10), TimeSpan.minutes(15), TimeSpan.minutes(30), }); job.setUser(true); job.schedule(); } }; updateAction.setId("update"); //$NON-NLS-1$ updateAction.setImageDescriptor(UIActivator.imageDescriptorFromPlugin("icons/etool16/refresh.gif")); //$NON-NLS-1$ updateAction.setEnabled(true); editAction = new Action("Edit") { @Override public void run() { IStructuredSelection selection = (IStructuredSelection) editor.getViewer().getSelection(); if (selection.size() != 1) { return; } final Object element = selection.getFirstElement(); Display.getDefault().asyncExec(new Runnable() { @Override public void run() { if (!editor.getControl().isDisposed()) { editor.getViewer().editElement(element, 0); } } }); } }; editAction.setEnabled(true); goIntoAction = new Action("Zoom-In") { @Override public void run() { if (stackLayout.topControl == editor.getControl()) { goInto(); } } }; goIntoAction.setImageDescriptor(UIActivator.getImageDescriptor("icons/elcl16/zoom_in.png")); goIntoAction.setEnabled(false); backUpAction = new Action("Zoom-Out") { @Override public void run() { if (stackLayout.topControl != editor.getControl()) { setContentDescription(""); stackLayout.topControl = editor.getControl(); stackContainer.layout(); } goIntoAction.setEnabled(stackLayout.topControl == editor.getControl()); backUpAction.setEnabled(stackLayout.topControl != editor.getControl()); } }; backUpAction.setImageDescriptor(UIActivator.getImageDescriptor("icons/elcl16/zoom_out.png")); backUpAction.setEnabled(false); } /* (non-Javadoc) * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite) */ @Override public void createPartControl(Composite parent) { stackContainer = new Composite(parent, SWT.NONE); stackLayout = new StackLayout(); stackLayout.marginWidth = stackLayout.marginHeight = 0; stackContainer.setLayout(stackLayout); editor = new HistoryDataEditor(stackContainer); editor.addPropertyChangeListener(dirtyChangeListener); stackLayout.topControl = editor.getControl(); createContextMenu(); editor.getViewer().addSelectionChangedListener(new ISelectionChangedListener() { @Override public void selectionChanged(SelectionChangedEvent event) { goIntoAction.setEnabled(!event.getSelection().isEmpty()); } }); editor.getViewer().addOpenListener(new IOpenListener() { @Override public void open(OpenEvent event) { if (stackLayout.topControl == editor.getControl()) { goInto(); } } }); if (security != null) { setPartName(NLS.bind("{0} - {1}", new Object[] { //$NON-NLS-1$ security.getName(), "History", })); editor.load(security); } } void createContextMenu() { contextMenuManager = new MenuManager("#popupMenu", "popupMenu"); //$NON-NLS-1$ //$NON-NLS-2$ contextMenuManager.setRemoveAllWhenShown(true); contextMenuManager.addMenuListener(new IMenuListener() { @Override public void menuAboutToShow(IMenuManager menuManager) { menuManager.add(new Separator("group.new")); menuManager.add(new GroupMarker("group.goto")); menuManager.add(new Separator("group.show")); menuManager.add(new Separator("group.edit")); menuManager.add(new GroupMarker("group.reorganize")); menuManager.add(new GroupMarker("group.port")); menuManager.add(new Separator("group.generate")); menuManager.add(new Separator("group.search")); menuManager.add(new Separator("group.build")); menuManager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); menuManager.add(new Separator("group.properties")); menuManager.appendToGroup("group.goto", goIntoAction); menuManager.appendToGroup("group.goto", backUpAction); menuManager.appendToGroup("group.edit", editAction); } }); editor.getViewer().getControl().setMenu(contextMenuManager.createContextMenu(editor.getViewer().getControl())); getSite().registerContextMenu(contextMenuManager, getSite().getSelectionProvider()); } /* (non-Javadoc) * @see org.eclipse.ui.part.WorkbenchPart#setFocus() */ @Override public void setFocus() { if (stackContainer != null) { stackContainer.setFocus(); } } /* (non-Javadoc) * @see org.eclipse.ui.part.WorkbenchPart#dispose() */ @Override public void dispose() { editor.dispose(); for (HistoryDataDetailEditor treeEditor : editorMap.values()) { treeEditor.dispose(); } super.dispose(); } /* (non-Javadoc) * @see org.eclipse.ui.ISaveablePart#doSave(org.eclipse.core.runtime.IProgressMonitor) */ @Override public void doSave(IProgressMonitor monitor) { final IRepositoryService repository = UIActivator.getDefault().getRepositoryService(); repository.runInService(new IRepositoryRunnable() { @Override @SuppressWarnings("rawtypes") public IStatus run(IProgressMonitor monitor) throws Exception { for (HistoryDataDetailEditor treeEditor : editorMap.values()) { if (!treeEditor.isDirty()) { continue; } HistoryDataDetailEditorModel treeModel = treeEditor.getModel(); for (Entry<IHistory, HistoryDataEditorModel> entry : treeModel.getMap().entrySet()) { IHistory history = (IHistory) ((Entry) entry).getKey(); HistoryDataEditorModel model = (HistoryDataEditorModel) ((Entry) entry).getValue(); HistoryDay saveableHistory = (HistoryDay) history.getAdapter(HistoryDay.class); if (saveableHistory != null) { saveableHistory.setOHLC(model.toOHLC()); repository.saveAdaptable(new IAdaptable[] { history }); treeEditor.setDirty(false); } } } if (editor.isDirty()) { History history = (History) editor.getHistory().getAdapter(History.class); if (history != null) { history.setOHLC(editor.getModel().toOHLC()); repository.saveAdaptable(new IAdaptable[] { history }); } editor.setDirty(false); } return Status.OK_STATUS; } }, monitor); dirty = false; firePropertyChange(PROP_DIRTY); } /* (non-Javadoc) * @see org.eclipse.ui.ISaveablePart#doSaveAs() */ @Override public void doSaveAs() { } /* (non-Javadoc) * @see org.eclipse.ui.ISaveablePart#isDirty() */ @Override public boolean isDirty() { return dirty; } /* (non-Javadoc) * @see org.eclipse.ui.ISaveablePart#isSaveAsAllowed() */ @Override public boolean isSaveAsAllowed() { return false; } /* (non-Javadoc) * @see org.eclipse.ui.ISaveablePart#isSaveOnCloseNeeded() */ @Override public boolean isSaveOnCloseNeeded() { return dirty; } private void goInto() { IStructuredSelection selection = (IStructuredSelection) editor.getViewer().getSelection(); if (selection.size() != 1) { return; } final HistoryDataElement element = (HistoryDataElement) selection.getFirstElement(); if (element.getDate() == null) { return; } BusyIndicator.showWhile(Display.getDefault(), new Runnable() { @Override public void run() { HistoryDataDetailEditor treeEditor = editorMap.get(element.getDate()); if (treeEditor == null) { treeEditor = new HistoryDataDetailEditor(stackContainer); treeEditor.addPropertyChangeListener(dirtyChangeListener); treeEditor.getViewer().getControl().setMenu(contextMenuManager.createContextMenu(treeEditor.getViewer().getControl())); treeEditor.load(editor.getHistory(), element.getDate()); editorMap.put(element.getDate(), treeEditor); } setContentDescription(" " + Util.getDateFormat().format(element.getDate())); //$NON-NLS-1$ stackLayout.topControl = treeEditor.getControl(); stackContainer.layout(); goIntoAction.setEnabled(stackLayout.topControl == editor.getControl()); backUpAction.setEnabled(stackLayout.topControl != editor.getControl()); } }); } }