| /**************************************************************************** |
| * 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; |
| } |
| } |
| } |