### Eclipse Workspace Patch 1.0 #P org.eclipse.ecf.docshare Index: META-INF/MANIFEST.MF =================================================================== RCS file: /cvsroot/rt/org.eclipse.ecf/framework/bundles/org.eclipse.ecf.docshare/META-INF/MANIFEST.MF,v retrieving revision 1.5 diff -u -r1.5 MANIFEST.MF --- META-INF/MANIFEST.MF 27 Nov 2008 11:48:46 -0000 1.5 +++ META-INF/MANIFEST.MF 29 Nov 2008 08:15:51 -0000 @@ -16,6 +16,7 @@ org.eclipse.ecf.presence, org.eclipse.ui.ide, org.eclipse.core.filesystem, + org.eclipse.core.resources, org.eclipse.ecf.sync;bundle-version="1.0.0" Bundle-RequiredExecutionEnvironment: J2SE-1.4 Eclipse-LazyStart: true Index: src/org/eclipse/ecf/docshare/menu/DocShareRosterMenuHandler.java =================================================================== RCS file: /cvsroot/rt/org.eclipse.ecf/framework/bundles/org.eclipse.ecf.docshare/src/org/eclipse/ecf/docshare/menu/DocShareRosterMenuHandler.java,v retrieving revision 1.6 diff -u -r1.6 DocShareRosterMenuHandler.java --- src/org/eclipse/ecf/docshare/menu/DocShareRosterMenuHandler.java 28 Nov 2008 06:48:02 -0000 1.6 +++ src/org/eclipse/ecf/docshare/menu/DocShareRosterMenuHandler.java 29 Nov 2008 08:15:51 -0000 @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (c) 2007 Composent, Inc. and others. + * Copyright (c) 2007, 2008 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 @@ -11,21 +11,23 @@ package org.eclipse.ecf.docshare.menu; -import org.eclipse.ecf.docshare.DocShare; - import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.ecf.core.IContainer; import org.eclipse.ecf.core.user.IUser; +import org.eclipse.ecf.docshare.DocShare; import org.eclipse.ecf.internal.docshare.Activator; import org.eclipse.ecf.internal.docshare.Messages; import org.eclipse.ecf.presence.roster.IRoster; import org.eclipse.ecf.presence.roster.IRosterEntry; import org.eclipse.ecf.presence.ui.menu.AbstractRosterMenuHandler; import org.eclipse.jface.dialogs.ErrorDialog; -import org.eclipse.ui.*; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.handlers.HandlerUtil; import org.eclipse.ui.texteditor.ITextEditor; /** @@ -40,29 +42,15 @@ super(entry); } - protected ITextEditor getTextEditor() { - final IWorkbench workbench = PlatformUI.getWorkbench(); - if (workbench == null) - return null; - final IWorkbenchWindow ww = workbench.getActiveWorkbenchWindow(); - if (ww == null) - return null; - final IWorkbenchPage wp = ww.getActivePage(); - if (wp == null) - return null; - final IEditorPart ep = wp.getActiveEditor(); - if (ep instanceof ITextEditor) - return (ITextEditor) ep; - return null; + protected ITextEditor getTextEditor(ExecutionEvent event) { + IEditorPart part = HandlerUtil.getActiveEditor(event); + return part instanceof ITextEditor ? (ITextEditor) part : null; } private String getFileName(IEditorPart editorPart) { final IEditorInput input = editorPart.getEditorInput(); - if (input instanceof IFileEditorInput) { - final IFileEditorInput fei = (IFileEditorInput) input; - return fei.getName(); - } - return null; + IFile file = (IFile) input.getAdapter(IFile.class); + return file == null ? null : file.getFullPath().toString(); } private void showErrorMessage(String errorMessage) { @@ -72,7 +60,7 @@ /** * @throws ExecutionException */ - public Object execute(ExecutionEvent arg0) throws ExecutionException { + public Object execute(ExecutionEvent event) throws ExecutionException { IRosterEntry rosterEntry = getRosterEntry(); if (rosterEntry != null) { IRoster roster = rosterEntry.getRoster(); @@ -84,14 +72,14 @@ showErrorMessage(Messages.DocShareRosterMenuHandler_ERROR_NO_SENDER); if (sender.isSharing()) showErrorMessage(Messages.DocShareRosterMenuHandler_ERROR_EDITOR_ALREADY_SHARING); - final ITextEditor textEditor = getTextEditor(); + final ITextEditor textEditor = getTextEditor(event); if (textEditor == null) showErrorMessage(Messages.DocShareRosterMenuHandler_EXCEPTION_EDITOR_NOT_TEXT); - final String fileName = getFileName(textEditor); - if (fileName == null) + final String filePath = getFileName(textEditor); + if (filePath == null) showErrorMessage(Messages.DocShareRosterMenuHandler_NO_FILENAME_WITH_CONTENT); final IUser user = roster.getUser(); - sender.startShare(user.getID(), user.getName(), rosterEntry.getUser().getID(), fileName, textEditor); + sender.startShare(user.getID(), user.getName(), rosterEntry.getUser().getID(), filePath, textEditor); } return null; } Index: src/org/eclipse/ecf/internal/docshare/messages.properties =================================================================== RCS file: /cvsroot/rt/org.eclipse.ecf/framework/bundles/org.eclipse.ecf.docshare/src/org/eclipse/ecf/internal/docshare/messages.properties,v retrieving revision 1.13 diff -u -r1.13 messages.properties --- src/org/eclipse/ecf/internal/docshare/messages.properties 26 Nov 2008 23:54:03 -0000 1.13 +++ src/org/eclipse/ecf/internal/docshare/messages.properties 29 Nov 2008 08:15:51 -0000 @@ -10,6 +10,7 @@ ################################################################################ DocShare_EDITOR_SHARE_POPUP_MESSAGE=Editor share request from {0} for {1}.\n\nDo you want to accept and open editor? DocShare_EDITOR_SHARE_POPUP_TITLE=Editor Share +DocShare_EDITOR_SHARE_FILE_EXISTS_POPUP_MESSAGE=The file {0} already exists in your workspace and its contents may differ from the remote peer's. Are you sure you wish to proceed? Proceeding will cause the file's content to be overridden by the remote copy. DocShare_ERROR_STARTING_EDITOR_MESSAGE=Error Starting Editor Sharing {0} DocShare_ERROR_STARTING_EDITOR_TITLE=Error DocShare_EXCEPTION_DESERIALIZING_MESSAGE0=Exception deserializing DocumentChangeMessage Index: src/org/eclipse/ecf/internal/docshare/Messages.java =================================================================== RCS file: /cvsroot/rt/org.eclipse.ecf/framework/bundles/org.eclipse.ecf.docshare/src/org/eclipse/ecf/internal/docshare/Messages.java,v retrieving revision 1.6 diff -u -r1.6 Messages.java --- src/org/eclipse/ecf/internal/docshare/Messages.java 26 Nov 2008 23:54:03 -0000 1.6 +++ src/org/eclipse/ecf/internal/docshare/Messages.java 29 Nov 2008 08:15:51 -0000 @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (c) 2007 Composent, Inc. and others. + * Copyright (c) 2007, 2008 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 @@ -20,6 +20,7 @@ private static final String BUNDLE_NAME = "org.eclipse.ecf.internal.docshare.messages"; //$NON-NLS-1$ public static String DocShare_EDITOR_SHARE_POPUP_MESSAGE; public static String DocShare_EDITOR_SHARE_POPUP_TITLE; + public static String DocShare_EDITOR_SHARE_FILE_EXISTS_POPUP_MESSAGE; public static String DocShare_ERROR_STARTING_EDITOR_MESSAGE; public static String DocShare_ERROR_STARTING_EDITOR_TITLE; public static String DocShare_EXCEPTION_DESERIALIZING_MESSAGE0; Index: src/org/eclipse/ecf/docshare/DocShare.java =================================================================== RCS file: /cvsroot/rt/org.eclipse.ecf/framework/bundles/org.eclipse.ecf.docshare/src/org/eclipse/ecf/docshare/DocShare.java,v retrieving revision 1.17 diff -u -r1.17 DocShare.java --- src/org/eclipse/ecf/docshare/DocShare.java 28 Nov 2008 06:48:02 -0000 1.17 +++ src/org/eclipse/ecf/docshare/DocShare.java 29 Nov 2008 08:15:51 -0000 @@ -16,6 +16,8 @@ import java.io.*; import org.eclipse.core.filesystem.EFS; import org.eclipse.core.filesystem.IFileStore; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.*; import org.eclipse.core.runtime.Assert; import org.eclipse.ecf.core.IContainer; @@ -39,6 +41,8 @@ import org.eclipse.swt.widgets.*; import org.eclipse.ui.*; import org.eclipse.ui.editors.text.EditorsUI; +import org.eclipse.ui.ide.IDE; +import org.eclipse.ui.ide.ResourceUtil; import org.eclipse.ui.texteditor.IDocumentProvider; import org.eclipse.ui.texteditor.ITextEditor; @@ -220,15 +224,16 @@ * a name to present to the receiver. If * null, our.getName() will be used. * @param toID the ID of the intended receiver. Must not be null. - * @param fileName the file name of the file to be shared (with suffix type extension). Must not be null. + * @param filePath the workspace-relative path of the file to be shared (with suffix type extension). Must not be null. * @param editorPart the text editor currently showing the contents of this editor. Must not be null. */ - public void startShare(final ID our, final String fromName, final ID toID, final String fileName, final ITextEditor editorPart) { - Trace.entering(Activator.PLUGIN_ID, DocshareDebugOptions.METHODS_ENTERING, DocShare.class, "startShare", new Object[] {our, fromName, toID, fileName, editorPart}); //$NON-NLS-1$ + public void startShare(final ID our, final String fromName, final ID toID, final String filePath, final ITextEditor editorPart) { + Trace.entering(Activator.PLUGIN_ID, DocshareDebugOptions.METHODS_ENTERING, DocShare.class, "startShare", new Object[] {our, fromName, toID, filePath, editorPart}); //$NON-NLS-1$ Assert.isNotNull(our); final String fName = (fromName == null) ? our.getName() : fromName; Assert.isNotNull(toID); Assert.isNotNull(fName); + Assert.isNotNull(filePath); Assert.isNotNull(editorPart); Display.getDefault().syncExec(new Runnable() { public void run() { @@ -240,7 +245,7 @@ // Get content from local document final String content = editorPart.getDocumentProvider().getDocument(editorPart.getEditorInput()).get(); // Send start message with current content - sendMessage(toID, new StartMessage(our, fName, toID, content, fileName).serialize()); + sendMessage(toID, new StartMessage(our, fName, toID, content, filePath).serialize()); // Set local sharing start (to setup doc listener) localStartShare(getLocalRosterManager(), our, our, toID, editorPart); } catch (final Exception e) { @@ -308,8 +313,8 @@ Assert.isNotNull(senderUsername); final ID our = message.getReceiverID(); Assert.isNotNull(our); - final String filename = message.getFilename(); - Assert.isNotNull(filename); + final String filePath = message.getFilename(); + Assert.isNotNull(filePath); final String documentContent = message.getDocumentContent(); Assert.isNotNull(documentContent); @@ -334,13 +339,39 @@ public void run() { try { // First, ask user if they want to receive the doc - if (openReceiverDialog(senderID, senderUsername, filename)) { - // If so, then we create a new DocShareEditorInput - final DocShareEditorInput dsei = new DocShareEditorInput(getTempFileStore(senderUsername, filename, startContent), senderUsername, filename); - // Then open up text editor - final ITextEditor ep = (ITextEditor) PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().openEditor(dsei, getEditorIdForFileName(filename)); - // Then change our local state - localStartShare(getLocalRosterManager(), our, senderID, our, ep); + if (openReceiverDialog(senderID, senderUsername, filePath)) { + IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); + IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(filePath)); + // check if the file exists + if (file.exists()) { + // if it does, prompt for overwrite + if (openOverwritePrompt(filePath)) { + // find an existing editor + ITextEditor textEditor = (ITextEditor) ResourceUtil.findEditor(page, file); + if (textEditor == null) { + // none found, open one + textEditor = (ITextEditor) IDE.openEditor(page, file, getEditorIdForFileName(filePath)); + } + // retrieve the document + IDocument document = textEditor.getDocumentProvider().getDocument(textEditor.getEditorInput()); + // alter its contents to match the remote peer's + document.set(startContent); + // Then change our local state + localStartShare(getLocalRosterManager(), our, senderID, our, textEditor); + } else { + // User doesn't want to overwrite with remote changes, send stop message to initiator + sendStopMessage(); + // Then we stop the local share + localStopShare(); + } + } else { + // The file doesn't exist, so we create a new DocShareEditorInput + final DocShareEditorInput dsei = new DocShareEditorInput(getTempFileStore(senderUsername, filePath, startContent), senderUsername, filePath); + // Then open up text editor + final ITextEditor ep = (ITextEditor) page.openEditor(dsei, getEditorIdForFileName(filePath)); + // Then change our local state + localStartShare(getLocalRosterManager(), our, senderID, our, ep); + } } else { // Send stop message to initiator sendStopMessage(); @@ -473,6 +504,10 @@ return MessageDialog.openQuestion(null, Messages.DocShare_EDITOR_SHARE_POPUP_TITLE, NLS.bind(Messages.DocShare_EDITOR_SHARE_POPUP_MESSAGE, fromUsername, fileName)); } + boolean openOverwritePrompt(String filePath) { + return MessageDialog.openQuestion(null, Messages.DocShare_EDITOR_SHARE_POPUP_TITLE, NLS.bind(Messages.DocShare_EDITOR_SHARE_FILE_EXISTS_POPUP_MESSAGE, filePath)); + } + protected void handleDisconnectEvent(IChannelDisconnectEvent cde) { boolean weDisconnected = (ourID != null && ourID.equals(cde.getTargetID())); Shell shell = null;