@@ -124,6 +124,7 @@ private void processModelChanged(IAnnotationModel model, AnnotationModelEvent ev
124124 fProjectionSummary .updateSummaries ();
125125 }
126126 processCatchupRequest (event );
127+ correctChangedAnnotationVisibility (event );
127128
128129 } else if (model == getAnnotationModel () && fProjectionSummary != null ) {
129130 fProjectionSummary .updateSummaries ();
@@ -770,15 +771,46 @@ public void setVisibleRegion(int start, int length) {
770771 // If the visible region changes, make sure collapsed regions outside of the old visible regions are expanded
771772 // and collapse everything outside the new visible region
772773 int end = computeEndOfVisibleRegion (start , length , document );
774+ Region newVisibleRegion = new Region (start , end - start - 1 );
775+ expandProjectionAnnotationsBorderingRegion (newVisibleRegion );
773776 expandOutsideCurrentVisibleRegion (document );
774777 collapseOutsideOfNewVisibleRegion (start , end , document );
775- fConfiguredVisibleRegion = new Region (start , end - start - 1 );
778+ fConfiguredVisibleRegion = newVisibleRegion ;
779+ hideProjectionAnnotationsOutsideOfVisibleRegion ();
776780 } catch (BadLocationException e ) {
777781 ILog log = ILog .of (getClass ());
778782 log .log (new Status (IStatus .WARNING , getClass (), IStatus .OK , null , e ));
779783 }
780784 }
781785
786+ private void expandProjectionAnnotationsBorderingRegion (Region region ) throws BadLocationException {
787+ for (Iterator <Annotation > it = fProjectionAnnotationModel .getAnnotationIterator (); it .hasNext ();) {
788+ Annotation annotation = it .next ();
789+ Position position = fProjectionAnnotationModel .getPosition (annotation );
790+ if (bordersRegion (position , region )) {
791+ fProjectionAnnotationModel .expand (annotation );
792+ }
793+ }
794+ }
795+
796+ private void hideProjectionAnnotationsOutsideOfVisibleRegion () throws BadLocationException {
797+ for (Iterator <Annotation > it = fProjectionAnnotationModel .getAnnotationIterator (); it .hasNext ();) {
798+ Annotation annotation = it .next ();
799+ hideProjectionAnnotationIfPartsAreOutsideOfVisibleRegion (annotation );
800+ }
801+ }
802+
803+ private void hideProjectionAnnotationIfPartsAreOutsideOfVisibleRegion (Annotation annotation ) throws BadLocationException {
804+ Position position = fProjectionAnnotationModel .getPosition (annotation );
805+ if (annotation instanceof ProjectionAnnotation a ) {
806+ if (overlapsWithNonVisibleRegions (position .getOffset (), position .getLength ())) {
807+ a .setHidden (true );
808+ } else {
809+ a .setHidden (false );
810+ }
811+ }
812+ }
813+
782814 private void expandOutsideCurrentVisibleRegion (IDocument document ) throws BadLocationException {
783815 if (fConfiguredVisibleRegion != null ) {
784816 expand (0 , fConfiguredVisibleRegion .getOffset (), false , true );
@@ -855,6 +887,12 @@ public void resetVisibleRegion() {
855887 super .resetVisibleRegion ();
856888 }
857889 fConfiguredVisibleRegion = null ;
890+ for (Iterator <Annotation > it = fProjectionAnnotationModel .getAnnotationIterator (); it .hasNext ();) {
891+ Annotation annotation = it .next ();
892+ if (annotation instanceof ProjectionAnnotation a ) {
893+ a .setHidden (false );
894+ }
895+ }
858896 }
859897
860898 @ Override
@@ -1014,11 +1052,25 @@ private boolean overlapsWithNonVisibleRegions(int offset, int length) throws Bad
10141052 return false ;
10151053 }
10161054 // ignore overlaps within the same line
1017- int visibleRegionStartLineOffset = getDocument (). getLineInformationOfOffset ( fConfiguredVisibleRegion .getOffset ()). getOffset ( );
1018- int regionToCheckEndLineOffset = getDocument (). getLineInformationOfOffset ( offset + length ). getOffset ( );
1055+ int visibleRegionStartLineOffset = atStartOfLine ( fConfiguredVisibleRegion .getOffset ());
1056+ int regionToCheckEndLineOffset = atStartOfLine ( offset + length );
10191057 return offset < visibleRegionStartLineOffset || regionToCheckEndLineOffset > fConfiguredVisibleRegion .getOffset () + fConfiguredVisibleRegion .getLength ();
10201058 }
10211059
1060+
1061+ private boolean bordersRegion (Position position , Region region ) throws BadLocationException {
1062+ if (position .getOffset () > atStartOfLine (region .getOffset ())
1063+ && atStartOfLine (position .getOffset () + position .getLength ()) < region .getOffset () + region .getLength ()) {
1064+ return true ;
1065+ }
1066+ return atStartOfLine (position .getOffset ()) < region .getOffset ()
1067+ && position .getOffset () + position .getLength () > atStartOfLine (region .getOffset () + region .getLength ());
1068+ }
1069+
1070+ private int atStartOfLine (int off ) throws BadLocationException {
1071+ return getDocument ().getLineInformationOfOffset (off ).getOffset ();
1072+ }
1073+
10221074 /**
10231075 * Processes the request for catch up with the annotation model in the UI thread. If the current
10241076 * thread is not the UI thread or there are pending catch up requests, a new request is posted.
@@ -1090,6 +1142,20 @@ protected final void postCatchupRequest(final AnnotationModelEvent event) {
10901142 }
10911143 }
10921144
1145+ private void correctChangedAnnotationVisibility (AnnotationModelEvent event ) {
1146+ try {
1147+ for (Annotation annotation : event .getAddedAnnotations ()) {
1148+ hideProjectionAnnotationIfPartsAreOutsideOfVisibleRegion (annotation );
1149+ }
1150+ for (Annotation annotation : event .getChangedAnnotations ()) {
1151+ hideProjectionAnnotationIfPartsAreOutsideOfVisibleRegion (annotation );
1152+ }
1153+ } catch (BadLocationException e ) {
1154+ ILog log = ILog .of (getClass ());
1155+ log .log (new Status (IStatus .WARNING , getClass (), IStatus .OK , null , e ));
1156+ }
1157+ }
1158+
10931159 /**
10941160 * Tests whether the visible document's master document
10951161 * is identical to this viewer's document.
0 commit comments