diff options
author | slewis | 2007-03-23 22:08:45 +0000 |
---|---|---|
committer | slewis | 2007-03-23 22:08:45 +0000 |
commit | 3e2d6874e3a3ec31d7de951e3dd7be9d451b1682 (patch) | |
tree | 12c8698e00a40a4cc4adf68b0874db29756f49e3 /framework/bundles/org.eclipse.ecf.ui | |
parent | 6dad614dcd670f3d28d79b76ec6a60eaf69b9232 (diff) | |
download | org.eclipse.ecf-3e2d6874e3a3ec31d7de951e3dd7be9d451b1682.tar.gz org.eclipse.ecf-3e2d6874e3a3ec31d7de951e3dd7be9d451b1682.tar.xz org.eclipse.ecf-3e2d6874e3a3ec31d7de951e3dd7be9d451b1682.zip |
Addition of RosterView user interface for file sending/receiving
Diffstat (limited to 'framework/bundles/org.eclipse.ecf.ui')
6 files changed, 294 insertions, 28 deletions
diff --git a/framework/bundles/org.eclipse.ecf.ui/META-INF/MANIFEST.MF b/framework/bundles/org.eclipse.ecf.ui/META-INF/MANIFEST.MF index 0ba83e0b1..1f82d23c5 100644 --- a/framework/bundles/org.eclipse.ecf.ui/META-INF/MANIFEST.MF +++ b/framework/bundles/org.eclipse.ecf.ui/META-INF/MANIFEST.MF @@ -29,5 +29,6 @@ Require-Bundle: org.eclipse.ecf, org.eclipse.ecf.sharedobject, org.eclipse.jface.text, org.eclipse.ui, - org.eclipse.core.runtime + org.eclipse.core.runtime, + org.eclipse.ecf.filetransfer diff --git a/framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/internal/ui/Messages.java b/framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/internal/ui/Messages.java index ad335e0fe..314be046f 100644 --- a/framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/internal/ui/Messages.java +++ b/framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/internal/ui/Messages.java @@ -23,6 +23,30 @@ public class Messages extends NLS { public static String ConnectWizard_title; + public static String RosterView_ReceiveFile_title; + + public static String RosterView_ReceiveFile_message; + + public static String RosterView_ReceiveFile_filesavetitle; + + public static String RosterView_ReceiveFile_acceptexception_title; + + public static String RosterView_ReceiveFile_acceptexception_message; + + public static String RosterView_SendFile_title; + + public static String RosterView_SendFile_response_title; + + public static String RosterView_SendFile_response_message; + + public static String RosterView_SendFile_requestexception_title; + + public static String RosterView_SendFile_requestexception_message; + + public static String RosterView_SendIM_menutext; + + public static String RosterView_SendFile_menutext; + static { // load message values from bundle file NLS.initializeMessages(BUNDLE_NAME, Messages.class); diff --git a/framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/internal/ui/messages.properties b/framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/internal/ui/messages.properties index b4b79aabc..d2afbd538 100644 --- a/framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/internal/ui/messages.properties +++ b/framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/internal/ui/messages.properties @@ -1,3 +1,44 @@ +################################################################################ +# Copyright (c) 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 +################################################################################ + +########################## +# Messages for EN locale # +########################## + Select = Select Wizard ConfigurationWizard_title = Configuration Wizard -ConnectWizard_title = Connect Wizard
\ No newline at end of file +ConnectWizard_title = Connect Wizard + +RosterView_ReceiveFile_title = File Receive Request From {0} +RosterView_ReceiveFile_message = User {0} would like to send you a file called {1}\n\nThe size of the file is {2}\nDescription: {3}\n\nDo you want to receive this file? + +RosterView_ReceiveFile_filesavetitle = Save File From {0} + +RosterView_ReceiveFile_acceptexception_title = Receive Error + +RosterView_ReceiveFile_acceptexception_message = Error receiving file {0} from {1}. Error: {2} + +RosterView_SendFile_title = Choose File For {0} + +RosterView_SendFile_response_title = File Send Refused + +RosterView_SendFile_response_message = Send of {0} refused by {1} + +RosterView_SendFile_requestexception_title = Send Error + +RosterView_SendFile_requestexception_message = Error sending file {0}. Error: {1} + +RosterView_SendIM_menutext = Send IM to {0} + +RosterView_SendFile_menutext = Send File to {0} + + + diff --git a/framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/ui/views/RosterUserAccount.java b/framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/ui/views/RosterUserAccount.java index 1e8781762..0a9dfccb4 100644 --- a/framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/ui/views/RosterUserAccount.java +++ b/framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/ui/views/RosterUserAccount.java @@ -10,6 +10,7 @@ *****************************************************************************/ package org.eclipse.ecf.ui.views; +import org.eclipse.ecf.core.IContainer; import org.eclipse.ecf.core.identity.ID; import org.eclipse.ecf.core.sharedobject.ISharedObject; import org.eclipse.ecf.core.sharedobject.ISharedObjectContainer; @@ -27,8 +28,10 @@ public class RosterUserAccount { IUser user; ILocalInputHandler inputHandler; + + IContainer container = null; - IPresenceContainerAdapter container; + IPresenceContainerAdapter presenceContainer; ISharedObjectContainer soContainer; @@ -36,13 +39,15 @@ public class RosterUserAccount { public RosterUserAccount(RosterView rosterView, ID serviceID, IUser user, ILocalInputHandler handler, - IPresenceContainerAdapter container, + IContainer container, + IPresenceContainerAdapter presenceContainer, ISharedObjectContainer soContainer) { this.rosterView = rosterView; this.serviceID = serviceID; this.user = user; this.inputHandler = handler; this.container = container; + this.presenceContainer = presenceContainer; this.soContainer = soContainer; this.sharedObject = this.rosterView.createAndAddSharedObjectForAccount(this); } @@ -59,9 +64,13 @@ public class RosterUserAccount { return inputHandler; } - public IPresenceContainerAdapter getPresenceContainer() { + public IContainer getContainer() { return container; } + + public IPresenceContainerAdapter getPresenceContainer() { + return presenceContainer; + } public ISharedObjectContainer getSOContainer() { return soContainer; diff --git a/framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/ui/views/RosterView.java b/framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/ui/views/RosterView.java index 4c9977537..bc87effe0 100644 --- a/framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/ui/views/RosterView.java +++ b/framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/ui/views/RosterView.java @@ -10,6 +10,8 @@ *****************************************************************************/ package org.eclipse.ecf.ui.views; +import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; @@ -26,6 +28,7 @@ import java.util.Set; import org.eclipse.ecf.core.ContainerConnectException; import org.eclipse.ecf.core.ContainerCreateException; +import org.eclipse.ecf.core.IContainer; import org.eclipse.ecf.core.identity.ID; import org.eclipse.ecf.core.identity.IDFactory; import org.eclipse.ecf.core.security.Callback; @@ -38,7 +41,17 @@ import org.eclipse.ecf.core.sharedobject.ISharedObjectContainer; import org.eclipse.ecf.core.user.IUser; import org.eclipse.ecf.core.user.User; import org.eclipse.ecf.core.util.ECFException; +import org.eclipse.ecf.filetransfer.IFileTransferInfo; +import org.eclipse.ecf.filetransfer.IFileTransferListener; +import org.eclipse.ecf.filetransfer.IIncomingFileTransferRequestListener; +import org.eclipse.ecf.filetransfer.IOutgoingFileTransferContainerAdapter; +import org.eclipse.ecf.filetransfer.OutgoingFileTransferException; +import org.eclipse.ecf.filetransfer.events.IFileTransferEvent; +import org.eclipse.ecf.filetransfer.events.IFileTransferRequestEvent; +import org.eclipse.ecf.filetransfer.events.IIncomingFileTransferReceiveDoneEvent; +import org.eclipse.ecf.filetransfer.events.IOutgoingFileTransferResponseEvent; import org.eclipse.ecf.internal.ui.Activator; +import org.eclipse.ecf.internal.ui.Messages; import org.eclipse.ecf.presence.IAccountManager; import org.eclipse.ecf.presence.IIMMessageEvent; import org.eclipse.ecf.presence.IIMMessageListener; @@ -73,9 +86,11 @@ import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.ViewerSorter; import org.eclipse.jface.window.Window; +import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Menu; import org.eclipse.ui.IActionBars; import org.eclipse.ui.ISharedImages; @@ -110,12 +125,96 @@ public class RosterView extends ViewPart implements IIMMessageListener, private Action openChatRoomAccountAction; + private Action fileSendAction; + protected Hashtable chatThreads = new Hashtable(); protected Hashtable accounts = new Hashtable(); protected Hashtable chatRooms = new Hashtable(); + protected IIncomingFileTransferRequestListener requestListener = new IIncomingFileTransferRequestListener() { + public void handleFileTransferRequest( + final IFileTransferRequestEvent event) { + Display.getDefault().asyncExec(new Runnable() { + public void run() { + String username = event.getRequesterID().getName(); + IFileTransferInfo transferInfo = event + .getFileTransferInfo(); + String fileName = transferInfo.getFile().getName(); + Object[] bindings = new Object[] { + username, + fileName, + ((transferInfo.getFileSize() == -1) ? "unknown" + : (transferInfo.getFileSize() + " bytes")), + (transferInfo.getDescription() == null) ? "none" + : transferInfo.getDescription() }; + if (MessageDialog.openQuestion(getSite().getShell(), NLS + .bind(Messages.RosterView_ReceiveFile_title, + username), NLS.bind( + Messages.RosterView_ReceiveFile_message, bindings))) { + FileDialog fd = new FileDialog(getSite().getShell(), + SWT.OPEN); + // XXX this should be some default path gotten from + // preference. For now we'll have it be the user.home + // system property + fd.setFilterPath(System.getProperty("user.home")); + fd.setFileName(fileName); + int suffixLoc = fileName.lastIndexOf('.'); + if (suffixLoc != -1) { + String ext = fileName.substring(fileName.lastIndexOf('.')); + fd.setFilterExtensions(new String[] { ext }); + } + fd.setText(NLS.bind( + Messages.RosterView_ReceiveFile_filesavetitle, + username)); + final String res = fd.open(); + if (res == null) + event.reject(); + else { + try { + final FileOutputStream fos = new FileOutputStream(new File(res)); + event.accept( + fos, + new IFileTransferListener() { + public void handleTransferEvent( + IFileTransferEvent event) { + // XXX Should have some some UI + // for transfer events + System.out + .println("handleTransferEvent(" + + event + ")"); + if (event instanceof IIncomingFileTransferReceiveDoneEvent) { + try { + fos.close(); + } catch (IOException e) { + } + } + } + }); + } catch (Exception e) { + MessageDialog + .openError( + getSite().getShell(), + Messages.RosterView_ReceiveFile_acceptexception_title, + NLS + .bind( + Messages.RosterView_ReceiveFile_acceptexception_message, + new Object[] { + fileName, + username, + e + .getLocalizedMessage() })); + } + } + } else + event.reject(); + } + }); + } + + }; + /** * Called when an account is added to a RosterView. By default, this method * simply returns null, meaning that no shared object is to be associated @@ -137,6 +236,10 @@ public class RosterView extends ViewPart implements IIMMessageListener, ID accountID = account.getServiceID(); if (accountID != null) { vcp.addAccount(accountID, accountID.getName()); + IOutgoingFileTransferContainerAdapter ft = getFileTransferAdapterForContainer(account + .getContainer()); + if (ft != null) + ft.addListener(requestListener); accounts.put(accountID, account); refreshView(); } @@ -147,6 +250,20 @@ public class RosterView extends ViewPart implements IIMMessageListener, return (RosterUserAccount) accounts.get(serviceID); } + protected IOutgoingFileTransferContainerAdapter getFileTransferAdapterForContainer( + IContainer container) { + return (IOutgoingFileTransferContainerAdapter) container + .getAdapter(IOutgoingFileTransferContainerAdapter.class); + } + + protected IOutgoingFileTransferContainerAdapter getFileTransferAdapterForAccount( + ID accountID) { + RosterUserAccount account = getAccount(accountID); + if (account == null) + return null; + return getFileTransferAdapterForContainer(account.getContainer()); + } + protected void removeAccount(ID serviceID) { synchronized (accounts) { for (Iterator i = accounts.keySet().iterator(); i.hasNext();) { @@ -177,7 +294,7 @@ public class RosterView extends ViewPart implements IIMMessageListener, handlers.add(account.getInputHandler()); } } - for(Iterator i=handlers.iterator(); i.hasNext(); ) { + for (Iterator i = handlers.iterator(); i.hasNext();) { ILocalInputHandler handler = (ILocalInputHandler) i.next(); handler.disconnect(); } @@ -240,6 +357,60 @@ public class RosterView extends ViewPart implements IIMMessageListener, manager.add(openChatRoomAction); } + private void sendFileToTarget( + IOutgoingFileTransferContainerAdapter fileTransfer, + final ID targetID) { + FileDialog fd = new FileDialog(getSite().getShell(), SWT.OPEN); + // XXX this should be some default path set by preferences + fd.setFilterPath(System.getProperty("user.home")); + fd.setText(NLS.bind(Messages.RosterView_SendFile_title, targetID + .getName())); + final String res = fd.open(); + if (res != null) { + File aFile = new File(res); + try { + fileTransfer.sendOutgoingRequest(targetID, aFile, + new IFileTransferListener() { + public void handleTransferEvent( + final IFileTransferEvent event) { + Display.getDefault().asyncExec(new Runnable() { + public void run() { + // XXX This should be handled more + // gracefully/with better UI (progress + // bar?) + if (event instanceof IOutgoingFileTransferResponseEvent) { + if (!((IOutgoingFileTransferResponseEvent) event) + .requestAccepted()) + MessageDialog + .openInformation( + getSite() + .getShell(), + Messages.RosterView_SendFile_response_title, + NLS + .bind( + Messages.RosterView_SendFile_response_message, + res, + targetID + .getName())); + } + } + }); + } + }, null); + } catch (OutgoingFileTransferException e) { + MessageDialog + .openError( + getSite().getShell(), + Messages.RosterView_SendFile_requestexception_title, + NLS + .bind( + Messages.RosterView_SendFile_requestexception_message, + new Object[] { res, + e.getLocalizedMessage() })); + } + } + } + /** * Called when time to fill the context menu. First allows super class to * fill menu, then adds on test action that simply sends shared object @@ -261,11 +432,39 @@ public class RosterView extends ViewPart implements IIMMessageListener, openChatWindowForTarget(targetID); } }; - selectedChatAction.setText("Send IM to " - + rosterObject.getID().getName()); + selectedChatAction.setText(NLS.bind( + Messages.RosterView_SendIM_menutext, rosterObject + .getID().getName())); selectedChatAction.setImageDescriptor(SharedImages .getImageDescriptor(SharedImages.IMG_MESSAGE)); manager.add(selectedChatAction); + manager.add(new Separator()); + + final IOutgoingFileTransferContainerAdapter fileTransfer = getFileTransferAdapterForAccount(tb + .getServiceID()); + + fileSendAction = new Action() { + public void run() { + sendFileToTarget(fileTransfer, targetID); + } + }; + fileSendAction.setText(NLS.bind( + Messages.RosterView_SendFile_menutext, rosterObject + .getID().getName())); + fileSendAction.setImageDescriptor(PlatformUI.getWorkbench() + .getSharedImages().getImageDescriptor( + ISharedImages.IMG_OBJ_FILE)); + manager.add(fileSendAction); + manager.add(new Separator()); + IPresence presence = tb.getPresence(); + boolean type = (presence == null)?false:presence.getType().equals( + IPresence.Type.AVAILABLE); + boolean mode = (presence == null)?false:presence.getMode().equals( + IPresence.Mode.AVAILABLE); + fileSendAction.setEnabled(fileTransfer != null + && type + && mode); + RosterObject parent = rosterObject.getParent(); RosterGroup tg = null; if (parent != null && parent instanceof RosterGroup) { @@ -764,9 +963,11 @@ public class RosterView extends ViewPart implements IIMMessageListener, chatroomview .handleJoin(participant); } - - public void handleUpdated(IUser updatedParticipant) { - chatroomview.handleUpdated(updatedParticipant); + + public void handleUpdated( + IUser updatedParticipant) { + chatroomview + .handleUpdated(updatedParticipant); } public void handleDeparted( @@ -791,10 +992,9 @@ public class RosterView extends ViewPart implements IIMMessageListener, } // Now actually connect to chatroom try { - chatRoom.connect(selectedInfo.getRoomID(), - null); -// getChatJoinContext("Nickname for " -// + selectedInfo.getName()) + chatRoom.connect(selectedInfo.getRoomID(), null); + // getChatJoinContext("Nickname for " + // + selectedInfo.getName()) } catch (ContainerConnectException e1) { Activator.log("Exception connecting to chat room " + selectedInfo.getRoomID(), e1); @@ -934,7 +1134,6 @@ public class RosterView extends ViewPart implements IIMMessageListener, viewer.getControl().setFocus(); } - protected RosterUserAccount getAccountForUser(ID userID) { RosterViewContentProvider vcp = (RosterViewContentProvider) viewer .getContentProvider(); @@ -1019,14 +1218,6 @@ public class RosterView extends ViewPart implements IIMMessageListener, } /* - * public void handleMessage(ID groupID, ID fromID, ID toID, - * IMessageListener.Type type, String subject, String message) { ChatWindow - * window = openChatWindowForTarget(fromID); // finally, show message if - * (window != null) { window.handleMessage(fromID, toID, type, subject, - * message); window.setStatus("last message received at " + (new - * SimpleDateFormat("hh:mm:ss").format(new Date()))); } } - */ - /* * (non-Javadoc) * * @see org.eclipse.ecf.presence.IIMMessageListener#handleMessageEvent(org.eclipse.ecf.presence.IIMMessageEvent) @@ -1042,10 +1233,10 @@ public class RosterView extends ViewPart implements IIMMessageListener, } public void addAccount(ID account, IUser user, ILocalInputHandler handler, - IPresenceContainerAdapter container, + IContainer container, IPresenceContainerAdapter presenceContainer, ISharedObjectContainer soContainer) { addAccount(new RosterUserAccount(this, account, user, handler, - container, soContainer)); + container, presenceContainer, soContainer)); setToolbarEnabled(true); } @@ -1162,9 +1353,8 @@ public class RosterView extends ViewPart implements IIMMessageListener, vcp.handlePresence(groupID, userID, presence); refreshView(); } - - } + } public void handleRosterEntryUpdate(ID groupID, IRosterEntry entry) { if (groupID == null || entry == null) diff --git a/framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/ui/views/RosterViewContentProvider.java b/framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/ui/views/RosterViewContentProvider.java index 32e853877..65e66dc61 100644 --- a/framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/ui/views/RosterViewContentProvider.java +++ b/framework/bundles/org.eclipse.ecf.ui/src/org/eclipse/ecf/ui/views/RosterViewContentProvider.java @@ -106,6 +106,7 @@ public class RosterViewContentProvider implements IStructuredContentProvider, String name = entry.getName(); if (name == null) name = this.rosterView.getUserNameFromID(entry.getUser().getID()); + name = name.replace('?','\''); IPresence presence = entry.getPresence(); RosterBuddy newBuddy = null; if (oldBuddy == null) |