Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 237923 | Differences between
and this patch

Collapse All | Expand All

(-)plugin.xml (+48 lines)
Lines 29-33 Link Here
29
      </menuContribution>
29
      </menuContribution>
30
   </extension>
30
   </extension>
31
31
32
   <extension
33
         point="org.eclipse.ui.editors.annotationTypes">
34
      <type
35
            name="org.eclipse.ecf.docshare.annotations.RemoteSelection">
36
      </type>
37
      <type
38
            name="org.eclipse.ecf.docshare.annotations.RemoteCursor"
39
            super="org.eclipse.ecf.docshare.annotations.RemoteSelection">
40
      </type>
41
   </extension>
42
   <extension
43
         point="org.eclipse.ui.editors.markerAnnotationSpecification">
44
      <specification
45
            annotationType="org.eclipse.ecf.docshare.annotations.RemoteSelection"
46
            colorPreferenceKey="remoteSelectionColor"
47
            colorPreferenceValue="231,223,143"
48
            contributesToHeader="false"
49
            highlightPreferenceKey="remoteSelectionHighlighting"
50
            highlightPreferenceValue="true"
51
            includeOnPreferencePage="true"
52
            label="Remote Selection"
53
            overviewRulerPreferenceKey="remoteSelectionIndicationInOverviewRuler"
54
            overviewRulerPreferenceValue="true"
55
            presentationLayer="5"
56
            textPreferenceKey="remoteSelectionTextIndication"
57
            textPreferenceValue="false"
58
            textStylePreferenceKey="remoteSelectionTextIndicationStyle"
59
            textStylePreferenceValue="NONE">
60
      </specification>
61
      <specification
62
            annotationType="org.eclipse.ecf.docshare.annotations.RemoteCursor"
63
            colorPreferenceKey="remoteCursorColor"
64
            colorPreferenceValue="166,138,60"
65
            contributesToHeader="false"
66
            highlightPreferenceKey="remoteCursorHighlighting"
67
            highlightPreferenceValue="false"
68
            includeOnPreferencePage="true"
69
            label="Remote Cursor"
70
            overviewRulerPreferenceKey="remoteCursorIndicationInOverviewRuler"
71
            overviewRulerPreferenceValue="true"
72
            presentationLayer="5"
73
            textPreferenceKey="remoteCursorTextIndication"
74
            textPreferenceValue="true"
75
            textStylePreferenceKey="remoteCursorTextIndicationStyle"
76
            textStylePreferenceValue="IBEAM">
77
      </specification>
78
   </extension>
79
32
   
80
   
33
</plugin>
81
</plugin>
(-)src/org/eclipse/ecf/internal/provisional/docshare/DocShare.java (-2 / +150 lines)
Lines 13-20 Link Here
13
package org.eclipse.ecf.internal.provisional.docshare;
13
package org.eclipse.ecf.internal.provisional.docshare;
14
14
15
import java.io.*;
15
import java.io.*;
16
import java.util.Iterator;
16
import java.util.*;
17
import java.util.List;
18
import org.eclipse.core.filesystem.EFS;
17
import org.eclipse.core.filesystem.EFS;
19
import org.eclipse.core.filesystem.IFileStore;
18
import org.eclipse.core.filesystem.IFileStore;
20
import org.eclipse.core.runtime.*;
19
import org.eclipse.core.runtime.*;
Lines 31-36 Link Here
31
import org.eclipse.ecf.internal.provisional.docshare.messages.*;
30
import org.eclipse.ecf.internal.provisional.docshare.messages.*;
32
import org.eclipse.jface.dialogs.MessageDialog;
31
import org.eclipse.jface.dialogs.MessageDialog;
33
import org.eclipse.jface.text.*;
32
import org.eclipse.jface.text.*;
33
import org.eclipse.jface.text.source.*;
34
import org.eclipse.jface.viewers.*;
34
import org.eclipse.osgi.util.NLS;
35
import org.eclipse.osgi.util.NLS;
35
import org.eclipse.swt.custom.StyledText;
36
import org.eclipse.swt.custom.StyledText;
36
import org.eclipse.swt.widgets.Control;
37
import org.eclipse.swt.widgets.Control;
Lines 48-53 Link Here
48
 */
49
 */
49
public class DocShare extends AbstractShare {
50
public class DocShare extends AbstractShare {
50
51
52
	private static class SelectionReceiver {
53
54
		private static final String SELECTION_ANNOTATION_ID = "org.eclipse.ecf.docshare.annotations.RemoteSelection"; //$NON-NLS-1$
55
		private static final String CURSOR_ANNOTATION_ID = "org.eclipse.ecf.docshare.annotations.RemoteCursor"; //$NON-NLS-1$
56
57
		/**
58
		 * Annotation model of current document
59
		 */
60
		private IAnnotationModel annotationModel;
61
62
		/**
63
		 * Object to use as lock for changing in annotation model
64
		 */
65
		private Object annotationModelLock;
66
67
		/**
68
		 * Annotation for remote selection in annotationModel
69
		 */
70
		private Annotation currentAnnotation;
71
72
		public SelectionReceiver(ITextEditor editor) {
73
			if (editor == null) {
74
				return;
75
			}
76
			IDocumentProvider documentProvider = editor.getDocumentProvider();
77
			if (documentProvider != null) {
78
				this.annotationModel = documentProvider.getAnnotationModel(editor.getEditorInput());
79
			}
80
			if (this.annotationModel instanceof ISynchronizable) {
81
				this.annotationModelLock = ((ISynchronizable) this.annotationModel).getLockObject();
82
			}
83
			if (this.annotationModelLock == null) {
84
				this.annotationModelLock = this;
85
			}
86
87
		}
88
89
		void handleMessage(final SelectionMessage remoteMsg) {
90
			final Position newPosition = new Position(remoteMsg.getOffset(), remoteMsg.getLength());
91
			final Annotation newAnnotation = new Annotation(newPosition.getLength() > 0 ? SELECTION_ANNOTATION_ID : CURSOR_ANNOTATION_ID, false, "Remote Selection");
92
			if (this.annotationModel != null) {
93
				synchronized (this.annotationModelLock) {
94
					// initial selection, create new
95
					if (this.currentAnnotation == null) {
96
						this.currentAnnotation = newAnnotation;
97
						this.annotationModel.addAnnotation(newAnnotation, newPosition);
98
						return;
99
					}
100
					// selection not changed, skip
101
					if (this.currentAnnotation.getType() == newAnnotation.getType()) {
102
						Position oldPosition = this.annotationModel.getPosition(this.currentAnnotation);
103
						if (oldPosition == null || newPosition.equals(oldPosition)) {
104
							return;
105
						}
106
					}
107
					// selection changed, replace annotation
108
					if (this.annotationModel instanceof IAnnotationModelExtension) {
109
						Annotation[] oldAnnotations = new Annotation[] {this.currentAnnotation};
110
						this.currentAnnotation = newAnnotation;
111
						Map newAnnotations = new TreeMap();
112
						newAnnotations.put(newAnnotation, newPosition);
113
						((IAnnotationModelExtension) this.annotationModel).replaceAnnotations(oldAnnotations, newAnnotations);
114
					} else {
115
						this.annotationModel.removeAnnotation(this.currentAnnotation);
116
						this.annotationModel.addAnnotation(newAnnotation, newPosition);
117
					}
118
				}
119
			}
120
		}
121
122
		void dispose() {
123
			if (this.annotationModel != null) {
124
				synchronized (this.annotationModelLock) {
125
					if (this.currentAnnotation != null) {
126
						this.annotationModel.removeAnnotation(this.currentAnnotation);
127
						this.currentAnnotation = null;
128
					}
129
				}
130
			}
131
		}
132
133
	}
134
51
	/**
135
	/**
52
	 * The ID of the initiator
136
	 * The ID of the initiator
53
	 */
137
	 */
Lines 83-88 Link Here
83
	// TODO provide for a user-interactive selection mechanism
167
	// TODO provide for a user-interactive selection mechanism
84
	SynchronizationStrategy sync;
168
	SynchronizationStrategy sync;
85
169
170
	SelectionReceiver selectionReceiver;
171
86
	/**
172
	/**
87
	 * The document listener is the listener for changes to the *local* copy of
173
	 * The document listener is the listener for changes to the *local* copy of
88
	 * the IDocument. This listener is responsible for sending document update
174
	 * the IDocument. This listener is responsible for sending document update
Lines 131-136 Link Here
131
		}
217
		}
132
	};
218
	};
133
219
220
	ISelectionChangedListener selectionListener = new ISelectionChangedListener() {
221
222
		public void selectionChanged(final SelectionChangedEvent event) {
223
			// If the channel is gone, then no reason to handle this.
224
			if (getChannel() == null || !Activator.getDefault().isListenerActive()) {
225
				return;
226
			}
227
			// If the listener is not active, ignore input
228
			if (!Activator.getDefault().isListenerActive()) {
229
				// The local editor is being updated by a remote peer, so we do
230
				// not
231
				// wish to echo this change.
232
				return;
233
			}
234
			Trace.trace(Activator.PLUGIN_ID, NLS.bind("{0}.selectionChanged[{1}]", DocShare.this, event)); //$NON-NLS-1$
235
236
			if (!(event.getSelection() instanceof ITextSelection)) {
237
				return;
238
			}
239
			final ITextSelection textSelection = (ITextSelection) event.getSelection();
240
			final SelectionMessage msg = new SelectionMessage(textSelection.getOffset(), textSelection.getLength());
241
242
			sendSelectionMsg(msg);
243
		}
244
245
	};
246
134
	/**
247
	/**
135
	 * Create a document sharing session instance.
248
	 * Create a document sharing session instance.
136
	 * 
249
	 * 
Lines 255-260 Link Here
255
				handleStartMessage((StartMessage) message);
368
				handleStartMessage((StartMessage) message);
256
			} else if (message instanceof UpdateMessage) {
369
			} else if (message instanceof UpdateMessage) {
257
				handleUpdateMessage((UpdateMessage) message);
370
				handleUpdateMessage((UpdateMessage) message);
371
			} else if (message instanceof SelectionMessage) {
372
				SelectionReceiver receiver = selectionReceiver;
373
				if (receiver != null) {
374
					receiver.handleMessage((SelectionMessage) message);
375
				}
258
			} else if (message instanceof StopMessage) {
376
			} else if (message instanceof StopMessage) {
259
				handleStopMessage((StopMessage) message);
377
				handleStopMessage((StopMessage) message);
260
			} else {
378
			} else {
Lines 499-504 Link Here
499
			final IDocument doc = getDocumentFromEditor();
617
			final IDocument doc = getDocumentFromEditor();
500
			if (doc != null)
618
			if (doc != null)
501
				doc.addDocumentListener(documentListener);
619
				doc.addDocumentListener(documentListener);
620
			if (this.editor != null) {
621
				ISelectionProvider selectionProvider = this.editor.getSelectionProvider();
622
				if (selectionProvider instanceof IPostSelectionProvider) {
623
					((IPostSelectionProvider) selectionProvider).addPostSelectionChangedListener(selectionListener);
624
				}
625
				selectionReceiver = new SelectionReceiver(this.editor);
626
			}
502
		}
627
		}
503
		// used to have the ColaSynchronizer.getInstanceFor(...) call here ...
628
		// used to have the ColaSynchronizer.getInstanceFor(...) call here ...
504
		// TODO needs to be moved to a more appropriate spot, where ColaSynch'er
629
		// TODO needs to be moved to a more appropriate spot, where ColaSynch'er
Lines 508-513 Link Here
508
	}
633
	}
509
634
510
	void localStopShare() {
635
	void localStopShare() {
636
		SelectionReceiver oldSelectionReceiver;
511
		synchronized (stateLock) {
637
		synchronized (stateLock) {
512
			this.ourID = null;
638
			this.ourID = null;
513
			this.initiatorID = null;
639
			this.initiatorID = null;
Lines 516-523 Link Here
516
			final IDocument doc = getDocumentFromEditor();
642
			final IDocument doc = getDocumentFromEditor();
517
			if (doc != null)
643
			if (doc != null)
518
				doc.removeDocumentListener(documentListener);
644
				doc.removeDocumentListener(documentListener);
645
			if (this.editor != null) {
646
				ISelectionProvider selectionProvider = this.editor.getSelectionProvider();
647
				if (selectionProvider instanceof IPostSelectionProvider) {
648
					((IPostSelectionProvider) selectionProvider).removePostSelectionChangedListener(selectionListener);
649
				}
650
			}
651
			oldSelectionReceiver = this.selectionReceiver;
652
			this.selectionReceiver = null;
519
			this.editor = null;
653
			this.editor = null;
520
		}
654
		}
655
656
		if (oldSelectionReceiver != null) {
657
			oldSelectionReceiver.dispose();
658
		}
521
		// clean up if necessary
659
		// clean up if necessary
522
		// TODO abstract this to work for SynchronizationStrategy
660
		// TODO abstract this to work for SynchronizationStrategy
523
		ColaSynchronizer.cleanUpFor(this);
661
		ColaSynchronizer.cleanUpFor(this);
Lines 534-539 Link Here
534
		}
672
		}
535
	}
673
	}
536
674
675
	void sendSelectionMsg(SelectionMessage msg) {
676
		if (isSharing()) {
677
			try {
678
				send(getOtherID(), msg);
679
			} catch (final Exception e) {
680
				logError(Messages.DocShare_EXCEPTION_SEND_MESSAGE, e);
681
			}
682
		}
683
	}
684
537
	void sendStopMessage() {
685
	void sendStopMessage() {
538
		sendStopMessage(getOtherID());
686
		sendStopMessage(getOtherID());
539
	}
687
	}

Return to bug 237923