/**************************************************************************** * Copyright (c) 2004, 2007 Composent, Inc. and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Composent, Inc. - initial API and implementation *****************************************************************************/ package org.eclipse.ecf.presence.ui; import java.io.ByteArrayInputStream; import java.util.*; import java.util.List; import org.eclipse.core.runtime.*; import org.eclipse.ecf.core.IContainer; import org.eclipse.ecf.core.identity.ID; import org.eclipse.ecf.core.util.ECFException; import org.eclipse.ecf.internal.presence.ui.Activator; import org.eclipse.ecf.internal.presence.ui.Messages; import org.eclipse.ecf.internal.presence.ui.dialogs.*; import org.eclipse.ecf.presence.*; import org.eclipse.ecf.presence.IPresence.Mode; import org.eclipse.ecf.presence.chatroom.IChatRoomInfo; import org.eclipse.ecf.presence.im.*; import org.eclipse.ecf.presence.roster.*; import org.eclipse.ecf.presence.service.IPresenceService; import org.eclipse.ecf.presence.ui.chatroom.*; import org.eclipse.ecf.presence.ui.dnd.IRosterViewerDropTarget; import org.eclipse.ecf.ui.SharedImages; import org.eclipse.ecf.ui.dialogs.ContainerConnectErrorDialog; import org.eclipse.jface.action.*; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.util.LocalSelectionTransfer; import org.eclipse.jface.viewers.*; import org.eclipse.jface.window.ToolTip; import org.eclipse.jface.window.Window; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; import org.eclipse.swt.dnd.*; import org.eclipse.swt.graphics.*; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.*; import org.eclipse.ui.*; import org.eclipse.ui.forms.FormColors; import org.eclipse.ui.forms.IFormColors; import org.eclipse.ui.forms.widgets.*; import org.eclipse.ui.part.*; /** * View class for displaying multiple rosters in a tree viewer. This view part * implements {@link IMultiRosterViewPart} and provides the ability to display * multiple rosters in a single tree viewer. This class may be subclassed as * desired to add or customize behavior. */ public class MultiRosterView extends ViewPart implements IMultiRosterViewPart { public static final String VIEW_ID = "org.eclipse.ecf.presence.ui.MultiRosterView"; //$NON-NLS-1$ protected static final int DEFAULT_EXPAND_LEVEL = 3; private static final String ROSTER_VIEWER_DROP_TARGET_EPOINT = Activator.PLUGIN_ID + "." //$NON-NLS-1$ + "rosterViewerDropTarget"; //$NON-NLS-1$ private static final String ROSTER_VIEWER_DROP_TARGET_CLASS_ATTR = "class"; //$NON-NLS-1$ private static final Transfer[] dndTransferTypes = {EditorInputTransfer.getInstance(), FileTransfer.getInstance(), HTMLTransfer.getInstance(), LocalSelectionTransfer.getTransfer(), PluginTransfer.getInstance(), RTFTransfer.getInstance(), TextTransfer.getInstance()}; private static final int dndOperations = DND.DROP_COPY | DND.DROP_MOVE | DND.DROP_LINK; protected TreeViewer treeViewer; protected List rosterAccounts = new ArrayList(); private Hashtable chatRooms = new Hashtable(); private IMenuManager setStatusMenu; private IAction imAction; private IAction removeAction; private IAction setAvailableAction; private IAction setAwayAction; private IAction setDNDAction; private IAction setInvisibleAction; private IAction setOfflineAction; private IAction showOfflineAction; private IAction showEmptyGroupsAction; private IAction showAwayAction; private IAction addContactAction; private IAction searchContactAction; private IAction openChatRoomAction; private IAction openAccountChatRoomAction; private IAction changePasswordAction; private IAction disconnectAllAccountsAction; private IAction disconnectAccountAction; // private IRosterSubscriptionListener subscriptionListener; private IPresenceListener presenceListener; private RosterViewerDropAdapter dropAdapter; private PageBook pageBook; private Label helpMessageLabel; private ViewerFilter hideOfflineFilter = new ViewerFilter() { public boolean select(Viewer viewer, Object parentElement, Object element) { if (element instanceof IRosterEntry) { IRosterEntry entry = (IRosterEntry) element; IPresence presence = entry.getPresence(); if (presence != null) return (presence.getType() != IPresence.Type.UNAVAILABLE); return true; } return true; } }; private ViewerFilter hideEmptyGroupsFilter = new ViewerFilter() { public boolean select(Viewer viewer, Object parentElement, Object element) { if (element instanceof IRosterGroup) { return !((IRosterGroup) element).getEntries().isEmpty(); } return true; } }; private ViewerFilter showAwayFilter = new ViewerFilter() { public boolean select(Viewer viewer, Object parentElement, Object element) { if (element instanceof IRosterEntry) { IRosterEntry entry = (IRosterEntry) element; IPresence presence = entry.getPresence(); if (presence != null) { Mode m = presence.getMode(); return (m == IPresence.Mode.AVAILABLE || m == IPresence.Mode.CHAT || m == IPresence.Mode.DND); } return true; } return true; } }; /* * (non-Javadoc) * * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite) */ public void createPartControl(Composite parent) { pageBook = new PageBook(parent, SWT.NONE); createHelpMessage(pageBook); setupTreeViewer(pageBook); if (rosterAccounts.size() == 0) pageBook.showPage(helpMessageLabel); } private void createHelpMessage(Composite parent) { if (!parent.isDisposed()) { helpMessageLabel = new Label(parent, SWT.TOP + SWT.LEFT + SWT.WRAP); helpMessageLabel.setText(Messages.MultiRosterView_HELP_MESSAGE); } } protected void setupTreeViewer(Composite parent) { treeViewer = new TreeViewer(parent, SWT.BORDER | SWT.SINGLE | SWT.V_SCROLL); getSite().setSelectionProvider(treeViewer); presenceListener = new PresenceListener(); treeViewer.setContentProvider(new MultiRosterContentProvider()); treeViewer.setLabelProvider(new MultiRosterLabelProvider()); treeViewer.addFilter(hideOfflineFilter); treeViewer.addFilter(hideEmptyGroupsFilter); treeViewer.addFilter(showAwayFilter); treeViewer.setInput(rosterAccounts); treeViewer.addOpenListener(new IOpenListener() { public void open(OpenEvent e) { message((IStructuredSelection) e.getSelection()); } }); ToolTip toolTip = new ViewerToolTip(treeViewer.getControl()); toolTip.setHideOnMouseDown(false); toolTip.setPopupDelay(200); toolTip.setShift(new Point(5, 5)); makeActions(); hookContextMenu(); contributeToActionBars(); hookDropSupport(); retrieveServices(); treeViewer.expandToLevel(DEFAULT_EXPAND_LEVEL); } class RosterViewerDropAdapter extends ViewerDropAdapter { private List rosterDropTargets = new ArrayList(); private List rosterPerformDrop = new ArrayList(); public RosterViewerDropAdapter(TreeViewer treeViewer, IRosterViewerDropTarget dropTarget) { super(treeViewer); Assert.isNotNull(dropTarget); setFeedbackEnabled(false); addRosterDropTarget(dropTarget); } public boolean addRosterDropTarget(IRosterViewerDropTarget rosterDropTarget) { return rosterDropTargets.add(rosterDropTarget); } public boolean performDrop(Object data) { boolean result = false; for (Iterator i = rosterPerformDrop.iterator(); i.hasNext();) { IRosterViewerDropTarget rdt = (IRosterViewerDropTarget) i.next(); if (rdt.performDrop(data)) result = true; } rosterPerformDrop.clear(); return result; } public void dispose() { rosterDropTargets.clear(); rosterPerformDrop.clear(); } public boolean validateDrop(Object target, int operation, TransferData transferType) { if (target instanceof IRosterItem) { rosterPerformDrop.clear(); boolean result = false; for (Iterator i = rosterDropTargets.iterator(); i.hasNext();) { IRosterViewerDropTarget rdt = (IRosterViewerDropTarget) i.next(); if (rdt.validateDrop((IRosterItem) target, operation, transferType)) { result = true; rosterPerformDrop.add(rdt); } } return result; } return false; } } private void hookDropSupport() { IExtensionRegistry reg = Activator.getDefault().getExtensionRegistry(); if (reg != null) { IExtensionPoint extensionPoint = reg.getExtensionPoint(ROSTER_VIEWER_DROP_TARGET_EPOINT); if (extensionPoint == null) { return; } IConfigurationElement[] configurationElements = extensionPoint.getConfigurationElements(); for (int i = 0; i < configurationElements.length; i++) { try { IRosterViewerDropTarget rosterDropTarget = (IRosterViewerDropTarget) configurationElements[i].createExecutableExtension(ROSTER_VIEWER_DROP_TARGET_CLASS_ATTR); if (dropAdapter == null) { dropAdapter = new RosterViewerDropAdapter(treeViewer, rosterDropTarget); treeViewer.addDropSupport(dndOperations, dndTransferTypes, dropAdapter); } else dropAdapter.addRosterDropTarget(rosterDropTarget); } catch (CoreException e) { // Log Activator.getDefault().getLog().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, IStatus.ERROR, Messages.MultiRosterView_ROSTER_VIEW_EXT_POINT_ERROR_MESSAGE, e)); } } } } private void retrieveServices() { IPresenceService[] services = Activator.getDefault().getPresenceServices(); for (int i = 0; i < services.length; i++) { IContainer container = (IContainer) services[i].getAdapter(IContainer.class); if (container != null && container.getConnectedID() != null) { addContainer(container); } } } protected IChatRoomCommandListener createChatRoomCommandListener() { return null; } protected IChatRoomViewCloseListener createChatRoomViewCloseListener(final ID connectedID) { return new IChatRoomViewCloseListener() { public void chatRoomViewClosing() { chatRooms.remove(connectedID); } }; } /** * For the given container, join the chat room specified by roomInfo. NOTE: * this is to be considered provisional 'Gunner' API and may not be * available in subsequent versions of this class. * * @param container * the IContainer instance that exposes the chat room. Must not * be <code>null</code>. Also must be the same container * associated with one of the accounts managed by this * MultiRosterView. * @param roomInfo * chat room information that will be used to join. Must not be * <code>null</code>. * @param password * a password associated with chat room access. May be * <code>null</code>. * @throws ECFException * if the given container is not connected, or if the given * container is not managed by this MultiRosterView, or if * {@link ChatRoomManagerView} cannot be initialized. */ protected void joinChatRoom(IContainer container, IChatRoomInfo roomInfo, String password) throws ECFException { Assert.isNotNull(container); Assert.isNotNull(roomInfo); // Check to make sure given container is connected. ID connectedID = container.getConnectedID(); if (connectedID == null) throw new ECFException(Messages.MultiRosterView_EXCEPTION_JOIN_ROOM_NOT_CONNECTED); // Check to make sure that the given container is one that we have in // our accounts set if (findAccountForContainer(container) == null) throw new ECFException(Messages.MultiRosterView_EXCEPTION_JOIN_ROOM_INVALID_ACCOUNT); IWorkbenchWindow ww = getViewSite().getPage().getWorkbenchWindow(); IWorkbenchPage wp = ww.getActivePage(); // Get existing roomView...if it's there RoomWithAView roomView = (RoomWithAView) chatRooms.get(connectedID); if (roomView != null) { // We've already connected to this room, so just show it. ChatRoomManagerView chatroommanagerview = roomView.getView(); wp.activate(chatroommanagerview); chatroommanagerview.joinRoom(roomInfo, password); return; } try { IViewReference ref = wp.findViewReference(org.eclipse.ecf.presence.ui.chatroom.ChatRoomManagerView.VIEW_ID, connectedID.getName()); // Open view for given connectedID (secondaryID) final ChatRoomManagerView chatroommanagerview = (ChatRoomManagerView) ((ref == null) ? wp.showView(org.eclipse.ecf.presence.ui.chatroom.ChatRoomManagerView.VIEW_ID, connectedID.getName(), IWorkbenchPage.VIEW_ACTIVATE) : ref.getView(true)); // initialize new view chatroommanagerview.initializeWithoutManager(ChatRoomManagerView.getUsernameFromID(connectedID), ChatRoomManagerView.getHostnameFromID(connectedID), createChatRoomCommandListener(), createChatRoomViewCloseListener(connectedID)); // join room chatroommanagerview.joinRoom(roomInfo, password); roomView = new RoomWithAView(chatroommanagerview, connectedID); chatRooms.put(roomView.getID(), roomView); } catch (Exception e1) { throw new ECFException(e1); } } private void selectAndJoinChatRoomForAccounts(MultiRosterAccount[] accounts) { // Create chat room selection dialog with managers, open ChatRoomSelectionDialog dialog = new ChatRoomSelectionDialog(getViewSite().getShell(), accounts); dialog.open(); // If selection cancelled then simply return if (dialog.getReturnCode() != Window.OK) return; // Get selected room, selected manager, and selected IChatRoomInfo IChatRoomInfo selectedInfo = dialog.getSelectedRoom().getRoomInfo(); MultiRosterAccount account = dialog.getSelectedRoom().getAccount(); // Now get the secondary ID from the selected room id final IContainer container = account.getContainer(); final ID connectedID = container.getConnectedID(); if (connectedID == null) { MessageDialog.openError(getViewSite().getShell(), Messages.MultiRosterView_NO_IDENTIFIER_FOR_ROOM_TITLE, NLS.bind(Messages.MultiRosterView_NO_IDENTIFIER_FOR_ROOM_MESSAGE, selectedInfo.getRoomID())); return; } try { joinChatRoom(container, selectedInfo, null); } catch (ECFException e) { Throwable e1 = e.getStatus().getException(); Activator.getDefault().getLog().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, IStatus.ERROR, Messages.MultiRosterView_EXCEPTION_LOG_JOIN_ROOM, e1)); ContainerConnectErrorDialog ed = new ContainerConnectErrorDialog(getViewSite().getShell(), selectedInfo.getRoomID().getName(), e1); ed.open(); } } private void makeActions() { imAction = new Action() { public void run() { message((IStructuredSelection) treeViewer.getSelection()); } }; imAction.setImageDescriptor(SharedImages.getImageDescriptor(SharedImages.IMG_MESSAGE)); removeAction = new Action() { public void run() { IStructuredSelection iss = (IStructuredSelection) treeViewer.getSelection(); remove((IRosterEntry) iss.getFirstElement()); } }; removeAction.setText(Messages.MultiRosterView_Remove); removeAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_TOOL_DELETE)); setAvailableAction = new Action(Messages.MultiRosterView_SetAvailable, IAction.AS_RADIO_BUTTON) { public void run() { if (isChecked()) { sendPresence(IPresence.Mode.AVAILABLE); } } }; setAwayAction = new Action(Messages.MultiRosterView_SetAway, IAction.AS_RADIO_BUTTON) { public void run() { if (isChecked()) { sendPresence(IPresence.Mode.AWAY); } } }; setDNDAction = new Action(Messages.MultiRosterView_SetDoNotDisturb, IAction.AS_RADIO_BUTTON) { public void run() { if (isChecked()) { sendPresence(IPresence.Mode.DND); } } }; setInvisibleAction = new Action(Messages.MultiRosterView_SetInvisible, IAction.AS_RADIO_BUTTON) { public void run() { if (isChecked()) { sendPresence(IPresence.Mode.INVISIBLE); } } }; setOfflineAction = new Action(Messages.MultiRosterView_SetOffline, IAction.AS_RADIO_BUTTON) { public void run() { if (isChecked()) { for (int i = 0; i < rosterAccounts.size(); i++) { MultiRosterAccount account = (MultiRosterAccount) rosterAccounts.get(i); treeViewer.remove(account); } rosterAccounts.clear(); refreshTreeViewer(null, false); setStatusMenu.setVisible(false); getViewSite().getActionBars().getMenuManager().update(false); } } }; setOfflineAction.setChecked(true); showOfflineAction = new Action(Messages.MultiRosterView_ShowOffline, IAction.AS_CHECK_BOX) { public void run() { if (isChecked()) { treeViewer.removeFilter(hideOfflineFilter); } else { treeViewer.addFilter(hideOfflineFilter); } } }; showEmptyGroupsAction = new Action(Messages.MultiRosterView_ShowEmptyGroups, IAction.AS_CHECK_BOX) { public void run() { if (isChecked()) { treeViewer.removeFilter(hideEmptyGroupsFilter); } else { treeViewer.addFilter(hideEmptyGroupsFilter); } } }; showAwayAction = new Action(Messages.MultiRosterView_ShowAway, IAction.AS_CHECK_BOX) { public void run() { if (isChecked()) { treeViewer.removeFilter(showAwayFilter); } else { treeViewer.addFilter(showAwayFilter); } } }; addContactAction = new Action(Messages.MultiRosterView_AddContact, SharedImages.getImageDescriptor(SharedImages.IMG_ADD_BUDDY)) { public void run() { AddContactDialog dialog = new AddContactDialog(treeViewer.getControl().getShell()); IStructuredSelection iss = (IStructuredSelection) treeViewer.getSelection(); IRoster roster = (IRoster) iss.getFirstElement(); MultiRosterAccount account = findAccountForUser(roster.getUser().getID()); dialog.setInput(rosterAccounts); dialog.setDefaultRosterAccount(account); if (Window.OK == dialog.open()) { IPresenceContainerAdapter ipca = dialog.getSelection(); IRosterSubscriptionSender sender = ipca.getRosterManager().getRosterSubscriptionSender(); try { sender.sendRosterAdd(dialog.getAccountID(), dialog.getAlias(), null); } catch (ECFException e) { Activator.getDefault().getLog().log(e.getStatus()); } } } }; searchContactAction = new Action() { public void run() { IStructuredSelection iss = (IStructuredSelection) treeViewer.getSelection(); IRoster roster = (IRoster) iss.getFirstElement(); MultiRosterAccount account = findAccountForUser(roster.getUser().getID()); if (account != null) { SearchContactDialog dialog = new SearchContactDialog(treeViewer.getControl().getShell(), account); dialog.open(); } } }; searchContactAction.setText(Messages.MultiRosterView_SearchContact); openChatRoomAction = new Action() { public void run() { selectAndJoinChatRoomForAccounts((MultiRosterAccount[]) rosterAccounts.toArray(new MultiRosterAccount[] {})); } }; openChatRoomAction.setText(Messages.MultiRosterView_ENTER_CHATROOM_ACTION_TEXT); openChatRoomAction.setToolTipText(Messages.MultiRosterView_ENTER_CHATROOM_TOOLTIP_TEXT); openChatRoomAction.setImageDescriptor(SharedImages.getImageDescriptor(SharedImages.IMG_ADD_CHAT)); openChatRoomAction.setEnabled(true); openAccountChatRoomAction = new Action() { public void run() { IStructuredSelection iss = (IStructuredSelection) treeViewer.getSelection(); IRoster roster = (IRoster) iss.getFirstElement(); MultiRosterAccount account = findAccountForUser(roster.getUser().getID()); if (account != null) selectAndJoinChatRoomForAccounts(new MultiRosterAccount[] {account}); } }; openAccountChatRoomAction.setText(Messages.MultiRosterView_SHOW_CHAT_ROOMS_FOR_ACCOUNT_ACTION_TEXT); openAccountChatRoomAction.setEnabled(true); openAccountChatRoomAction.setImageDescriptor(SharedImages.getImageDescriptor(SharedImages.IMG_ADD_CHAT)); changePasswordAction = new Action() { public void run() { IStructuredSelection iss = (IStructuredSelection) treeViewer.getSelection(); IRoster roster = (IRoster) iss.getFirstElement(); MultiRosterAccount account = findAccountForUser(roster.getUser().getID()); if (account != null) changePasswordForAccount(account); } }; changePasswordAction.setText(Messages.MultiRosterView_CHANGE_PASSWORD_MENU); changePasswordAction.setEnabled(true); disconnectAllAccountsAction = new Action() { public void run() { if (MessageDialog.openQuestion(getViewSite().getShell(), Messages.MultiRosterView_DISCONNECT_QUESTION_TITLE, Messages.MultiRosterView_DISCONNECT_ALL_ACCOUNTS_QUESTION_MESSAGE)) { disconnectAccounts((MultiRosterAccount[]) rosterAccounts.toArray(new MultiRosterAccount[] {})); } } }; disconnectAllAccountsAction.setText(Messages.MultiRosterView_DISCONNECT_ALL_ACCOUNTS_ACTION_TEXT); disconnectAllAccountsAction.setEnabled(true); disconnectAllAccountsAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_TOOL_DELETE)); disconnectAccountAction = new Action() { public void run() { IStructuredSelection iss = (IStructuredSelection) treeViewer.getSelection(); IRoster roster = (IRoster) iss.getFirstElement(); MultiRosterAccount account = findAccountForUser(roster.getUser().getID()); ID connectedID = account.getContainer().getConnectedID(); if (account != null && connectedID != null && MessageDialog.openQuestion(getViewSite().getShell(), Messages.MultiRosterView_DISCONNECT_QUESTION_TITLE, NLS.bind(Messages.MultiRosterView_DISCONNECT_ACCOUNT_QUESTION_MESSAGE, connectedID.getName()))) { disconnectAccounts(new MultiRosterAccount[] {account}); } } }; disconnectAccountAction.setText(Messages.MultiRosterView_DISCONNECT_ACCOUNT_ACTION_TEXT); disconnectAccountAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_TOOL_DELETE)); } protected void changePasswordForAccount(MultiRosterAccount account) { ChangePasswordDialog cpd = new ChangePasswordDialog(getViewSite().getShell(), account.getRoster().getUser().getID().getName()); cpd.open(); if (cpd.getResult() == Window.OK) { IPresenceContainerAdapter pc = account.getPresenceContainerAdapter(); IAccountManager am = pc.getAccountManager(); try { if (am.changePassword(cpd.getNewPassword())) MessageDialog.openInformation(getViewSite().getShell(), Messages.MultiRosterView_PASSWORD_CHANGED_DIALOG_TITLE, Messages.MultiRosterView_PASSWORD_CHANGED_MESSAGE); else MessageDialog.openInformation(getViewSite().getShell(), Messages.MultiRosterView_PASSWORD_NOT_CHANGED_TITLE, Messages.MultiRosterView_PASSWORD_NOT_CHANGED_MESSAGE); } catch (ECFException e) { MessageDialog.openError(getViewSite().getShell(), Messages.MultiRosterView_PASSWORD_NOT_CHANGED_TITLE, Messages.MultiRosterView_PASSWORD_CHANGE_ERROR); Activator.getDefault().getLog().log(e.getStatus()); } } } protected void disconnectAccounts(MultiRosterAccount[] accounts) { for (int i = 0; i < accounts.length; i++) accounts[i].getContainer().disconnect(); } private MultiRosterAccount findAccountForUser(ID userID) { for (Iterator i = rosterAccounts.iterator(); i.hasNext();) { MultiRosterAccount account = (MultiRosterAccount) i.next(); if (account.getRoster().getUser().getID().equals(userID)) return account; } return null; } private void sendPresence(IPresence.Mode mode) { try { for (Iterator i = rosterAccounts.iterator(); i.hasNext();) { MultiRosterAccount account = (MultiRosterAccount) i.next(); account.getRosterManager().getPresenceSender().sendPresenceUpdate(null, new Presence(IPresence.Type.AVAILABLE, null, mode)); } } catch (ECFException e) { Activator.getDefault().getLog().log(e.getStatus()); } } private void hookContextMenu() { MenuManager menuMgr = new MenuManager(); menuMgr.setRemoveAllWhenShown(true); menuMgr.addMenuListener(new IMenuListener() { public void menuAboutToShow(IMenuManager manager) { fillContextMenu(manager); } }); Menu menu = menuMgr.createContextMenu(treeViewer.getControl()); treeViewer.getControl().setMenu(menu); getSite().registerContextMenu(menuMgr, treeViewer); } private void fillContextMenu(IMenuManager manager) { IStructuredSelection iss = (IStructuredSelection) treeViewer.getSelection(); Object element = iss.getFirstElement(); if (element instanceof IRosterEntry) { IRosterEntry entry = (IRosterEntry) element; manager.add(imAction); imAction.setText(Messages.MultiRosterView_SendIM); // if the person is not online, we'll disable the action imAction.setEnabled(entry.getPresence().getType() == IPresence.Type.AVAILABLE); manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); manager.add(removeAction); } else if (element instanceof IRoster) { IAccountManager accountManager = ((IRoster) element).getPresenceContainerAdapter().getAccountManager(); if (accountManager != null) { manager.add(changePasswordAction); manager.add(new Separator()); } manager.add(addContactAction); manager.add(new Separator()); //add if the provider supports user search if (((IRoster) element).getPresenceContainerAdapter().getUserSearchManager().isEnabled()) { manager.add(searchContactAction); manager.add(new Separator()); } manager.add(openAccountChatRoomAction); manager.add(new Separator()); manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); manager.add(disconnectAccountAction); } else { manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); } } private IRosterEntry find(Collection items, ID userID) { for (Iterator it = items.iterator(); it.hasNext();) { Object item = it.next(); if (item instanceof IRosterGroup) { IRosterEntry entry = find(((IRosterGroup) item).getEntries(), userID); if (entry != null) { return entry; } } else if (userID.equals(((IRosterEntry) item).getUser().getID())) { return (IRosterEntry) item; } } return null; } private MultiRosterAccount findAccountForContainer(IContainer container) { if (container == null) return null; synchronized (rosterAccounts) { for (Iterator i = rosterAccounts.iterator(); i.hasNext();) { MultiRosterAccount account = (MultiRosterAccount) i.next(); if (account.getContainer().getID().equals(container.getID())) return account; } } return null; } private void remove(IRosterEntry entry) { try { IRoster roster = entry.getRoster(); if (roster != null) { roster.getPresenceContainerAdapter().getRosterManager().getRosterSubscriptionSender().sendRosterRemove(entry.getUser().getID()); } } catch (ECFException e) { MessageDialog.openError(getViewSite().getShell(), Messages.MultiRosterView_ERROR_CONTACT_REMOVE_TITLE, NLS.bind(Messages.MultiRosterView_ERROR_CONTACT_REMOVED_MESSAGE, entry.getUser().getID().getName())); Activator.getDefault().getLog().log(e.getStatus()); } } private void message(IStructuredSelection iss) { Object element = iss.getFirstElement(); if (!(element instanceof IRosterEntry)) { return; } IRosterEntry entry = (IRosterEntry) element; IRoster roster = entry.getRoster(); if (roster != null) { IChatManager manager = roster.getPresenceContainerAdapter().getChatManager(); IChatMessageSender icms = manager.getChatMessageSender(); ITypingMessageSender itms = manager.getTypingMessageSender(); try { MessagesView view = (MessagesView) getSite().getWorkbenchWindow().getActivePage().showView(MessagesView.VIEW_ID); view.selectTab(icms, itms, roster.getUser().getID(), entry.getUser().getID(), entry.getUser().getName()); } catch (PartInitException e) { e.printStackTrace(); } } } private void contributeToActionBars() { IActionBars bars = getViewSite().getActionBars(); fillLocalPullDown(bars.getMenuManager()); } private void setLocalPullDownEnabled(boolean enabled) { setAvailableAction.setEnabled(enabled); setAwayAction.setEnabled(enabled); setDNDAction.setEnabled(enabled); setInvisibleAction.setEnabled(enabled); setOfflineAction.setEnabled(enabled); showOfflineAction.setEnabled(enabled); showAwayAction.setEnabled(enabled); showEmptyGroupsAction.setEnabled(enabled); addContactAction.setEnabled(enabled); searchContactAction.setEnabled(enabled); openChatRoomAction.setEnabled(enabled); disconnectAllAccountsAction.setEnabled(enabled); } private void fillLocalPullDown(IMenuManager manager) { setStatusMenu = new MenuManager(Messages.MultiRosterView_SetStatusAs, null); setStatusMenu.add(setAvailableAction); setStatusMenu.add(setAwayAction); setStatusMenu.add(setDNDAction); setStatusMenu.add(setInvisibleAction); setStatusMenu.add(setOfflineAction); manager.add(setStatusMenu); manager.add(new Separator()); manager.add(showOfflineAction); manager.add(showEmptyGroupsAction); manager.add(showAwayAction); manager.add(new Separator()); manager.add(addContactAction); manager.add(new Separator()); manager.add(searchContactAction); manager.add(new Separator()); manager.add(openChatRoomAction); manager.add(new Separator()); manager.add(disconnectAllAccountsAction); setLocalPullDownEnabled(false); } /* * (non-Javadoc) * * @see org.eclipse.ui.part.WorkbenchPart#dispose() */ public void dispose() { if (dropAdapter != null) { dropAdapter.dispose(); dropAdapter = null; } treeViewer = null; for (Iterator i = rosterAccounts.iterator(); i.hasNext();) { MultiRosterAccount account = (MultiRosterAccount) i.next(); account.getRosterManager().removePresenceListener(presenceListener); // detach listeners account.dispose(); } rosterAccounts.clear(); super.dispose(); } protected boolean containerPresent(IContainer container) { // Then check if this new account is already in rosterAccounts (container ID the same). for (Iterator i = rosterAccounts.iterator(); i.hasNext();) { MultiRosterAccount existingAccount = (MultiRosterAccount) i.next(); if (existingAccount.getContainer().getID().equals(container.getID())) return true; } return false; } protected boolean addRosterAccount(MultiRosterAccount account) { // If account is null, we don't add it. This is just a sanity check. if (account == null) return false; // Not found, so we continue with add boolean result = rosterAccounts.add(account); if (result) setLocalPullDownEnabled(true); return result; } protected void rosterAccountDisconnected(MultiRosterAccount disconnectedAccount) { // remove account. This will be changed to maintain the roster account // info even though disconnected...see bug // https://bugs.eclipse.org/bugs/show_bug.cgi?id=166670 removeRosterAccount(disconnectedAccount); } protected void removeRosterAccount(MultiRosterAccount account) { // Remove presence listener account.getRosterManager().removePresenceListener(presenceListener); if (treeViewer != null) treeViewer.remove(account.getRoster()); // Remove account rosterAccounts.remove(account); if (rosterAccounts.size() == 0) { setLocalPullDownEnabled(false); // container may disconnect while widgets are being disposed, check for this if (!pageBook.isDisposed()) { pageBook.showPage(helpMessageLabel); } } account.dispose(); refreshTreeViewer(null, true); } /* * (non-Javadoc) * * @see org.eclipse.ui.part.WorkbenchPart#setFocus() */ public void setFocus() { treeViewer.getControl().setFocus(); } protected void refreshTreeViewer(Object val, boolean labels) { if (treeViewer != null) { Control c = treeViewer.getControl(); if (c != null && !c.isDisposed()) { if (val != null) { treeViewer.refresh(val, labels); ViewerFilter[] filters = treeViewer.getFilters(); if (filters.length != 0) { treeViewer.refresh(labels); } } else { treeViewer.refresh(labels); } treeViewer.expandToLevel(DEFAULT_EXPAND_LEVEL); } } } protected void addEntryToTreeViewer(IRosterEntry entry) { if (treeViewer != null) treeViewer.add(entry.getParent(), entry); } protected void removeEntryFromTreeViewer(IRosterEntry entry) { if (treeViewer != null) treeViewer.remove(entry); } protected void removeEntryFromTreeViewer(ID entryID) { synchronized (rosterAccounts) { for (Iterator i = rosterAccounts.iterator(); i.hasNext();) { MultiRosterAccount account = (MultiRosterAccount) i.next(); final IRosterEntry entry = find(account.getRoster().getItems(), entryID); if (entry != null) treeViewer.remove(entry); } } } /* * (non-Javadoc) * * @see org.eclipse.ecf.presence.ui.IMultiRosterViewPart#addContainer(org.eclipse.ecf.core.IContainer) */ public boolean addContainer(IContainer container) { if (container == null) return false; IPresenceContainerAdapter containerAdapter = (IPresenceContainerAdapter) container.getAdapter(IPresenceContainerAdapter.class); if (containerAdapter == null) return false; if (containerPresent(container)) return false; MultiRosterAccount account = new MultiRosterAccount(this, container, containerAdapter); if (!addRosterAccount(account)) return false; IRosterManager manager = containerAdapter.getRosterManager(); try { if (setAvailableAction.isChecked() || setOfflineAction.isChecked()) { manager.getPresenceSender().sendPresenceUpdate(null, new Presence(null, null, IPresence.Mode.AVAILABLE)); setOfflineAction.setChecked(false); setAvailableAction.setChecked(true); } else if (setAwayAction.isChecked()) { manager.getPresenceSender().sendPresenceUpdate(null, new Presence(null, null, IPresence.Mode.AWAY)); } else if (setDNDAction.isChecked()) { manager.getPresenceSender().sendPresenceUpdate(null, new Presence(null, null, IPresence.Mode.DND)); } else if (setInvisibleAction.isChecked()) { manager.getPresenceSender().sendPresenceUpdate(null, new Presence(null, null, IPresence.Mode.INVISIBLE)); } } catch (ECFException e) { Activator.getDefault().getLog().log(e.getStatus()); } containerAdapter.getRosterManager().addPresenceListener(presenceListener); setStatusMenu.setVisible(true); getViewSite().getActionBars().getMenuManager().update(true); treeViewer.add(treeViewer.getInput(), account.getRoster()); pageBook.showPage(treeViewer.getControl()); return true; } private class PresenceListener implements IPresenceListener { /* * (non-Javadoc) * * @see org.eclipse.ecf.presence.IParticipantListener#handlePresence(org.eclipse.ecf.core.identity.ID, * org.eclipse.ecf.presence.IPresence) */ public void handlePresence(ID fromID, IPresence presence) { // do nothing } } private class ViewerToolTip extends ToolTip { private Image image; public ViewerToolTip(Control control) { super(control); } protected Composite createToolTipContentArea(Event event, Composite parent) { TreeItem item = treeViewer.getTree().getItem(new Point(event.x, event.y)); IRosterEntry entry = (IRosterEntry) item.getData(); FormToolkit toolkit = new FormToolkit(parent.getDisplay()); FormColors colors = toolkit.getColors(); Color top = colors.getColor(IFormColors.H_GRADIENT_END); Color bot = colors.getColor(IFormColors.H_GRADIENT_START); // create the base form Form form = toolkit.createForm(parent); form.setText(entry.getName()); form.setImage(SharedImages.getImage(SharedImages.IMG_USER_AVAILABLE)); form.setTextBackground(new Color[] {top, bot}, new int[] {100}, true); GridLayout layout = new GridLayout(); layout.numColumns = 3; form.getBody().setLayout(layout); // create the text FormText text = toolkit.createFormText(form.getBody(), true); GridData td = new GridData(); td.horizontalSpan = 2; td.heightHint = 100; td.widthHint = 250; text.setLayoutData(td); String buffer = getRosterEntryChildrenFromPresence(entry); text.setText(buffer, true, false); // create the picture td = new GridData(); td.horizontalSpan = 1; td.heightHint = 100; td.widthHint = 64; FormText formImage = toolkit.createFormText(form.getBody(), false); formImage.setText("<form><p><img href=\"image\"/></p></form>", true, false); //$NON-NLS-1$ formImage.setLayoutData(td); // grab the image and resize it byte[] data = entry.getPresence().getPictureData(); if (data.length != 0) { Image originalImage = new Image(parent.getDisplay(), new ByteArrayInputStream(data)); image = resize(originalImage, 64, 64); formImage.setImage("image", image); //$NON-NLS-1$ originalImage.dispose(); } return parent; } public void deactivate() { super.deactivate(); if (image != null) image.dispose(); } private Image resize(Image image1, int width, int height) { final Image scaled = new Image(Display.getDefault(), width, height); GC gc = new GC(scaled); gc.setAntialias(SWT.ON); gc.setInterpolation(SWT.HIGH); gc.drawImage(image1, 0, 0, image1.getBounds().width, image1.getBounds().height, 0, 0, width, height); gc.dispose(); return scaled; } private String getResourceName(ID id) { IFQID fqid = (IFQID) id.getAdapter(IFQID.class); if (fqid != null) { return fqid.getResourceName(); } return null; } private String getRosterEntryChildrenFromPresence(IRosterEntry entry) { IPresence presence = entry.getPresence(); Map properties = presence.getProperties(); String resourceName = getResourceName(entry.getUser().getID()); StringBuffer buffer = new StringBuffer(); buffer.append("<form>"); //$NON-NLS-1$ buffer.append("<p>"); //$NON-NLS-1$ buffer.append(NLS.bind(Messages.RosterWorkbenchAdapterFactory_Account, entry.getUser().getID().getName())); buffer.append("</p>"); //$NON-NLS-1$ buffer.append("<p>"); //$NON-NLS-1$ buffer.append(NLS.bind(Messages.RosterWorkbenchAdapterFactory_Type, presence.getType())); buffer.append("</p>"); //$NON-NLS-1$ buffer.append("<p>");//$NON-NLS-1$ buffer.append(NLS.bind(Messages.RosterWorkbenchAdapterFactory_Mode, presence.getMode().toString())); buffer.append("</p>"); //$NON-NLS-1$ buffer.append("<p>"); //$NON-NLS-1$ buffer.append(NLS.bind(Messages.RosterWorkbenchAdapterFactory_Resource, ((resourceName == null) ? "" : resourceName))); //$NON-NLS-1$ buffer.append("</p>"); //$NON-NLS-1$ for (Iterator i = properties.keySet().iterator(); i.hasNext();) { buffer.append("<p>"); //$NON-NLS-1$ Object key = i.next(); buffer.append(key).append(": ").append(properties.get(key)); //$NON-NLS-1$ buffer.append("</p>"); //$NON-NLS-1$ } buffer.append("</form>"); //$NON-NLS-1$ return buffer.toString(); } protected boolean shouldCreateToolTip(Event e) { if (super.shouldCreateToolTip(e)) { TreeItem item = treeViewer.getTree().getItem(new Point(e.x, e.y)); return item != null && item.getData() instanceof IRosterEntry; } return false; } } class RoomWithAView { ChatRoomManagerView view; ID secondaryID; RoomWithAView(ChatRoomManagerView view, ID secondaryID) { this.view = view; this.secondaryID = secondaryID; } public ChatRoomManagerView getView() { return view; } public ID getID() { return secondaryID; } } }