Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*
3 : : * Version: MPL 1.1 / GPLv3+ / LGPLv3+
4 : : *
5 : : * The contents of this file are subject to the Mozilla Public License Version
6 : : * 1.1 (the "License"); you may not use this file except in compliance with
7 : : * the License. You may obtain a copy of the License at
8 : : * http://www.mozilla.org/MPL/
9 : : *
10 : : * Software distributed under the License is distributed on an "AS IS" basis,
11 : : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : : * for the specific language governing rights and limitations under the
13 : : * License.
14 : : *
15 : : * The Initial Developer of the Original Code is
16 : : * Jonas Finnemann Jensen <jopsen@gmail.com>
17 : : * Portions created by the Initial Developer are Copyright (C) 2010 the
18 : : * Initial Developer. All Rights Reserved.
19 : : *
20 : : * Contributor(s): Jonas Finnemann Jensen <jopsen@gmail.com>
21 : : *
22 : : * Alternatively, the contents of this file may be used under the terms of
23 : : * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
24 : : * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
25 : : * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
26 : : * instead of those above.
27 : : */
28 : : #include "visitors.hxx"
29 : : #include "cursor.hxx"
30 : :
31 : : ///////////////////////////////////// SmVisitorTest /////////////////////////////////////
32 : :
33 : 0 : void SmVisitorTest::Visit( SmTableNode* pNode )
34 : : {
35 : : OSL_ENSURE( pNode->GetType( ) == NTABLE, "the visitor-patterns isn't implemented correctly" );
36 : 0 : VisitChildren( pNode );
37 : 0 : }
38 : :
39 : 0 : void SmVisitorTest::Visit( SmBraceNode* pNode )
40 : : {
41 : : OSL_ENSURE( pNode->GetType( ) == NBRACE, "the visitor-patterns isn't implemented correctly" );
42 : 0 : VisitChildren( pNode );
43 : 0 : }
44 : :
45 : 0 : void SmVisitorTest::Visit( SmBracebodyNode* pNode )
46 : : {
47 : : OSL_ENSURE( pNode->GetType( ) == NBRACEBODY, "the visitor-patterns isn't implemented correctly" );
48 : 0 : VisitChildren( pNode );
49 : 0 : }
50 : :
51 : 0 : void SmVisitorTest::Visit( SmOperNode* pNode )
52 : : {
53 : : OSL_ENSURE( pNode->GetType( ) == NOPER, "the visitor-patterns isn't implemented correctly" );
54 : 0 : VisitChildren( pNode );
55 : 0 : }
56 : :
57 : 0 : void SmVisitorTest::Visit( SmAlignNode* pNode )
58 : : {
59 : : OSL_ENSURE( pNode->GetType( ) == NALIGN, "the visitor-patterns isn't implemented correctly" );
60 : 0 : VisitChildren( pNode );
61 : 0 : }
62 : :
63 : 0 : void SmVisitorTest::Visit( SmAttributNode* pNode )
64 : : {
65 : : OSL_ENSURE( pNode->GetType( ) == NATTRIBUT, "the visitor-patterns isn't implemented correctly" );
66 : 0 : VisitChildren( pNode );
67 : 0 : }
68 : :
69 : 0 : void SmVisitorTest::Visit( SmFontNode* pNode )
70 : : {
71 : : OSL_ENSURE( pNode->GetType( ) == NFONT, "the visitor-patterns isn't implemented correctly" );
72 : 0 : VisitChildren( pNode );
73 : 0 : }
74 : :
75 : 0 : void SmVisitorTest::Visit( SmUnHorNode* pNode )
76 : : {
77 : : OSL_ENSURE( pNode->GetType( ) == NUNHOR, "the visitor-patterns isn't implemented correctly" );
78 : 0 : VisitChildren( pNode );
79 : 0 : }
80 : :
81 : 0 : void SmVisitorTest::Visit( SmBinHorNode* pNode )
82 : : {
83 : : OSL_ENSURE( pNode->GetType( ) == NBINHOR, "the visitor-patterns isn't implemented correctly" );
84 : 0 : VisitChildren( pNode );
85 : 0 : }
86 : :
87 : 0 : void SmVisitorTest::Visit( SmBinVerNode* pNode )
88 : : {
89 : : OSL_ENSURE( pNode->GetType( ) == NBINVER, "the visitor-patterns isn't implemented correctly" );
90 : 0 : VisitChildren( pNode );
91 : 0 : }
92 : :
93 : 0 : void SmVisitorTest::Visit( SmBinDiagonalNode* pNode )
94 : : {
95 : : OSL_ENSURE( pNode->GetType( ) == NBINDIAGONAL, "the visitor-patterns isn't implemented correctly" );
96 : 0 : VisitChildren( pNode );
97 : 0 : }
98 : :
99 : 0 : void SmVisitorTest::Visit( SmSubSupNode* pNode )
100 : : {
101 : : OSL_ENSURE( pNode->GetType( ) == NSUBSUP, "the visitor-patterns isn't implemented correctly" );
102 : 0 : VisitChildren( pNode );
103 : 0 : }
104 : :
105 : 0 : void SmVisitorTest::Visit( SmMatrixNode* pNode )
106 : : {
107 : : OSL_ENSURE( pNode->GetType( ) == NMATRIX, "the visitor-patterns isn't implemented correctly" );
108 : 0 : VisitChildren( pNode );
109 : 0 : }
110 : :
111 : 0 : void SmVisitorTest::Visit( SmPlaceNode* pNode )
112 : : {
113 : : OSL_ENSURE( pNode->GetType( ) == NPLACE, "the visitor-patterns isn't implemented correctly" );
114 : 0 : VisitChildren( pNode );
115 : 0 : }
116 : :
117 : 0 : void SmVisitorTest::Visit( SmTextNode* pNode )
118 : : {
119 : : OSL_ENSURE( pNode->GetType( ) == NTEXT, "the visitor-patterns isn't implemented correctly" );
120 : 0 : VisitChildren( pNode );
121 : 0 : }
122 : :
123 : 0 : void SmVisitorTest::Visit( SmSpecialNode* pNode )
124 : : {
125 : : OSL_ENSURE( pNode->GetType( ) == NSPECIAL, "the visitor-patterns isn't implemented correctly" );
126 : 0 : VisitChildren( pNode );
127 : 0 : }
128 : :
129 : 0 : void SmVisitorTest::Visit( SmGlyphSpecialNode* pNode )
130 : : {
131 : : OSL_ENSURE( pNode->GetType( ) == NGLYPH_SPECIAL, "the visitor-patterns isn't implemented correctly" );
132 : 0 : VisitChildren( pNode );
133 : 0 : }
134 : :
135 : 0 : void SmVisitorTest::Visit( SmMathSymbolNode* pNode )
136 : : {
137 : : OSL_ENSURE( pNode->GetType( ) == NMATH, "the visitor-patterns isn't implemented correctly" );
138 : 0 : VisitChildren( pNode );
139 : 0 : }
140 : :
141 : 0 : void SmVisitorTest::Visit( SmBlankNode* pNode )
142 : : {
143 : : OSL_ENSURE( pNode->GetType( ) == NBLANK, "the visitor-patterns isn't implemented correctly" );
144 : 0 : VisitChildren( pNode );
145 : 0 : }
146 : :
147 : 0 : void SmVisitorTest::Visit( SmErrorNode* pNode )
148 : : {
149 : : OSL_ENSURE( pNode->GetType( ) == NERROR, "the visitor-patterns isn't implemented correctly" );
150 : 0 : VisitChildren( pNode );
151 : 0 : }
152 : :
153 : 0 : void SmVisitorTest::Visit( SmLineNode* pNode )
154 : : {
155 : : OSL_ENSURE( pNode->GetType( ) == NLINE, "the visitor-patterns isn't implemented correctly" );
156 : 0 : VisitChildren( pNode );
157 : 0 : }
158 : :
159 : 0 : void SmVisitorTest::Visit( SmExpressionNode* pNode )
160 : : {
161 : : OSL_ENSURE( pNode->GetType( ) == NEXPRESSION, "the visitor-patterns isn't implemented correctly" );
162 : 0 : VisitChildren( pNode );
163 : 0 : }
164 : :
165 : 0 : void SmVisitorTest::Visit( SmPolyLineNode* pNode )
166 : : {
167 : : OSL_ENSURE( pNode->GetType( ) == NPOLYLINE, "the visitor-patterns isn't implemented correctly" );
168 : 0 : VisitChildren( pNode );
169 : 0 : }
170 : :
171 : 0 : void SmVisitorTest::Visit( SmRootNode* pNode )
172 : : {
173 : : OSL_ENSURE( pNode->GetType( ) == NROOT, "the visitor-patterns isn't implemented correctly" );
174 : 0 : VisitChildren( pNode );
175 : 0 : }
176 : :
177 : 0 : void SmVisitorTest::Visit( SmRootSymbolNode* pNode )
178 : : {
179 : : OSL_ENSURE( pNode->GetType( ) == NROOTSYMBOL, "the visitor-patterns isn't implemented correctly" );
180 : 0 : VisitChildren( pNode );
181 : 0 : }
182 : :
183 : 0 : void SmVisitorTest::Visit( SmRectangleNode* pNode )
184 : : {
185 : : OSL_ENSURE( pNode->GetType( ) == NRECTANGLE, "the visitor-patterns isn't implemented correctly" );
186 : 0 : VisitChildren( pNode );
187 : 0 : }
188 : :
189 : 0 : void SmVisitorTest::Visit( SmVerticalBraceNode* pNode )
190 : : {
191 : : OSL_ENSURE( pNode->GetType( ) == NVERTICAL_BRACE, "the visitor-patterns isn't implemented correctly" );
192 : 0 : VisitChildren( pNode );
193 : 0 : }
194 : :
195 : 0 : void SmVisitorTest::VisitChildren( SmNode* pNode )
196 : : {
197 [ # # ]: 0 : SmNodeIterator it( pNode );
198 [ # # ][ # # ]: 0 : while( it.Next( ) )
199 [ # # ]: 0 : it->Accept( this );
200 : 0 : }
201 : :
202 : : /////////////////////////////// SmDefaultingVisitor ////////////////////////////////
203 : :
204 : 0 : void SmDefaultingVisitor::Visit( SmTableNode* pNode )
205 : : {
206 : 0 : DefaultVisit( pNode );
207 : 0 : }
208 : :
209 : 0 : void SmDefaultingVisitor::Visit( SmBraceNode* pNode )
210 : : {
211 : 0 : DefaultVisit( pNode );
212 : 0 : }
213 : :
214 : 0 : void SmDefaultingVisitor::Visit( SmBracebodyNode* pNode )
215 : : {
216 : 0 : DefaultVisit( pNode );
217 : 0 : }
218 : :
219 : 0 : void SmDefaultingVisitor::Visit( SmOperNode* pNode )
220 : : {
221 : 0 : DefaultVisit( pNode );
222 : 0 : }
223 : :
224 : 0 : void SmDefaultingVisitor::Visit( SmAlignNode* pNode )
225 : : {
226 : 0 : DefaultVisit( pNode );
227 : 0 : }
228 : :
229 : 0 : void SmDefaultingVisitor::Visit( SmAttributNode* pNode )
230 : : {
231 : 0 : DefaultVisit( pNode );
232 : 0 : }
233 : :
234 : 0 : void SmDefaultingVisitor::Visit( SmFontNode* pNode )
235 : : {
236 : 0 : DefaultVisit( pNode );
237 : 0 : }
238 : :
239 : 0 : void SmDefaultingVisitor::Visit( SmUnHorNode* pNode )
240 : : {
241 : 0 : DefaultVisit( pNode );
242 : 0 : }
243 : :
244 : 0 : void SmDefaultingVisitor::Visit( SmBinHorNode* pNode )
245 : : {
246 : 0 : DefaultVisit( pNode );
247 : 0 : }
248 : :
249 : 0 : void SmDefaultingVisitor::Visit( SmBinVerNode* pNode )
250 : : {
251 : 0 : DefaultVisit( pNode );
252 : 0 : }
253 : :
254 : 0 : void SmDefaultingVisitor::Visit( SmBinDiagonalNode* pNode )
255 : : {
256 : 0 : DefaultVisit( pNode );
257 : 0 : }
258 : :
259 : 0 : void SmDefaultingVisitor::Visit( SmSubSupNode* pNode )
260 : : {
261 : 0 : DefaultVisit( pNode );
262 : 0 : }
263 : :
264 : 0 : void SmDefaultingVisitor::Visit( SmMatrixNode* pNode )
265 : : {
266 : 0 : DefaultVisit( pNode );
267 : 0 : }
268 : :
269 : 0 : void SmDefaultingVisitor::Visit( SmPlaceNode* pNode )
270 : : {
271 : 0 : DefaultVisit( pNode );
272 : 0 : }
273 : :
274 : 0 : void SmDefaultingVisitor::Visit( SmTextNode* pNode )
275 : : {
276 : 0 : DefaultVisit( pNode );
277 : 0 : }
278 : :
279 : 0 : void SmDefaultingVisitor::Visit( SmSpecialNode* pNode )
280 : : {
281 : 0 : DefaultVisit( pNode );
282 : 0 : }
283 : :
284 : 0 : void SmDefaultingVisitor::Visit( SmGlyphSpecialNode* pNode )
285 : : {
286 : 0 : DefaultVisit( pNode );
287 : 0 : }
288 : :
289 : 0 : void SmDefaultingVisitor::Visit( SmMathSymbolNode* pNode )
290 : : {
291 : 0 : DefaultVisit( pNode );
292 : 0 : }
293 : :
294 : 0 : void SmDefaultingVisitor::Visit( SmBlankNode* pNode )
295 : : {
296 : 0 : DefaultVisit( pNode );
297 : 0 : }
298 : :
299 : 0 : void SmDefaultingVisitor::Visit( SmErrorNode* pNode )
300 : : {
301 : 0 : DefaultVisit( pNode );
302 : 0 : }
303 : :
304 : 0 : void SmDefaultingVisitor::Visit( SmLineNode* pNode )
305 : : {
306 : 0 : DefaultVisit( pNode );
307 : 0 : }
308 : :
309 : 0 : void SmDefaultingVisitor::Visit( SmExpressionNode* pNode )
310 : : {
311 : 0 : DefaultVisit( pNode );
312 : 0 : }
313 : :
314 : 0 : void SmDefaultingVisitor::Visit( SmPolyLineNode* pNode )
315 : : {
316 : 0 : DefaultVisit( pNode );
317 : 0 : }
318 : :
319 : 0 : void SmDefaultingVisitor::Visit( SmRootNode* pNode )
320 : : {
321 : 0 : DefaultVisit( pNode );
322 : 0 : }
323 : :
324 : 0 : void SmDefaultingVisitor::Visit( SmRootSymbolNode* pNode )
325 : : {
326 : 0 : DefaultVisit( pNode );
327 : 0 : }
328 : :
329 : 0 : void SmDefaultingVisitor::Visit( SmRectangleNode* pNode )
330 : : {
331 : 0 : DefaultVisit( pNode );
332 : 0 : }
333 : :
334 : 0 : void SmDefaultingVisitor::Visit( SmVerticalBraceNode* pNode )
335 : : {
336 : 0 : DefaultVisit( pNode );
337 : 0 : }
338 : :
339 : : /////////////////////////////// SmCaretDrawingVisitor ////////////////////////////////
340 : :
341 : 0 : SmCaretDrawingVisitor::SmCaretDrawingVisitor( OutputDevice& rDevice,
342 : : SmCaretPos position,
343 : : Point offset,
344 : : bool caretVisible )
345 : 0 : : rDev( rDevice )
346 : : {
347 : 0 : pos = position;
348 : 0 : Offset = offset;
349 : 0 : isCaretVisible = caretVisible;
350 : : OSL_ENSURE( position.IsValid( ), "Cannot draw invalid position!" );
351 [ # # ]: 0 : if( !position.IsValid( ) )
352 : 0 : return;
353 : :
354 : : //Save device state
355 [ # # ]: 0 : rDev.Push( PUSH_FONT | PUSH_MAPMODE | PUSH_LINECOLOR | PUSH_FILLCOLOR | PUSH_TEXTCOLOR );
356 : :
357 [ # # ]: 0 : pos.pSelectedNode->Accept( this );
358 : : //Restore device state
359 [ # # ]: 0 : rDev.Pop( );
360 : : }
361 : :
362 : 0 : void SmCaretDrawingVisitor::Visit( SmTextNode* pNode )
363 : : {
364 : 0 : long i = pos.Index;
365 : :
366 [ # # ]: 0 : rDev.SetFont( pNode->GetFont( ) );
367 : :
368 : : //Find the line
369 [ # # ]: 0 : SmNode* pLine = SmCursor::FindTopMostNodeInLine( pNode );
370 : :
371 : : //Find coordinates
372 [ # # ]: 0 : long left = pNode->GetLeft( ) + rDev.GetTextWidth( pNode->GetText( ), 0, i ) + Offset.X( );
373 : 0 : long top = pLine->GetTop( ) + Offset.Y( );
374 [ # # ]: 0 : long height = pLine->GetHeight( );
375 : 0 : long left_line = pLine->GetLeft( ) + Offset.X( );
376 [ # # ]: 0 : long right_line = pLine->GetRight( ) + Offset.X( );
377 : :
378 : : //Set color
379 [ # # ]: 0 : rDev.SetLineColor( Color( COL_BLACK ) );
380 : :
381 [ # # ]: 0 : if ( isCaretVisible ) {
382 : : //Draw vertical line
383 : 0 : Point p1( left, top );
384 : 0 : Point p2( left, top + height );
385 [ # # ]: 0 : rDev.DrawLine( p1, p2 );
386 : : }
387 : :
388 : : //Underline the line
389 : 0 : Point pLeft( left_line, top + height );
390 : 0 : Point pRight( right_line, top + height );
391 [ # # ]: 0 : rDev.DrawLine( pLeft, pRight );
392 : 0 : }
393 : :
394 : 0 : void SmCaretDrawingVisitor::DefaultVisit( SmNode* pNode )
395 : : {
396 [ # # ]: 0 : rDev.SetLineColor( Color( COL_BLACK ) );
397 : :
398 : : //Find the line
399 [ # # ]: 0 : SmNode* pLine = SmCursor::FindTopMostNodeInLine( pNode );
400 : :
401 : : //Find coordinates
402 [ # # ][ # # ]: 0 : long left = pNode->GetLeft( ) + Offset.X( ) + ( pos.Index == 1 ? pNode->GetWidth( ) : 0 );
403 : 0 : long top = pLine->GetTop( ) + Offset.Y( );
404 [ # # ]: 0 : long height = pLine->GetHeight( );
405 : 0 : long left_line = pLine->GetLeft( ) + Offset.X( );
406 [ # # ]: 0 : long right_line = pLine->GetRight( ) + Offset.X( );
407 : :
408 : : //Set color
409 [ # # ]: 0 : rDev.SetLineColor( Color( COL_BLACK ) );
410 : :
411 [ # # ]: 0 : if ( isCaretVisible ) {
412 : : //Draw vertical line
413 : 0 : Point p1( left, top );
414 : 0 : Point p2( left, top + height );
415 [ # # ]: 0 : rDev.DrawLine( p1, p2 );
416 : : }
417 : :
418 : : //Underline the line
419 : 0 : Point pLeft( left_line, top + height );
420 : 0 : Point pRight( right_line, top + height );
421 [ # # ]: 0 : rDev.DrawLine( pLeft, pRight );
422 : 0 : }
423 : :
424 : : /////////////////////////////// SmCaretPos2LineVisitor ////////////////////////////////
425 : :
426 : 0 : void SmCaretPos2LineVisitor::Visit( SmTextNode* pNode )
427 : : {
428 : : //Save device state
429 : 0 : pDev->Push( PUSH_FONT | PUSH_TEXTCOLOR );
430 : :
431 : 0 : long i = pos.Index;
432 : :
433 : 0 : pDev->SetFont( pNode->GetFont( ) );
434 : :
435 : : //Find coordinates
436 : 0 : long left = pNode->GetLeft( ) + pDev->GetTextWidth( pNode->GetText( ), 0, i );
437 : 0 : long top = pNode->GetTop( );
438 : 0 : long height = pNode->GetHeight( );
439 : :
440 : 0 : line = SmCaretLine( left, top, height );
441 : :
442 : : //Restore device state
443 : 0 : pDev->Pop( );
444 : 0 : }
445 : :
446 : 0 : void SmCaretPos2LineVisitor::DefaultVisit( SmNode* pNode )
447 : : {
448 : : //Vertical line ( code from SmCaretDrawingVisitor )
449 : 0 : Point p1 = pNode->GetTopLeft( );
450 [ # # ]: 0 : if( pos.Index == 1 )
451 [ # # ]: 0 : p1.Move( pNode->GetWidth( ), 0 );
452 : :
453 [ # # ]: 0 : line = SmCaretLine( p1.X( ), p1.Y( ), pNode->GetHeight( ) );
454 : 0 : }
455 : :
456 : : /////////////////////////////// Nasty temporary device!!! ////////////////////////////////
457 : :
458 : : #include <tools/gen.hxx>
459 : : #include <tools/fract.hxx>
460 : : #include <rtl/math.hxx>
461 : : #include <tools/color.hxx>
462 : : #include <vcl/metric.hxx>
463 : : #include <vcl/lineinfo.hxx>
464 : : #include <vcl/outdev.hxx>
465 : : #include <sfx2/module.hxx>
466 : : #include "symbol.hxx"
467 : : #include "smmod.hxx"
468 : :
469 : : class SmTmpDevice2
470 : : {
471 : : OutputDevice &rOutDev;
472 : :
473 : : // disallow use of copy-constructor and assignment-operator
474 : : SmTmpDevice2( const SmTmpDevice2 &rTmpDev );
475 : : SmTmpDevice2 & operator = ( const SmTmpDevice2 &rTmpDev );
476 : :
477 : : Color Impl_GetColor( const Color& rColor );
478 : :
479 : : public:
480 : : SmTmpDevice2( OutputDevice &rTheDev, bool bUseMap100th_mm );
481 : 65803 : ~SmTmpDevice2( ) { rOutDev.Pop( ); }
482 : :
483 : : void SetFont( const Font &rNewFont );
484 : :
485 [ # # ]: 0 : void SetLineColor( const Color& rColor ) { rOutDev.SetLineColor( Impl_GetColor( rColor ) ); }
486 [ + - ]: 3648 : void SetFillColor( const Color& rColor ) { rOutDev.SetFillColor( Impl_GetColor( rColor ) ); }
487 : : void SetTextColor( const Color& rColor ) { rOutDev.SetTextColor( Impl_GetColor( rColor ) ); }
488 : :
489 : : operator OutputDevice & ( ) const { return rOutDev; }
490 : : };
491 : :
492 : 65803 : SmTmpDevice2::SmTmpDevice2( OutputDevice &rTheDev, bool bUseMap100th_mm ) :
493 : 65803 : rOutDev( rTheDev )
494 : : {
495 : : rOutDev.Push( PUSH_FONT | PUSH_MAPMODE |
496 : 65803 : PUSH_LINECOLOR | PUSH_FILLCOLOR | PUSH_TEXTCOLOR );
497 [ - + ][ - + ]: 65803 : if ( bUseMap100th_mm && MAP_100TH_MM != rOutDev.GetMapMode( ).GetMapUnit( ) )
[ + + ]
498 : : {
499 : : OSL_FAIL( "incorrect MapMode?" );
500 [ # # ]: 0 : rOutDev.SetMapMode( MAP_100TH_MM ); //format for 100% always
501 : : }
502 : 65803 : }
503 : :
504 : 69451 : Color SmTmpDevice2::Impl_GetColor( const Color& rColor )
505 : : {
506 : 69451 : ColorData nNewCol = rColor.GetColor( );
507 [ + + ]: 69451 : if ( COL_AUTO == nNewCol )
508 : : {
509 [ - + ]: 68875 : if ( OUTDEV_PRINTER == rOutDev.GetOutDevType( ) )
510 : 0 : nNewCol = COL_BLACK;
511 : : else
512 : : {
513 [ + - ]: 68875 : Color aBgCol( rOutDev.GetBackground( ).GetColor( ) );
514 [ + + ]: 68875 : if ( OUTDEV_WINDOW == rOutDev.GetOutDevType( ) )
515 [ + - ][ + - ]: 43 : aBgCol = ( ( Window & ) rOutDev ).GetDisplayBackground( ).GetColor( );
516 : :
517 [ + - ][ + - ]: 68875 : nNewCol = SM_MOD( )->GetColorConfig( ).GetColorValue( svtools::FONTCOLOR ).nColor;
[ + - ]
518 : :
519 : 68875 : Color aTmpColor( nNewCol );
520 [ - + ][ # # ]: 68875 : if ( aBgCol.IsDark( ) && aTmpColor.IsDark( ) )
[ # # ][ - + ]
[ + - ]
521 : 0 : nNewCol = COL_WHITE;
522 [ + - ][ + - ]: 68875 : else if ( aBgCol.IsBright( ) && aTmpColor.IsBright( ) )
[ + - ][ - + ]
[ - + ]
523 : 68875 : nNewCol = COL_BLACK;
524 : : }
525 : : }
526 : 69451 : return Color( nNewCol );
527 : : }
528 : :
529 : 65803 : void SmTmpDevice2::SetFont( const Font &rNewFont )
530 : : {
531 : 65803 : rOutDev.SetFont( rNewFont );
532 [ + - ]: 65803 : rOutDev.SetTextColor( Impl_GetColor( rNewFont.GetColor( ) ) );
533 : 65803 : }
534 : :
535 : : /////////////////////////////// SmDrawingVisitor ////////////////////////////////
536 : :
537 : 7719 : void SmDrawingVisitor::Visit( SmTableNode* pNode )
538 : : {
539 : 7719 : DrawChildren( pNode );
540 : 7719 : }
541 : :
542 : 4320 : void SmDrawingVisitor::Visit( SmBraceNode* pNode )
543 : : {
544 : 4320 : DrawChildren( pNode );
545 : 4320 : }
546 : :
547 : 4320 : void SmDrawingVisitor::Visit( SmBracebodyNode* pNode )
548 : : {
549 : 4320 : DrawChildren( pNode );
550 : 4320 : }
551 : :
552 : 1353 : void SmDrawingVisitor::Visit( SmOperNode* pNode )
553 : : {
554 : 1353 : DrawChildren( pNode );
555 : 1353 : }
556 : :
557 : 0 : void SmDrawingVisitor::Visit( SmAlignNode* pNode )
558 : : {
559 : 0 : DrawChildren( pNode );
560 : 0 : }
561 : :
562 : 2693 : void SmDrawingVisitor::Visit( SmAttributNode* pNode )
563 : : {
564 : 2693 : DrawChildren( pNode );
565 : 2693 : }
566 : :
567 : 0 : void SmDrawingVisitor::Visit( SmFontNode* pNode )
568 : : {
569 : 0 : DrawChildren( pNode );
570 : 0 : }
571 : :
572 : 96 : void SmDrawingVisitor::Visit( SmUnHorNode* pNode )
573 : : {
574 : 96 : DrawChildren( pNode );
575 : 96 : }
576 : :
577 : 7015 : void SmDrawingVisitor::Visit( SmBinHorNode* pNode )
578 : : {
579 : 7015 : DrawChildren( pNode );
580 : 7015 : }
581 : :
582 : 2688 : void SmDrawingVisitor::Visit( SmBinVerNode* pNode )
583 : : {
584 : 2688 : DrawChildren( pNode );
585 : 2688 : }
586 : :
587 : 0 : void SmDrawingVisitor::Visit( SmBinDiagonalNode* pNode )
588 : : {
589 : 0 : DrawChildren( pNode );
590 : 0 : }
591 : :
592 : 6240 : void SmDrawingVisitor::Visit( SmSubSupNode* pNode )
593 : : {
594 : 6240 : DrawChildren( pNode );
595 : 6240 : }
596 : :
597 : 192 : void SmDrawingVisitor::Visit( SmMatrixNode* pNode )
598 : : {
599 : 192 : DrawChildren( pNode );
600 : 192 : }
601 : :
602 : 576 : void SmDrawingVisitor::Visit( SmPlaceNode* pNode )
603 : : {
604 : 576 : DrawSpecialNode( pNode );
605 : 576 : }
606 : :
607 : 40438 : void SmDrawingVisitor::Visit( SmTextNode* pNode )
608 : : {
609 : 40438 : DrawTextNode( pNode );
610 : 40438 : }
611 : :
612 : 0 : void SmDrawingVisitor::Visit( SmSpecialNode* pNode )
613 : : {
614 : 0 : DrawSpecialNode( pNode );
615 : 0 : }
616 : :
617 : 0 : void SmDrawingVisitor::Visit( SmGlyphSpecialNode* pNode )
618 : : {
619 : 0 : DrawSpecialNode( pNode );
620 : 0 : }
621 : :
622 : 20661 : void SmDrawingVisitor::Visit( SmMathSymbolNode* pNode )
623 : : {
624 : 20661 : DrawSpecialNode( pNode );
625 : 20661 : }
626 : :
627 : 0 : void SmDrawingVisitor::Visit( SmBlankNode* pNode )
628 : : {
629 : 0 : DrawChildren( pNode );
630 : 0 : }
631 : :
632 : 0 : void SmDrawingVisitor::Visit( SmErrorNode* pNode )
633 : : {
634 : 0 : DrawSpecialNode( pNode );
635 : 0 : }
636 : :
637 : 6855 : void SmDrawingVisitor::Visit( SmLineNode* pNode )
638 : : {
639 : 6855 : DrawChildren( pNode );
640 : 6855 : }
641 : :
642 : 38343 : void SmDrawingVisitor::Visit( SmExpressionNode* pNode )
643 : : {
644 : 38343 : DrawChildren( pNode );
645 : 38343 : }
646 : :
647 : 576 : void SmDrawingVisitor::Visit( SmRootNode* pNode )
648 : : {
649 : 576 : DrawChildren( pNode );
650 : 576 : }
651 : :
652 : 384 : void SmDrawingVisitor::Visit( SmVerticalBraceNode* pNode )
653 : : {
654 : 384 : DrawChildren( pNode );
655 : 384 : }
656 : :
657 : 576 : void SmDrawingVisitor::Visit( SmRootSymbolNode* pNode )
658 : : {
659 [ + - ]: 576 : if ( pNode->IsPhantom( ) )
660 : 576 : return;
661 : :
662 : : // draw root-sign itself
663 [ + - ]: 576 : DrawSpecialNode( pNode );
664 : :
665 [ + - ]: 576 : SmTmpDevice2 aTmpDev( ( OutputDevice & ) rDev, true );
666 [ + - ][ + - ]: 576 : aTmpDev.SetFillColor( pNode->GetFont( ).GetColor( ) );
667 [ + - ]: 576 : rDev.SetLineColor( );
668 [ + - ]: 576 : aTmpDev.SetFont( pNode->GetFont( ) );
669 : :
670 : : // since the width is always unscaled it corresponds ot the _original_
671 : : // _unscaled_ font height to be used, we use that to calculate the
672 : : // bar height. Thus it is independent of the arguments height.
673 : : // ( see display of sqrt QQQ versus sqrt stack{Q#Q#Q#Q} )
674 [ + - ]: 576 : long nBarHeight = pNode->GetWidth( ) * 7L / 100L;
675 : 576 : long nBarWidth = pNode->GetBodyWidth( ) + pNode->GetBorderWidth( );
676 [ + - ]: 576 : Point aBarOffset( pNode->GetWidth( ), +pNode->GetBorderWidth( ) );
677 : 576 : Point aBarPos( Position + aBarOffset );
678 : :
679 [ + - ]: 576 : Rectangle aBar( aBarPos, Size( nBarWidth, nBarHeight ) );
680 : : //! avoid GROWING AND SHRINKING of drawn rectangle when constantly
681 : : //! increasing zoomfactor.
682 : : // This is done by shifting its output-position to a point that
683 : : // corresponds exactly to a pixel on the output device.
684 [ + - ][ + - ]: 576 : Point aDrawPos( rDev.PixelToLogic( rDev.LogicToPixel( aBar.TopLeft( ) ) ) );
685 : 576 : aBar.SetPos( aDrawPos );
686 : :
687 [ + - ][ + - ]: 576 : rDev.DrawRect( aBar );
688 : : }
689 : :
690 : 0 : void SmDrawingVisitor::Visit( SmPolyLineNode* pNode )
691 : : {
692 [ # # ]: 0 : if ( pNode->IsPhantom( ) )
693 : 0 : return;
694 : :
695 [ # # ]: 0 : long nBorderwidth = pNode->GetFont( ).GetBorderWidth( );
696 : :
697 [ # # ]: 0 : LineInfo aInfo;
698 [ # # ]: 0 : aInfo.SetWidth( pNode->GetWidth( ) - 2 * nBorderwidth );
699 : :
700 [ # # ]: 0 : Point aOffset ( Point( ) - pNode->GetPolygon( ).GetBoundRect( ).TopLeft( )
701 : 0 : + Point( nBorderwidth, nBorderwidth ) ),
702 : 0 : aPos ( Position + aOffset );
703 [ # # ]: 0 : pNode->GetPolygon( ).Move( aPos.X( ), aPos.Y( ) ); //Works because Polygon wraps a pointer
704 : :
705 [ # # ]: 0 : SmTmpDevice2 aTmpDev ( ( OutputDevice & ) rDev, false );
706 [ # # ][ # # ]: 0 : aTmpDev.SetLineColor( pNode->GetFont( ).GetColor( ) );
707 : :
708 [ # # ][ # # ]: 0 : rDev.DrawPolyLine( pNode->GetPolygon( ), aInfo );
[ # # ]
709 : : }
710 : :
711 : 3072 : void SmDrawingVisitor::Visit( SmRectangleNode* pNode )
712 : : {
713 [ + - ]: 3072 : if ( pNode->IsPhantom( ) )
714 : 3072 : return;
715 : :
716 [ + - ]: 3072 : SmTmpDevice2 aTmpDev ( ( OutputDevice & ) rDev, false );
717 [ + - ][ + - ]: 3072 : aTmpDev.SetFillColor( pNode->GetFont( ).GetColor( ) );
718 [ + - ]: 3072 : rDev.SetLineColor( );
719 [ + - ]: 3072 : aTmpDev.SetFont( pNode->GetFont( ) );
720 : :
721 [ + - ]: 3072 : sal_uLong nTmpBorderWidth = pNode->GetFont( ).GetBorderWidth( );
722 : :
723 : : // get rectangle and remove borderspace
724 [ + - ][ + - ]: 3072 : Rectangle aTmp ( pNode->AsRectangle( ) + Position - pNode->GetTopLeft( ) );
[ + - ]
725 : 3072 : aTmp.Left( ) += nTmpBorderWidth;
726 : 3072 : aTmp.Right( ) -= nTmpBorderWidth;
727 : 3072 : aTmp.Top( ) += nTmpBorderWidth;
728 : 3072 : aTmp.Bottom( ) -= nTmpBorderWidth;
729 : :
730 : : OSL_ENSURE( aTmp.GetHeight( ) > 0 && aTmp.GetWidth( ) > 0,
731 : : "Sm: leeres Rechteck" );
732 : :
733 : : //! avoid GROWING AND SHRINKING of drawn rectangle when constantly
734 : : //! increasing zoomfactor.
735 : : // This is done by shifting its output-position to a point that
736 : : // corresponds exactly to a pixel on the output device.
737 [ + - ][ + - ]: 3072 : Point aPos ( rDev.PixelToLogic( rDev.LogicToPixel( aTmp.TopLeft( ) ) ) );
738 : 3072 : aTmp.SetPos( aPos );
739 : :
740 [ + - ][ + - ]: 3072 : rDev.DrawRect( aTmp );
741 : : }
742 : :
743 : 62251 : void SmDrawingVisitor::DrawTextNode( SmTextNode* pNode )
744 : : {
745 [ + - ][ + + ]: 62251 : if ( pNode->IsPhantom( ) || pNode->GetText( ).Len( ) == 0 || pNode->GetText( ).GetChar( 0 ) == xub_Unicode( '\0' ) )
[ - + ][ + + ]
746 : 62251 : return;
747 : :
748 [ + - ]: 62155 : SmTmpDevice2 aTmpDev ( ( OutputDevice & ) rDev, false );
749 [ + - ]: 62155 : aTmpDev.SetFont( pNode->GetFont( ) );
750 : :
751 : 62155 : Point aPos ( Position );
752 [ + - ]: 62155 : aPos.Y( ) += pNode->GetBaselineOffset( );
753 : : // auf Pixelkoordinaten runden
754 [ + - ][ + - ]: 62155 : aPos = rDev.PixelToLogic( rDev.LogicToPixel( aPos ) );
755 : :
756 [ + - ][ + - ]: 62251 : rDev.DrawStretchText( aPos, pNode->GetWidth( ), pNode->GetText( ) );
[ + - ]
757 : : }
758 : :
759 : 21813 : void SmDrawingVisitor::DrawSpecialNode( SmSpecialNode* pNode )
760 : : {
761 : : //! since this chars might come from any font, that we may not have
762 : : //! set to ALIGN_BASELINE yet, we do it now.
763 : 21813 : pNode->GetFont( ).SetAlign( ALIGN_BASELINE );
764 : :
765 : 21813 : DrawTextNode( pNode );
766 : 21813 : }
767 : :
768 : 82794 : void SmDrawingVisitor::DrawChildren( SmNode* pNode )
769 : : {
770 [ + - ]: 82794 : if ( pNode->IsPhantom( ) )
771 : 82794 : return;
772 : :
773 : 82794 : Point rPosition = Position;
774 : :
775 [ + - ]: 82794 : SmNodeIterator it( pNode );
776 [ + - ][ + + ]: 224056 : while( it.Next( ) )
777 : : {
778 : 141262 : Point aOffset ( it->GetTopLeft( ) - pNode->GetTopLeft( ) );
779 : 141262 : Position = rPosition + aOffset;
780 [ + - ]: 141262 : it->Accept( this );
781 : : }
782 : : }
783 : :
784 : : /////////////////////////////// SmSetSelectionVisitor ////////////////////////////////
785 : :
786 : 0 : SmSetSelectionVisitor::SmSetSelectionVisitor( SmCaretPos startPos, SmCaretPos endPos, SmNode* pTree) {
787 : 0 : StartPos = startPos;
788 : 0 : EndPos = endPos;
789 : 0 : IsSelecting = false;
790 : :
791 : : //Assume that pTree is a SmTableNode
792 : : OSL_ENSURE(pTree->GetType() == NTABLE, "pTree should be a SmTableNode!");
793 : : //Visit root node, this is special as this node cannot be selected, but its children can!
794 [ # # ]: 0 : if(pTree->GetType() == NTABLE){
795 : : //Change state if StartPos is in front of this node
796 [ # # ][ # # ]: 0 : if( StartPos.pSelectedNode == pTree && StartPos.Index == 0 )
797 : 0 : IsSelecting = !IsSelecting;
798 : : //Change state if EndPos is in front of this node
799 [ # # ][ # # ]: 0 : if( EndPos.pSelectedNode == pTree && EndPos.Index == 0 )
800 : 0 : IsSelecting = !IsSelecting;
801 : : OSL_ENSURE(!IsSelecting, "Caret positions needed to set IsSelecting about, shouldn't be possible!");
802 : :
803 : : //Visit lines
804 [ # # ]: 0 : SmNodeIterator it( pTree );
805 [ # # ][ # # ]: 0 : while( it.Next( ) ) {
806 [ # # ]: 0 : it->Accept( this );
807 : : //If we started a selection in this line and it haven't ended, we do that now!
808 [ # # ]: 0 : if(IsSelecting) {
809 : 0 : IsSelecting = false;
810 [ # # ]: 0 : SetSelectedOnAll(it.Current(), true);
811 : : //Set StartPos and EndPos to invalid positions, this ensures that an unused
812 : : //start or end (because we forced end above), doesn't start a new selection.
813 : 0 : StartPos = EndPos = SmCaretPos();
814 : : }
815 : : }
816 : : //Check if pTree isn't selected
817 : : OSL_ENSURE(!pTree->IsSelected(), "pTree should never be selected!");
818 : : //Discard the selection if there's a bug (it's better than crashing)
819 [ # # ]: 0 : if(pTree->IsSelected())
820 [ # # ]: 0 : SetSelectedOnAll(pTree, false);
821 : : }else //This shouldn't happen, but I don't see any reason to die if it does
822 [ # # ]: 0 : pTree->Accept(this);
823 : 0 : }
824 : :
825 : 0 : void SmSetSelectionVisitor::SetSelectedOnAll( SmNode* pSubTree, bool IsSelected ) {
826 : 0 : pSubTree->SetSelected( IsSelected );
827 : :
828 : : //Quick BFS to set all selections
829 [ # # ]: 0 : SmNodeIterator it( pSubTree );
830 [ # # ][ # # ]: 0 : while( it.Next( ) )
831 [ # # ]: 0 : SetSelectedOnAll( it.Current( ), IsSelected );
832 : 0 : }
833 : :
834 : 0 : void SmSetSelectionVisitor::DefaultVisit( SmNode* pNode ) {
835 : : //Change state if StartPos is in front of this node
836 [ # # ][ # # ]: 0 : if( StartPos.pSelectedNode == pNode && StartPos.Index == 0 )
837 : 0 : IsSelecting = !IsSelecting;
838 : : //Change state if EndPos is in front of this node
839 [ # # ][ # # ]: 0 : if( EndPos.pSelectedNode == pNode && EndPos.Index == 0 )
840 : 0 : IsSelecting = !IsSelecting;
841 : :
842 : : //Cache current state
843 : 0 : bool WasSelecting = IsSelecting;
844 : 0 : bool ChangedState = false;
845 : :
846 : : //Set selected
847 : 0 : pNode->SetSelected( IsSelecting );
848 : :
849 : : //Visit children
850 [ # # ]: 0 : SmNodeIterator it( pNode );
851 [ # # ][ # # ]: 0 : while( it.Next( ) )
852 : : {
853 [ # # ]: 0 : it->Accept( this );
854 [ # # ][ # # ]: 0 : ChangedState = ( WasSelecting != IsSelecting ) || ChangedState;
855 : : }
856 : :
857 : : //If state changed
858 [ # # ]: 0 : if( ChangedState )
859 : : {
860 : : //Select this node and all of its children
861 : : //(Make exception for SmBracebodyNode)
862 [ # # # # : 0 : if( pNode->GetType() != NBRACEBODY ||
# # ][ # # ]
863 : 0 : !pNode->GetParent() ||
864 : 0 : pNode->GetParent()->GetType() != NBRACE )
865 [ # # ]: 0 : SetSelectedOnAll( pNode, true );
866 : : else
867 [ # # ]: 0 : SetSelectedOnAll( pNode->GetParent(), true );
868 : : /* If the equation is: sqrt{2 + 4} + 5
869 : : * And the selection is: sqrt{2 + [4} +] 5
870 : : * Where [ denotes StartPos and ] denotes EndPos
871 : : * Then the sqrt node should be selected, so that the
872 : : * effective selection is: [sqrt{2 + 4} +] 5
873 : : * The same is the case if we swap StartPos and EndPos.
874 : : */
875 : : }
876 : :
877 : : //Change state if StartPos is after this node
878 [ # # ][ # # ]: 0 : if( StartPos.pSelectedNode == pNode && StartPos.Index == 1 )
879 : : {
880 : 0 : IsSelecting = !IsSelecting;
881 : : }
882 : : //Change state if EndPos is after of this node
883 [ # # ][ # # ]: 0 : if( EndPos.pSelectedNode == pNode && EndPos.Index == 1 )
884 : : {
885 : 0 : IsSelecting = !IsSelecting;
886 : : }
887 : 0 : }
888 : :
889 : 0 : void SmSetSelectionVisitor::VisitCompositionNode( SmNode* pNode ) {
890 : : //Change state if StartPos is in front of this node
891 [ # # ][ # # ]: 0 : if( StartPos.pSelectedNode == pNode && StartPos.Index == 0 )
892 : 0 : IsSelecting = !IsSelecting;
893 : : //Change state if EndPos is in front of this node
894 [ # # ][ # # ]: 0 : if( EndPos.pSelectedNode == pNode && EndPos.Index == 0 )
895 : 0 : IsSelecting = !IsSelecting;
896 : :
897 : : //Cache current state
898 : 0 : bool WasSelecting = IsSelecting;
899 : :
900 : : //Visit children
901 [ # # ]: 0 : SmNodeIterator it( pNode );
902 [ # # ][ # # ]: 0 : while( it.Next( ) )
903 [ # # ]: 0 : it->Accept( this );
904 : :
905 : : //Set selected, if everything was selected
906 [ # # ][ # # ]: 0 : pNode->SetSelected( WasSelecting && IsSelecting );
907 : :
908 : : //Change state if StartPos is after this node
909 [ # # ][ # # ]: 0 : if( StartPos.pSelectedNode == pNode && StartPos.Index == 1 )
910 : 0 : IsSelecting = !IsSelecting;
911 : : //Change state if EndPos is after of this node
912 [ # # ][ # # ]: 0 : if( EndPos.pSelectedNode == pNode && EndPos.Index == 1 )
913 : 0 : IsSelecting = !IsSelecting;
914 : 0 : }
915 : :
916 : 0 : void SmSetSelectionVisitor::Visit( SmTextNode* pNode ) {
917 : 0 : long i1 = -1,
918 : 0 : i2 = -1;
919 [ # # ]: 0 : if( StartPos.pSelectedNode == pNode )
920 : 0 : i1 = StartPos.Index;
921 [ # # ]: 0 : if( EndPos.pSelectedNode == pNode )
922 : 0 : i2 = EndPos.Index;
923 : :
924 : : long start, end;
925 : 0 : pNode->SetSelected( true );
926 [ # # ][ # # ]: 0 : if( i1 != -1 && i2 != -1 ) {
927 [ # # ]: 0 : start = i1 < i2 ? i1 : i2; //MIN
928 [ # # ]: 0 : end = i1 > i2 ? i1 : i2; //MAX
929 [ # # ][ # # ]: 0 : } else if( IsSelecting && i1 != -1 ) {
930 : 0 : start = 0;
931 : 0 : end = i1;
932 : 0 : IsSelecting = false;
933 [ # # ][ # # ]: 0 : } else if( IsSelecting && i2 != -1 ) {
934 : 0 : start = 0;
935 : 0 : end = i2;
936 : 0 : IsSelecting = false;
937 [ # # ][ # # ]: 0 : } else if( !IsSelecting && i1 != -1 ) {
938 : 0 : start = i1;
939 : 0 : end = pNode->GetText( ).Len( );
940 : 0 : IsSelecting = true;
941 [ # # ][ # # ]: 0 : } else if( !IsSelecting && i2 != -1 ) {
942 : 0 : start = i2;
943 : 0 : end = pNode->GetText( ).Len( );
944 : 0 : IsSelecting = true;
945 [ # # ]: 0 : } else if( IsSelecting ) {
946 : 0 : start = 0;
947 : 0 : end = pNode->GetText( ).Len( );
948 : : } else {
949 : 0 : pNode->SetSelected( false );
950 : 0 : start = 0;
951 : 0 : end = 0;
952 : : }
953 : 0 : pNode->SetSelected( start != end );
954 : 0 : pNode->SetSelectionStart( start );
955 : 0 : pNode->SetSelectionEnd( end );
956 : 0 : }
957 : :
958 : 0 : void SmSetSelectionVisitor::Visit( SmExpressionNode* pNode ) {
959 : 0 : VisitCompositionNode( pNode );
960 : 0 : }
961 : :
962 : 0 : void SmSetSelectionVisitor::Visit( SmLineNode* pNode ) {
963 : 0 : VisitCompositionNode( pNode );
964 : 0 : }
965 : :
966 : 0 : void SmSetSelectionVisitor::Visit( SmAlignNode* pNode ) {
967 : 0 : VisitCompositionNode( pNode );
968 : 0 : }
969 : :
970 : 0 : void SmSetSelectionVisitor::Visit( SmBinHorNode* pNode ) {
971 : 0 : VisitCompositionNode( pNode );
972 : 0 : }
973 : :
974 : 0 : void SmSetSelectionVisitor::Visit( SmUnHorNode* pNode ) {
975 : 0 : VisitCompositionNode( pNode );
976 : 0 : }
977 : :
978 : 0 : void SmSetSelectionVisitor::Visit( SmFontNode* pNode ) {
979 : 0 : VisitCompositionNode( pNode );
980 : 0 : }
981 : :
982 : : /////////////////////////////// SmCaretPosGraphBuildingVisitor ////////////////////////////////
983 : :
984 : 0 : SmCaretPosGraphBuildingVisitor::SmCaretPosGraphBuildingVisitor( SmNode* pRootNode ) {
985 : 0 : pRightMost = NULL;
986 [ # # ]: 0 : pGraph = new SmCaretPosGraph( );
987 : : //pRootNode should always be a table
988 : : OSL_ENSURE( pRootNode->GetType( ) == NTABLE, "pRootNode must be a table node");
989 : : //Handle the special case where NTABLE is used a rootnode
990 [ # # ]: 0 : if( pRootNode->GetType( ) == NTABLE ){
991 : : //Children are SmLineNodes
992 : : //Or so I thought... Aparently, the children can be instances of SmExpression
993 : : //especially if there's a error in the formula... So he we go, a simple work around.
994 [ # # ]: 0 : SmNodeIterator it( pRootNode );
995 [ # # ][ # # ]: 0 : while( it.Next( ) ){
996 : : //There's a special invariant between this method and the Visit( SmLineNode* )
997 : : //Usually pRightMost may not be NULL, to avoid this pRightMost should here be
998 : : //set to a new SmCaretPos in front of it.Current( ), however, if it.Current( ) is
999 : : //an instance of SmLineNode we let SmLineNode create this position in front of
1000 : : //the visual line.
1001 : : //The argument for doing this is that we now don't have to worry about SmLineNode
1002 : : //being a visual line composition node. Thus, no need for yet another special case
1003 : : //in SmCursor::IsLineCompositionNode and everywhere this method is used.
1004 : : //if( it->GetType( ) != NLINE )
1005 [ # # ]: 0 : pRightMost = pGraph->Add( SmCaretPos( it.Current( ), 0 ) );
1006 [ # # ]: 0 : it->Accept( this );
1007 : : }
1008 : : }else
1009 [ # # ]: 0 : pRootNode->Accept(this);
1010 : 0 : }
1011 : :
1012 : 0 : void SmCaretPosGraphBuildingVisitor::Visit( SmLineNode* pNode ){
1013 [ # # ]: 0 : SmNodeIterator it( pNode );
1014 [ # # ][ # # ]: 0 : while( it.Next( ) ){
1015 [ # # ]: 0 : it->Accept( this );
1016 : : }
1017 : 0 : }
1018 : :
1019 : : /** Build SmCaretPosGraph for SmTableNode
1020 : : * This method covers cases where SmTableNode is used in a binom or stack,
1021 : : * the special case where it is used as root node for the entire formula is
1022 : : * handled in the constructor.
1023 : : */
1024 : 0 : void SmCaretPosGraphBuildingVisitor::Visit( SmTableNode* pNode ){
1025 : 0 : SmCaretPosGraphEntry *left = pRightMost,
1026 [ # # ]: 0 : *right = pGraph->Add( SmCaretPos( pNode, 1) );
1027 : 0 : bool bIsFirst = true;
1028 [ # # ]: 0 : SmNodeIterator it( pNode );
1029 [ # # ][ # # ]: 0 : while( it.Next() ){
1030 [ # # ]: 0 : pRightMost = pGraph->Add( SmCaretPos( it.Current(), 0 ), left);
1031 [ # # ]: 0 : if(bIsFirst)
1032 : 0 : left->SetRight(pRightMost);
1033 [ # # ]: 0 : it->Accept( this );
1034 : 0 : pRightMost->SetRight(right);
1035 [ # # ]: 0 : if(bIsFirst)
1036 : 0 : right->SetLeft(pRightMost);
1037 : 0 : bIsFirst = false;
1038 : : }
1039 : 0 : pRightMost = right;
1040 : 0 : }
1041 : :
1042 : : /** Build SmCaretPosGraph for SmSubSupNode
1043 : : *
1044 : : * The child positions in a SubSupNode, where H is the body:
1045 : : * \code
1046 : : * CSUP
1047 : : *
1048 : : * LSUP H H RSUP
1049 : : * H H
1050 : : * HHHH
1051 : : * H H
1052 : : * LSUB H H RSUB
1053 : : *
1054 : : * CSUB
1055 : : * \endcode
1056 : : *
1057 : : * Graph over these, where "left" is before the SmSubSupNode and "right" is after:
1058 : : * \dot
1059 : : * digraph Graph{
1060 : : * left -> H;
1061 : : * H -> right;
1062 : : * LSUP -> H;
1063 : : * LSUB -> H;
1064 : : * CSUP -> right;
1065 : : * CSUB -> right;
1066 : : * RSUP -> right;
1067 : : * RSUB -> right;
1068 : : * };
1069 : : * \enddot
1070 : : *
1071 : : */
1072 : 0 : void SmCaretPosGraphBuildingVisitor::Visit( SmSubSupNode* pNode )
1073 : : {
1074 : : SmCaretPosGraphEntry *left,
1075 : : *right,
1076 : : *bodyLeft,
1077 : : *bodyRight;
1078 : :
1079 : 0 : left = pRightMost;
1080 : : OSL_ENSURE( pRightMost, "pRightMost shouldn't be NULL here!" );
1081 : :
1082 : : //Create bodyLeft
1083 : : OSL_ENSURE( pNode->GetBody( ), "SmSubSupNode Doesn't have a body!" );
1084 [ # # ]: 0 : bodyLeft = pGraph->Add( SmCaretPos( pNode->GetBody( ), 0 ), left );
1085 : 0 : left->SetRight( bodyLeft ); //TODO: Don't make this if LSUP or LSUB are NULL ( not sure??? )
1086 : :
1087 : : //Create right
1088 [ # # ]: 0 : right = pGraph->Add( SmCaretPos( pNode, 1 ) );
1089 : :
1090 : : //Visit the body, to get bodyRight
1091 : 0 : pRightMost = bodyLeft;
1092 : 0 : pNode->GetBody( )->Accept( this );
1093 : 0 : bodyRight = pRightMost;
1094 : 0 : bodyRight->SetRight( right );
1095 : 0 : right->SetLeft( bodyRight );
1096 : :
1097 : : SmNode* pChild;
1098 : : //If there's an LSUP
1099 [ # # ]: 0 : if( ( pChild = pNode->GetSubSup( LSUP ) ) ){
1100 : : SmCaretPosGraphEntry *cLeft; //Child left
1101 [ # # ]: 0 : cLeft = pGraph->Add( SmCaretPos( pChild, 0 ), left );
1102 : :
1103 : 0 : pRightMost = cLeft;
1104 : 0 : pChild->Accept( this );
1105 : :
1106 : 0 : pRightMost->SetRight( bodyLeft );
1107 : : }
1108 : : //If there's an LSUB
1109 [ # # ]: 0 : if( ( pChild = pNode->GetSubSup( LSUB ) ) ){
1110 : : SmCaretPosGraphEntry *cLeft; //Child left
1111 [ # # ]: 0 : cLeft = pGraph->Add( SmCaretPos( pChild, 0 ), left );
1112 : :
1113 : 0 : pRightMost = cLeft;
1114 : 0 : pChild->Accept( this );
1115 : :
1116 : 0 : pRightMost->SetRight( bodyLeft );
1117 : : }
1118 : : //If there's an CSUP
1119 [ # # ]: 0 : if( ( pChild = pNode->GetSubSup( CSUP ) ) ){
1120 : : SmCaretPosGraphEntry *cLeft; //Child left
1121 [ # # ]: 0 : cLeft = pGraph->Add( SmCaretPos( pChild, 0 ), left );
1122 : :
1123 : 0 : pRightMost = cLeft;
1124 : 0 : pChild->Accept( this );
1125 : :
1126 : 0 : pRightMost->SetRight( right );
1127 : : }
1128 : : //If there's an CSUB
1129 [ # # ]: 0 : if( ( pChild = pNode->GetSubSup( CSUB ) ) ){
1130 : : SmCaretPosGraphEntry *cLeft; //Child left
1131 [ # # ]: 0 : cLeft = pGraph->Add( SmCaretPos( pChild, 0 ), left );
1132 : :
1133 : 0 : pRightMost = cLeft;
1134 : 0 : pChild->Accept( this );
1135 : :
1136 : 0 : pRightMost->SetRight( right );
1137 : : }
1138 : : //If there's an RSUP
1139 [ # # ]: 0 : if( ( pChild = pNode->GetSubSup( RSUP ) ) ){
1140 : : SmCaretPosGraphEntry *cLeft; //Child left
1141 [ # # ]: 0 : cLeft = pGraph->Add( SmCaretPos( pChild, 0 ), bodyRight );
1142 : :
1143 : 0 : pRightMost = cLeft;
1144 : 0 : pChild->Accept( this );
1145 : :
1146 : 0 : pRightMost->SetRight( right );
1147 : : }
1148 : : //If there's an RSUB
1149 [ # # ]: 0 : if( ( pChild = pNode->GetSubSup( RSUB ) ) ){
1150 : : SmCaretPosGraphEntry *cLeft; //Child left
1151 [ # # ]: 0 : cLeft = pGraph->Add( SmCaretPos( pChild, 0 ), bodyRight );
1152 : :
1153 : 0 : pRightMost = cLeft;
1154 : 0 : pChild->Accept( this );
1155 : :
1156 : 0 : pRightMost->SetRight( right );
1157 : : }
1158 : :
1159 : : //Set return parameters
1160 : 0 : pRightMost = right;
1161 : 0 : }
1162 : :
1163 : : /** Build caret position for SmOperNode
1164 : : *
1165 : : * If first child is an SmSubSupNode we will ignore its
1166 : : * body, as this body is a SmMathSymbol, for SUM, INT or similar
1167 : : * that shouldn't be subject to modification.
1168 : : * If first child is not a SmSubSupNode, ignore it completely
1169 : : * as it is a SmMathSymbol.
1170 : : *
1171 : : * The child positions in a SmOperNode, where H is symbol, e.g. int, sum or similar:
1172 : : * \code
1173 : : * TO
1174 : : *
1175 : : * LSUP H H RSUP BBB BB BBB B B
1176 : : * H H B B B B B B B B
1177 : : * HHHH BBB B B B B B
1178 : : * H H B B B B B B B
1179 : : * LSUB H H RSUB BBB BB BBB B
1180 : : *
1181 : : * FROM
1182 : : * \endcode
1183 : : * Notice, CSUP, etc. are actually granchildren, but inorder to ignore H, these are visited
1184 : : * from here. If they are present, that is if pOper is an instance of SmSubSupNode.
1185 : : *
1186 : : * Graph over these, where "left" is before the SmOperNode and "right" is after:
1187 : : * \dot
1188 : : * digraph Graph{
1189 : : * left -> BODY;
1190 : : * BODY -> right;
1191 : : * LSUP -> BODY;
1192 : : * LSUB -> BODY;
1193 : : * TO -> BODY;
1194 : : * FROM -> BODY;
1195 : : * RSUP -> BODY;
1196 : : * RSUB -> BODY;
1197 : : * };
1198 : : * \enddot
1199 : : */
1200 : 0 : void SmCaretPosGraphBuildingVisitor::Visit( SmOperNode* pNode )
1201 : : {
1202 : 0 : SmNode *pOper = pNode->GetSubNode( 0 ),
1203 : 0 : *pBody = pNode->GetSubNode( 1 );
1204 : :
1205 : 0 : SmCaretPosGraphEntry *left = pRightMost,
1206 : : *bodyLeft,
1207 : : *bodyRight,
1208 : : *right;
1209 : : //Create body left
1210 [ # # ]: 0 : bodyLeft = pGraph->Add( SmCaretPos( pBody, 0 ), left );
1211 : 0 : left->SetRight( bodyLeft );
1212 : :
1213 : : //Visit body, get bodyRight
1214 : 0 : pRightMost = bodyLeft;
1215 : 0 : pBody->Accept( this );
1216 : 0 : bodyRight = pRightMost;
1217 : :
1218 : : //Create right
1219 [ # # ]: 0 : right = pGraph->Add( SmCaretPos( pNode, 1 ), bodyRight );
1220 : 0 : bodyRight->SetRight( right );
1221 : :
1222 : : //Get subsup pNode if any
1223 [ # # ]: 0 : SmSubSupNode* pSubSup = pOper->GetType( ) == NSUBSUP ? ( SmSubSupNode* )pOper : NULL;
1224 : :
1225 : : SmNode* pChild;
1226 : : SmCaretPosGraphEntry *childLeft;
1227 [ # # ][ # # ]: 0 : if( pSubSup && ( pChild = pSubSup->GetSubSup( LSUP ) ) ) {
[ # # ]
1228 : : //Create position in front of pChild
1229 [ # # ]: 0 : childLeft = pGraph->Add( SmCaretPos( pChild, 0 ), left );
1230 : : //Visit pChild
1231 : 0 : pRightMost = childLeft;
1232 : 0 : pChild->Accept( this );
1233 : : //Set right on pRightMost from pChild
1234 : 0 : pRightMost->SetRight( bodyLeft );
1235 : : }
1236 [ # # ][ # # ]: 0 : if( pSubSup && ( pChild = pSubSup->GetSubSup( LSUB ) ) ) {
[ # # ]
1237 : : //Create position in front of pChild
1238 [ # # ]: 0 : childLeft = pGraph->Add( SmCaretPos( pChild, 0 ), left );
1239 : : //Visit pChild
1240 : 0 : pRightMost = childLeft;
1241 : 0 : pChild->Accept( this );
1242 : : //Set right on pRightMost from pChild
1243 : 0 : pRightMost->SetRight( bodyLeft );
1244 : : }
1245 [ # # ][ # # ]: 0 : if( pSubSup && ( pChild = pSubSup->GetSubSup( CSUP ) ) ) {//TO
[ # # ]
1246 : : //Create position in front of pChild
1247 [ # # ]: 0 : childLeft = pGraph->Add( SmCaretPos( pChild, 0 ), left );
1248 : : //Visit pChild
1249 : 0 : pRightMost = childLeft;
1250 : 0 : pChild->Accept( this );
1251 : : //Set right on pRightMost from pChild
1252 : 0 : pRightMost->SetRight( bodyLeft );
1253 : : }
1254 [ # # ][ # # ]: 0 : if( pSubSup && ( pChild = pSubSup->GetSubSup( CSUB ) ) ) { //FROM
[ # # ]
1255 : : //Create position in front of pChild
1256 [ # # ]: 0 : childLeft = pGraph->Add( SmCaretPos( pChild, 0 ), left );
1257 : : //Visit pChild
1258 : 0 : pRightMost = childLeft;
1259 : 0 : pChild->Accept( this );
1260 : : //Set right on pRightMost from pChild
1261 : 0 : pRightMost->SetRight( bodyLeft );
1262 : : }
1263 [ # # ][ # # ]: 0 : if( pSubSup && ( pChild = pSubSup->GetSubSup( RSUP ) ) ) {
[ # # ]
1264 : : //Create position in front of pChild
1265 [ # # ]: 0 : childLeft = pGraph->Add( SmCaretPos( pChild, 0 ), left );
1266 : : //Visit pChild
1267 : 0 : pRightMost = childLeft;
1268 : 0 : pChild->Accept( this );
1269 : : //Set right on pRightMost from pChild
1270 : 0 : pRightMost->SetRight( bodyLeft );
1271 : : }
1272 [ # # ][ # # ]: 0 : if( pSubSup && ( pChild = pSubSup->GetSubSup( RSUB ) ) ) {
[ # # ]
1273 : : //Create position in front of pChild
1274 [ # # ]: 0 : childLeft = pGraph->Add( SmCaretPos( pChild, 0 ), left );
1275 : : //Visit pChild
1276 : 0 : pRightMost = childLeft;
1277 : 0 : pChild->Accept( this );
1278 : : //Set right on pRightMost from pChild
1279 : 0 : pRightMost->SetRight( bodyLeft );
1280 : : }
1281 : :
1282 : : //Return right
1283 : 0 : pRightMost = right;
1284 : 0 : }
1285 : :
1286 : 0 : void SmCaretPosGraphBuildingVisitor::Visit( SmMatrixNode* pNode )
1287 : : {
1288 : 0 : SmCaretPosGraphEntry *left = pRightMost,
1289 [ # # ]: 0 : *right = pGraph->Add( SmCaretPos( pNode, 1 ) );
1290 : :
1291 [ # # ]: 0 : for ( sal_uInt16 i = 0; i < pNode->GetNumRows( ); i++ ) {
1292 : 0 : SmCaretPosGraphEntry* r = left;
1293 [ # # ]: 0 : for ( sal_uInt16 j = 0; j < pNode->GetNumCols( ); j++ ){
1294 : 0 : SmNode* pSubNode = pNode->GetSubNode( i * pNode->GetNumCols( ) + j );
1295 : :
1296 [ # # ]: 0 : pRightMost = pGraph->Add( SmCaretPos( pSubNode, 0 ), r );
1297 [ # # ][ # # ]: 0 : if( j != 0 || ( pNode->GetNumRows( ) - 1 ) / 2 == i )
[ # # ]
1298 : 0 : r->SetRight( pRightMost );
1299 : :
1300 : 0 : pSubNode->Accept( this );
1301 : :
1302 : 0 : r = pRightMost;
1303 : : }
1304 : 0 : pRightMost->SetRight( right );
1305 [ # # ]: 0 : if( ( pNode->GetNumRows( ) - 1 ) / 2 == i )
1306 : 0 : right->SetLeft( pRightMost );
1307 : : }
1308 : :
1309 : 0 : pRightMost = right;
1310 : 0 : }
1311 : :
1312 : : /** Build SmCaretPosGraph for SmTextNode
1313 : : *
1314 : : * Lines in an SmTextNode:
1315 : : * \code
1316 : : * A B C
1317 : : * \endcode
1318 : : * Where A B and C are characters in the text.
1319 : : *
1320 : : * Graph over these, where "left" is before the SmTextNode and "right" is after:
1321 : : * \dot
1322 : : * digraph Graph{
1323 : : * left -> A;
1324 : : * A -> B
1325 : : * B -> right;
1326 : : * };
1327 : : * \enddot
1328 : : * Notice that C and right is the same position here.
1329 : : */
1330 : 0 : void SmCaretPosGraphBuildingVisitor::Visit( SmTextNode* pNode )
1331 : : {
1332 : : OSL_ENSURE( pNode->GetText( ).Len( ) > 0, "Empty SmTextNode is bad" );
1333 : :
1334 : 0 : int size = pNode->GetText( ).Len( );
1335 [ # # ]: 0 : for( int i = 1; i <= size; i++ ){
1336 : 0 : SmCaretPosGraphEntry* pRight = pRightMost;
1337 [ # # ]: 0 : pRightMost = pGraph->Add( SmCaretPos( pNode, i ), pRight );
1338 : 0 : pRight->SetRight( pRightMost );
1339 : : }
1340 : 0 : }
1341 : :
1342 : : /** Build SmCaretPosGraph for SmBinVerNode
1343 : : *
1344 : : * Lines in an SmBinVerNode:
1345 : : * \code
1346 : : * A
1347 : : * -----
1348 : : * B
1349 : : * \endcode
1350 : : *
1351 : : * Graph over these, where "left" is before the SmBinVerNode and "right" is after:
1352 : : * \dot
1353 : : * digraph Graph{
1354 : : * left -> A;
1355 : : * A -> right;
1356 : : * B -> right;
1357 : : * };
1358 : : * \enddot
1359 : : */
1360 : 0 : void SmCaretPosGraphBuildingVisitor::Visit( SmBinVerNode* pNode )
1361 : : {
1362 : : //None if these children can be NULL, see SmBinVerNode::Arrange
1363 : 0 : SmNode *pNum = pNode->GetSubNode( 0 ),
1364 : 0 : *pDenom = pNode->GetSubNode( 2 );
1365 : :
1366 : : SmCaretPosGraphEntry *left,
1367 : : *right,
1368 : : *numLeft,
1369 : : *denomLeft;
1370 : :
1371 : : //Set left
1372 : 0 : left = pRightMost;
1373 : : OSL_ENSURE( pRightMost, "There must be a position in front of this" );
1374 : :
1375 : : //Create right
1376 [ # # ]: 0 : right = pGraph->Add( SmCaretPos( pNode, 1 ) );
1377 : :
1378 : : //Create numLeft
1379 [ # # ]: 0 : numLeft = pGraph->Add( SmCaretPos( pNum, 0 ), left );
1380 : 0 : left->SetRight( numLeft );
1381 : :
1382 : : //Visit pNum
1383 : 0 : pRightMost = numLeft;
1384 : 0 : pNum->Accept( this );
1385 : 0 : pRightMost->SetRight( right );
1386 : 0 : right->SetLeft( pRightMost );
1387 : :
1388 : : //Create denomLeft
1389 [ # # ]: 0 : denomLeft = pGraph->Add( SmCaretPos( pDenom, 0 ), left );
1390 : :
1391 : : //Visit pDenom
1392 : 0 : pRightMost = denomLeft;
1393 : 0 : pDenom->Accept( this );
1394 : 0 : pRightMost->SetRight( right );
1395 : :
1396 : : //Set return parameter
1397 : 0 : pRightMost = right;
1398 : 0 : }
1399 : :
1400 : : /** Build SmCaretPosGraph for SmVerticalBraceNode
1401 : : *
1402 : : * Lines in an SmVerticalBraceNode:
1403 : : * \code
1404 : : * pScript
1405 : : * ________
1406 : : * / \
1407 : : * pBody
1408 : : * \endcode
1409 : : *
1410 : : */
1411 : 0 : void SmCaretPosGraphBuildingVisitor::Visit( SmVerticalBraceNode* pNode )
1412 : : {
1413 : 0 : SmNode *pBody = pNode->GetSubNode( 0 ),
1414 : 0 : *pScript = pNode->GetSubNode( 2 );
1415 : : //None of these children can be NULL
1416 : :
1417 : : SmCaretPosGraphEntry *left,
1418 : : *bodyLeft,
1419 : : *scriptLeft,
1420 : : *right;
1421 : :
1422 : 0 : left = pRightMost;
1423 : :
1424 : : //Create right
1425 [ # # ]: 0 : right = pGraph->Add( SmCaretPos( pNode, 1 ) );
1426 : :
1427 : : //Create bodyLeft
1428 [ # # ]: 0 : bodyLeft = pGraph->Add( SmCaretPos( pBody, 0 ), left );
1429 : 0 : left->SetRight( bodyLeft );
1430 : 0 : pRightMost = bodyLeft;
1431 : 0 : pBody->Accept( this );
1432 : 0 : pRightMost->SetRight( right );
1433 : 0 : right->SetLeft( pRightMost );
1434 : :
1435 : : //Create script
1436 [ # # ]: 0 : scriptLeft = pGraph->Add( SmCaretPos( pScript, 0 ), left );
1437 : 0 : pRightMost = scriptLeft;
1438 : 0 : pScript->Accept( this );
1439 : 0 : pRightMost->SetRight( right );
1440 : :
1441 : : //Set return value
1442 : 0 : pRightMost = right;
1443 : 0 : }
1444 : :
1445 : : /** Build SmCaretPosGraph for SmBinDiagonalNode
1446 : : *
1447 : : * Lines in an SmBinDiagonalNode:
1448 : : * \code
1449 : : * A /
1450 : : * /
1451 : : * / B
1452 : : * \endcode
1453 : : * Where A and B are lines.
1454 : : *
1455 : : * Used in formulas such as "A wideslash B"
1456 : : */
1457 : 0 : void SmCaretPosGraphBuildingVisitor::Visit( SmBinDiagonalNode* pNode )
1458 : : {
1459 : 0 : SmNode *A = pNode->GetSubNode( 0 ),
1460 : 0 : *B = pNode->GetSubNode( 1 );
1461 : :
1462 : : SmCaretPosGraphEntry *left,
1463 : : *leftA,
1464 : : *rightA,
1465 : : *leftB,
1466 : : *right;
1467 : 0 : left = pRightMost;
1468 : :
1469 : : //Create right
1470 [ # # ]: 0 : right = pGraph->Add( SmCaretPos( pNode, 1 ) );
1471 : :
1472 : : //Create left A
1473 [ # # ]: 0 : leftA = pGraph->Add( SmCaretPos( A, 0 ), left );
1474 : 0 : left->SetRight( leftA );
1475 : :
1476 : : //Visit A
1477 : 0 : pRightMost = leftA;
1478 : 0 : A->Accept( this );
1479 : 0 : rightA = pRightMost;
1480 : :
1481 : : //Create left B
1482 [ # # ]: 0 : leftB = pGraph->Add( SmCaretPos( B, 0 ), rightA );
1483 : 0 : rightA->SetRight( leftB );
1484 : :
1485 : : //Visit B
1486 : 0 : pRightMost = leftB;
1487 : 0 : B->Accept( this );
1488 : 0 : pRightMost->SetRight( right );
1489 : 0 : right->SetLeft( pRightMost );
1490 : :
1491 : : //Set return value
1492 : 0 : pRightMost = right;
1493 : 0 : }
1494 : :
1495 : : //Straigt forward ( I think )
1496 : 0 : void SmCaretPosGraphBuildingVisitor::Visit( SmBinHorNode* pNode )
1497 : : {
1498 [ # # ]: 0 : SmNodeIterator it( pNode );
1499 [ # # ][ # # ]: 0 : while( it.Next( ) )
1500 [ # # ]: 0 : it->Accept( this );
1501 : 0 : }
1502 : 0 : void SmCaretPosGraphBuildingVisitor::Visit( SmUnHorNode* pNode )
1503 : : {
1504 : : // Unary operator node
1505 [ # # ]: 0 : SmNodeIterator it( pNode );
1506 [ # # ][ # # ]: 0 : while( it.Next( ) )
1507 [ # # ]: 0 : it->Accept( this );
1508 : :
1509 : 0 : }
1510 : :
1511 : 0 : void SmCaretPosGraphBuildingVisitor::Visit( SmExpressionNode* pNode )
1512 : : {
1513 [ # # ]: 0 : SmNodeIterator it( pNode );
1514 [ # # ][ # # ]: 0 : while( it.Next( ) )
1515 [ # # ]: 0 : it->Accept( this );
1516 : 0 : }
1517 : :
1518 : 0 : void SmCaretPosGraphBuildingVisitor::Visit( SmFontNode* pNode )
1519 : : {
1520 : : //Has only got one child, should act as an expression if possible
1521 [ # # ]: 0 : SmNodeIterator it( pNode );
1522 [ # # ][ # # ]: 0 : while( it.Next( ) )
1523 [ # # ]: 0 : it->Accept( this );
1524 : 0 : }
1525 : :
1526 : : /** Build SmCaretPosGraph for SmBracebodyNode
1527 : : * Acts as an SmExpressionNode
1528 : : *
1529 : : * Below is an example of a formula tree that has multiple children for SmBracebodyNode
1530 : : * \dot
1531 : : * digraph {
1532 : : * labelloc = "t";
1533 : : * label= "Equation: \"lbrace i mline i in setZ rbrace\"";
1534 : : * n0 [label="SmTableNode"];
1535 : : * n0 -> n1 [label="0"];
1536 : : * n1 [label="SmLineNode"];
1537 : : * n1 -> n2 [label="0"];
1538 : : * n2 [label="SmExpressionNode"];
1539 : : * n2 -> n3 [label="0"];
1540 : : * n3 [label="SmBraceNode"];
1541 : : * n3 -> n4 [label="0"];
1542 : : * n4 [label="SmMathSymbolNode: {"];
1543 : : * n3 -> n5 [label="1"];
1544 : : * n5 [label="SmBracebodyNode"];
1545 : : * n5 -> n6 [label="0"];
1546 : : * n6 [label="SmExpressionNode"];
1547 : : * n6 -> n7 [label="0"];
1548 : : * n7 [label="SmTextNode: i"];
1549 : : * n5 -> n8 [label="1"];
1550 : : * n8 [label="SmMathSymbolNode: ∣"];
1551 : : * n5 -> n9 [label="2"];
1552 : : * n9 [label="SmExpressionNode"];
1553 : : * n9 -> n10 [label="0"];
1554 : : * n10 [label="SmBinHorNode"];
1555 : : * n10 -> n11 [label="0"];
1556 : : * n11 [label="SmTextNode: i"];
1557 : : * n10 -> n12 [label="1"];
1558 : : * n12 [label="SmMathSymbolNode: ∈"];
1559 : : * n10 -> n13 [label="2"];
1560 : : * n13 [label="SmMathSymbolNode: ℤ"];
1561 : : * n3 -> n14 [label="2"];
1562 : : * n14 [label="SmMathSymbolNode: }"];
1563 : : * }
1564 : : * \enddot
1565 : : */
1566 : 0 : void SmCaretPosGraphBuildingVisitor::Visit( SmBracebodyNode* pNode )
1567 : : {
1568 [ # # ]: 0 : SmNodeIterator it( pNode );
1569 [ # # ][ # # ]: 0 : while( it.Next( ) ) {
1570 [ # # ]: 0 : SmCaretPosGraphEntry* pStart = pGraph->Add( SmCaretPos( it.Current(), 0), pRightMost );
1571 : 0 : pRightMost->SetRight( pStart );
1572 : 0 : pRightMost = pStart;
1573 [ # # ]: 0 : it->Accept( this );
1574 : : }
1575 : 0 : }
1576 : :
1577 : : /** Build SmCaretPosGraph for SmAlignNode
1578 : : * Acts as an SmExpressionNode, as it only has one child this okay
1579 : : */
1580 : 0 : void SmCaretPosGraphBuildingVisitor::Visit( SmAlignNode* pNode )
1581 : : {
1582 [ # # ]: 0 : SmNodeIterator it( pNode );
1583 [ # # ][ # # ]: 0 : while( it.Next( ) )
1584 [ # # ]: 0 : it->Accept( this );
1585 : 0 : }
1586 : :
1587 : : /** Build SmCaretPosGraph for SmRootNode
1588 : : *
1589 : : * Lines in an SmRootNode:
1590 : : * \code
1591 : : * _________
1592 : : * A/
1593 : : * \/ B
1594 : : *
1595 : : * \endcode
1596 : : * A: pExtra ( optional, can be NULL ),
1597 : : * B: pBody
1598 : : *
1599 : : * Graph over these, where "left" is before the SmRootNode and "right" is after:
1600 : : * \dot
1601 : : * digraph Graph{
1602 : : * left -> B;
1603 : : * B -> right;
1604 : : * A -> B;
1605 : : * }
1606 : : * \enddot
1607 : : */
1608 : 0 : void SmCaretPosGraphBuildingVisitor::Visit( SmRootNode* pNode )
1609 : : {
1610 : 0 : SmNode *pExtra = pNode->GetSubNode( 0 ), //Argument, NULL for sqrt, and SmTextNode if cubicroot
1611 : 0 : *pBody = pNode->GetSubNode( 2 ); //Body of the root
1612 : : OSL_ENSURE( pBody, "pBody cannot be NULL" );
1613 : :
1614 : : SmCaretPosGraphEntry *left,
1615 : : *right,
1616 : : *bodyLeft,
1617 : : *bodyRight;
1618 : :
1619 : : //Get left and save it
1620 : : OSL_ENSURE( pRightMost, "There must be a position in front of this" );
1621 : 0 : left = pRightMost;
1622 : :
1623 : : //Create body left
1624 [ # # ]: 0 : bodyLeft = pGraph->Add( SmCaretPos( pBody, 0 ), left );
1625 : 0 : left->SetRight( bodyLeft );
1626 : :
1627 : : //Create right
1628 [ # # ]: 0 : right = pGraph->Add( SmCaretPos( pNode, 1 ) );
1629 : :
1630 : : //Visit body
1631 : 0 : pRightMost = bodyLeft;
1632 : 0 : pBody->Accept( this );
1633 : 0 : bodyRight = pRightMost;
1634 : 0 : bodyRight->SetRight( right );
1635 : 0 : right->SetLeft( bodyRight );
1636 : :
1637 : : //Visit pExtra
1638 [ # # ]: 0 : if( pExtra ){
1639 [ # # ]: 0 : pRightMost = pGraph->Add( SmCaretPos( pExtra, 0 ), left );
1640 : 0 : pExtra->Accept( this );
1641 : 0 : pRightMost->SetRight( bodyLeft );
1642 : : }
1643 : :
1644 : 0 : pRightMost = right;
1645 : 0 : }
1646 : :
1647 : : /** Build SmCaretPosGraph for SmPlaceNode
1648 : : * Consider this a single character.
1649 : : */
1650 : 0 : void SmCaretPosGraphBuildingVisitor::Visit( SmPlaceNode* pNode )
1651 : : {
1652 [ # # ]: 0 : SmCaretPosGraphEntry* right = pGraph->Add( SmCaretPos( pNode, 1 ), pRightMost );
1653 : 0 : pRightMost->SetRight( right );
1654 : 0 : pRightMost = right;
1655 : 0 : }
1656 : :
1657 : : /** SmErrorNode is context dependent metadata, it can't be selected
1658 : : *
1659 : : * @remarks There's no point in deleting, copying and/or moving an instance
1660 : : * of SmErrorNode as it may not exist in an other context! Thus there are no
1661 : : * positions to select an SmErrorNode.
1662 : : */
1663 : 0 : void SmCaretPosGraphBuildingVisitor::Visit( SmErrorNode* )
1664 : : {
1665 : 0 : }
1666 : :
1667 : : /** Build SmCaretPosGraph for SmBlankNode
1668 : : * Consider this a single character, as it is only a blank space
1669 : : */
1670 : 0 : void SmCaretPosGraphBuildingVisitor::Visit( SmBlankNode* pNode )
1671 : : {
1672 [ # # ]: 0 : SmCaretPosGraphEntry* right = pGraph->Add( SmCaretPos( pNode, 1 ), pRightMost );
1673 : 0 : pRightMost->SetRight( right );
1674 : 0 : pRightMost = right;
1675 : 0 : }
1676 : :
1677 : : /** Build SmCaretPosGraph for SmBraceNode
1678 : : *
1679 : : * Lines in an SmBraceNode:
1680 : : * \code
1681 : : * | |
1682 : : * | B |
1683 : : * | |
1684 : : * \endcode
1685 : : * B: Body
1686 : : *
1687 : : * Graph over these, where "left" is before the SmBraceNode and "right" is after:
1688 : : * \dot
1689 : : * digraph Graph{
1690 : : * left -> B;
1691 : : * B -> right;
1692 : : * }
1693 : : * \enddot
1694 : : */
1695 : 0 : void SmCaretPosGraphBuildingVisitor::Visit( SmBraceNode* pNode )
1696 : : {
1697 : 0 : SmNode* pBody = pNode->GetSubNode( 1 );
1698 : :
1699 : 0 : SmCaretPosGraphEntry *left = pRightMost,
1700 [ # # ]: 0 : *right = pGraph->Add( SmCaretPos( pNode, 1 ) );
1701 : :
1702 [ # # ]: 0 : if( pBody->GetType() != NBRACEBODY ) {
1703 [ # # ]: 0 : pRightMost = pGraph->Add( SmCaretPos( pBody, 0 ), left );
1704 : 0 : left->SetRight( pRightMost );
1705 : : }else
1706 : 0 : pRightMost = left;
1707 : :
1708 : 0 : pBody->Accept( this );
1709 : 0 : pRightMost->SetRight( right );
1710 : 0 : right->SetLeft( pRightMost );
1711 : :
1712 : 0 : pRightMost = right;
1713 : 0 : }
1714 : :
1715 : : /** Build SmCaretPosGraph for SmAttributNode
1716 : : *
1717 : : * Lines in an SmAttributNode:
1718 : : * \code
1719 : : * Attr
1720 : : * Body
1721 : : * \endcode
1722 : : *
1723 : : * There's a body and an attribute, the construction is used for "widehat A", where "A" is the body
1724 : : * and "^" is the attribute ( note GetScaleMode( ) on SmAttributNode tells how the attribute should be
1725 : : * scaled ).
1726 : : */
1727 : 0 : void SmCaretPosGraphBuildingVisitor::Visit( SmAttributNode* pNode )
1728 : : {
1729 : 0 : SmNode *pAttr = pNode->GetSubNode( 0 ),
1730 : 0 : *pBody = pNode->GetSubNode( 1 );
1731 : : //None of the children can be NULL
1732 : :
1733 : 0 : SmCaretPosGraphEntry *left = pRightMost,
1734 : : *attrLeft,
1735 : : *bodyLeft,
1736 : : *bodyRight,
1737 : : *right;
1738 : :
1739 : : //Creating bodyleft
1740 [ # # ]: 0 : bodyLeft = pGraph->Add( SmCaretPos( pBody, 0 ), left );
1741 : 0 : left->SetRight( bodyLeft );
1742 : :
1743 : : //Creating right
1744 [ # # ]: 0 : right = pGraph->Add( SmCaretPos( pNode, 1 ) );
1745 : :
1746 : : //Visit the body
1747 : 0 : pRightMost = bodyLeft;
1748 : 0 : pBody->Accept( this );
1749 : 0 : bodyRight = pRightMost;
1750 : 0 : bodyRight->SetRight( right );
1751 : 0 : right->SetLeft( bodyRight );
1752 : :
1753 : : //Create attrLeft
1754 [ # # ]: 0 : attrLeft = pGraph->Add( SmCaretPos( pAttr, 0 ), left );
1755 : :
1756 : : //Visit attribute
1757 : 0 : pRightMost = attrLeft;
1758 : 0 : pAttr->Accept( this );
1759 : 0 : pRightMost->SetRight( right );
1760 : :
1761 : : //Set return value
1762 : 0 : pRightMost = right;
1763 : 0 : }
1764 : :
1765 : : //Consider these single symboles
1766 : 0 : void SmCaretPosGraphBuildingVisitor::Visit( SmSpecialNode* pNode )
1767 : : {
1768 [ # # ]: 0 : SmCaretPosGraphEntry* right = pGraph->Add( SmCaretPos( pNode, 1 ), pRightMost );
1769 : 0 : pRightMost->SetRight( right );
1770 : 0 : pRightMost = right;
1771 : 0 : }
1772 : 0 : void SmCaretPosGraphBuildingVisitor::Visit( SmGlyphSpecialNode* pNode )
1773 : : {
1774 [ # # ]: 0 : SmCaretPosGraphEntry* right = pGraph->Add( SmCaretPos( pNode, 1 ), pRightMost );
1775 : 0 : pRightMost->SetRight( right );
1776 : 0 : pRightMost = right;
1777 : 0 : }
1778 : 0 : void SmCaretPosGraphBuildingVisitor::Visit( SmMathSymbolNode* pNode )
1779 : : {
1780 [ # # ]: 0 : SmCaretPosGraphEntry* right = pGraph->Add( SmCaretPos( pNode, 1 ), pRightMost );
1781 : 0 : pRightMost->SetRight( right );
1782 : 0 : pRightMost = right;
1783 : 0 : }
1784 : :
1785 : 0 : void SmCaretPosGraphBuildingVisitor::Visit( SmRootSymbolNode* )
1786 : : {
1787 : : //Do nothing
1788 : 0 : }
1789 : 0 : void SmCaretPosGraphBuildingVisitor::Visit( SmRectangleNode* )
1790 : : {
1791 : : //Do nothing
1792 : 0 : }
1793 : 0 : void SmCaretPosGraphBuildingVisitor::Visit( SmPolyLineNode* )
1794 : : {
1795 : : //Do nothing
1796 : 0 : }
1797 : :
1798 : : /////////////////////////////// SmCloningVisitor ///////////////////////////////
1799 : :
1800 : 0 : SmNode* SmCloningVisitor::Clone( SmNode* pNode )
1801 : : {
1802 : 0 : SmNode* pCurrResult = pResult;
1803 : 0 : pNode->Accept( this );
1804 : 0 : SmNode* pClone = pResult;
1805 : 0 : pResult = pCurrResult;
1806 : 0 : return pClone;
1807 : : }
1808 : :
1809 : 0 : void SmCloningVisitor::CloneNodeAttr( SmNode* pSource, SmNode* pTarget )
1810 : : {
1811 : 0 : pTarget->SetScaleMode( pSource->GetScaleMode( ) );
1812 : : //Other attributes are set when prepare or arrange is executed
1813 : : //and may depend on stuff not being cloned here.
1814 : 0 : }
1815 : :
1816 : 0 : void SmCloningVisitor::CloneKids( SmStructureNode* pSource, SmStructureNode* pTarget )
1817 : : {
1818 : : //Cache current result
1819 : 0 : SmNode* pCurrResult = pResult;
1820 : :
1821 : : //Create array for holding clones
1822 [ # # ]: 0 : sal_uInt16 nSize = pSource->GetNumSubNodes( );
1823 [ # # ]: 0 : SmNodeArray aNodes( nSize );
1824 : :
1825 : : //Clone children
1826 : : SmNode* pKid;
1827 [ # # ]: 0 : for( sal_uInt16 i = 0; i < nSize; i++ ){
1828 [ # # ][ # # ]: 0 : if( NULL != ( pKid = pSource->GetSubNode( i ) ) )
1829 [ # # ]: 0 : pKid->Accept( this );
1830 : : else
1831 : 0 : pResult = NULL;
1832 : 0 : aNodes[i] = pResult;
1833 : : }
1834 : :
1835 : : //Set subnodes of pTarget
1836 [ # # ]: 0 : pTarget->SetSubNodes( aNodes );
1837 : :
1838 : : //Restore result as where prior to call
1839 : 0 : pResult = pCurrResult;
1840 : 0 : }
1841 : :
1842 : 0 : void SmCloningVisitor::Visit( SmTableNode* pNode )
1843 : : {
1844 [ # # ]: 0 : SmTableNode* pClone = new SmTableNode( pNode->GetToken( ) );
1845 : 0 : CloneNodeAttr( pNode, pClone );
1846 : 0 : CloneKids( pNode, pClone );
1847 : 0 : pResult = pClone;
1848 : 0 : }
1849 : :
1850 : 0 : void SmCloningVisitor::Visit( SmBraceNode* pNode )
1851 : : {
1852 [ # # ]: 0 : SmBraceNode* pClone = new SmBraceNode( pNode->GetToken( ) );
1853 : 0 : CloneNodeAttr( pNode, pClone );
1854 : 0 : CloneKids( pNode, pClone );
1855 : 0 : pResult = pClone;
1856 : 0 : }
1857 : :
1858 : 0 : void SmCloningVisitor::Visit( SmBracebodyNode* pNode )
1859 : : {
1860 [ # # ]: 0 : SmBracebodyNode* pClone = new SmBracebodyNode( pNode->GetToken( ) );
1861 : 0 : CloneNodeAttr( pNode, pClone );
1862 : 0 : CloneKids( pNode, pClone );
1863 : 0 : pResult = pClone;
1864 : 0 : }
1865 : :
1866 : 0 : void SmCloningVisitor::Visit( SmOperNode* pNode )
1867 : : {
1868 [ # # ]: 0 : SmOperNode* pClone = new SmOperNode( pNode->GetToken( ) );
1869 : 0 : CloneNodeAttr( pNode, pClone );
1870 : 0 : CloneKids( pNode, pClone );
1871 : 0 : pResult = pClone;
1872 : 0 : }
1873 : :
1874 : 0 : void SmCloningVisitor::Visit( SmAlignNode* pNode )
1875 : : {
1876 [ # # ]: 0 : SmAlignNode* pClone = new SmAlignNode( pNode->GetToken( ) );
1877 : 0 : CloneNodeAttr( pNode, pClone );
1878 : 0 : CloneKids( pNode, pClone );
1879 : 0 : pResult = pClone;
1880 : 0 : }
1881 : :
1882 : 0 : void SmCloningVisitor::Visit( SmAttributNode* pNode )
1883 : : {
1884 [ # # ]: 0 : SmAttributNode* pClone = new SmAttributNode( pNode->GetToken( ) );
1885 : 0 : CloneNodeAttr( pNode, pClone );
1886 : 0 : CloneKids( pNode, pClone );
1887 : 0 : pResult = pClone;
1888 : 0 : }
1889 : :
1890 : 0 : void SmCloningVisitor::Visit( SmFontNode* pNode )
1891 : : {
1892 [ # # ]: 0 : SmFontNode* pClone = new SmFontNode( pNode->GetToken( ) );
1893 : 0 : pClone->SetSizeParameter( pNode->GetSizeParameter( ), pNode->GetSizeType( ) );
1894 : 0 : CloneNodeAttr( pNode, pClone );
1895 : 0 : CloneKids( pNode, pClone );
1896 : 0 : pResult = pClone;
1897 : 0 : }
1898 : :
1899 : 0 : void SmCloningVisitor::Visit( SmUnHorNode* pNode )
1900 : : {
1901 [ # # ]: 0 : SmUnHorNode* pClone = new SmUnHorNode( pNode->GetToken( ) );
1902 : 0 : CloneNodeAttr( pNode, pClone );
1903 : 0 : CloneKids( pNode, pClone );
1904 : 0 : pResult = pClone;
1905 : 0 : }
1906 : :
1907 : 0 : void SmCloningVisitor::Visit( SmBinHorNode* pNode )
1908 : : {
1909 [ # # ]: 0 : SmBinHorNode* pClone = new SmBinHorNode( pNode->GetToken( ) );
1910 : 0 : CloneNodeAttr( pNode, pClone );
1911 : 0 : CloneKids( pNode, pClone );
1912 : 0 : pResult = pClone;
1913 : 0 : }
1914 : :
1915 : 0 : void SmCloningVisitor::Visit( SmBinVerNode* pNode )
1916 : : {
1917 [ # # ]: 0 : SmBinVerNode* pClone = new SmBinVerNode( pNode->GetToken( ) );
1918 : 0 : CloneNodeAttr( pNode, pClone );
1919 : 0 : CloneKids( pNode, pClone );
1920 : 0 : pResult = pClone;
1921 : 0 : }
1922 : :
1923 : 0 : void SmCloningVisitor::Visit( SmBinDiagonalNode* pNode )
1924 : : {
1925 [ # # ]: 0 : SmBinDiagonalNode *pClone = new SmBinDiagonalNode( pNode->GetToken( ) );
1926 : 0 : pClone->SetAscending( pNode->IsAscending( ) );
1927 : 0 : CloneNodeAttr( pNode, pClone );
1928 : 0 : CloneKids( pNode, pClone );
1929 : 0 : pResult = pClone;
1930 : 0 : }
1931 : :
1932 : 0 : void SmCloningVisitor::Visit( SmSubSupNode* pNode )
1933 : : {
1934 [ # # ]: 0 : SmSubSupNode *pClone = new SmSubSupNode( pNode->GetToken( ) );
1935 : 0 : pClone->SetUseLimits( pNode->IsUseLimits( ) );
1936 : 0 : CloneNodeAttr( pNode, pClone );
1937 : 0 : CloneKids( pNode, pClone );
1938 : 0 : pResult = pClone;
1939 : 0 : }
1940 : :
1941 : 0 : void SmCloningVisitor::Visit( SmMatrixNode* pNode )
1942 : : {
1943 [ # # ]: 0 : SmMatrixNode *pClone = new SmMatrixNode( pNode->GetToken( ) );
1944 : 0 : pClone->SetRowCol( pNode->GetNumRows( ), pNode->GetNumCols( ) );
1945 : 0 : CloneNodeAttr( pNode, pClone );
1946 : 0 : CloneKids( pNode, pClone );
1947 : 0 : pResult = pClone;
1948 : 0 : }
1949 : :
1950 : 0 : void SmCloningVisitor::Visit( SmPlaceNode* pNode )
1951 : : {
1952 [ # # ]: 0 : pResult = new SmPlaceNode( pNode->GetToken( ) );
1953 : 0 : CloneNodeAttr( pNode, pResult );
1954 : 0 : }
1955 : :
1956 : 0 : void SmCloningVisitor::Visit( SmTextNode* pNode )
1957 : : {
1958 [ # # ]: 0 : SmTextNode* pClone = new SmTextNode( pNode->GetToken( ), pNode->GetFontDesc( ) );
1959 : 0 : pClone->ChangeText( pNode->GetText( ) );
1960 : 0 : CloneNodeAttr( pNode, pClone );
1961 : 0 : pResult = pClone;
1962 : 0 : }
1963 : :
1964 : 0 : void SmCloningVisitor::Visit( SmSpecialNode* pNode )
1965 : : {
1966 [ # # ]: 0 : pResult = new SmSpecialNode( pNode->GetToken( ) );
1967 : 0 : CloneNodeAttr( pNode, pResult );
1968 : 0 : }
1969 : :
1970 : 0 : void SmCloningVisitor::Visit( SmGlyphSpecialNode* pNode )
1971 : : {
1972 [ # # ]: 0 : pResult = new SmGlyphSpecialNode( pNode->GetToken( ) );
1973 : 0 : CloneNodeAttr( pNode, pResult );
1974 : 0 : }
1975 : :
1976 : 0 : void SmCloningVisitor::Visit( SmMathSymbolNode* pNode )
1977 : : {
1978 [ # # ]: 0 : pResult = new SmMathSymbolNode( pNode->GetToken( ) );
1979 : 0 : CloneNodeAttr( pNode, pResult );
1980 : 0 : }
1981 : :
1982 : 0 : void SmCloningVisitor::Visit( SmBlankNode* pNode )
1983 : : {
1984 [ # # ]: 0 : SmBlankNode* pClone = new SmBlankNode( pNode->GetToken( ) );
1985 : 0 : pClone->SetBlankNum( pNode->GetBlankNum( ) );
1986 : 0 : pResult = pClone;
1987 : 0 : CloneNodeAttr( pNode, pResult );
1988 : 0 : }
1989 : :
1990 : 0 : void SmCloningVisitor::Visit( SmErrorNode* pNode )
1991 : : {
1992 : : //PE_NONE is used the information have been discarded and isn't used
1993 [ # # ]: 0 : pResult = new SmErrorNode( PE_NONE, pNode->GetToken( ) );
1994 : 0 : CloneNodeAttr( pNode, pResult );
1995 : 0 : }
1996 : :
1997 : 0 : void SmCloningVisitor::Visit( SmLineNode* pNode )
1998 : : {
1999 [ # # ]: 0 : SmLineNode* pClone = new SmLineNode( pNode->GetToken( ) );
2000 : 0 : CloneNodeAttr( pNode, pClone );
2001 : 0 : CloneKids( pNode, pClone );
2002 : 0 : pResult = pClone;
2003 : 0 : }
2004 : :
2005 : 0 : void SmCloningVisitor::Visit( SmExpressionNode* pNode )
2006 : : {
2007 [ # # ]: 0 : SmExpressionNode* pClone = new SmExpressionNode( pNode->GetToken( ) );
2008 : 0 : CloneNodeAttr( pNode, pClone );
2009 : 0 : CloneKids( pNode, pClone );
2010 : 0 : pResult = pClone;
2011 : 0 : }
2012 : :
2013 : 0 : void SmCloningVisitor::Visit( SmPolyLineNode* pNode )
2014 : : {
2015 [ # # ]: 0 : pResult = new SmPolyLineNode( pNode->GetToken( ) );
2016 : 0 : CloneNodeAttr( pNode, pResult );
2017 : 0 : }
2018 : :
2019 : 0 : void SmCloningVisitor::Visit( SmRootNode* pNode )
2020 : : {
2021 [ # # ]: 0 : SmRootNode* pClone = new SmRootNode( pNode->GetToken( ) );
2022 : 0 : CloneNodeAttr( pNode, pClone );
2023 : 0 : CloneKids( pNode, pClone );
2024 : 0 : pResult = pClone;
2025 : 0 : }
2026 : :
2027 : 0 : void SmCloningVisitor::Visit( SmRootSymbolNode* pNode )
2028 : : {
2029 [ # # ]: 0 : pResult = new SmRootSymbolNode( pNode->GetToken( ) );
2030 : 0 : CloneNodeAttr( pNode, pResult );
2031 : 0 : }
2032 : :
2033 : 0 : void SmCloningVisitor::Visit( SmRectangleNode* pNode )
2034 : : {
2035 [ # # ]: 0 : pResult = new SmRectangleNode( pNode->GetToken( ) );
2036 : 0 : CloneNodeAttr( pNode, pResult );
2037 : 0 : }
2038 : :
2039 : 0 : void SmCloningVisitor::Visit( SmVerticalBraceNode* pNode )
2040 : : {
2041 [ # # ]: 0 : SmVerticalBraceNode* pClone = new SmVerticalBraceNode( pNode->GetToken( ) );
2042 : 0 : CloneNodeAttr( pNode, pClone );
2043 : 0 : CloneKids( pNode, pClone );
2044 : 0 : pResult = pClone;
2045 : 0 : }
2046 : :
2047 : : /////////////////////////////// SmSelectionDrawingVisitor ///////////////////////////////
2048 : :
2049 : 0 : SmSelectionDrawingVisitor::SmSelectionDrawingVisitor( OutputDevice& rDevice, SmNode* pTree, Point Offset )
2050 [ # # ]: 0 : : rDev( rDevice ) {
2051 : 0 : bHasSelectionArea = false;
2052 : :
2053 : : //Visit everything
2054 : : OSL_ENSURE( pTree, "pTree can't be null!" );
2055 [ # # ]: 0 : if( pTree )
2056 [ # # ]: 0 : pTree->Accept( this );
2057 : :
2058 : : //Draw selection if there's any
2059 [ # # ]: 0 : if( bHasSelectionArea ){
2060 [ # # ]: 0 : aSelectionArea.Move( Offset.X( ), Offset.Y( ) );
2061 : :
2062 : : //Save device state
2063 [ # # ]: 0 : rDev.Push( PUSH_LINECOLOR | PUSH_FILLCOLOR );
2064 : : //Change colors
2065 [ # # ]: 0 : rDev.SetLineColor( );
2066 [ # # ]: 0 : rDev.SetFillColor( Color( COL_LIGHTGRAY ) );
2067 : :
2068 : : //Draw rectangle
2069 [ # # ]: 0 : rDev.DrawRect( aSelectionArea );
2070 : :
2071 : : //Restore device state
2072 [ # # ]: 0 : rDev.Pop( );
2073 : : }
2074 : 0 : }
2075 : :
2076 : 0 : void SmSelectionDrawingVisitor::ExtendSelectionArea( Rectangle aArea )
2077 : : {
2078 [ # # ]: 0 : if ( ! bHasSelectionArea ) {
2079 : 0 : aSelectionArea = aArea;
2080 : 0 : bHasSelectionArea = true;
2081 : : } else
2082 : 0 : aSelectionArea.Union( aArea );
2083 : 0 : }
2084 : :
2085 : 0 : void SmSelectionDrawingVisitor::DefaultVisit( SmNode* pNode )
2086 : : {
2087 [ # # ]: 0 : if( pNode->IsSelected( ) )
2088 : 0 : ExtendSelectionArea( pNode->AsRectangle( ) );
2089 : 0 : VisitChildren( pNode );
2090 : 0 : }
2091 : :
2092 : 0 : void SmSelectionDrawingVisitor::VisitChildren( SmNode* pNode )
2093 : : {
2094 [ # # ]: 0 : SmNodeIterator it( pNode );
2095 [ # # ][ # # ]: 0 : while( it.Next( ) )
2096 [ # # ]: 0 : it->Accept( this );
2097 : 0 : }
2098 : :
2099 : 0 : void SmSelectionDrawingVisitor::Visit( SmTextNode* pNode )
2100 : : {
2101 [ # # ]: 0 : if( pNode->IsSelected( ) ){
2102 [ # # ]: 0 : rDev.Push( PUSH_TEXTCOLOR | PUSH_FONT );
2103 : :
2104 [ # # ]: 0 : rDev.SetFont( pNode->GetFont( ) );
2105 : 0 : Point Position = pNode->GetTopLeft( );
2106 [ # # ]: 0 : long left = Position.getX( ) + rDev.GetTextWidth( pNode->GetText( ), 0, pNode->GetSelectionStart( ) );
2107 [ # # ]: 0 : long right = Position.getX( ) + rDev.GetTextWidth( pNode->GetText( ), 0, pNode->GetSelectionEnd( ) );
2108 : 0 : long top = Position.getY( );
2109 [ # # ]: 0 : long bottom = top + pNode->GetHeight( );
2110 [ # # ]: 0 : Rectangle rect( left, top, right, bottom );
2111 : :
2112 [ # # ]: 0 : ExtendSelectionArea( rect );
2113 : :
2114 [ # # ]: 0 : rDev.Pop( );
2115 : : }
2116 : 0 : }
2117 : :
2118 : : /////////////////////////////// SmNodeToTextVisitor ///////////////////////////////
2119 : :
2120 : 0 : void SmNodeToTextVisitor::Visit( SmTableNode* pNode )
2121 : : {
2122 [ # # ]: 0 : if( pNode->GetToken( ).eType == TBINOM ) {
2123 : 0 : Append( "{ binom" );
2124 : 0 : LineToText( pNode->GetSubNode( 0 ) );
2125 : 0 : LineToText( pNode->GetSubNode( 1 ) );
2126 : 0 : Append("} ");
2127 [ # # ]: 0 : } else if( pNode->GetToken( ).eType == TSTACK ) {
2128 [ # # ]: 0 : Append( "stack{ " );
2129 [ # # ]: 0 : SmNodeIterator it( pNode );
2130 [ # # ]: 0 : it.Next( );
2131 : 0 : while( true ) {
2132 [ # # ]: 0 : LineToText( it.Current( ) );
2133 [ # # ][ # # ]: 0 : if( it.Next( ) ) {
2134 [ # # ]: 0 : Separate( );
2135 [ # # ]: 0 : Append( "# " );
2136 : : }else
2137 : 0 : break;
2138 : : }
2139 [ # # ]: 0 : Separate( );
2140 [ # # ]: 0 : Append( "}" );
2141 : : } else { //Assume it's a toplevel table, containing lines
2142 [ # # ]: 0 : SmNodeIterator it( pNode );
2143 [ # # ]: 0 : it.Next( );
2144 : 0 : while( true ) {
2145 [ # # ]: 0 : Separate( );
2146 [ # # ]: 0 : it->Accept( this );
2147 [ # # ][ # # ]: 0 : if( it.Next( ) ) {
2148 [ # # ]: 0 : Separate( );
2149 [ # # ]: 0 : Append( "newline" );
2150 : : }else
2151 : 0 : break;
2152 : : }
2153 : : }
2154 : 0 : }
2155 : :
2156 : 0 : void SmNodeToTextVisitor::Visit( SmBraceNode* pNode )
2157 : : {
2158 : 0 : SmNode *pLeftBrace = pNode->GetSubNode( 0 ),
2159 : 0 : *pBody = pNode->GetSubNode( 1 ),
2160 : 0 : *pRightBrace = pNode->GetSubNode( 2 );
2161 : : //Handle special case where it's absolute function
2162 [ # # ]: 0 : if( pNode->GetToken( ).eType == TABS ) {
2163 : 0 : Append( "abs" );
2164 : 0 : LineToText( pBody );
2165 : : } else {
2166 [ # # ]: 0 : if( pNode->GetScaleMode( ) == SCALE_HEIGHT )
2167 : 0 : Append( "left " );
2168 : 0 : pLeftBrace->Accept( this );
2169 : 0 : Separate( );
2170 : 0 : pBody->Accept( this );
2171 : 0 : Separate( );
2172 [ # # ]: 0 : if( pNode->GetScaleMode( ) == SCALE_HEIGHT )
2173 : 0 : Append( "right " );
2174 : 0 : pRightBrace->Accept( this );
2175 : : }
2176 : 0 : }
2177 : :
2178 : 0 : void SmNodeToTextVisitor::Visit( SmBracebodyNode* pNode )
2179 : : {
2180 [ # # ]: 0 : SmNodeIterator it( pNode );
2181 [ # # ][ # # ]: 0 : while( it.Next( ) ){
2182 [ # # ]: 0 : Separate( );
2183 [ # # ]: 0 : it->Accept( this );
2184 : : }
2185 : 0 : }
2186 : :
2187 : 0 : void SmNodeToTextVisitor::Visit( SmOperNode* pNode )
2188 : : {
2189 : 0 : Append( pNode->GetToken( ).aText );
2190 : 0 : Separate( );
2191 [ # # ]: 0 : if( pNode->GetToken( ).eType == TOPER ){
2192 : : //There's an SmGlyphSpecialNode if eType == TOPER
2193 [ # # ]: 0 : if( pNode->GetSubNode( 0 )->GetType( ) == NSUBSUP )
2194 : 0 : Append( pNode->GetSubNode( 0 )->GetSubNode( 0 )->GetToken( ).aText );
2195 : : else
2196 : 0 : Append( pNode->GetSubNode( 0 )->GetToken( ).aText );
2197 : : }
2198 [ # # ]: 0 : if( pNode->GetSubNode( 0 )->GetType( ) == NSUBSUP ) {
2199 : 0 : SmSubSupNode *pSubSup = ( SmSubSupNode* )pNode->GetSubNode( 0 );
2200 : : SmNode* pChild;
2201 [ # # ]: 0 : if( ( pChild = pSubSup->GetSubSup( LSUP ) ) ) {
2202 : 0 : Separate( );
2203 : 0 : Append( "lsup { " );
2204 : 0 : LineToText( pChild );
2205 : 0 : Append( "} " );
2206 : : }
2207 [ # # ]: 0 : if( ( pChild = pSubSup->GetSubSup( LSUB ) ) ) {
2208 : 0 : Separate( );
2209 : 0 : Append( "lsub { " );
2210 : 0 : LineToText( pChild );
2211 : 0 : Append( "} " );
2212 : : }
2213 [ # # ]: 0 : if( ( pChild = pSubSup->GetSubSup( RSUP ) ) ) {
2214 : 0 : Separate( );
2215 : 0 : Append( "^ { " );
2216 : 0 : LineToText( pChild );
2217 : 0 : Append( "} " );
2218 : : }
2219 [ # # ]: 0 : if( ( pChild = pSubSup->GetSubSup( RSUB ) ) ) {
2220 : 0 : Separate( );
2221 : 0 : Append( "_ { " );
2222 : 0 : LineToText( pChild );
2223 : 0 : Append( "} " );
2224 : : }
2225 [ # # ]: 0 : if( ( pChild = pSubSup->GetSubSup( CSUB ) ) ) {
2226 : 0 : Separate( );
2227 [ # # ]: 0 : if (pSubSup->IsUseLimits())
2228 : 0 : Append( "from { " );
2229 : : else
2230 : 0 : Append( "csub { " );
2231 : 0 : LineToText( pChild );
2232 : 0 : Append( "} " );
2233 : : }
2234 [ # # ]: 0 : if( ( pChild = pSubSup->GetSubSup( CSUP ) ) ) {
2235 : 0 : Separate( );
2236 [ # # ]: 0 : if (pSubSup->IsUseLimits())
2237 : 0 : Append( "to { " );
2238 : : else
2239 : 0 : Append( "csup { " );
2240 : 0 : LineToText( pChild );
2241 : 0 : Append( "} " );
2242 : : }
2243 : : }
2244 : 0 : LineToText( pNode->GetSubNode( 1 ) );
2245 : 0 : }
2246 : :
2247 : 0 : void SmNodeToTextVisitor::Visit( SmAlignNode* pNode )
2248 : : {
2249 : 0 : Append( pNode->GetToken( ).aText );
2250 : 0 : LineToText( pNode->GetSubNode( 0 ) );
2251 : 0 : }
2252 : :
2253 : 0 : void SmNodeToTextVisitor::Visit( SmAttributNode* pNode )
2254 : : {
2255 : 0 : Append( pNode->GetToken( ).aText );
2256 : 0 : LineToText( pNode->GetSubNode( 1 ) );
2257 : 0 : }
2258 : :
2259 : 0 : void SmNodeToTextVisitor::Visit( SmFontNode* pNode )
2260 : : {
2261 [ # # # # : 0 : switch ( pNode->GetToken( ).eType )
# # # # #
# # # # #
# # # # ]
2262 : : {
2263 : : case TBOLD:
2264 : 0 : Append( "bold " );
2265 : 0 : break;
2266 : : case TNBOLD:
2267 : 0 : Append( "nbold " );
2268 : 0 : break;
2269 : : case TITALIC:
2270 : 0 : Append( "italic " );
2271 : 0 : break;
2272 : : case TNITALIC:
2273 : 0 : Append( "nitalic " );
2274 : 0 : break;
2275 : : case TPHANTOM:
2276 : 0 : Append( "phantom " );
2277 : 0 : break;
2278 : : case TSIZE:
2279 : : {
2280 : 0 : Append( "size " );
2281 [ # # # # : 0 : switch ( pNode->GetSizeType( ) )
# ]
2282 : : {
2283 : : case FNTSIZ_PLUS:
2284 : 0 : Append( "+" );
2285 : 0 : break;
2286 : : case FNTSIZ_MINUS:
2287 : 0 : Append( "-" );
2288 : 0 : break;
2289 : : case FNTSIZ_MULTIPLY:
2290 : 0 : Append( "*" );
2291 : 0 : break;
2292 : : case FNTSIZ_DIVIDE:
2293 : 0 : Append( "/" );
2294 : 0 : break;
2295 : : case FNTSIZ_ABSOLUT:
2296 : : default:
2297 : 0 : break;
2298 : : }
2299 : : Append( String( ::rtl::math::doubleToUString(
2300 : 0 : static_cast<double>( pNode->GetSizeParameter( ) ),
2301 : : rtl_math_StringFormat_Automatic,
2302 [ # # ][ # # ]: 0 : rtl_math_DecimalPlaces_Max, '.', sal_True ) ) );
[ # # ]
2303 : 0 : Append( " " );
2304 : : }
2305 : 0 : break;
2306 : : case TBLACK:
2307 : 0 : Append( "color black " );
2308 : 0 : break;
2309 : : case TWHITE:
2310 : 0 : Append( "color white " );
2311 : 0 : break;
2312 : : case TRED:
2313 : 0 : Append( "color red " );
2314 : 0 : break;
2315 : : case TGREEN:
2316 : 0 : Append( "color green " );
2317 : 0 : break;
2318 : : case TBLUE:
2319 : 0 : Append( "color blue " );
2320 : 0 : break;
2321 : : case TCYAN:
2322 : 0 : Append( "color cyan " );
2323 : 0 : break;
2324 : : case TMAGENTA:
2325 : 0 : Append( "color magenta " );
2326 : 0 : break;
2327 : : case TYELLOW:
2328 : 0 : Append( "color yellow " );
2329 : 0 : break;
2330 : : case TSANS:
2331 : 0 : Append( "font sans " );
2332 : 0 : break;
2333 : : case TSERIF:
2334 : 0 : Append( "font serif " );
2335 : 0 : break;
2336 : : case TFIXED:
2337 : 0 : Append( "font fixed " );
2338 : 0 : break;
2339 : : default:
2340 : 0 : break;
2341 : : }
2342 : 0 : LineToText( pNode->GetSubNode( 1 ) );
2343 : 0 : }
2344 : :
2345 : 0 : void SmNodeToTextVisitor::Visit( SmUnHorNode* pNode )
2346 : : {
2347 [ # # ][ # # ]: 0 : SmNodeIterator it( pNode, pNode->GetSubNode( 1 )->GetToken( ).eType == TFACT );
2348 [ # # ][ # # ]: 0 : while( it.Next( ) ) {
2349 [ # # ]: 0 : Separate( );
2350 [ # # ]: 0 : it->Accept( this );
2351 : : }
2352 : 0 : }
2353 : :
2354 : 0 : void SmNodeToTextVisitor::Visit( SmBinHorNode* pNode )
2355 : : {
2356 : 0 : SmNode *pLeft = pNode->GetSubNode( 0 ),
2357 : 0 : *pOper = pNode->GetSubNode( 1 ),
2358 : 0 : *pRight = pNode->GetSubNode( 2 );
2359 : 0 : Separate( );
2360 : 0 : pLeft->Accept( this );
2361 : 0 : Separate( );
2362 : 0 : pOper->Accept( this );
2363 : 0 : Separate( );
2364 : 0 : pRight->Accept( this );
2365 : 0 : Separate( );
2366 : 0 : }
2367 : :
2368 : 0 : void SmNodeToTextVisitor::Visit( SmBinVerNode* pNode )
2369 : : {
2370 : 0 : SmNode *pNum = pNode->GetSubNode( 0 ),
2371 : 0 : *pDenom = pNode->GetSubNode( 2 );
2372 : 0 : Append( "{ " );
2373 : 0 : LineToText( pNum );
2374 : 0 : Append( "over" );
2375 : 0 : LineToText( pDenom );
2376 : 0 : Append( "} " );
2377 : 0 : }
2378 : :
2379 : 0 : void SmNodeToTextVisitor::Visit( SmBinDiagonalNode* pNode )
2380 : : {
2381 : 0 : SmNode *pLeftOperand = pNode->GetSubNode( 0 ),
2382 : 0 : *pRightOperand = pNode->GetSubNode( 1 );
2383 : 0 : Append( "{ " );
2384 : 0 : LineToText( pLeftOperand );
2385 : 0 : Separate( );
2386 : 0 : Append( "wideslash " );
2387 : 0 : LineToText( pRightOperand );
2388 : 0 : Append( "} " );
2389 : 0 : }
2390 : :
2391 : 0 : void SmNodeToTextVisitor::Visit( SmSubSupNode* pNode )
2392 : : {
2393 : 0 : LineToText( pNode->GetBody( ) );
2394 : : SmNode *pChild;
2395 [ # # ]: 0 : if( ( pChild = pNode->GetSubSup( LSUP ) ) ) {
2396 : 0 : Separate( );
2397 : 0 : Append( "lsup " );
2398 : 0 : LineToText( pChild );
2399 : : }
2400 [ # # ]: 0 : if( ( pChild = pNode->GetSubSup( LSUB ) ) ) {
2401 : 0 : Separate( );
2402 : 0 : Append( "lsub " );
2403 : 0 : LineToText( pChild );
2404 : : }
2405 [ # # ]: 0 : if( ( pChild = pNode->GetSubSup( RSUP ) ) ) {
2406 : 0 : Separate( );
2407 : 0 : Append( "^ " );
2408 : 0 : LineToText( pChild );
2409 : : }
2410 [ # # ]: 0 : if( ( pChild = pNode->GetSubSup( RSUB ) ) ) {
2411 : 0 : Separate( );
2412 : 0 : Append( "_ " );
2413 : 0 : LineToText( pChild );
2414 : : }
2415 [ # # ]: 0 : if( ( pChild = pNode->GetSubSup( CSUB ) ) ) {
2416 : 0 : Separate( );
2417 [ # # ]: 0 : if (pNode->IsUseLimits())
2418 : 0 : Append( "from " );
2419 : : else
2420 : 0 : Append( "csub " );
2421 : 0 : LineToText( pChild );
2422 : : }
2423 [ # # ]: 0 : if( ( pChild = pNode->GetSubSup( CSUP ) ) ) {
2424 : 0 : Separate( );
2425 [ # # ]: 0 : if (pNode->IsUseLimits())
2426 : 0 : Append( "to " );
2427 : : else
2428 : 0 : Append( "csup " );
2429 : 0 : LineToText( pChild );
2430 : : }
2431 : 0 : }
2432 : :
2433 : 0 : void SmNodeToTextVisitor::Visit( SmMatrixNode* pNode )
2434 : : {
2435 : 0 : Append( "matrix{" );
2436 [ # # ]: 0 : for ( sal_uInt16 i = 0; i < pNode->GetNumRows( ); i++ ) {
2437 [ # # ]: 0 : for ( sal_uInt16 j = 0; j < pNode->GetNumCols( ); j++ ) {
2438 : 0 : SmNode* pSubNode = pNode->GetSubNode( i * pNode->GetNumCols( ) + j );
2439 : 0 : Separate( );
2440 : 0 : pSubNode->Accept( this );
2441 : 0 : Separate( );
2442 [ # # ]: 0 : if( j != pNode->GetNumCols( ) - 1 )
2443 : 0 : Append( "#" );
2444 : : }
2445 : 0 : Separate( );
2446 [ # # ]: 0 : if( i != pNode->GetNumRows( ) - 1 )
2447 : 0 : Append( "##" );
2448 : : }
2449 : 0 : Append( "} " );
2450 : 0 : }
2451 : :
2452 : 0 : void SmNodeToTextVisitor::Visit( SmPlaceNode* )
2453 : : {
2454 : 0 : Append( "<?>" );
2455 : 0 : }
2456 : :
2457 : 0 : void SmNodeToTextVisitor::Visit( SmTextNode* pNode )
2458 : : {
2459 : : //TODO: This method might need improvements, see SmTextNode::CreateTextFromNode
2460 [ # # ]: 0 : if( pNode->GetToken( ).eType == TTEXT )
2461 : 0 : Append( "\"" );
2462 : 0 : Append( pNode->GetText( ) );
2463 [ # # ]: 0 : if( pNode->GetToken( ).eType == TTEXT )
2464 : 0 : Append( "\"" );
2465 : 0 : }
2466 : :
2467 : 0 : void SmNodeToTextVisitor::Visit( SmSpecialNode* pNode )
2468 : : {
2469 : 0 : Append( pNode->GetToken( ).aText );
2470 : 0 : }
2471 : :
2472 : 0 : void SmNodeToTextVisitor::Visit( SmGlyphSpecialNode* pNode )
2473 : : {
2474 [ # # ]: 0 : if( pNode->GetToken( ).eType == TBOPER )
2475 : 0 : Append( "boper " );
2476 : : else
2477 : 0 : Append( "uoper " );
2478 : 0 : Append( pNode->GetToken( ).aText );
2479 : 0 : }
2480 : :
2481 : 0 : void SmNodeToTextVisitor::Visit( SmMathSymbolNode* pNode )
2482 : : {
2483 : 0 : Append( pNode->GetToken( ).aText );
2484 : 0 : }
2485 : :
2486 : 0 : void SmNodeToTextVisitor::Visit( SmBlankNode* pNode )
2487 : : {
2488 : 0 : Append( pNode->GetToken( ).aText );
2489 : 0 : }
2490 : :
2491 : 0 : void SmNodeToTextVisitor::Visit( SmErrorNode* )
2492 : : {
2493 : 0 : }
2494 : :
2495 : 0 : void SmNodeToTextVisitor::Visit( SmLineNode* pNode )
2496 : : {
2497 [ # # ]: 0 : SmNodeIterator it( pNode );
2498 [ # # ][ # # ]: 0 : while( it.Next( ) ){
2499 [ # # ]: 0 : Separate( );
2500 [ # # ]: 0 : it->Accept( this );
2501 : : }
2502 : 0 : }
2503 : :
2504 : 0 : void SmNodeToTextVisitor::Visit( SmExpressionNode* pNode )
2505 : : {
2506 [ # # ][ # # ]: 0 : bool bracketsNeeded = pNode->GetNumSubNodes() != 1 || pNode->GetSubNode(0)->GetType() == NBINHOR;
[ # # ][ # # ]
2507 : : // nested subsups
2508 : : bracketsNeeded |=
2509 : 0 : pNode->GetParent()->GetType() == NSUBSUP &&
2510 [ # # ]: 0 : pNode->GetNumSubNodes() == 1 &&
2511 [ # # ][ # # ]: 0 : pNode->GetSubNode(0)->GetType() == NSUBSUP;
[ # # ][ # # ]
2512 : :
2513 [ # # ]: 0 : if (bracketsNeeded) {
2514 [ # # ]: 0 : Append( "{ " );
2515 : : }
2516 [ # # ]: 0 : SmNodeIterator it( pNode );
2517 [ # # ][ # # ]: 0 : while( it.Next( ) ) {
2518 [ # # ]: 0 : it->Accept( this );
2519 [ # # ]: 0 : Separate( );
2520 : : }
2521 [ # # ]: 0 : if (bracketsNeeded) {
2522 [ # # ]: 0 : Append( "} " );
2523 : : }
2524 : 0 : }
2525 : :
2526 : 0 : void SmNodeToTextVisitor::Visit( SmPolyLineNode* )
2527 : : {
2528 : 0 : }
2529 : :
2530 : 0 : void SmNodeToTextVisitor::Visit( SmRootNode* pNode )
2531 : : {
2532 : 0 : SmNode *pExtra = pNode->GetSubNode( 0 ),
2533 : 0 : *pBody = pNode->GetSubNode( 2 );
2534 [ # # ]: 0 : if( pExtra ) {
2535 : 0 : Append( "nroot" );
2536 : 0 : LineToText( pExtra );
2537 : : } else
2538 : 0 : Append( "sqrt" );
2539 : 0 : LineToText( pBody );
2540 : 0 : }
2541 : :
2542 : 0 : void SmNodeToTextVisitor::Visit( SmRootSymbolNode* )
2543 : : {
2544 : 0 : }
2545 : :
2546 : 0 : void SmNodeToTextVisitor::Visit( SmRectangleNode* )
2547 : : {
2548 : 0 : }
2549 : :
2550 : 0 : void SmNodeToTextVisitor::Visit( SmVerticalBraceNode* pNode )
2551 : : {
2552 : 0 : SmNode *pBody = pNode->GetSubNode( 0 ),
2553 : 0 : *pScript = pNode->GetSubNode( 2 );
2554 : 0 : LineToText( pBody );
2555 : 0 : Append( pNode->GetToken( ).aText );
2556 : 0 : LineToText( pScript );
2557 [ + - ][ + - ]: 30 : }
2558 : :
2559 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|