blob: 96b8b19c6addb59535eac7daa2c1e7e3514d14f1 [file] [log] [blame]
/****************************************************************************
* 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.util.ArrayList;
import java.util.Collection;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
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.AddContactDialog;
import org.eclipse.ecf.internal.presence.ui.dialogs.ChangePasswordDialog;
import org.eclipse.ecf.internal.presence.ui.dialogs.ChatRoomSelectionDialog;
import org.eclipse.ecf.presence.IAccountManager;
import org.eclipse.ecf.presence.IPresence;
import org.eclipse.ecf.presence.IPresenceContainerAdapter;
import org.eclipse.ecf.presence.IPresenceListener;
import org.eclipse.ecf.presence.Presence;
import org.eclipse.ecf.presence.chatroom.IChatRoomInfo;
import org.eclipse.ecf.presence.im.IChatManager;
import org.eclipse.ecf.presence.im.IChatMessageSender;
import org.eclipse.ecf.presence.im.ITypingMessageSender;
import org.eclipse.ecf.presence.roster.IRoster;
import org.eclipse.ecf.presence.roster.IRosterEntry;
import org.eclipse.ecf.presence.roster.IRosterGroup;
import org.eclipse.ecf.presence.roster.IRosterItem;
import org.eclipse.ecf.presence.roster.IRosterManager;
import org.eclipse.ecf.presence.roster.IRosterSubscriptionSender;
import org.eclipse.ecf.presence.service.IPresenceService;
import org.eclipse.ecf.presence.ui.chatroom.ChatRoomManagerView;
import org.eclipse.ecf.presence.ui.chatroom.IChatRoomCommandListener;
import org.eclipse.ecf.presence.ui.chatroom.IChatRoomViewCloseListener;
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.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.util.LocalSelectionTransfer;
import org.eclipse.jface.viewers.IOpenListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.OpenEvent;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerDropAdapter;
import org.eclipse.jface.viewers.ViewerFilter;
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.DND;
import org.eclipse.swt.dnd.FileTransfer;
import org.eclipse.swt.dnd.HTMLTransfer;
import org.eclipse.swt.dnd.RTFTransfer;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.dnd.TransferData;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.IViewReference;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.EditorInputTransfer;
import org.eclipse.ui.part.PluginTransfer;
import org.eclipse.ui.part.ViewPart;
/**
* 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 addContactAction;
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 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);
else
return true;
} else {
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();
} else {
return true;
}
}
};
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
*/
public void createPartControl(Composite parent) {
setupTreeViewer(parent);
}
protected String getRosterEntryChildrenFromPresence(IRosterEntry entry) {
IPresence presence = entry.getPresence();
Map properties = presence.getProperties();
int fixedEntries = 3;
StringBuffer buffer = new StringBuffer();
buffer.append(NLS.bind(Messages.RosterWorkbenchAdapterFactory_Account,
entry.getUser().getID().getName()));
buffer.append(Text.DELIMITER);
buffer.append(NLS.bind(Messages.RosterWorkbenchAdapterFactory_Type,
presence.getType()));
buffer.append(Text.DELIMITER);
buffer.append(NLS.bind(Messages.RosterWorkbenchAdapterFactory_Mode,
presence.getMode().toString()));
for (Iterator i = properties.keySet().iterator(); i.hasNext(); fixedEntries++) {
buffer.append(Text.DELIMITER);
Object key = i.next();
buffer.append(key).append(": ").append(properties.get(key)); //$NON-NLS-1$
}
return buffer.toString();
}
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.setInput(rosterAccounts);
treeViewer.addOpenListener(new IOpenListener() {
public void open(OpenEvent e) {
message((IStructuredSelection) e.getSelection());
}
});
JFaceResources.getColorRegistry().put(ViewerToolTip.HEADER_BG_COLOR,
new RGB(255, 255, 255));
JFaceResources.getFontRegistry().put(
ViewerToolTip.HEADER_FONT,
JFaceResources.getFontRegistry().getBold(
JFaceResources.getDefaultFont().getFontData()[0]
.getName()).getFontData());
ToolTip toolTip = new ViewerToolTip(treeViewer.getControl());
toolTip.setHideOnMouseDown(false);
toolTip.setPopupDelay(200);
makeActions();
hookContextMenu();
contributeToActionBars();
retrieveServices();
hookDropSupport();
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 != null && 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;
} else
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;
} else {
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,
Action.AS_CHECK_BOX) {
public void run() {
if (isChecked()) {
treeViewer.removeFilter(hideOfflineFilter);
} else {
treeViewer.addFilter(hideOfflineFilter);
}
}
};
showEmptyGroupsAction = new Action(
Messages.MultiRosterView_ShowEmptyGroups, Action.AS_CHECK_BOX) {
public void run() {
if (isChecked()) {
treeViewer.removeFilter(hideEmptyGroupsFilter);
} else {
treeViewer.addFilter(hideEmptyGroupsFilter);
}
}
};
addContactAction = new Action(Messages.MultiRosterView_AddContact,
SharedImages.getImageDescriptor(SharedImages.IMG_ADD_BUDDY)) {
public void run() {
AddContactDialog dialog = new AddContactDialog(treeViewer
.getControl().getShell());
dialog.setInput(rosterAccounts);
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());
}
}
}
};
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) {
manager.add(changePasswordAction);
manager.add(new Separator());
manager.add(addContactAction);
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()); //$NON-NLS-1$
}
}
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());
} 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);
showEmptyGroupsAction.setEnabled(enabled);
addContactAction.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(new Separator());
manager.add(addContactAction);
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);
}
rosterAccounts.clear();
super.dispose();
}
protected boolean addRosterAccount(MultiRosterAccount account) {
boolean result = account != null && 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);
// Disable local pull down window if no more accounts
setLocalPullDownEnabled(rosterAccounts.size() > 0);
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;
else {
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());
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) {
}
}
private class ViewerToolTip extends ToolTip {
public static final String HEADER_BG_COLOR = Activator.PLUGIN_ID
+ ".TOOLTIP_HEAD_BG_COLOR"; //$NON-NLS-1$
public static final String HEADER_FONT = Activator.PLUGIN_ID
+ ".TOOLTIP_HEAD_FONT"; //$NON-NLS-1$
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();
GridLayout gl = new GridLayout();
gl.marginBottom = 0;
gl.marginTop = 0;
gl.marginHeight = 0;
gl.marginWidth = 0;
gl.marginLeft = 0;
gl.marginRight = 0;
gl.verticalSpacing = 1;
parent.setLayout(gl);
Composite topArea = new Composite(parent, SWT.NONE);
GridData data = new GridData(SWT.FILL, SWT.FILL, true, false);
data.widthHint = 200;
topArea.setLayoutData(data);
topArea.setBackground(JFaceResources.getColorRegistry().get(
HEADER_BG_COLOR));
gl = new GridLayout();
gl.marginBottom = 2;
gl.marginTop = 2;
gl.marginHeight = 0;
gl.marginWidth = 0;
gl.marginLeft = 5;
gl.marginRight = 2;
topArea.setLayout(gl);
Label l = new Label(topArea, SWT.NONE);
l.setText(entry.getName());
l.setBackground(JFaceResources.getColorRegistry().get(
HEADER_BG_COLOR));
l.setFont(JFaceResources.getFontRegistry().get(HEADER_FONT));
l.setLayoutData(new GridData(GridData.FILL_BOTH));
createContentArea(parent, entry).setLayoutData(
new GridData(GridData.FILL_BOTH));
return parent;
}
protected Composite createContentArea(Composite parent,
IRosterEntry entry) {
Composite comp = new Composite(parent, SWT.NONE);
comp.setBackground(parent.getDisplay().getSystemColor(
SWT.COLOR_INFO_BACKGROUND));
comp.setLayout(new FillLayout());
Label label = new Label(comp, SWT.NONE);
label.setText(getRosterEntryChildrenFromPresence(entry));
return comp;
}
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;
} else {
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;
}
}
}