Lines 15-20
Link Here
|
15 |
package org.eclipse.ecf.docshare; |
15 |
package org.eclipse.ecf.docshare; |
16 |
|
16 |
|
17 |
import java.io.*; |
17 |
import java.io.*; |
|
|
18 |
import java.util.Collections; |
19 |
import java.util.Map; |
18 |
import org.eclipse.core.filesystem.EFS; |
20 |
import org.eclipse.core.filesystem.EFS; |
19 |
import org.eclipse.core.filesystem.IFileStore; |
21 |
import org.eclipse.core.filesystem.IFileStore; |
20 |
import org.eclipse.core.runtime.*; |
22 |
import org.eclipse.core.runtime.*; |
Lines 36-41
Link Here
|
36 |
import org.eclipse.ecf.sync.doc.IDocumentSynchronizationStrategyFactory; |
38 |
import org.eclipse.ecf.sync.doc.IDocumentSynchronizationStrategyFactory; |
37 |
import org.eclipse.jface.dialogs.MessageDialog; |
39 |
import org.eclipse.jface.dialogs.MessageDialog; |
38 |
import org.eclipse.jface.text.*; |
40 |
import org.eclipse.jface.text.*; |
|
|
41 |
import org.eclipse.jface.text.source.*; |
42 |
import org.eclipse.jface.viewers.*; |
39 |
import org.eclipse.osgi.util.NLS; |
43 |
import org.eclipse.osgi.util.NLS; |
40 |
import org.eclipse.swt.custom.StyledText; |
44 |
import org.eclipse.swt.custom.StyledText; |
41 |
import org.eclipse.swt.widgets.*; |
45 |
import org.eclipse.swt.widgets.*; |
Lines 50-55
Link Here
|
50 |
*/ |
54 |
*/ |
51 |
public class DocShare extends AbstractShare { |
55 |
public class DocShare extends AbstractShare { |
52 |
|
56 |
|
|
|
57 |
public static class SelectionReceiver { |
58 |
|
59 |
private static final String SELECTION_ANNOTATION_ID = "org.eclipse.ecf.docshare.annotations.RemoteSelection"; //$NON-NLS-1$ |
60 |
private static final String CURSOR_ANNOTATION_ID = "org.eclipse.ecf.docshare.annotations.RemoteCursor"; //$NON-NLS-1$ |
61 |
|
62 |
/** |
63 |
* Annotation model of current document |
64 |
*/ |
65 |
private IAnnotationModel annotationModel; |
66 |
|
67 |
/** |
68 |
* Object to use as lock for changing in annotation model, |
69 |
* <code>null</code> if no model is provided. |
70 |
*/ |
71 |
private Object annotationModelLock; |
72 |
|
73 |
/** |
74 |
* Annotation for remote selection in annotationModel |
75 |
*/ |
76 |
private Annotation currentAnnotation; |
77 |
|
78 |
public SelectionReceiver(ITextEditor editor) { |
79 |
if (editor == null) { |
80 |
return; |
81 |
} |
82 |
IDocumentProvider documentProvider = editor.getDocumentProvider(); |
83 |
if (documentProvider != null) { |
84 |
this.annotationModel = documentProvider.getAnnotationModel(editor.getEditorInput()); |
85 |
if (this.annotationModel != null) { |
86 |
if (this.annotationModel instanceof ISynchronizable) { |
87 |
this.annotationModelLock = ((ISynchronizable) this.annotationModel).getLockObject(); |
88 |
} |
89 |
if (this.annotationModelLock == null) { |
90 |
this.annotationModelLock = this; |
91 |
} |
92 |
} |
93 |
} |
94 |
} |
95 |
|
96 |
public void handleMessage(final SelectionMessage remoteMsg) { |
97 |
if (this.annotationModelLock == null) { |
98 |
return; |
99 |
} |
100 |
final Position newPosition = new Position(remoteMsg.getOffset(), remoteMsg.getLength()); |
101 |
final Annotation newAnnotation = new Annotation(newPosition.getLength() > 0 ? SELECTION_ANNOTATION_ID : CURSOR_ANNOTATION_ID, false, "Remote Selection"); |
102 |
synchronized (this.annotationModelLock) { |
103 |
if (this.annotationModel != null) { |
104 |
// initial selection, create new |
105 |
if (this.currentAnnotation == null) { |
106 |
this.currentAnnotation = newAnnotation; |
107 |
this.annotationModel.addAnnotation(newAnnotation, newPosition); |
108 |
return; |
109 |
} |
110 |
// selection not changed, skip |
111 |
if (this.currentAnnotation.getType() == newAnnotation.getType()) { |
112 |
Position oldPosition = this.annotationModel.getPosition(this.currentAnnotation); |
113 |
if (oldPosition == null || newPosition.equals(oldPosition)) { |
114 |
return; |
115 |
} |
116 |
} |
117 |
// selection changed, replace annotation |
118 |
if (this.annotationModel instanceof IAnnotationModelExtension) { |
119 |
Annotation[] oldAnnotations = new Annotation[] {this.currentAnnotation}; |
120 |
this.currentAnnotation = newAnnotation; |
121 |
Map newAnnotations = Collections.singletonMap(newAnnotation, newPosition); |
122 |
((IAnnotationModelExtension) this.annotationModel).replaceAnnotations(oldAnnotations, newAnnotations); |
123 |
} else { |
124 |
this.annotationModel.removeAnnotation(this.currentAnnotation); |
125 |
this.annotationModel.addAnnotation(newAnnotation, newPosition); |
126 |
} |
127 |
} |
128 |
} |
129 |
} |
130 |
|
131 |
public void dispose() { |
132 |
if (this.annotationModelLock == null) { |
133 |
return; |
134 |
} |
135 |
synchronized (this.annotationModelLock) { |
136 |
if (this.annotationModel != null) { |
137 |
if (this.currentAnnotation != null) { |
138 |
this.annotationModel.removeAnnotation(this.currentAnnotation); |
139 |
this.currentAnnotation = null; |
140 |
} |
141 |
this.annotationModel = null; |
142 |
} |
143 |
} |
144 |
} |
145 |
|
146 |
} |
147 |
|
53 |
/** |
148 |
/** |
54 |
* The ID of the initiator |
149 |
* The ID of the initiator |
55 |
*/ |
150 |
*/ |
Lines 91-96
Link Here
|
91 |
IDocumentSynchronizationStrategyFactory factory; |
186 |
IDocumentSynchronizationStrategyFactory factory; |
92 |
|
187 |
|
93 |
/** |
188 |
/** |
|
|
189 |
* Handler for SelectionMessage (painting remote selection) |
190 |
*/ |
191 |
SelectionReceiver selectionReceiver; |
192 |
|
193 |
/** |
94 |
* Create a document sharing session instance. |
194 |
* Create a document sharing session instance. |
95 |
* |
195 |
* |
96 |
* @param adapter |
196 |
* @param adapter |
Lines 210-215
Link Here
|
210 |
} |
310 |
} |
211 |
}; |
311 |
}; |
212 |
|
312 |
|
|
|
313 |
ISelectionChangedListener selectionListener = new ISelectionChangedListener() { |
314 |
|
315 |
public void selectionChanged(final SelectionChangedEvent event) { |
316 |
// If the channel is gone, then no reason to handle this. |
317 |
if (getChannel() == null || !Activator.getDefault().isListenerActive()) { |
318 |
return; |
319 |
} |
320 |
// If the listener is not active, ignore input |
321 |
if (!Activator.getDefault().isListenerActive()) { |
322 |
// The local editor is being updated by a remote peer, so we do |
323 |
// not |
324 |
// wish to echo this change. |
325 |
return; |
326 |
} |
327 |
Trace.trace(Activator.PLUGIN_ID, NLS.bind("{0}.selectionChanged[{1}]", DocShare.this, event)); //$NON-NLS-1$ |
328 |
|
329 |
if (!(event.getSelection() instanceof ITextSelection)) { |
330 |
return; |
331 |
} |
332 |
final ITextSelection textSelection = (ITextSelection) event.getSelection(); |
333 |
final SelectionMessage msg = new SelectionMessage(textSelection.getOffset(), textSelection.getLength()); |
334 |
|
335 |
try { |
336 |
sendMessage(getOtherID(), msg.serialize()); |
337 |
} catch (final Exception e) { |
338 |
logError(Messages.DocShare_EXCEPTION_SEND_MESSAGE, e); |
339 |
} |
340 |
} |
341 |
|
342 |
}; |
343 |
|
213 |
/** |
344 |
/** |
214 |
* Start sharing an editor's contents between two participants. This will |
345 |
* Start sharing an editor's contents between two participants. This will |
215 |
* send a request to start sharing with the target identified by the |
346 |
* send a request to start sharing with the target identified by the |
Lines 283-288
Link Here
|
283 |
|
414 |
|
284 |
if (message instanceof DocumentChangeMessage) { |
415 |
if (message instanceof DocumentChangeMessage) { |
285 |
handleUpdateMessage((DocumentChangeMessage) message); |
416 |
handleUpdateMessage((DocumentChangeMessage) message); |
|
|
417 |
} else if (message instanceof SelectionMessage) { |
418 |
SelectionReceiver receiver = selectionReceiver; |
419 |
if (receiver != null) { |
420 |
receiver.handleMessage((SelectionMessage) message); |
421 |
} |
286 |
} else if (message instanceof StartMessage) { |
422 |
} else if (message instanceof StartMessage) { |
287 |
handleStartMessage((StartMessage) message); |
423 |
handleStartMessage((StartMessage) message); |
288 |
} else if (message instanceof StopMessage) { |
424 |
} else if (message instanceof StopMessage) { |
Lines 590-600
Link Here
|
590 |
final IDocument doc = getDocumentFromEditor(); |
726 |
final IDocument doc = getDocumentFromEditor(); |
591 |
if (doc != null) |
727 |
if (doc != null) |
592 |
doc.addDocumentListener(documentListener); |
728 |
doc.addDocumentListener(documentListener); |
|
|
729 |
if (this.editor != null) { |
730 |
ISelectionProvider selectionProvider = this.editor.getSelectionProvider(); |
731 |
if (selectionProvider instanceof IPostSelectionProvider) { |
732 |
((IPostSelectionProvider) selectionProvider).addPostSelectionChangedListener(selectionListener); |
733 |
} |
734 |
selectionReceiver = new SelectionReceiver(this.editor); |
735 |
} |
593 |
} |
736 |
} |
594 |
|
737 |
|
595 |
} |
738 |
} |
596 |
|
739 |
|
597 |
void localStopShare() { |
740 |
void localStopShare() { |
|
|
741 |
SelectionReceiver oldSelectionReceiver; |
598 |
synchronized (stateLock) { |
742 |
synchronized (stateLock) { |
599 |
if (rosterManager != null) |
743 |
if (rosterManager != null) |
600 |
rosterManager.removeRosterListener(rosterListener); |
744 |
rosterManager.removeRosterListener(rosterListener); |
Lines 606-617
Link Here
|
606 |
final IDocument doc = getDocumentFromEditor(); |
750 |
final IDocument doc = getDocumentFromEditor(); |
607 |
if (doc != null) |
751 |
if (doc != null) |
608 |
doc.removeDocumentListener(documentListener); |
752 |
doc.removeDocumentListener(documentListener); |
609 |
if (editor != null) { |
753 |
if (this.editor != null) { |
610 |
editor.getSite().getPage().removePartListener(partListener); |
754 |
this.editor.getSite().getPage().removePartListener(partListener); |
|
|
755 |
|
756 |
ISelectionProvider selectionProvider = this.editor.getSelectionProvider(); |
757 |
if (selectionProvider instanceof IPostSelectionProvider) { |
758 |
((IPostSelectionProvider) selectionProvider).removePostSelectionChangedListener(selectionListener); |
759 |
} |
611 |
} |
760 |
} |
|
|
761 |
oldSelectionReceiver = this.selectionReceiver; |
762 |
this.selectionReceiver = null; |
763 |
|
612 |
this.editor = null; |
764 |
this.editor = null; |
613 |
} |
765 |
} |
614 |
|
766 |
|
|
|
767 |
if (oldSelectionReceiver != null) { |
768 |
oldSelectionReceiver.dispose(); |
769 |
} |
615 |
} |
770 |
} |
616 |
|
771 |
|
617 |
void sendStopMessage() { |
772 |
void sendStopMessage() { |