org.csstudio.dal.ui.internal.connectionview.ConnectionStateView.java Source code

Java tutorial

Introduction

Here is the source code for org.csstudio.dal.ui.internal.connectionview.ConnectionStateView.java

Source

/*
 * Copyright (c) 2008 Stiftung Deutsches Elektronen-Synchrotron,
 * Member of the Helmholtz Association, (DESY), HAMBURG, GERMANY.
 *
 * THIS SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN "../AS IS" BASIS.
 * WITHOUT WARRANTY OF ANY KIND, EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR PARTICULAR PURPOSE AND
 * NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
 * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
 * THE USE OR OTHER DEALINGS IN THE SOFTWARE. SHOULD THE SOFTWARE PROVE DEFECTIVE
 * IN ANY RESPECT, THE USER ASSUMES THE COST OF ANY NECESSARY SERVICING, REPAIR OR
 * CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE.
 * NO USE OF ANY SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
 * DESY HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
 * OR MODIFICATIONS.
 * THE FULL LICENSE SPECIFYING FOR THE SOFTWARE THE REDISTRIBUTION, MODIFICATION,
 * USAGE AND OTHER RIGHTS AND OBLIGATIONS IS INCLUDED WITH THE DISTRIBUTION OF THIS
 * PROJECT IN THE FILE LICENSE.HTML. IF THE LICENSE IS NOT INCLUDED YOU MAY FIND A COPY
 * AT HTTP://WWW.DESY.DE/LEGAL/LICENSE.HTM
 */
package org.csstudio.dal.ui.internal.connectionview;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.csstudio.dal.ui.dnd.rfc.ProcessVariableExchangeUtil;
import org.csstudio.dal.ui.util.LayoutUtil;
import org.csstudio.platform.model.pvs.IProcessVariableAddress;
import org.csstudio.platform.model.pvs.IProcessVariableAdressProvider;
import org.csstudio.platform.simpledal.ConnectionState;
import org.csstudio.platform.simpledal.IConnector;
import org.csstudio.platform.simpledal.IProcessVariableConnectionService;
import org.csstudio.platform.simpledal.ProcessVariableConnectionServiceFactory;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.action.GroupMarker;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.viewers.ColumnViewerToolTipSupport;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.jface.window.ToolTip;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Table;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.part.ViewPart;
import org.eclipse.ui.progress.UIJob;

/**
 * A view that displays the state of all channel connections that were opened
 * using the {@link IProcessVariableConnectionService} that has been created via
 * {@link ProcessVariableConnectionServiceFactory#getDefault()}.
 *
 * @author Sven Wende
 *
 */
public final class ConnectionStateView extends ViewPart {
    /**
     * The views ID.
     */
    public static final String VIEW_ID = "org.csstudio.platform.ui.ConnectionStateView";

    /**
     * The viewer.
     */
    private TableViewer _viewer;

    /**
     * A UI job used to refresh the view at a fixed delay.
     */
    private UIJob _updateJob;

    private SortDirection _sortDirection = SortDirection.BY_NAME;

    class FilterByConnectionStateMouseListener extends MouseAdapter {
        private final Set<ConnectionState> _connectionStates;

        public FilterByConnectionStateMouseListener(final Set<ConnectionState> connectionStates) {
            assert connectionStates != null;
            _connectionStates = connectionStates;
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public void mouseUp(final MouseEvent e) {
            final ViewerFilter filter = new ViewerFilter() {
                @Override
                public boolean select(final Viewer viewer, final Object parentElement, final Object element) {
                    final IConnector s = (IConnector) element;
                    return _connectionStates.contains(s.getLatestConnectionState());
                }
            };

            _viewer.setFilters(new ViewerFilter[] { filter });
        }
    }

    // private Button createFilterButton(Composite parent, String label,
    // ConnectionState... connectionStates) {
    //
    // Button button = new Button(parent, SWT.NONE);
    // button.setText(label);
    // button
    // .addMouseListener(new FilterByConnectionStateMouseListener(
    // states));
    //
    // return button;
    // }

    class FilterButton {
        private final Button _swtButton;
        private final Set<ConnectionState> _connectionStates;
        private final String _baseLabel;

        public FilterButton(final Composite parent, final int style, final String label,
                final ConnectionState... connectionStates) {
            _swtButton = new Button(parent, style);
            assert connectionStates != null;
            assert label != null;

            // remember label
            _baseLabel = label;

            // remember connection states
            _connectionStates = new HashSet<ConnectionState>();
            for (final ConnectionState s : connectionStates) {
                _connectionStates.add(s);
            }

            // add action listener
            _swtButton.addMouseListener(new FilterByConnectionStateMouseListener(_connectionStates));

            // initialize label
            refreshLabel(Collections.EMPTY_LIST);

        }

        public void refreshLabel(final List<IConnector> statistics) {
            assert statistics != null;

            int count = 0;

            if (statistics != null) {
                for (final IConnector s : statistics) {
                    if (_connectionStates.contains(s.getLatestConnectionState())) {
                        count++;
                    }
                }
            }
            _swtButton.setText(_baseLabel + " (" + count + ")");
        }

    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void createPartControl(final Composite parent) {
        // layout
        parent.setLayout(new GridLayout());

        // create button panel
        final Composite buttons = new Composite(parent, SWT.NONE);
        buttons.setLayout(new FillLayout());
        buttons.setLayoutData(LayoutUtil.createGridDataForHorizontalFillingCell());

        final FilterButton buttonAll = new FilterButton(buttons, SWT.FLAT, "all", ConnectionState.values());
        final FilterButton buttonConnected = new FilterButton(buttons, SWT.FLAT, "connected",
                ConnectionState.CONNECTED);
        final FilterButton buttonNotConnected = new FilterButton(buttons, SWT.FLAT, "not connected",
                ConnectionState.CONNECTION_LOST, ConnectionState.INITIAL, ConnectionState.CONNECTION_FAILED,
                ConnectionState.DISCONNECTED, ConnectionState.UNKNOWN);

        // create the viewer and ...
        _viewer = createChannelTable(parent);

        // .. initialize layout
        _viewer.getControl().setLayoutData(LayoutUtil.createGridDataForFillingCell());

        // .. initialize content provider
        _viewer.setContentProvider(new IStructuredContentProvider() {
            /**
             * {@inheritDoc}
             */
            @Override
            public void inputChanged(final Viewer viewer, final Object oldInput, final Object newInput) {

            }

            /**
             * {@inheritDoc}
             */
            @Override
            public Object[] getElements(final Object parent) {
                final List<IConnector> statistics = ((IProcessVariableConnectionService) parent).getConnectors();

                // refresh the filter button states
                buttonAll.refreshLabel(statistics);
                buttonConnected.refreshLabel(statistics);
                buttonNotConnected.refreshLabel(statistics);

                return statistics.toArray();
            }

            /**
             * {@inheritDoc}
             */
            @Override
            public void dispose() {

            }

        });

        // ... initialize label provider
        _viewer.setLabelProvider(new LabelProvider());
        _viewer.setInput(
                ProcessVariableConnectionServiceFactory.getDefault().getProcessVariableConnectionService());

        // ... initialize comparators (important for sorting)
        _viewer.setComparator(new ViewerComparator() {
            @Override
            public int compare(final Viewer viewer, final Object e1, final Object e2) {
                return _sortDirection.getComparator().compare((IConnector) e1, (IConnector) e2);
            }
        });

        // ... initialize tooltip support
        ColumnViewerToolTipSupport.enableFor(_viewer, ToolTip.NO_RECREATE);

        // ... initialize context menu
        final MenuManager menuManager = new MenuManager();
        // menuManager.addMenuListener(new IMenuListener() {
        //
        // public void menuAboutToShow(final IMenuManager manager) {
        // manager.add(new GroupMarker(
        // IWorkbenchActionConstants.MB_ADDITIONS));
        // }
        // });

        menuManager.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));

        _viewer.getControl().setMenu(menuManager.createContextMenu(_viewer.getControl()));

        getViewSite().registerContextMenu(menuManager, _viewer);
        getViewSite().setSelectionProvider(_viewer);

        // initialize the update job
        _updateJob = new UIJob("Update Connector State View") {
            @Override
            public IStatus runInUIThread(final IProgressMonitor monitor) {
                _viewer.refresh();
                if (!monitor.isCanceled()) {
                    _updateJob.schedule(2000);
                    return Status.OK_STATUS;
                } else {
                    return Status.CANCEL_STATUS;
                }
            }
        };

        _updateJob.schedule(5000);

    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void dispose() {
        _updateJob.cancel();
        super.dispose();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void setFocus() {
    }

    private TableViewer createChannelTable(final Composite parent) {
        // define column names
        final String[] columnNames = new String[] { "PROP_DESCRIPTION", "PROP_NAME", "PROP_VALUE" }; //$NON-NLS-1$ //$NON-NLS-2$

        // create table
        final Table table = new Table(parent,
                SWT.FULL_SELECTION | SWT.MULTI | SWT.HIDE_SELECTION | SWT.DOUBLE_BUFFERED | SWT.SCROLL_PAGE);

        table.setLinesVisible(true);
        table.setLayoutData(LayoutUtil.createGridDataForFillingCell());
        table.setHeaderVisible(true);

        // create viewer
        final TableViewer viewer = new TableViewer(table);

        TableViewerColumn tvColumn;
        tvColumn = new TableViewerColumn(viewer, SWT.NONE);
        tvColumn.getColumn().setText("Channel");
        tvColumn.getColumn().setMoveable(false);
        tvColumn.getColumn().setWidth(300);

        tvColumn = new TableViewerColumn(viewer, SWT.NONE);
        tvColumn.getColumn().setText("Connection State");
        tvColumn.getColumn().setMoveable(false);
        tvColumn.getColumn().setWidth(200);

        tvColumn = new TableViewerColumn(viewer, SWT.NONE);
        tvColumn.getColumn().setText("Latest Value");
        tvColumn.getColumn().setMoveable(false);
        tvColumn.getColumn().setWidth(200);

        viewer.setUseHashlookup(true);

        // define column properties
        viewer.setColumnProperties(columnNames);

        // DnD
        ProcessVariableExchangeUtil.addProcessVariableAdressDragSupport(viewer.getControl(),
                DND.DROP_MOVE | DND.DROP_COPY, new IProcessVariableAdressProvider() {
                    @Override
                    public List<IProcessVariableAddress> getProcessVariableAdresses() {
                        final List<IProcessVariableAddress> result = new ArrayList<IProcessVariableAddress>();

                        final IStructuredSelection sel = (IStructuredSelection) viewer.getSelection();
                        final Iterator<IProcessVariableAdressProvider> it = sel.iterator();

                        while (it.hasNext()) {
                            result.add(it.next().getPVAdress());
                        }

                        return result;
                    }

                    @Override
                    public IProcessVariableAddress getPVAdress() {
                        final IStructuredSelection sel = (IStructuredSelection) viewer.getSelection();
                        final IProcessVariableAdressProvider pvProvider = (IProcessVariableAdressProvider) sel
                                .getFirstElement();
                        return pvProvider != null ? pvProvider.getPVAdress() : null;
                    }

                });

        return viewer;
    }

    class ChangeSortDirectionListener implements SelectionListener {
        private final SortDirection _sortDirection;

        public ChangeSortDirectionListener(final SortDirection sortDirection) {
            assert sortDirection != null;
            _sortDirection = sortDirection;
        }

        @Override
        public void widgetDefaultSelected(final SelectionEvent e) {

        }

        @Override
        public void widgetSelected(final SelectionEvent e) {
            ConnectionStateView.this._sortDirection = this._sortDirection;
        }
    }

}