org.dawnsci.plotting.tools.InfoPixelTool.java Source code

Java tutorial

Introduction

Here is the source code for org.dawnsci.plotting.tools.InfoPixelTool.java

Source

/*
 * Copyright (c) 2012 Diamond Light Source Ltd.
 *
 * 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
 */

package org.dawnsci.plotting.tools;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.dawnsci.plotting.tools.preference.InfoPixelConstants;
import org.dawnsci.plotting.tools.preference.InfoPixelPreferencePage;
import org.dawnsci.plotting.tools.region.RegionColorListener;
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.dawnsci.analysis.api.roi.IROI;
import org.eclipse.dawnsci.analysis.dataset.roi.PointROI;
import org.eclipse.dawnsci.plotting.api.IPlottingSystem;
import org.eclipse.dawnsci.plotting.api.preferences.BasePlottingConstants;
import org.eclipse.dawnsci.plotting.api.region.IROIListener;
import org.eclipse.dawnsci.plotting.api.region.IRegion;
import org.eclipse.dawnsci.plotting.api.region.IRegion.RegionType;
import org.eclipse.dawnsci.plotting.api.region.IRegionListener;
import org.eclipse.dawnsci.plotting.api.region.MouseEvent;
import org.eclipse.dawnsci.plotting.api.region.MouseListener;
import org.eclipse.dawnsci.plotting.api.region.ROIEvent;
import org.eclipse.dawnsci.plotting.api.region.RegionEvent;
import org.eclipse.dawnsci.plotting.api.region.RegionUtils;
import org.eclipse.dawnsci.plotting.api.tool.AbstractToolPage;
import org.eclipse.dawnsci.plotting.api.trace.ITraceListener;
import org.eclipse.dawnsci.plotting.api.trace.TraceEvent;
import org.eclipse.draw2d.ColorConstants;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IContributionItem;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.preference.PreferenceDialog;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.PreferencesUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public abstract class InfoPixelTool extends AbstractToolPage
        implements IROIListener, IRegionListener, MouseListener {

    private final static Logger logger = LoggerFactory.getLogger(InfoPixelTool.class);

    private ITraceListener traceListener;
    private IRegion xHair, yHair;

    private Composite composite;
    private TableViewer viewer;
    private RegionColorListener viewUpdateListener;

    // Jobs
    private Job updateInfoPixelData;

    // Internal jobs items
    @SuppressWarnings("unused")
    private boolean isUpdateRunning = false;

    private IPropertyChangeListener propListener;

    public InfoPixelTool() {

        try {

            this.traceListener = new ITraceListener.Stub() {
                @Override
                public void tracesAdded(TraceEvent evt) {

                    if (!(evt.getSource() instanceof List<?>)) {
                        return;
                    }

                }
            };

        } catch (Exception e) {
            logger.error("Cannot get plotting system!", e);
        }

        this.propListener = new IPropertyChangeListener() {

            @Override
            public void propertyChange(PropertyChangeEvent event) {
                if (isActive()) {
                    if (isInterestedProperty(event))
                        viewer.refresh();
                }
            }

            private boolean isInterestedProperty(PropertyChangeEvent event) {
                final String propName = event.getProperty();
                return InfoPixelConstants.PIXEL_POS_FORMAT.equals(propName)
                        || InfoPixelConstants.DATA_FORMAT.equals(propName)
                        || InfoPixelConstants.Q_FORMAT.equals(propName)
                        || InfoPixelConstants.THETA_FORMAT.equals(propName)
                        || InfoPixelConstants.RESOLUTION_FORMAT.equals(propName);
            }
        };
    }

    @Override
    public void createControl(Composite parent) {

        this.composite = new Composite(parent, SWT.NONE);
        composite.setLayout(new FillLayout());

        viewer = new TableViewer(composite,
                SWT.FULL_SELECTION | SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
        createColumns(viewer);
        viewer.getTable().setLinesVisible(true);
        viewer.getTable().setHeaderVisible(true);

        createActions();

        getSite().setSelectionProvider(viewer);

        viewer.setContentProvider(new IStructuredContentProvider() {
            @Override
            public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
                // TODO Auto-generated method stub

            }

            @Override
            public void dispose() {
                // TODO Auto-generated method stub

            }

            @Override
            public Object[] getElements(Object inputElement) {
                final Collection<IRegion> regions = getPlottingSystem().getRegions();
                if (regions == null || regions.isEmpty())
                    return new Object[] { "-" };

                final List<IRegion> visible = new ArrayList<IRegion>();

                for (IRegion region : regions) {
                    if (region.getRegionType() == RegionType.XAXIS_LINE)
                        visible.add(region);
                }

                for (IRegion region : regions) {
                    if (region.getRegionType() == RegionType.POINT)
                        visible.add(region);
                }

                return visible.toArray(new IRegion[visible.size()]);
            }
        });

        viewer.setInput(new Object());

        activate();
    }

    private void createRegions() {

        if (getPlottingSystem() == null)
            return;
        try {
            if (xHair == null || getPlottingSystem().getRegion(xHair.getName()) == null) {
                this.xHair = getPlottingSystem().createRegion(
                        RegionUtils.getUniqueName("X Driver", getPlottingSystem()), IRegion.RegionType.XAXIS_LINE);
                addRegion("Updating x cross hair", xHair);

            }

            if (yHair == null || getPlottingSystem().getRegion(yHair.getName()) == null) {
                this.yHair = getPlottingSystem().createRegion(
                        RegionUtils.getUniqueName("Y Driver", getPlottingSystem()), IRegion.RegionType.YAXIS_LINE);
                addRegion("Updating y cross hair", yHair);
            }

        } catch (Exception ne) {
            logger.error("Cannot create initial regions in pixel info tool!", ne);
        }
    }

    protected IROI getXHair() {
        return xHair.getROI();
    }

    protected IROI getYHair() {
        return yHair.getROI();
    }

    private void addRegion(String jobName, IRegion region) {
        region.setVisible(false);
        region.setTrackMouse(true);
        region.setRegionColor(ColorConstants.red);
        region.setUserRegion(false); // They cannot see preferences or change it!
        getPlottingSystem().addRegion(region);
    }

    @Override
    public void setFocus() {
        if (viewer != null && !viewer.getControl().isDisposed())
            viewer.getControl().setFocus();
    }

    private boolean isListenerAdded = false;

    public void activate() {

        if (viewer != null && viewer.getControl().isDisposed())
            return;
        Activator.getPlottingPreferenceStore().addPropertyChangeListener(propListener);

        createRegions();
        if (xHair != null) {
            if (!isListenerAdded) {
                xHair.addMouseListener(this);
                isListenerAdded = true;
            }
            xHair.setVisible(true);
            xHair.addROIListener(this);
        }
        if (yHair != null) {
            yHair.setVisible(true);
            yHair.addROIListener(this);
        }

        if (getPlottingSystem() != null) {
            getPlottingSystem().addTraceListener(traceListener);
            getPlottingSystem().addRegionListener(this);
            getPlottingSystem().setDefaultCursor(IPlottingSystem.CROSS_CURSOR);
        }

        // We stop the adding of other regions because this tool does
        // not like it when other regions are added.
        setOtherRegionsEnabled(false);

        // Needed to refresh the table when activated as other tools may create points
        // which should be in the table.
        try {
            if (viewer != null) {
                viewer.getTable().clearAll();
                viewer.refresh();
            }
        } catch (Throwable ignored) {
            // Not a failure if we cannot refresh.
        }
        super.activate();

    }

    private void setOtherRegionsEnabled(boolean isVisible) {

        final IActionBars bars = getPlottingSystem().getActionBars();
        if (bars.getToolBarManager().find(BasePlottingConstants.ADD_REGION) != null) {
            bars.getToolBarManager().find(BasePlottingConstants.ADD_REGION).setVisible(isVisible);
            bars.getToolBarManager().update(true);
        }
        if (bars.getMenuManager().find(BasePlottingConstants.ADD_REGION) != null) {
            bars.getMenuManager().find(BasePlottingConstants.ADD_REGION).setVisible(isVisible);
            bars.getMenuManager().update(true);
        }
    }

    public void deactivate() {

        super.deactivate();
        Activator.getPlottingPreferenceStore().removePropertyChangeListener(propListener);
        setOtherRegionsEnabled(true);

        if (xHair != null) {
            xHair.removeMouseListener(this);
            isListenerAdded = false;
            xHair.setVisible(false);
            xHair.removeROIListener(this);
            getPlottingSystem().removeRegion(xHair);
            xHair = null;
            updateInfoPixelData = null;
        }
        if (yHair != null) {
            yHair.setVisible(false);
            yHair.removeROIListener(this);
            getPlottingSystem().removeRegion(yHair);
            yHair = null;
            getPlottingSystem().setDefaultCursor(IPlottingSystem.NORMAL_CURSOR);
        }

        try {
            if (getPlottingSystem() != null) {
                getPlottingSystem().removeTraceListener(traceListener);
                getPlottingSystem().removeRegionListener(this);
                final Collection<IRegion> regions = getPlottingSystem().getRegions();
                if (regions != null)
                    for (IRegion iRegion : regions)
                        iRegion.removeROIListener(this);
            }
        } catch (Exception e) {
            logger.error("Cannot remove region listeners!", e);
        }
    }

    public void dispose() {

        Activator.getPlottingPreferenceStore().removePropertyChangeListener(propListener);

        if (viewUpdateListener != null)
            viewer.removeSelectionChangedListener(viewUpdateListener);
        viewUpdateListener = null;

        if (viewer != null)
            viewer.getControl().dispose();

        super.dispose();
    }

    @Override
    public Control getControl() {
        return composite;
    }

    @Override
    public void mousePressed(MouseEvent evt) {

        if (evt.getButton() == 1) {// left click
            if (!isActive())
                return;

            final Collection<IRegion> regions = getPlottingSystem().getRegions();
            if (regions == null || regions.isEmpty())
                logger.debug("no region selected");

            try {
                // add a point region
                final IRegion point = getPlottingSystem()
                        .createRegion(RegionUtils.getUniqueName("Point", getPlottingSystem()), RegionType.POINT);
                final PointROI regionBounds = new PointROI();
                double x = getPlottingSystem().getSelectedXAxis().getPositionValue(evt.getX());
                double y = getPlottingSystem().getSelectedYAxis().getPositionValue(evt.getY());
                regionBounds.setPoint(new double[] { x, y });
                point.setROI(regionBounds);
                point.setMobile(true);

                getPlottingSystem().addRegion(point);

            } catch (Exception e) {
                logger.error("Cannot create point!", e);
            }
        } //end if
    }

    @Override
    public void mouseReleased(MouseEvent me) {
        // TODO Auto-generated method stub

    }

    @Override
    public void mouseDoubleClicked(MouseEvent me) {
        // TODO Auto-generated method stub
    }

    private void createActions() {

        final Action copy = new Action("Copy point values to clipboard",
                Activator.getImageDescriptor("icons/plot-tool-measure-copy.png")) {
            @Override
            public void run() {
                if (!isActive())
                    return;
                final IStructuredSelection sel = (IStructuredSelection) viewer.getSelection();
                if (sel != null && sel.getFirstElement() != null) {
                    Object selected = sel.getFirstElement();
                    if (selected instanceof IRegion) {
                        final IRegion region = (IRegion) sel.getFirstElement();
                        if (region == null || region.getROI() == null)
                            return;
                        final IROI bounds = region.getROI();
                        if (bounds.getPointRef() == null)
                            return;

                        final Clipboard cb = new Clipboard(composite.getDisplay());
                        TextTransfer textTransfer = TextTransfer.getInstance();
                        cb.setContents(new Object[] { region.getName() + "  " + bounds },
                                new Transfer[] { textTransfer });
                    }
                }
            }
        };
        copy.setToolTipText("Copies the point values as text to clipboard which can then be pasted externally.");

        getSite().getActionBars().getToolBarManager().add(copy);
        getSite().getActionBars().getMenuManager().add(copy);

        final Action delete = new Action("Delete selected point",
                Activator.getImageDescriptor("icons/plot-tool-measure-delete.png")) {
            @Override
            public void run() {
                if (!isActive())
                    return;
                final IStructuredSelection sel = (IStructuredSelection) viewer.getSelection();

                // ignore table item at index 0 as represents current point
                if (sel != null && sel.getFirstElement() != null && viewer.getTable().getSelectionIndex() != 0) {
                    final IRegion region = (IRegion) sel.getFirstElement();
                    getPlottingSystem().removeRegion(region);
                    viewer.refresh();
                }
            }
        };
        delete.setToolTipText("Delete selected point, if there is one.");

        getSite().getActionBars().getToolBarManager().add(delete);
        getSite().getActionBars().getMenuManager().add(delete);

        final Separator sep = new Separator(getClass().getName() + ".separator1");
        getSite().getActionBars().getToolBarManager().add(sep);
        getSite().getActionBars().getMenuManager().add(sep);

        final Action show = new Action("Show all vertex values", IAction.AS_CHECK_BOX) {
            @Override
            public void run() {
                if (!isActive())
                    return;
                final Object[] oa = ((IStructuredContentProvider) viewer.getContentProvider()).getElements(null);
                for (Object object : oa) {
                    if (object instanceof IRegion)
                        ((IRegion) object).setShowPosition(isChecked());
                }
            }
        };
        show.setToolTipText("Show vertices in all visible regions");
        show.setImageDescriptor(Activator.getImageDescriptor("icons/plot-tool-measure-vertices.png"));

        final Action preferences = new Action("Preferences...") {
            public void run() {
                if (!isActive())
                    return;
                PreferenceDialog pref = PreferencesUtil.createPreferenceDialogOn(
                        PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), InfoPixelPreferencePage.ID,
                        null, null);
                if (pref != null)
                    pref.open();
            }
        };

        getSite().getActionBars().getToolBarManager().add(show);
        getSite().getActionBars().getMenuManager().add(show);
        getSite().getActionBars().getMenuManager().add(preferences);
        createRightClickMenu();
    }

    private void createRightClickMenu() {
        final MenuManager menuManager = new MenuManager();
        for (IContributionItem item : getSite().getActionBars().getMenuManager().getItems())
            menuManager.add(item);
        viewer.getControl().setMenu(menuManager.createContextMenu(viewer.getControl()));
    }

    protected abstract void createColumns(final TableViewer viewer);

    public IROI getBounds(IRegion region) {
        return region.getROI();
    }

    private void updateRegion(ROIEvent evt) {

        if (viewer != null) {
            IRegion region = null;
            try {
                region = (IRegion) evt.getSource();

                //viewer.refresh(region);
                updateInfoPixel(region);

            } catch (Exception e) {
                logger.error("problem creating point region:", e);
            }
        }
    }

    @Override
    public void regionNameChanged(RegionEvent evt, String oldName) {
        // TODO Auto-generated method stub

    }

    @Override
    public void regionAdded(RegionEvent evt) {
        if (!isActive())
            return;
        if (viewer != null)
            viewer.refresh();
        if (evt.getRegion() != null) {
            evt.getRegion().addROIListener(this);
        }
    }

    @Override
    public void regionRemoved(RegionEvent evt) {
        if (!isActive())
            return;
        if (viewer != null)
            viewer.refresh();
        if (evt.getRegion() != null) {
            evt.getRegion().removeROIListener(this);
        }
    }

    @Override
    public void regionsRemoved(RegionEvent evt) {
        if (!isActive())
            return;
        createRegions();
        if (viewer != null)
            viewer.refresh();
    }

    @Override
    public void regionCreated(RegionEvent evt) {
    }

    @Override
    public void regionCancelled(RegionEvent evt) {
    }

    @Override
    public void roiDragged(ROIEvent evt) {
        //logger.debug("ROI dragged ====> ");
        if (viewer != null) {
            IRegion region = (IRegion) evt.getSource();

            if (region.getRegionType() == RegionType.POINT) {
                // update table for current point region            
                viewer.refresh(region);
                //updateInfoPixel(region);
            } else {
                updateRegion(evt);
            }
        }
    }

    @Override
    public void roiChanged(ROIEvent evt) {
    }

    @Override
    public void roiSelected(ROIEvent evt) {
        // TODO Auto-generated method stub

    }

    private synchronized void updateInfoPixel(final IRegion region) {

        if (updateInfoPixelData == null) {
            updateInfoPixelData = new Job("Info Pixel update") {

                @Override
                protected IStatus run(IProgressMonitor monitor) {
                    try {
                        isUpdateRunning = true;
                        //logger.debug("Update Running");
                        if (monitor.isCanceled())
                            return Status.CANCEL_STATUS;
                        PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() {
                            public void run() {
                                //Run the update table viewer on a separate thread than the GUI
                                viewer.refresh(region);

                            }

                        });
                        if (!isActive())
                            return Status.CANCEL_STATUS;
                        return Status.OK_STATUS;

                    } finally {
                        isUpdateRunning = false;
                    }
                }

            };

            updateInfoPixelData.setSystem(true);
            updateInfoPixelData.setUser(false);
            updateInfoPixelData.setPriority(Job.INTERACTIVE);
        }
        updateInfoPixelData.cancel();
        updateInfoPixelData.schedule();

    }
}