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

(-)src/org/eclipse/ecf/internal/provisional/docshare/DocShare.java (-2 / +158 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
		 * <code>null</code> if no model is provided.
65
		 */
66
		private Object annotationModelLock;
67
68
		/**
69
		 * Annotation for remote selection in annotationModel
70
		 */
71
		private Annotation currentAnnotation;
72
73
		public SelectionReceiver(ITextEditor editor) {
74
			if (editor == null) {
75
				return;
76
			}
77
			IDocumentProvider documentProvider = editor.getDocumentProvider();
78
			if (documentProvider != null) {
79
				this.annotationModel = documentProvider.getAnnotationModel(editor.getEditorInput());
80
				if (this.annotationModel != null) {
81
					if (this.annotationModel instanceof ISynchronizable) {
82
						this.annotationModelLock = ((ISynchronizable) this.annotationModel).getLockObject();
83
					}
84
					if (this.annotationModelLock == null) {
85
						this.annotationModelLock = this;
86
					}
87
				}
88
			}
89
		}
90
91
		void handleMessage(final SelectionMessage remoteMsg) {
92
			if (this.annotationModelLock == null) {
93
				return;
94
			}
95
			final Position newPosition = new Position(remoteMsg.getOffset(), remoteMsg.getLength());
96
			final Annotation newAnnotation = new Annotation(newPosition.getLength() > 0 ? SELECTION_ANNOTATION_ID : CURSOR_ANNOTATION_ID, false, "Remote Selection");
97
			synchronized (this.annotationModelLock) {
98
				if (this.annotationModel != null) {
99
					// initial selection, create new
100
					if (this.currentAnnotation == null) {
101
						this.currentAnnotation = newAnnotation;
102
						this.annotationModel.addAnnotation(newAnnotation, newPosition);
103
						return;
104
					}
105
					// selection not changed, skip
106
					if (this.currentAnnotation.getType() == newAnnotation.getType()) {
107
						Position oldPosition = this.annotationModel.getPosition(this.currentAnnotation);
108
						if (oldPosition == null || newPosition.equals(oldPosition)) {
109
							return;
110
						}
111
					}
112
					// selection changed, replace annotation
113
					if (this.annotationModel instanceof IAnnotationModelExtension) {
114
						Annotation[] oldAnnotations = new Annotation[] {this.currentAnnotation};
115
						this.currentAnnotation = newAnnotation;
116
						Map newAnnotations = Collections.singletonMap(newAnnotation, newPosition);
117
						((IAnnotationModelExtension) this.annotationModel).replaceAnnotations(oldAnnotations, newAnnotations);
118
					} else {
119
						this.annotationModel.removeAnnotation(this.currentAnnotation);
120
						this.annotationModel.addAnnotation(newAnnotation, newPosition);
121
					}
122
				}
123
			}
124
		}
125
126
		void dispose() {
127
			if (this.annotationModelLock == null) {
128
				return;
129
			}
130
			synchronized (this.annotationModelLock) {
131
				if (this.annotationModel != null) {
132
					if (this.currentAnnotation != null) {
133
						this.annotationModel.removeAnnotation(this.currentAnnotation);
134
						this.currentAnnotation = null;
135
					}
136
					this.annotationModel = null;
137
				}
138
			}
139
		}
140
141
	}
142
51
	/**
143
	/**
52
	 * The ID of the initiator
144
	 * The ID of the initiator
53
	 */
145
	 */
Lines 83-88 Link Here
83
	// TODO provide for a user-interactive selection mechanism
175
	// TODO provide for a user-interactive selection mechanism
84
	SynchronizationStrategy sync;
176
	SynchronizationStrategy sync;
85
177
178
	SelectionReceiver selectionReceiver;
179
86
	/**
180
	/**
87
	 * The document listener is the listener for changes to the *local* copy of
181
	 * The document listener is the listener for changes to the *local* copy of
88
	 * the IDocument. This listener is responsible for sending document update
182
	 * the IDocument. This listener is responsible for sending document update
Lines 131-136 Link Here
131
		}
225
		}
132
	};
226
	};
133
227
228
	ISelectionChangedListener selectionListener = new ISelectionChangedListener() {
229
230
		public void selectionChanged(final SelectionChangedEvent event) {
231
			// If the channel is gone, then no reason to handle this.
232
			if (getChannel() == null || !Activator.getDefault().isListenerActive()) {
233
				return;
234
			}
235
			// If the listener is not active, ignore input
236
			if (!Activator.getDefault().isListenerActive()) {
237
				// The local editor is being updated by a remote peer, so we do
238
				// not
239
				// wish to echo this change.
240
				return;
241
			}
242
			Trace.trace(Activator.PLUGIN_ID, NLS.bind("{0}.selectionChanged[{1}]", DocShare.this, event)); //$NON-NLS-1$
243
244
			if (!(event.getSelection() instanceof ITextSelection)) {
245
				return;
246
			}
247
			final ITextSelection textSelection = (ITextSelection) event.getSelection();
248
			final SelectionMessage msg = new SelectionMessage(textSelection.getOffset(), textSelection.getLength());
249
250
			sendSelectionMsg(msg);
251
		}
252
253
	};
254
134
	/**
255
	/**
135
	 * Create a document sharing session instance.
256
	 * Create a document sharing session instance.
136
	 * 
257
	 * 
Lines 255-260 Link Here
255
				handleStartMessage((StartMessage) message);
376
				handleStartMessage((StartMessage) message);
256
			} else if (message instanceof UpdateMessage) {
377
			} else if (message instanceof UpdateMessage) {
257
				handleUpdateMessage((UpdateMessage) message);
378
				handleUpdateMessage((UpdateMessage) message);
379
			} else if (message instanceof SelectionMessage) {
380
				SelectionReceiver receiver = selectionReceiver;
381
				if (receiver != null) {
382
					receiver.handleMessage((SelectionMessage) message);
383
				}
258
			} else if (message instanceof StopMessage) {
384
			} else if (message instanceof StopMessage) {
259
				handleStopMessage((StopMessage) message);
385
				handleStopMessage((StopMessage) message);
260
			} else {
386
			} else {
Lines 499-504 Link Here
499
			final IDocument doc = getDocumentFromEditor();
625
			final IDocument doc = getDocumentFromEditor();
500
			if (doc != null)
626
			if (doc != null)
501
				doc.addDocumentListener(documentListener);
627
				doc.addDocumentListener(documentListener);
628
			if (this.editor != null) {
629
				ISelectionProvider selectionProvider = this.editor.getSelectionProvider();
630
				if (selectionProvider instanceof IPostSelectionProvider) {
631
					((IPostSelectionProvider) selectionProvider).addPostSelectionChangedListener(selectionListener);
632
				}
633
				selectionReceiver = new SelectionReceiver(this.editor);
634
			}
502
		}
635
		}
503
		// used to have the ColaSynchronizer.getInstanceFor(...) call here ...
636
		// used to have the ColaSynchronizer.getInstanceFor(...) call here ...
504
		// TODO needs to be moved to a more appropriate spot, where ColaSynch'er
637
		// TODO needs to be moved to a more appropriate spot, where ColaSynch'er
Lines 508-513 Link Here
508
	}
641
	}
509
642
510
	void localStopShare() {
643
	void localStopShare() {
644
		SelectionReceiver oldSelectionReceiver;
511
		synchronized (stateLock) {
645
		synchronized (stateLock) {
512
			this.ourID = null;
646
			this.ourID = null;
513
			this.initiatorID = null;
647
			this.initiatorID = null;
Lines 516-523 Link Here
516
			final IDocument doc = getDocumentFromEditor();
650
			final IDocument doc = getDocumentFromEditor();
517
			if (doc != null)
651
			if (doc != null)
518
				doc.removeDocumentListener(documentListener);
652
				doc.removeDocumentListener(documentListener);
653
			if (this.editor != null) {
654
				ISelectionProvider selectionProvider = this.editor.getSelectionProvider();
655
				if (selectionProvider instanceof IPostSelectionProvider) {
656
					((IPostSelectionProvider) selectionProvider).removePostSelectionChangedListener(selectionListener);
657
				}
658
			}
659
			oldSelectionReceiver = this.selectionReceiver;
660
			this.selectionReceiver = null;
519
			this.editor = null;
661
			this.editor = null;
520
		}
662
		}
663
664
		if (oldSelectionReceiver != null) {
665
			oldSelectionReceiver.dispose();
666
		}
521
		// clean up if necessary
667
		// clean up if necessary
522
		// TODO abstract this to work for SynchronizationStrategy
668
		// TODO abstract this to work for SynchronizationStrategy
523
		ColaSynchronizer.cleanUpFor(this);
669
		ColaSynchronizer.cleanUpFor(this);
Lines 534-539 Link Here
534
		}
680
		}
535
	}
681
	}
536
682
683
	void sendSelectionMsg(SelectionMessage msg) {
684
		if (isSharing()) {
685
			try {
686
				send(getOtherID(), msg);
687
			} catch (final Exception e) {
688
				logError(Messages.DocShare_EXCEPTION_SEND_MESSAGE, e);
689
			}
690
		}
691
	}
692
537
	void sendStopMessage() {
693
	void sendStopMessage() {
538
		sendStopMessage(getOtherID());
694
		sendStopMessage(getOtherID());
539
	}
695
	}
(-)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>

Return to bug 237923