|
1 | 1 | Partial Public Class SelectionHelper
|
2 | 2 | Implements IEnumerable(Of MathElement)
|
3 | 3 |
|
4 |
| - Private This As MathDocument |
| 4 | + Protected This As MathDocument |
| 5 | + Private WithEvents CA_SEL, CA_START, CA_END As MathElement |
| 6 | + |
5 | 7 | Public Sub New(ByVal This As MathDocument)
|
6 | 8 | Me.This = This
|
7 |
| - SetSelection(This, Nothing, Nothing) |
| 9 | + SetSelection(This, This.LastChild, Nothing) |
8 | 10 | End Sub
|
9 | 11 |
|
10 | 12 | Private IsSelectionChanging As Boolean
|
|
43 | 45 | Private Sub SetSelection(ByVal StartPoint As Selection, ByVal EndPoint As Selection)
|
44 | 46 |
|
45 | 47 | ' Compute _Selection
|
46 |
| - Dim CA = StartPoint.SelectionStart.GetCommonAncestrorWith(EndPoint.SelectionEnd) |
47 | 48 | Dim SS = StartPoint.SelectionStart
|
48 |
| - Dim SE = StartPoint.SelectionEnd |
| 49 | + Dim SE = EndPoint.SelectionEnd |
| 50 | + |
| 51 | + ' Collapse selection points |
| 52 | + StartPoint = New Selection(StartPoint.CommonAncestror, SS, StartPoint.CommonAncestror.Children.After(SS)) |
| 53 | + EndPoint = New Selection(EndPoint.CommonAncestror, EndPoint.CommonAncestror.Children.After(SE), SE) |
| 54 | + |
| 55 | + Dim CA = If(SS, SE) |
| 56 | + If StartPoint.CommonAncestror Is EndPoint.CommonAncestror Then |
| 57 | + CA = StartPoint.CommonAncestror |
| 58 | + Else |
| 59 | + CA = StartPoint.CommonAncestror.GetCommonAncestrorWith(EndPoint.CommonAncestror) |
49 | 60 |
|
50 |
| - While SS.Parent IsNot CA |
51 |
| - SS = SS.Parent |
52 |
| - End While |
| 61 | + While SS.Parent IsNot CA |
| 62 | + SS = SS.Parent |
| 63 | + End While |
53 | 64 |
|
54 |
| - While SE.Parent IsNot SE |
55 |
| - SE = SE.Parent |
56 |
| - End While |
| 65 | + While SE.Parent IsNot SE |
| 66 | + SE = SE.Parent |
| 67 | + End While |
57 | 68 |
|
58 |
| - ' Insert StartPoint and EndPoint if needed |
59 |
| - Dim Dir = SelectionDirection.LTR |
| 69 | + End If |
60 | 70 |
|
61 |
| - If SE.IsBefore(SS) Then |
| 71 | + ' Invert StartPoint and EndPoint if needed |
| 72 | + Dim Dir As SelectionDirection = SelectionDirection.LTR |
| 73 | + If (SE IsNot Nothing) AndAlso (SS IsNot Nothing) AndAlso (SE Is SS OrElse SE.IsBefore(SS)) Then |
62 | 74 | Dir = SelectionDirection.RTL
|
63 |
| - Dim Temp = StartPoint |
64 |
| - StartPoint = EndPoint |
65 |
| - EndPoint = Temp |
| 75 | + Dim ST = SE.PreviousSibling |
| 76 | + SE = SS.NextSibling : SS = ST |
66 | 77 | End If
|
67 | 78 |
|
68 | 79 | ' Set the selection
|
69 | 80 | SetSelection_Internal(New Selection(CA, SS, SE), StartPoint, EndPoint)
|
| 81 | + _Dir = Dir |
70 | 82 |
|
71 | 83 | End Sub
|
72 | 84 |
|
73 |
| - Public Sub SetSelection(ByVal Point As Selection, Optional ByVal PointToChange As SelectionPointType = SelectionPointType.Selection) |
| 85 | + Public Sub SetSelection(ByVal NewPoint As Selection, Optional ByVal PointToChange As SelectionPointType = SelectionPointType.Selection) |
74 | 86 | Select Case PointToChange
|
75 | 87 | Case SelectionPointType.Selection
|
76 |
| - SetSelection(Point.CommonAncestror, Point.SelectionStart, Point.SelectionEnd) |
| 88 | + SetSelection(NewPoint.CommonAncestror, NewPoint.SelectionStart, NewPoint.SelectionEnd) |
77 | 89 | Case SelectionPointType.StartPoint
|
78 |
| - SetSelection(Point, EndPoint) |
| 90 | + SetSelection(NewPoint, EndPoint) |
79 | 91 | Case SelectionPointType.EndPoint
|
80 |
| - SetSelection(StartPoint, Point) |
| 92 | + SetSelection(StartPoint, NewPoint) |
81 | 93 | Case Else
|
82 | 94 | Throw New ArgumentException("Unknown value for the selection point type", "PointToChange")
|
83 | 95 | End Select
|
|
97 | 109 | End Function
|
98 | 110 |
|
99 | 111 | Public Sub SetSelection(ByVal CommonAncestror As MathElement, ByVal SelectionStart As MathElement, ByVal SelectionEnd As MathElement)
|
| 112 | + |
100 | 113 | ' Check if the selection is valid
|
101 | 114 | If (
|
102 |
| - (CommonAncestror.ParentDocument Is This) _ |
| 115 | + (CommonAncestror IsNot Nothing) _ |
| 116 | + AndAlso (CommonAncestror.ParentDocument Is This) _ |
103 | 117 | AndAlso (SelectionStart Is Nothing OrElse SelectionStart.Parent Is CommonAncestror) _
|
104 | 118 | AndAlso (SelectionEnd Is Nothing OrElse SelectionEnd.Parent Is CommonAncestror)
|
105 | 119 | ) Then
|
106 | 120 |
|
| 121 | + ' Invert StartPoint and EndPoint if needed |
| 122 | + Dim SS = SelectionStart, SE = SelectionEnd, CA = CommonAncestror |
| 123 | + If (SS Is Nothing) OrElse (SE IsNot Nothing AndAlso (SE Is SS OrElse SE.IsBefore(SS))) Then |
| 124 | + _Dir = SelectionDirection.RTL |
| 125 | + Dim ST = If(SE Is Nothing, Nothing, SE.PreviousSibling) |
| 126 | + SE = SS : SS = SE |
| 127 | + Else |
| 128 | + _Dir = SelectionDirection.LTR |
| 129 | + End If |
| 130 | + |
| 131 | + ' Perform the selection change |
107 | 132 | SetSelection_Internal(
|
108 |
| - New Selection(CommonAncestror, SelectionStart, SelectionEnd), |
109 |
| - New Selection(CommonAncestror, SelectionStart, CommonAncestror.Children.After(SelectionStart)), |
110 |
| - New Selection(CommonAncestror, CommonAncestror.Children.Before(SelectionEnd), SelectionEnd) |
| 133 | + New Selection(CA, SS, SE), |
| 134 | + New Selection(CA, SS, CA.Children.After(SS)), |
| 135 | + New Selection(CA, CA.Children.Before(SE), SE) |
111 | 136 | )
|
112 | 137 |
|
| 138 | + Else |
| 139 | + |
| 140 | + ' Notify of an error |
| 141 | + Throw New ArgumentException("Selection was invalid.") |
| 142 | + |
113 | 143 | End If
|
| 144 | + |
114 | 145 | End Sub
|
115 | 146 |
|
116 | 147 | Private Sub SetSelection_Internal(ByVal Selection As Selection, ByVal StartPoint As Selection, ByVal EndPoint As Selection)
|
|
122 | 153 | Selection.SelectionStart = Temp
|
123 | 154 | _Dir = SelectionDirection.RTL
|
124 | 155 | Else
|
| 156 | + ' TODO: Some SetSelection perfor the _Dir modification themselves... |
125 | 157 | _Dir = SelectionDirection.LTR
|
126 | 158 | End If
|
127 | 159 |
|
128 | 160 | ' Raise the BeforeSelectionChanged event
|
129 | 161 | If Not IsSelectionChanging Then
|
| 162 | + ' TODO: What about IsSelectionChanging and SelectionChanged ???? |
130 | 163 | RaiseEvent BeforeSelectionChanged(Me, EventArgs.Empty)
|
131 | 164 | End If
|
132 | 165 |
|
|
135 | 168 | _StartPoint = StartPoint
|
136 | 169 | _EndPoint = EndPoint
|
137 | 170 |
|
| 171 | + CA_START = StartPoint.CommonAncestror |
| 172 | + CA_END = EndPoint.CommonAncestror |
| 173 | + CA_SEL = Selection.CommonAncestror |
| 174 | + |
138 | 175 | End Sub
|
139 | 176 |
|
140 | 177 | Public Sub ReverseSelection()
|
|
214 | 251 | Private Function GetGenericEnumerator() As System.Collections.IEnumerator Implements System.Collections.IEnumerable.GetEnumerator
|
215 | 252 | Return GetEnumerator()
|
216 | 253 | End Function
|
| 254 | + |
| 255 | + Private Sub CA_END_ChildAdded(ByVal sender As Object, ByVal e As MathElement.TreeEventArgs) Handles CA_END.ChildAdded |
| 256 | + If EndPoint.SelectionEnd Is Nothing Then |
| 257 | + SetSelection(New Selection(CA_END, CA_END.LastChild, Nothing), PointToChange:=SelectionPointType.EndPoint) |
| 258 | + Else |
| 259 | + SetSelection(New Selection(CA_END, CA_END.Children.Before(_EndPoint.SelectionEnd), _EndPoint.SelectionEnd), PointToChange:=SelectionPointType.EndPoint) |
| 260 | + End If |
| 261 | + End Sub |
| 262 | + |
| 263 | + Private Sub CA_END_ChildRemoved(ByVal sender As Object, ByVal e As MathElement.TreeEventArgs) Handles CA_END.ChildRemoved |
| 264 | + |
| 265 | + ' |
| 266 | + ' Verify that the newly removed child don't make the Selection EndPoint invalid! |
| 267 | + ' |
| 268 | + If (_EndPoint.SelectionEnd Is Nothing) OrElse (CA_END.Children.Contains(_EndPoint.SelectionEnd)) Then |
| 269 | + SetSelection(New Selection(CA_END, CA_END.Children.Before(_EndPoint.SelectionEnd), _EndPoint.SelectionEnd), PointToChange:=SelectionPointType.EndPoint) |
| 270 | + Else |
| 271 | + If (_EndPoint.SelectionStart Is Nothing) OrElse (CA_END.Children.Contains(_EndPoint.SelectionStart)) Then |
| 272 | + SetSelection(New Selection(CA_END, _EndPoint.SelectionStart, CA_END.Children.After(_EndPoint.SelectionStart)), PointToChange:=SelectionPointType.EndPoint) |
| 273 | + Else |
| 274 | + SetSelection(New Selection(CA_END, CA_END.LastChild, Nothing), PointToChange:=SelectionPointType.EndPoint) |
| 275 | + End If |
| 276 | + End If |
| 277 | + |
| 278 | + End Sub |
| 279 | + |
| 280 | + Private Sub CA_START_ChildAdded(ByVal sender As Object, ByVal e As MathElement.TreeEventArgs) Handles CA_START.ChildAdded |
| 281 | + If StartPoint.SelectionStart Is Nothing Then |
| 282 | + SetSelection(New Selection(CA_START, Nothing, CA_START.FirstChild), PointToChange:=SelectionPointType.StartPoint) |
| 283 | + Else |
| 284 | + SetSelection(New Selection(CA_START, _StartPoint.SelectionStart, CA_START.Children.After(_StartPoint.SelectionStart)), PointToChange:=SelectionPointType.StartPoint) |
| 285 | + End If |
| 286 | + End Sub |
| 287 | + |
| 288 | + Private Sub CA_START_ChildRemoved(ByVal sender As Object, ByVal e As MathElement.TreeEventArgs) Handles CA_START.ChildRemoved |
| 289 | + |
| 290 | + ' |
| 291 | + ' Verify that the newly removed child don't make the Selection StartPoint invalid! |
| 292 | + ' |
| 293 | + If (_StartPoint.SelectionStart Is Nothing) OrElse (CA_START.Children.Contains(_StartPoint.SelectionStart)) Then |
| 294 | + SetSelection(New Selection(CA_START, _StartPoint.SelectionStart, CA_START.Children.After(_StartPoint.SelectionStart)), PointToChange:=SelectionPointType.StartPoint) |
| 295 | + Else |
| 296 | + If (_StartPoint.SelectionEnd Is Nothing) OrElse (CA_END.Children.Contains(_StartPoint.SelectionEnd)) Then |
| 297 | + SetSelection(New Selection(CA_START, CA_START.Children.Before(_StartPoint.SelectionEnd), _StartPoint.SelectionEnd), PointToChange:=SelectionPointType.StartPoint) |
| 298 | + Else |
| 299 | + SetSelection(New Selection(CA_END, CA_END.LastChild, Nothing), PointToChange:=SelectionPointType.StartPoint) |
| 300 | + End If |
| 301 | + End If |
| 302 | + |
| 303 | + End Sub |
217 | 304 | End Class
|
0 commit comments