connectivity/com.nokia.carbide.remoteConnections/src/com/nokia/carbide/internal/remoteconnections/settings/ui/DeviceStatusSelectorContribution.java
changeset 706 bba29393db80
parent 705 3051ec3010db
child 707 d320a6d36298
equal deleted inserted replaced
705:3051ec3010db 706:bba29393db80
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the License "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *
       
    16 */
       
    17 
       
    18 package com.nokia.carbide.internal.remoteconnections.settings.ui;
       
    19 
       
    20 import java.text.MessageFormat;
       
    21 import java.util.ArrayList;
       
    22 import java.util.Collections;
       
    23 import java.util.Comparator;
       
    24 import java.util.List;
       
    25 
       
    26 import org.eclipse.jface.layout.GridDataFactory;
       
    27 import org.eclipse.jface.layout.GridLayoutFactory;
       
    28 import org.eclipse.jface.resource.ImageDescriptor;
       
    29 import org.eclipse.swt.SWT;
       
    30 import org.eclipse.swt.custom.CLabel;
       
    31 import org.eclipse.swt.events.MouseAdapter;
       
    32 import org.eclipse.swt.events.MouseEvent;
       
    33 import org.eclipse.swt.events.SelectionAdapter;
       
    34 import org.eclipse.swt.events.SelectionEvent;
       
    35 import org.eclipse.swt.graphics.Image;
       
    36 import org.eclipse.swt.graphics.Point;
       
    37 import org.eclipse.swt.widgets.Composite;
       
    38 import org.eclipse.swt.widgets.Control;
       
    39 import org.eclipse.swt.widgets.Display;
       
    40 import org.eclipse.swt.widgets.Menu;
       
    41 import org.eclipse.swt.widgets.MenuItem;
       
    42 import org.eclipse.swt.widgets.Shell;
       
    43 import org.eclipse.ui.IWorkbench;
       
    44 import org.eclipse.ui.IWorkbenchWindow;
       
    45 import org.eclipse.ui.PartInitException;
       
    46 import org.eclipse.ui.PlatformUI;
       
    47 import org.eclipse.ui.menus.WorkbenchWindowControlContribution;
       
    48 
       
    49 import com.nokia.carbide.remoteconnections.Messages;
       
    50 import com.nokia.carbide.remoteconnections.RemoteConnectionsActivator;
       
    51 import com.nokia.carbide.remoteconnections.interfaces.IConnection;
       
    52 import com.nokia.carbide.remoteconnections.interfaces.IConnectionsManager;
       
    53 import com.nokia.carbide.remoteconnections.interfaces.IConnectionsManager.IConnectionListener;
       
    54 import com.nokia.carbide.remoteconnections.internal.api.IConnection2;
       
    55 import com.nokia.carbide.remoteconnections.internal.api.IConnection2.IStatus;
       
    56 import com.nokia.carbide.remoteconnections.internal.api.IConnection2.IStatusChangedListener;
       
    57 import com.nokia.carbide.remoteconnections.view.ConnectionsView;
       
    58 import com.nokia.cpp.internal.api.utils.core.TextUtils;
       
    59 import com.nokia.cpp.internal.api.utils.ui.WorkbenchUtils;
       
    60 
       
    61 
       
    62 /**
       
    63  * This widget appears in the Eclipse trim and allows the user to select the
       
    64  * "default" device connection and also see its status at a glance. 
       
    65  */
       
    66 public class DeviceStatusSelectorContribution extends WorkbenchWindowControlContribution
       
    67 		implements IConnectionListener, IStatusChangedListener {
       
    68 
       
    69 	private Composite container;
       
    70 	private CLabel deviceInfo;
       
    71 	private IConnectionsManager manager;
       
    72 	private Image deviceImage;
       
    73 	private IConnection defaultConnection;
       
    74 	
       
    75 	public DeviceStatusSelectorContribution() {
       
    76 		manager = RemoteConnectionsActivator.getConnectionsManager();
       
    77 	}
       
    78 	
       
    79 	/*
       
    80 	 * (non-Javadoc)
       
    81 	 * @see org.eclipse.jface.action.ControlContribution#createControl(org.eclipse.swt.widgets.Composite)
       
    82 	 */
       
    83 	@Override
       
    84 	protected Control createControl(Composite parent) {
       
    85 		
       
    86 		// This UI is recreated whenever the default connection changes.
       
    87 		
       
    88 		manager.addConnectionListener(this);
       
    89 		
       
    90 		container = new Composite(parent, SWT.NONE);
       
    91 		GridLayoutFactory.fillDefaults().margins(2, 0).applyTo(container);
       
    92 
       
    93 		// Create a label for the trim.
       
    94 		deviceInfo = new CLabel(container, SWT.FLAT);
       
    95 		GridDataFactory.fillDefaults().grab(false, true).applyTo(deviceInfo);
       
    96 		
       
    97 		String text = Messages.getString("DeviceStatusSelectorContribution_NoDefaultConnectionMessage"); //$NON-NLS-1$
       
    98 		defaultConnection = manager.getDefaultConnection();
       
    99 		if (defaultConnection != null) {
       
   100 			text = defaultConnection.getDisplayName();
       
   101 			if (defaultConnection instanceof IConnection2) {
       
   102 				((IConnection2) defaultConnection).addStatusChangedListener(DeviceStatusSelectorContribution.this);
       
   103 			}
       
   104 		}
       
   105 		
       
   106 		deviceInfo.setText(text);
       
   107 		
       
   108 		updateDeviceStatus(getDeviceStatus(defaultConnection));
       
   109 		
       
   110 		deviceInfo.addMouseListener (new MouseAdapter() {
       
   111 			public void mouseDown(MouseEvent event) {
       
   112 				Shell shell = deviceInfo.getShell();
       
   113 				final Display display = shell.getDisplay();
       
   114 				
       
   115 				final Menu menu = new Menu(shell, SWT.POP_UP);
       
   116 				populateConnectionMenu(menu);
       
   117 				
       
   118 				Point screenLoc = deviceInfo.toDisplay(event.x, event.y);
       
   119 				menu.setLocation(screenLoc.x, screenLoc.y);
       
   120 				menu.setVisible(true);
       
   121 				
       
   122 				while (!menu.isDisposed() && menu.isVisible()) {
       
   123 					if (!display.readAndDispatch())
       
   124 						display.sleep();
       
   125 				}
       
   126 				menu.dispose();
       
   127 			}
       
   128 			/* (non-Javadoc)
       
   129 			 * @see org.eclipse.swt.events.MouseAdapter#mouseDoubleClick(org.eclipse.swt.events.MouseEvent)
       
   130 			 */
       
   131 			@Override
       
   132 			public void mouseDoubleClick(MouseEvent ev) {
       
   133 				// NOTE: the menu usually comes up before double-click is seen
       
   134 				if (ev.button == 1) {
       
   135 					openConnectionsView();
       
   136 				}
       
   137 			}
       
   138 		});
       
   139 		
       
   140 		// TODO PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, null);
       
   141 		return container;
       
   142 	}
       
   143 
       
   144 	/**
       
   145 	 * @param ev
       
   146 	 */
       
   147 	protected void openConnectionsView() {
       
   148 		try {
       
   149 			WorkbenchUtils.getView(ConnectionsView.VIEW_ID);
       
   150         } 
       
   151         catch (PartInitException e) {
       
   152         	RemoteConnectionsActivator.logError(e);
       
   153         }
       
   154 	}
       
   155 
       
   156 	/**
       
   157 	 * @param defaultConnection
       
   158 	 * @param status
       
   159 	 * @return
       
   160 	 */
       
   161 	private String createDeviceStatusTooltip(IConnection defaultConnection,
       
   162 			IStatus status) {
       
   163 		if (defaultConnection == null) {
       
   164 			return Messages.getString("DeviceStatusSelectorContribution.NoDynamicOrManualConnectionsTooltip"); //$NON-NLS-1$
       
   165 		}
       
   166 		
       
   167 		String statusString = null;
       
   168 		if (status != null) {
       
   169 			statusString = status.getDescription();
       
   170 		}
       
   171 		
       
   172 		if (TextUtils.isEmpty(statusString))
       
   173 			statusString = Messages.getString("DeviceStatusSelectorContribution.UnknownStatus"); //$NON-NLS-1$
       
   174 		
       
   175 		return MessageFormat.format(Messages.getString("DeviceStatusSelectorContribution.DeviceStatusFormat"), defaultConnection.getDisplayName(), statusString); //$NON-NLS-1$
       
   176 	}
       
   177 
       
   178 	/**
       
   179 	 * Get the image representing the device status.
       
   180 	 * @param connection
       
   181 	 * @return Image, to be disposed
       
   182 	 */
       
   183 	private IStatus getDeviceStatus(IConnection connection) {
       
   184 		if (!(connection instanceof IConnection2)) {
       
   185 			return null;
       
   186 		} else {
       
   187 			return ((IConnection2) connection).getStatus();
       
   188 		}
       
   189 	}
       
   190 	
       
   191 	/**
       
   192 	 * Get the image representing the device status.
       
   193 	 * @param connection
       
   194 	 * @return Image, to be disposed
       
   195 	 */
       
   196 	private Image createDeviceStatusImage(IStatus status) {
       
   197 		Image statusImage = null;
       
   198 		
       
   199 		String file = null;
       
   200 		if (status != null) {
       
   201 			IStatus.EStatus severity = status.getEStatus();
       
   202 			
       
   203 			if (severity == IStatus.EStatus.READY)
       
   204 				file = "statusReady.png"; 
       
   205 			else if (severity == IStatus.EStatus.IN_USE)
       
   206 				file = "statusInUse.png";
       
   207 			else if (severity == IStatus.EStatus.NOT_READY)
       
   208 				file = "statusUnknown.png";			// <--- 		
       
   209 			else if (severity == IStatus.EStatus.IN_USE_DISCONNECTED)
       
   210 				file = "statusUnavailable.png";
       
   211 		}
       
   212 		
       
   213 		if (file != null) {
       
   214 			ImageDescriptor descriptor;
       
   215 			descriptor = RemoteConnectionsActivator.getImageDescriptor("icons/" + file);
       
   216 			if (descriptor != null) {
       
   217 				statusImage = descriptor.createImage();
       
   218 			}
       
   219 		}
       
   220 		return statusImage;
       
   221 	}
       
   222 
       
   223 	/**
       
   224 	 * @return
       
   225 	 */
       
   226 	protected void populateConnectionMenu(Menu menu) {
       
   227 		IConnection defaultConnection = manager.getDefaultConnection();
       
   228 
       
   229 		// Display the connections with dynamic ones first, 
       
   230 		// then static ones, separated by a separator
       
   231 
       
   232 		List<IConnection> dynamicConnections = new ArrayList<IConnection>();
       
   233 		List<IConnection> staticConnections = new ArrayList<IConnection>();
       
   234 		for (IConnection connection : RemoteConnectionsActivator.getConnectionsManager().getConnections()) {
       
   235 			if (connection instanceof IConnection2 && ((IConnection2)connection).isDynamic()) 
       
   236 				dynamicConnections.add(connection);
       
   237 			else
       
   238 				staticConnections.add(connection);
       
   239 		}
       
   240 		
       
   241 
       
   242 		Comparator<IConnection> connectionComparator = new Comparator<IConnection>() {
       
   243 			public int compare(IConnection o1, IConnection o2) {
       
   244 				return o1.getDisplayName().compareToIgnoreCase(o2.getDisplayName());
       
   245 			}
       
   246 		};
       
   247 		Collections.sort(dynamicConnections, connectionComparator);
       
   248 		Collections.sort(staticConnections, connectionComparator);
       
   249 
       
   250 		MenuItem label = new MenuItem(menu, SWT.NONE);
       
   251 		label.setEnabled(false);
       
   252 		label.setText(Messages.getString("DeviceStatusSelectorContribution_SelectTheDefaultConnectionMessage")); //$NON-NLS-1$
       
   253 		
       
   254 		for (IConnection connection : dynamicConnections) {
       
   255 			createConnectionMenuItem(menu, connection, defaultConnection);
       
   256 		}
       
   257 		
       
   258 		new MenuItem(menu, SWT.SEPARATOR);
       
   259 		
       
   260 		for (IConnection connection : staticConnections) {
       
   261 			createConnectionMenuItem(menu, connection, defaultConnection);
       
   262 		}
       
   263 		
       
   264 		new MenuItem(menu, SWT.SEPARATOR);
       
   265 		
       
   266 		MenuItem openView = new MenuItem(menu, SWT.PUSH);
       
   267 		openView.setText("Open Remote Connections view");
       
   268 		openView.addSelectionListener(new SelectionAdapter() {
       
   269 			@Override
       
   270 			public void widgetSelected(SelectionEvent e) {
       
   271 				openConnectionsView();
       
   272 			}
       
   273 		});
       
   274 	}
       
   275 
       
   276 	/**
       
   277 	 * @param menu
       
   278 	 * @param connection
       
   279 	 * @param defaultConnection 
       
   280 	 */
       
   281 	private MenuItem createConnectionMenuItem(Menu menu, final IConnection connection, IConnection defaultConnection) {
       
   282 		MenuItem item = new MenuItem(menu, SWT.CHECK);
       
   283 		
       
   284 		boolean isDefault = false;
       
   285 		isDefault = connection.equals(defaultConnection);
       
   286 		
       
   287 		item.setSelection(isDefault);
       
   288 		
       
   289 		item.setText(connection.getDisplayName());
       
   290 		
       
   291 		item.addSelectionListener(new SelectionAdapter() {
       
   292 			@Override
       
   293 			public void widgetSelected(SelectionEvent e) {
       
   294 				manager.setDefaultConnection(connection);
       
   295 			}
       
   296 		});		
       
   297 		
       
   298 		return item;
       
   299 	}
       
   300 
       
   301 	/*
       
   302 	 * (non-Javadoc)
       
   303 	 * @see org.eclipse.jface.action.ContributionItem#dispose()
       
   304 	 */
       
   305 	public void dispose() {
       
   306 		if (deviceImage != null) {
       
   307 			deviceImage.dispose();
       
   308 			deviceImage = null;
       
   309 		}
       
   310 		if (defaultConnection instanceof IConnection2)
       
   311 			((IConnection2) defaultConnection).removeStatusChangedListener(this);
       
   312 		
       
   313 		manager.removeConnectionListener(this);
       
   314 		super.dispose();
       
   315 	}
       
   316 
       
   317 	/* (non-Javadoc)
       
   318 	 * @see com.nokia.carbide.remoteconnections.interfaces.IConnectionsManager.IConnectionListener#connectionAdded(com.nokia.carbide.remoteconnections.interfaces.IConnection)
       
   319 	 */
       
   320 	public void connectionAdded(IConnection connection) {
       
   321 		updateUI();
       
   322 	}
       
   323 	
       
   324 	/* (non-Javadoc)
       
   325 	 * @see com.nokia.carbide.remoteconnections.interfaces.IConnectionsManager.IConnectionListener#connectionRemoved(com.nokia.carbide.remoteconnections.interfaces.IConnection)
       
   326 	 */
       
   327 	public void connectionRemoved(IConnection connection) {
       
   328 		updateUI();
       
   329 	}
       
   330 	/* (non-Javadoc)
       
   331 	 * @see com.nokia.carbide.remoteconnections.interfaces.IConnectionsManager.IConnectionListener#defaultConnectionSet(com.nokia.carbide.remoteconnections.interfaces.IConnection)
       
   332 	 */
       
   333 	public void defaultConnectionSet(IConnection connection) {
       
   334 		updateUI();
       
   335 	}
       
   336 
       
   337 	/* (non-Javadoc)
       
   338 	 * @see com.nokia.carbide.remoteconnections.internal.IConnection2.IStatusChangedListener#statusChanged(com.nokia.carbide.remoteconnections.internal.IConnection2.IStatus)
       
   339 	 */
       
   340 	public void statusChanged(IStatus status) {
       
   341 		updateDeviceStatus(status);
       
   342 	}
       
   343 	
       
   344 	/**
       
   345 	 * @param status
       
   346 	 */
       
   347 	private void updateDeviceStatus(IStatus status) {
       
   348 		if (deviceImage != null)
       
   349 			deviceImage.dispose();
       
   350 		
       
   351 		deviceImage = createDeviceStatusImage(status);
       
   352 		deviceInfo.setImage(deviceImage);
       
   353 		deviceInfo.setToolTipText(createDeviceStatusTooltip(defaultConnection, status));
       
   354 	}
       
   355 
       
   356 	/**
       
   357 	 * 
       
   358 	 */
       
   359 	private void updateUI() {
       
   360 		// perform update in UI thread
       
   361 		final IWorkbench workbench = PlatformUI.getWorkbench();
       
   362 		workbench.getDisplay().asyncExec(new Runnable() {
       
   363 			public void run() {
       
   364 				IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
       
   365 				if (window != null) {
       
   366 					update();
       
   367 				}
       
   368 			}
       
   369 		});		
       
   370 	}
       
   371 
       
   372 	/*
       
   373 	 * (non-Javadoc)
       
   374 	 * @see org.eclipse.jface.action.ContributionItem#isDynamic()
       
   375 	 */
       
   376 	@Override
       
   377 	public boolean isDynamic() {
       
   378 		return true;
       
   379 	}
       
   380 
       
   381 	/*
       
   382 	 * (non-Javadoc)
       
   383 	 * @see org.eclipse.jface.action.ContributionItem#update()
       
   384 	 */
       
   385 	@Override
       
   386 	public void update() {
       
   387 		getParent().update(true);
       
   388 	}
       
   389 
       
   390 }