com.nokia.carbide.remoteconnections.view.ConnectionsView.java Source code

Java tutorial

Introduction

Here is the source code for com.nokia.carbide.remoteconnections.view.ConnectionsView.java

Source

/*
* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of the License "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description: 
*
*/

package com.nokia.carbide.remoteconnections.view;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.LegacyActionTools;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.ColumnViewer;
import org.eclipse.jface.viewers.ColumnViewerEditor;
import org.eclipse.jface.viewers.ColumnViewerEditorActivationEvent;
import org.eclipse.jface.viewers.ColumnViewerEditorActivationStrategy;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.EditingSupport;
import org.eclipse.jface.viewers.ICellEditorListener;
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.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.jface.viewers.TreeColumnViewerLabelProvider;
import org.eclipse.jface.viewers.TreeNode;
import org.eclipse.jface.viewers.TreeNodeContentProvider;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.TreeViewerColumn;
import org.eclipse.jface.viewers.TreeViewerEditor;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.ViewPart;

import com.nokia.carbide.remoteconnections.Messages;
import com.nokia.carbide.remoteconnections.RemoteConnectionsActivator;
import com.nokia.carbide.remoteconnections.RemoteConnectionsActivator.IDiscoveryAgentsLoadedListener;
import com.nokia.carbide.remoteconnections.interfaces.IConnectedService;
import com.nokia.carbide.remoteconnections.interfaces.IConnectedService.IStatus;
import com.nokia.carbide.remoteconnections.interfaces.IConnectedService.IStatus.EStatus;
import com.nokia.carbide.remoteconnections.interfaces.IConnectedService.IStatusChangedListener;
import com.nokia.carbide.remoteconnections.interfaces.IConnection;
import com.nokia.carbide.remoteconnections.interfaces.IConnectionType;
import com.nokia.carbide.remoteconnections.interfaces.IConnectionsManager;
import com.nokia.carbide.remoteconnections.interfaces.IConnectionsManager.IConnectionListener;
import com.nokia.carbide.remoteconnections.interfaces.IConnectionsManager.IConnectionsManagerListener;
import com.nokia.carbide.remoteconnections.internal.ToggleDiscoveryAgentAction;
import com.nokia.carbide.remoteconnections.internal.api.IConnection2;
import com.nokia.carbide.remoteconnections.internal.api.IConnection2.IConnectionStatus;
import com.nokia.carbide.remoteconnections.internal.api.IConnection2.IConnectionStatus.EConnectionStatus;
import com.nokia.carbide.remoteconnections.internal.api.IConnection2.IConnectionStatusChangedListener;
import com.nokia.carbide.remoteconnections.internal.api.IDeviceDiscoveryAgent;
import com.nokia.carbide.remoteconnections.internal.api.IToggleServicesTestingListener;
import com.nokia.carbide.remoteconnections.internal.registry.Registry;
import com.nokia.carbide.remoteconnections.internal.ui.ConnectionUIUtils;
import com.nokia.carbide.remoteconnections.settings.ui.SettingsWizard;
import com.nokia.cpp.internal.api.utils.core.ObjectUtils;

/**
 * The view part for Remote connections
 */
@SuppressWarnings("deprecation")
public class ConnectionsView extends ViewPart {
    public static final String VIEW_ID = "com.nokia.carbide.remoteconnections.view.ConnectionsView"; //$NON-NLS-1$

    private TreeViewer viewer;
    private IConnectionsManagerListener connectionStoreChangedListener;
    private IConnectionListener connectionListener;
    private IToggleServicesTestingListener toggleServicesTestingListener;
    private Map<IConnectedService, IStatusChangedListener> serviceToListenerMap;
    private Map<IConnection2, IConnectionStatusChangedListener> connectionToListenerMap;
    private List<Action> actions;
    private List<Action> connectionSelectedActions;
    private List<Action> serviceSelectedActions;
    private List<Action> discoveryAgentActions;
    private static final String UID = ".uid"; //$NON-NLS-1$

    private static final ImageDescriptor CONNECTION_NEW_IMGDESC = RemoteConnectionsActivator
            .getImageDescriptor("icons/connectionNew.png"); //$NON-NLS-1$
    private static final ImageDescriptor CONNECTION_EDIT_IMGDESC = RemoteConnectionsActivator
            .getImageDescriptor("icons/connectionEdit.png"); //$NON-NLS-1$
    private static final ImageDescriptor SERVICE_TEST_IMGDESC = RemoteConnectionsActivator
            .getImageDescriptor("icons/serviceTest.png"); //$NON-NLS-1$
    private static final ImageDescriptor SERVICE_TEST_DISABLED_IMGDESC = RemoteConnectionsActivator
            .getImageDescriptor("icons/serviceTest_No.png"); //$NON-NLS-1$
    private static final ImageDescriptor CONNECTION_REFRESH_IMGDESC = RemoteConnectionsActivator
            .getImageDescriptor("icons/connectionRefresh.png"); //$NON-NLS-1$

    public static final int DESCRIPTION_COLUMN_INDEX = 3;

    private static final String NEW_ACTION = "ConnectionsView.new"; //$NON-NLS-1$
    private static final String EDIT_ACTION = "ConnectionsView.edit"; //$NON-NLS-1$
    private static final String RENAME_ACTION = "ConnectionsView.rename"; //$NON-NLS-1$
    private static final String ENABLE_SERVICE_ACTION = "ConnectionsView.enableService"; //$NON-NLS-1$
    private static final String REFRESH_ACTION = "ConnectionsView.refresh"; //$NON-NLS-1$
    private static final String DELETE_ACTION = "ConnectionsView.delete"; //$NON-NLS-1$
    private static final String HELP_ACTION = "ConnectionsView.help"; //$NON-NLS-1$
    private static final String SET_CURRENT_ACTION = "ConnectionsView.makeCurrent"; //$NON-NLS-1$
    private static final String TOGGLE_SERVICES_ACTION = "ConnectionsView.toggleServices"; //$NON-NLS-1$
    private KeyAdapter keyListener;
    private boolean isDisposed;

    // handle, do not dispose
    private Font boldViewerFont;
    private TextCellEditor nameEditor;
    private boolean refreshPending;

    private TreeNode[] loadConnections() {
        if (serviceToListenerMap == null)
            serviceToListenerMap = new HashMap<IConnectedService, IStatusChangedListener>();
        if (connectionToListenerMap == null)
            connectionToListenerMap = new HashMap<IConnection2, IConnectionStatusChangedListener>();
        removeStatusListeners();
        List<TreeNode> connectionNodes = new ArrayList<TreeNode>();
        Collection<IConnection> connections = Registry.instance().getConnections();
        for (IConnection connection : connections) {
            if (connection instanceof IConnection2) {
                IConnectionStatusChangedListener statusChangedListener = new IConnectionStatusChangedListener() {
                    public void statusChanged(IConnectionStatus status) {
                        refreshViewer();
                    }
                };
                IConnection2 connection2 = (IConnection2) connection;
                connection2.addStatusChangedListener(statusChangedListener);
                connectionToListenerMap.put(connection2, statusChangedListener);
            }
            // create a node for the connection
            TreeNode connectionNode = new TreeNode(connection);
            // create subnodes for the connected services
            List<TreeNode> serviceNodes = new ArrayList<TreeNode>();
            Collection<IConnectedService> connectedServicesForConnection = Registry.instance()
                    .getConnectedServices(connection);
            for (IConnectedService connectedService : connectedServicesForConnection) {
                final TreeNode treeNode = new TreeNode(connectedService);
                IStatusChangedListener statusChangedListener = new IStatusChangedListener() {
                    public void statusChanged(final IStatus status) {
                        refreshViewer();
                    }
                };
                connectedService.addStatusChangedListener(statusChangedListener);
                serviceToListenerMap.put(connectedService, statusChangedListener);
                serviceNodes.add(treeNode);
            }
            for (TreeNode serviceNode : serviceNodes) {
                serviceNode.setParent(connectionNode);
            }
            connectionNode.setChildren((TreeNode[]) serviceNodes.toArray(new TreeNode[serviceNodes.size()]));
            connectionNodes.add(connectionNode);
        }

        return (TreeNode[]) connectionNodes.toArray(new TreeNode[connectionNodes.size()]);
    }

    private void refreshViewer() {
        Display.getDefault().asyncExec(new Runnable() {
            public void run() {
                if (nameEditor != null && nameEditor.getControl() != null && !nameEditor.getControl().isDisposed()
                        && nameEditor.isActivated()) {
                    refreshPending = true;
                    return;
                }

                if (!isDisposed && !viewer.getControl().isDisposed()) {
                    viewer.refresh(true);
                    packColumns();
                }
                refreshPending = false;
            }
        });
    }

    private class NameEditingSupport extends EditingSupport {

        private NameEditingSupport(ColumnViewer viewer) {
            super(viewer);
            nameEditor = new TextCellEditor((Composite) viewer.getControl(), SWT.BORDER);
            nameEditor.addListener(new ICellEditorListener() {
                public void editorValueChanged(boolean oldValidState, boolean newValidState) {
                }

                public void cancelEditor() {
                    if (refreshPending)
                        refreshViewer();
                }

                public void applyEditorValue() {
                    if (refreshPending)
                        refreshViewer();
                }
            });
        }

        @Override
        protected boolean canEdit(Object element) {
            Object object = ((TreeNode) element).getValue();
            if (object instanceof IConnection && !isDynamicConnection(object))
                return true;
            return false;
        }

        @Override
        protected CellEditor getCellEditor(Object element) {
            return nameEditor;
        }

        @Override
        protected Object getValue(Object element) {
            IConnection connection = (IConnection) ((TreeNode) element).getValue();
            return connection.getDisplayName();
        }

        @Override
        protected void setValue(Object element, Object value) {
            IConnection connection = (IConnection) ((TreeNode) element).getValue();
            connection.setDisplayName(value.toString());
            Registry.instance().updateDisplays();
            Registry.instance().storeConnections();
        }
    }

    private class NameLabelProvider extends ColumnLabelProvider {

        public String getText(Object obj) {
            return getNodeDisplayName(obj);
        }

        @Override
        public Font getFont(Object element) {
            if (element instanceof TreeNode) {
                if (((TreeNode) element).getValue().equals(Registry.instance().getCurrentConnection())) {
                    return boldViewerFont;
                }
            }
            return super.getFont(element);
        }

        public Image getImage(Object obj) {
            TreeNode node = (TreeNode) obj;
            Object value = node.getValue();
            if (value instanceof IConnection) {
                return ConnectionUIUtils.getConnectionImage((IConnection) value);
            } else if (value instanceof IConnectedService) {
                EStatus status = ((IConnectedService) value).getStatus().getEStatus();
                IConnection connection = findConnection((IConnectedService) value);
                if (connection != null && ConnectionUIUtils.isSomeServiceInUse(connection))
                    status = EStatus.IN_USE;
                return ConnectionUIUtils.getConnectedServiceStatusImage(status);
            }
            return null;
        }
    }

    private class StatusLabelProvider extends ColumnLabelProvider {
        public String getText(Object obj) {
            TreeNode node = (TreeNode) obj;
            Object value = node.getValue();
            if (value instanceof IConnectedService) {
                IStatus status = null;
                IConnection connection = findConnection((IConnectedService) value);
                if (connection != null)
                    status = ConnectionUIUtils.getFirstInUseServiceStatus(connection);
                if (status == null) {
                    status = ((IConnectedService) value).getStatus();
                    return status.getShortDescription();
                }
            } else if (value instanceof IConnection) {
                IConnectionStatus connectionStatus = getConnectionStatus((IConnection) value);
                if (connectionStatus != null) {
                    return connectionStatus.getShortDescription();
                } else {
                    IStatus status = ConnectionUIUtils.getFirstInUseServiceStatus((IConnection) value);
                    if (status != null)
                        return status.getShortDescription();
                }
            }

            return null;
        }

        @Override
        public Color getForeground(Object obj) {
            TreeNode node = (TreeNode) obj;
            Object value = node.getValue();
            if (value instanceof IConnectedService) {
                EStatus status = ((IConnectedService) value).getStatus().getEStatus();
                switch (status) {
                case DOWN:
                    return ConnectionUIUtils.COLOR_RED;
                case UP:
                    return ConnectionUIUtils.COLOR_GREEN;
                case UNKNOWN:
                    return ConnectionUIUtils.COLOR_GREY;
                }
            } else if (value instanceof IConnection) // only showing in-use for connections
                return ConnectionUIUtils.COLOR_ELECTRIC;

            return null;
        }

        @Override
        public Font getFont(Object element) {
            // we need this to avoid letting the bold name column influence the others 
            return JFaceResources.getDefaultFont();
        }
    }

    private class TypeLabelProvider extends ColumnLabelProvider {

        public String getText(Object obj) {
            TreeNode node = (TreeNode) obj;
            Object value = node.getValue();
            if (value instanceof IConnection) {
                return ((IConnection) value).getConnectionType().getDisplayName();
            }
            return null;
        }

        @Override
        public Font getFont(Object element) {
            // we need this to avoid letting the bold name column influence the others 
            return JFaceResources.getDefaultFont();
        }
    }

    private class EnableConnectedServiceAction extends Action {
        private EnableConnectedServiceAction() {
            super("", SERVICE_TEST_IMGDESC); //$NON-NLS-1$
        }

        private IConnectedService getSelectedConnectedService() {
            ISelection selection = viewer.getSelection();
            if (selection.isEmpty())
                return null;
            TreeNode node = (TreeNode) ((IStructuredSelection) selection).getFirstElement();
            Object value = node.getValue();
            if (value instanceof IConnectedService) {
                return (IConnectedService) value;
            }
            return null;
        }

        @Override
        public void run() {
            IConnectedService connectedService = getSelectedConnectedService();
            if (connectedService != null) {
                connectedService.setEnabled(!connectedService.isEnabled());
                updateLabel();
            }
        }

        public void updateLabel() {
            IConnectedService connectedService = getSelectedConnectedService();
            if (connectedService == null)
                return;
            String label = connectedService.isEnabled()
                    ? Messages.getString("ConnectionsView.DisableTestActionLabel") //$NON-NLS-1$
                    : Messages.getString("ConnectionsView.EnableTestActionLabel"); //$NON-NLS-1$
            setText(label);
        }

        @Override
        public void setEnabled(boolean enabled) {
            super.setEnabled(enabled);
            updateLabel();
        }

        @Override
        public boolean isEnabled() {
            IConnectedService connectedService = getSelectedConnectedService();
            return connectedService != null && connectedService.getService().isTestable()
                    && RemoteConnectionsActivator.getDefault().getShouldTestServices();
        }
    }

    public void createPartControl(Composite parent) {
        viewer = new TreeViewer(parent, SWT.H_SCROLL | SWT.V_SCROLL);

        TreeViewerColumn nameColumn = new TreeViewerColumn(viewer, SWT.LEFT);
        nameColumn.setLabelProvider(new TreeColumnViewerLabelProvider(new NameLabelProvider()));
        nameColumn.getColumn().setText(Messages.getString("ConnectionsView.NameColumnHeader")); //$NON-NLS-1$
        nameColumn.setEditingSupport(new NameEditingSupport(nameColumn.getViewer()));
        ColumnViewerEditorActivationStrategy activationStrategy = new ColumnViewerEditorActivationStrategy(
                nameColumn.getViewer()) {
            @Override
            protected boolean isEditorActivationEvent(ColumnViewerEditorActivationEvent event) {
                return event.eventType == ColumnViewerEditorActivationEvent.PROGRAMMATIC;
            }
        };
        TreeViewerEditor.create(viewer, activationStrategy, ColumnViewerEditor.DEFAULT);

        boldViewerFont = JFaceResources.getFontRegistry().getBold(JFaceResources.DEFAULT_FONT);

        TreeViewerColumn typeColumn = new TreeViewerColumn(viewer, SWT.LEFT);
        typeColumn.setLabelProvider(new TypeLabelProvider());
        typeColumn.getColumn().setText(Messages.getString("ConnectionsView.TypeColumnHeader")); //$NON-NLS-1$

        TreeViewerColumn statusColumn = new TreeViewerColumn(viewer, SWT.LEFT);
        statusColumn.setLabelProvider(new StatusLabelProvider());
        statusColumn.getColumn().setText(Messages.getString("ConnectionsView.StatusColumnHeader")); //$NON-NLS-1$

        TreeViewerColumn descriptionColumn = new TreeViewerColumn(viewer, SWT.LEFT);
        descriptionColumn.setLabelProvider(new DescriptionLabelProvider(this, descriptionColumn));
        descriptionColumn.getColumn().setText(Messages.getString("ConnectionsView.DescriptionColumnHeader")); //$NON-NLS-1$

        viewer.setContentProvider(new TreeNodeContentProvider());
        viewer.setInput(loadConnections());
        viewer.expandAll();
        viewer.getTree().setHeaderVisible(true);
        viewer.getControl().setData(UID, "viewer"); //$NON-NLS-1$
        viewer.setSorter(new ViewerSorter() {
            @Override
            public int compare(Viewer viewer, Object e1, Object e2) {
                return getNodeDisplayName(e1).compareToIgnoreCase(getNodeDisplayName(e2));
            }
        });
        viewer.addSelectionChangedListener(new ISelectionChangedListener() {
            public void selectionChanged(SelectionChangedEvent event) {
                enableConnectionSelectedActions(false);
                enableServiceSelectedActions(false);
                ISelection selection = event.getSelection();
                if (!selection.isEmpty()) {
                    IStructuredSelection structuredSelection = (IStructuredSelection) selection;
                    TreeNode treeNode = (TreeNode) structuredSelection.getFirstElement();
                    Object value = treeNode.getValue();
                    if (value instanceof IConnection) {
                        enableConnectionSelectedActions(true);
                    } else if (value instanceof IConnectedService) {
                        enableServiceSelectedActions(true);
                    }
                }
            }
        });
        viewer.addDoubleClickListener(new IDoubleClickListener() {
            public void doubleClick(DoubleClickEvent event) {
                ISelection selection = event.getSelection();
                if (!selection.isEmpty()) {
                    IStructuredSelection structuredSelection = (IStructuredSelection) selection;
                    TreeNode treeNode = (TreeNode) structuredSelection.getFirstElement();
                    Object value = treeNode.getValue();
                    if (value instanceof IConnection) {
                        SettingsWizard wizard = new SettingsWizard((IConnection) value);
                        wizard.open(getViewSite().getShell());
                    } else if (value instanceof IConnectedService) {
                        if (RemoteConnectionsActivator.getDefault().getShouldTestServices()) {
                            IConnectedService connectedService = (IConnectedService) value;
                            connectedService.setEnabled(true);
                            connectedService.testStatus();
                            ((EnableConnectedServiceAction) getAction(ENABLE_SERVICE_ACTION)).updateLabel();
                        }
                    }
                }
            }
        });

        packColumns();

        makeActions();
        hookContextMenu();
        contributeToActionBars();
        hookAccelerators();

        connectionStoreChangedListener = new IConnectionsManagerListener() {
            public void connectionStoreChanged() {
                Display.getDefault().asyncExec(new Runnable() {
                    public void run() {
                        viewer.setInput(loadConnections());
                        viewer.expandAll();
                        packColumns();
                        if (viewer.getSelection().isEmpty() && viewer.getTree().getItemCount() > 0) {
                            TreeItem item = viewer.getTree().getItem(0);
                            if (item != null) {
                                viewer.getTree().select(item);
                            }
                        }
                        viewer.setSelection(viewer.getSelection()); // force selection changed
                    }
                });
            }

            public void displayChanged() {
                refreshViewer();
            }
        };
        Registry.instance().addConnectionStoreChangedListener(connectionStoreChangedListener);

        connectionListener = new IConnectionListener() {

            public void currentConnectionSet(IConnection connection) {
                refreshViewer();
            }

            public void connectionRemoved(IConnection connection) {
                // presumably the viewer itself handles this...
            }

            public void connectionAdded(IConnection connection) {
                // presumably the viewer itself handles this...
            }
        };
        Registry.instance().addConnectionListener(connectionListener);

        RemoteConnectionsActivator.setHelp(parent, ".connections_view"); //$NON-NLS-1$
    }

    // returns non-null status when status is not EConnectionStatus.NONE
    public IConnectionStatus getConnectionStatus(IConnection connection) {
        if (connection instanceof IConnection2) {
            IConnectionStatus status = ((IConnection2) connection).getStatus();
            if (status != null && status.getEConnectionStatus() != EConnectionStatus.NONE)
                return status;
        }
        return null;
    }

    private void packColumns() {
        TreeColumn[] columns = viewer.getTree().getColumns();
        for (TreeColumn column : columns) {
            column.pack();
        }
    }

    private String getNodeDisplayName(Object obj) {
        Object value = ((TreeNode) obj).getValue();
        if (value instanceof IConnection)
            return ((IConnection) value).getDisplayName();
        else if (value instanceof IConnectedService)
            return ((IConnectedService) value).getService().getDisplayName();

        return ""; //$NON-NLS-1$
    }

    private void hookContextMenu() {
        MenuManager menuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$
        menuMgr.setRemoveAllWhenShown(true);
        menuMgr.addMenuListener(new IMenuListener() {
            public void menuAboutToShow(IMenuManager manager) {
                ConnectionsView.this.fillContextMenu(manager);
            }
        });
        Menu menu = menuMgr.createContextMenu(viewer.getControl());
        viewer.getControl().setMenu(menu);
        getSite().registerContextMenu(menuMgr, viewer);
    }

    private void contributeToActionBars() {
        IActionBars bars = getViewSite().getActionBars();
        fillLocalPullDown(bars.getMenuManager());
        fillLocalToolBar(bars.getToolBarManager());
    }

    private void fillLocalPullDown(final IMenuManager manager) {
        if (discoveryAgentActions.isEmpty()) {
            IDiscoveryAgentsLoadedListener listener = new IDiscoveryAgentsLoadedListener() {
                public void agentsAreLoaded() {
                    makeToggleDiscoveryAgentActions();
                    addDiscoveryAgentActions(manager);
                    Display.getDefault().asyncExec(new Runnable() {
                        public void run() {
                            manager.update(true);
                        }
                    });
                }
            };
            RemoteConnectionsActivator.getDefault().addDiscoveryAgentsLoadedListener(listener);
        } else {
            addDiscoveryAgentActions(manager);
        }
    }

    private void addDiscoveryAgentActions(IMenuManager manager) {
        for (Action action : discoveryAgentActions) {
            manager.add(action);
        }
    }

    private void fillContextMenu(IMenuManager manager) {
        manager.add(getAction(NEW_ACTION));
        ISelection selection = viewer.getSelection();
        if (selection.isEmpty())
            return;
        TreeNode node = (TreeNode) ((IStructuredSelection) selection).getFirstElement();
        Object value = node.getValue();
        if (value instanceof IConnectedService) {
            manager.add(new Separator());
            manager.add(getAction(ENABLE_SERVICE_ACTION));
        } else if (value instanceof IConnection) {
            manager.add(new Separator());
            manager.add(getAction(RENAME_ACTION));
            manager.add(getAction(EDIT_ACTION));
            manager.add(getAction(DELETE_ACTION));
            IAction helpAction = getAction(HELP_ACTION);
            if (helpAction.isEnabled()) {
                helpAction.setText(helpAction.getText());
                manager.add(helpAction);
            }
            manager.add(getAction(SET_CURRENT_ACTION));
        }
    }

    private void fillLocalToolBar(IToolBarManager manager) {
        manager.add(getAction(TOGGLE_SERVICES_ACTION));
        manager.add(getAction(REFRESH_ACTION));
        manager.add(getAction(NEW_ACTION));
        manager.add(getAction(EDIT_ACTION));
    }

    private void makeActions() {
        actions = new ArrayList<Action>();
        connectionSelectedActions = new ArrayList<Action>();
        serviceSelectedActions = new ArrayList<Action>();

        Action action = new Action(Messages.getString("ConnectionsView.NewActionLabel"), CONNECTION_NEW_IMGDESC) { //$NON-NLS-1$
            @Override
            public void run() {
                SettingsWizard wizard = new SettingsWizard();
                wizard.open(getViewSite().getShell());
            }

        };
        action.setId(NEW_ACTION);
        actions.add(action);
        action.setEnabled(!Registry.instance().getConnectionTypes().isEmpty());

        String editLabel = Messages.getString("ConnectionsView.EditActionLabel"); //$NON-NLS-1$
        action = new Action(editLabel, CONNECTION_EDIT_IMGDESC) { //$NON-NLS-1$
            @Override
            public void run() {
                ISelection selection = viewer.getSelection();
                if (selection.isEmpty())
                    return;
                TreeNode node = (TreeNode) ((IStructuredSelection) selection).getFirstElement();
                Object value = node.getValue();
                if (value instanceof IConnection) {
                    SettingsWizard wizard = new SettingsWizard((IConnection) value);
                    wizard.open(getViewSite().getShell());
                }
            }
        };
        action.setId(EDIT_ACTION);
        actions.add(action);
        connectionSelectedActions.add(action);

        action = new Action() {
            @Override
            public void run() {
                ISelection selection = viewer.getSelection();
                if (selection.isEmpty())
                    return;
                TreeNode node = (TreeNode) ((IStructuredSelection) selection).getFirstElement();
                Object value = node.getValue();
                if (value instanceof IConnection) {
                    viewer.editElement(node, 0);
                }
            }

            @Override
            public boolean isEnabled() {
                return selectionCanBeEdited();
            }
        };
        action.setId(RENAME_ACTION);
        action.setAccelerator(SWT.F2);
        action.setText(Messages.getString("ConnectionsView.RenameMenuLabel") + //$NON-NLS-1$
                "\t" + //$NON-NLS-1$
                LegacyActionTools.convertAccelerator(action.getAccelerator()));
        actions.add(action);
        connectionSelectedActions.add(action);

        action = new EnableConnectedServiceAction();
        action.setId(ENABLE_SERVICE_ACTION);
        actions.add(action);
        serviceSelectedActions.add(action);

        action = new Action(Messages.getString("ConnectionsView.RefreshActionLabel"), CONNECTION_REFRESH_IMGDESC) { //$NON-NLS-1$
            @Override
            public void run() {
                IConnectionsManager connectionsManager = Registry.instance();
                for (IConnection connection : connectionsManager.getConnections()) {
                    Collection<IConnectedService> connectedServices = connectionsManager
                            .getConnectedServices(connection);
                    for (IConnectedService connectedService : connectedServices) {
                        connectedService.setEnabled(true);
                        connectedService.testStatus();
                    }
                }
                ((EnableConnectedServiceAction) getAction(ENABLE_SERVICE_ACTION)).updateLabel();
            }
        };
        action.setAccelerator(SWT.F5);
        action.setId(REFRESH_ACTION);
        action.setEnabled(RemoteConnectionsActivator.getDefault().getShouldTestServices());
        actions.add(action);

        action = new Action(Messages.getString("ConnectionsView.DeleteActionLabel"), //$NON-NLS-1$
                PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_TOOL_DELETE)) {
            @Override
            public void run() {
                ISelection selection = viewer.getSelection();
                if (selection.isEmpty() || !canBeEdited(selection))
                    return;
                TreeNode node = (TreeNode) ((IStructuredSelection) selection).getFirstElement();
                Object value = node.getValue();
                if (value instanceof IConnection) {
                    Registry.instance().removeConnection((IConnection) value);
                    Registry.instance().storeConnections();
                }
            }

            @Override
            public boolean isEnabled() {
                return selectionCanBeEdited();
            }
        };
        action.setAccelerator(SWT.DEL);
        action.setId(DELETE_ACTION);
        actions.add(action);
        connectionSelectedActions.add(action);

        Image image = JFaceResources.getImage(org.eclipse.jface.dialogs.Dialog.DLG_IMG_HELP);
        ImageDescriptor desc = ImageDescriptor.createFromImage(image);
        action = new Action(Messages.getString("ConnectionsView.NoHelpActionLabel"), desc) { //$NON-NLS-1$

            private String getHelpContextFromSelection() {
                IConnection connection = getSelectedConnection();
                if (connection != null) {
                    return connection.getConnectionType().getHelpContext();
                }
                return null;
            }

            @Override
            public String getText() {
                if (isEnabled()) {
                    IConnection connection = getSelectedConnection();
                    IConnectionType connectionType = connection.getConnectionType();
                    String displayName = connectionType.getDisplayName();
                    String pattern = Messages.getString("ConnectionsView.HelpActionLabel"); //$NON-NLS-1$
                    return MessageFormat.format(pattern, displayName);
                }
                return super.getText();
            }

            @Override
            public boolean isEnabled() {
                return getHelpContextFromSelection() != null;
            }

            @Override
            public void run() {
                PlatformUI.getWorkbench().getHelpSystem().displayHelp(getHelpContextFromSelection());
            }
        };
        action.setId(HELP_ACTION);
        actions.add(action);
        connectionSelectedActions.add(action);

        desc = ConnectionUIUtils.CONNECTION_IMGDESC;
        action = new Action(Messages.getString("ConnectionsView.SetCurrentActionLabel"), desc) { //$NON-NLS-1$

            @Override
            public boolean isEnabled() {
                return !ObjectUtils.equals(Registry.instance().getCurrentConnection(), getSelectedConnection());
            }

            @Override
            public void run() {
                Registry.instance().setCurrentConnection(getSelectedConnection());
                setEnabled(false);
            }
        };
        action.setId(SET_CURRENT_ACTION);
        actions.add(action);
        connectionSelectedActions.add(action);

        action = new Action(Messages.getString("ConnectionsView.ToggleServicesLabel"), IAction.AS_CHECK_BOX) { //$NON-NLS-1$
            public void setChecked(boolean checked) {
                if (isChecked() != checked) {
                    super.setChecked(checked);
                    RemoteConnectionsActivator.getDefault().setShouldTestServices(checked);
                    setImageDescriptor(checked ? SERVICE_TEST_IMGDESC : SERVICE_TEST_DISABLED_IMGDESC);
                }
            };
        };
        action.setId(TOGGLE_SERVICES_ACTION);
        action.setChecked(RemoteConnectionsActivator.getDefault().getShouldTestServices());
        action.setImageDescriptor(action.isChecked() ? SERVICE_TEST_IMGDESC : SERVICE_TEST_DISABLED_IMGDESC);
        actions.add(action);

        enableConnectionSelectedActions(false);
        enableServiceSelectedActions(false);

        makeToggleDiscoveryAgentActions();

        toggleServicesTestingListener = new IToggleServicesTestingListener() {
            public void servicesTestingToggled(boolean enabled) {
                getAction(TOGGLE_SERVICES_ACTION).setChecked(enabled);
                getAction(REFRESH_ACTION).setEnabled(enabled);
            }
        };
        RemoteConnectionsActivator.getDefault().addToggleServicesTestingListener(toggleServicesTestingListener);
    }

    private void makeToggleDiscoveryAgentActions() {
        discoveryAgentActions = new ArrayList<Action>();
        Collection<IDeviceDiscoveryAgent> discoveryAgents = RemoteConnectionsActivator.getDefault()
                .getDiscoveryAgents();
        for (IDeviceDiscoveryAgent agent : discoveryAgents) {
            discoveryAgentActions.add(new ToggleDiscoveryAgentAction(agent));
        }

    }

    private void enableConnectionSelectedActions(boolean enable) {
        for (Action action : connectionSelectedActions) {
            action.setEnabled(enable);
        }
    }

    private void enableServiceSelectedActions(boolean enable) {
        for (Action action : serviceSelectedActions) {
            action.setEnabled(enable);
        }
    }

    private Action getAction(String id) {
        for (Action action : actions) {
            if (action.getId().equals(id))
                return action;
        }

        return null;
    }

    private void hookAccelerators() {
        keyListener = new KeyAdapter() {
            public void keyPressed(KeyEvent e) {
                for (Action action : actions) {
                    if (e.keyCode == action.getAccelerator()) {
                        action.run();
                        break;
                    }
                }
            }
        };
        viewer.getControl().addKeyListener(keyListener);
    }

    /**
     * Passing the focus request to the viewer's control.
     */
    public void setFocus() {
        viewer.getControl().setFocus();
    }

    private void removeStatusListeners() {
        for (IConnectedService connectedService : serviceToListenerMap.keySet()) {
            IStatusChangedListener listener = serviceToListenerMap.get(connectedService);
            connectedService.removeStatusChangedListener(listener);
        }
        serviceToListenerMap.clear();
        for (IConnection2 connection : connectionToListenerMap.keySet()) {
            IConnectionStatusChangedListener listener = connectionToListenerMap.get(connection);
            connection.removeStatusChangedListener(listener);
        }
        connectionToListenerMap.clear();
    }

    @Override
    public void dispose() {
        removeStatusListeners();
        Registry.instance().removeConnectionStoreChangedListener(connectionStoreChangedListener);
        Registry.instance().removeConnectionListener(connectionListener);
        RemoteConnectionsActivator.getDefault().removeToggleServicesTestingListener(toggleServicesTestingListener);
        isDisposed = true;
        super.dispose();
    }

    public static IConnection findConnection(IConnectedService cs) {
        for (IConnection connection : Registry.instance().getConnections()) {
            for (IConnectedService connectedService : Registry.instance().getConnectedServices(connection)) {
                if (cs.equals(connectedService))
                    return connection;
            }
        }
        return null;
    }

    private static boolean isDynamicConnection(Object object) {
        return object instanceof IConnection2 && ((IConnection2) object).isDynamic();
    }

    private boolean selectionCanBeEdited() {
        ISelection selection = viewer.getSelection();
        return canBeEdited(selection);
    }

    private static boolean canBeEdited(ISelection selection) {
        if (selection.isEmpty())
            return false;
        TreeNode node = (TreeNode) ((IStructuredSelection) selection).getFirstElement();
        return !isDynamicConnection(node.getValue());
    }

    private IConnection getSelectedConnection() {
        ISelection selection = viewer.getSelection();
        if (!selection.isEmpty()) {
            TreeNode treeNode = (TreeNode) ((IStructuredSelection) selection).getFirstElement();
            Object value = treeNode.getValue();
            if (value instanceof IConnection) {
                return (IConnection) value;
            }
        }
        return null;
    }

    public void setSelectedConnection(IConnection connection) {
        if (viewer != null && !viewer.getControl().isDisposed()) {
            if (connection != null) {
                TreeNode node = new TreeNode(connection);
                viewer.setSelection(new StructuredSelection(node));
            } else {
                viewer.setSelection(null);
            }
        }
    }
}