1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
15 /** Base class for visitors that visits a tree of SmNodes
16 * @remarks all methods have been left abstract to ensure that implementers
17 * don't forget to implement one.
22 virtual void Visit( SmTableNode
* pNode
) = 0;
23 virtual void Visit( SmBraceNode
* pNode
) = 0;
24 virtual void Visit( SmBracebodyNode
* pNode
) = 0;
25 virtual void Visit( SmOperNode
* pNode
) = 0;
26 virtual void Visit( SmAlignNode
* pNode
) = 0;
27 virtual void Visit( SmAttributNode
* pNode
) = 0;
28 virtual void Visit( SmFontNode
* pNode
) = 0;
29 virtual void Visit( SmUnHorNode
* pNode
) = 0;
30 virtual void Visit( SmBinHorNode
* pNode
) = 0;
31 virtual void Visit( SmBinVerNode
* pNode
) = 0;
32 virtual void Visit( SmBinDiagonalNode
* pNode
) = 0;
33 virtual void Visit( SmSubSupNode
* pNode
) = 0;
34 virtual void Visit( SmMatrixNode
* pNode
) = 0;
35 virtual void Visit( SmPlaceNode
* pNode
) = 0;
36 virtual void Visit( SmTextNode
* pNode
) = 0;
37 virtual void Visit( SmSpecialNode
* pNode
) = 0;
38 virtual void Visit( SmGlyphSpecialNode
* pNode
) = 0;
39 virtual void Visit( SmMathSymbolNode
* pNode
) = 0;
40 virtual void Visit( SmBlankNode
* pNode
) = 0;
41 virtual void Visit( SmErrorNode
* pNode
) = 0;
42 virtual void Visit( SmLineNode
* pNode
) = 0;
43 virtual void Visit( SmExpressionNode
* pNode
) = 0;
44 virtual void Visit( SmPolyLineNode
* pNode
) = 0;
45 virtual void Visit( SmRootNode
* pNode
) = 0;
46 virtual void Visit( SmRootSymbolNode
* pNode
) = 0;
47 virtual void Visit( SmRectangleNode
* pNode
) = 0;
48 virtual void Visit( SmVerticalBraceNode
* pNode
) = 0;
54 /** Simple visitor for testing SmVisitor */
55 class SmVisitorTest
: public SmVisitor
58 virtual ~SmVisitorTest() {}
59 void Visit( SmTableNode
* pNode
);
60 void Visit( SmBraceNode
* pNode
);
61 void Visit( SmBracebodyNode
* pNode
);
62 void Visit( SmOperNode
* pNode
);
63 void Visit( SmAlignNode
* pNode
);
64 void Visit( SmAttributNode
* pNode
);
65 void Visit( SmFontNode
* pNode
);
66 void Visit( SmUnHorNode
* pNode
);
67 void Visit( SmBinHorNode
* pNode
);
68 void Visit( SmBinVerNode
* pNode
);
69 void Visit( SmBinDiagonalNode
* pNode
);
70 void Visit( SmSubSupNode
* pNode
);
71 void Visit( SmMatrixNode
* pNode
);
72 void Visit( SmPlaceNode
* pNode
);
73 void Visit( SmTextNode
* pNode
);
74 void Visit( SmSpecialNode
* pNode
);
75 void Visit( SmGlyphSpecialNode
* pNode
);
76 void Visit( SmMathSymbolNode
* pNode
);
77 void Visit( SmBlankNode
* pNode
);
78 void Visit( SmErrorNode
* pNode
);
79 void Visit( SmLineNode
* pNode
);
80 void Visit( SmExpressionNode
* pNode
);
81 void Visit( SmPolyLineNode
* pNode
);
82 void Visit( SmRootNode
* pNode
);
83 void Visit( SmRootSymbolNode
* pNode
);
84 void Visit( SmRectangleNode
* pNode
);
85 void Visit( SmVerticalBraceNode
* pNode
);
87 /** Auxiliary method for visiting the children of a pNode */
88 void VisitChildren( SmNode
* pNode
);
91 /////////////////////////////// SmDefaultingVisitor ////////////////////////////////
94 /** Visitor that uses DefaultVisit for handling visits by default
96 * This abstract baseclass is useful for visitors where many methods share the same
99 class SmDefaultingVisitor
: public SmVisitor
102 void Visit( SmTableNode
* pNode
);
103 void Visit( SmBraceNode
* pNode
);
104 void Visit( SmBracebodyNode
* pNode
);
105 void Visit( SmOperNode
* pNode
);
106 void Visit( SmAlignNode
* pNode
);
107 void Visit( SmAttributNode
* pNode
);
108 void Visit( SmFontNode
* pNode
);
109 void Visit( SmUnHorNode
* pNode
);
110 void Visit( SmBinHorNode
* pNode
);
111 void Visit( SmBinVerNode
* pNode
);
112 void Visit( SmBinDiagonalNode
* pNode
);
113 void Visit( SmSubSupNode
* pNode
);
114 void Visit( SmMatrixNode
* pNode
);
115 void Visit( SmPlaceNode
* pNode
);
116 void Visit( SmTextNode
* pNode
);
117 void Visit( SmSpecialNode
* pNode
);
118 void Visit( SmGlyphSpecialNode
* pNode
);
119 void Visit( SmMathSymbolNode
* pNode
);
120 void Visit( SmBlankNode
* pNode
);
121 void Visit( SmErrorNode
* pNode
);
122 void Visit( SmLineNode
* pNode
);
123 void Visit( SmExpressionNode
* pNode
);
124 void Visit( SmPolyLineNode
* pNode
);
125 void Visit( SmRootNode
* pNode
);
126 void Visit( SmRootSymbolNode
* pNode
);
127 void Visit( SmRectangleNode
* pNode
);
128 void Visit( SmVerticalBraceNode
* pNode
);
130 ~SmDefaultingVisitor() {}
132 /** Method invoked by Visit methods by default */
133 virtual void DefaultVisit( SmNode
* pNode
) = 0;
136 /////////////////////////////// SmCaretDrawingVisitor ////////////////////////////////
138 /** Visitor for drawing a caret position */
139 class SmCaretDrawingVisitor
: public SmDefaultingVisitor
142 /** Given position and device this constructor will draw the caret */
143 SmCaretDrawingVisitor( OutputDevice
& rDevice
, SmCaretPos position
, Point offset
, bool caretVisible
);
144 virtual ~SmCaretDrawingVisitor() {}
145 void Visit( SmTextNode
* pNode
);
146 using SmDefaultingVisitor::Visit
;
150 /** Offset to draw from */
154 /** Default method for drawing pNodes */
155 void DefaultVisit( SmNode
* pNode
);
158 /////////////////////////////// SmCaretPos2LineVisitor ////////////////////////////////
160 /** Visitor getting a line from a caret position */
161 class SmCaretPos2LineVisitor
: public SmDefaultingVisitor
164 /** Given position and device this constructor will compute a line for the caret */
165 SmCaretPos2LineVisitor( OutputDevice
*pDevice
, SmCaretPos position
) {
168 OSL_ENSURE( position
.IsValid( ), "Cannot draw invalid position!" );
170 pos
.pSelectedNode
->Accept( this );
172 virtual ~SmCaretPos2LineVisitor() {}
173 void Visit( SmTextNode
* pNode
);
174 using SmDefaultingVisitor::Visit
;
175 SmCaretLine
GetResult( ){
183 /** Default method for computing lines for pNodes */
184 void DefaultVisit( SmNode
* pNode
);
187 /////////////////////////////// SmDrawingVisitor ////////////////////////////////
189 /** Visitor for drawing SmNodes to OutputDevice */
190 class SmDrawingVisitor
: public SmVisitor
193 /** Create an instance of SmDrawingVisitor, and use it to draw a formula
194 * @param rDevice Device to draw on
195 * @param position Offset on device to draw the formula
196 * @param pTree Formula tree to draw
197 * @remarks This constructor will do the drawing, no need to anything more.
199 SmDrawingVisitor( OutputDevice
&rDevice
, Point position
, SmNode
* pTree
)
201 this->Position
= position
;
202 pTree
->Accept( this );
204 virtual ~SmDrawingVisitor() {}
205 void Visit( SmTableNode
* pNode
);
206 void Visit( SmBraceNode
* pNode
);
207 void Visit( SmBracebodyNode
* pNode
);
208 void Visit( SmOperNode
* pNode
);
209 void Visit( SmAlignNode
* pNode
);
210 void Visit( SmAttributNode
* pNode
);
211 void Visit( SmFontNode
* pNode
);
212 void Visit( SmUnHorNode
* pNode
);
213 void Visit( SmBinHorNode
* pNode
);
214 void Visit( SmBinVerNode
* pNode
);
215 void Visit( SmBinDiagonalNode
* pNode
);
216 void Visit( SmSubSupNode
* pNode
);
217 void Visit( SmMatrixNode
* pNode
);
218 void Visit( SmPlaceNode
* pNode
);
219 void Visit( SmTextNode
* pNode
);
220 void Visit( SmSpecialNode
* pNode
);
221 void Visit( SmGlyphSpecialNode
* pNode
);
222 void Visit( SmMathSymbolNode
* pNode
);
223 void Visit( SmBlankNode
* pNode
);
224 void Visit( SmErrorNode
* pNode
);
225 void Visit( SmLineNode
* pNode
);
226 void Visit( SmExpressionNode
* pNode
);
227 void Visit( SmPolyLineNode
* pNode
);
228 void Visit( SmRootNode
* pNode
);
229 void Visit( SmRootSymbolNode
* pNode
);
230 void Visit( SmRectangleNode
* pNode
);
231 void Visit( SmVerticalBraceNode
* pNode
);
233 /** Draw the children of a pNode
234 * This the default method, use by most pNodes
236 void DrawChildren( SmNode
* pNode
);
238 /** Draw an SmTextNode or a subclass of this */
239 void DrawTextNode( SmTextNode
* pNode
);
240 /** Draw an SmSpecialNode or a subclass of this */
241 void DrawSpecialNode( SmSpecialNode
* pNode
);
242 /** OutputDevice to draw on */
244 /** Position to draw on the rDev
245 * @remarks This variable is used to pass parameters in DrawChildren( ), this means
246 that after a call to DrawChildren( ) the contents of this method is undefined
247 so if needed cache it locally on the stack.
252 /////////////////////////////// SmSetSelectionVisitor ////////////////////////////////
254 /** Set Selection Visitor
255 * Sets the IsSelected( ) property on all SmNodes of the tree
257 class SmSetSelectionVisitor
: public SmDefaultingVisitor
260 SmSetSelectionVisitor( SmCaretPos startPos
, SmCaretPos endPos
, SmNode
* pNode
);
261 virtual ~SmSetSelectionVisitor() {}
262 void Visit( SmBinHorNode
* pNode
);
263 void Visit( SmUnHorNode
* pNode
);
264 void Visit( SmFontNode
* pNode
);
265 void Visit( SmTextNode
* pNode
);
266 void Visit( SmExpressionNode
* pNode
);
267 void Visit( SmLineNode
* pNode
);
268 void Visit( SmAlignNode
* pNode
);
269 using SmDefaultingVisitor::Visit
;
270 /** Set IsSelected on all pNodes of pSubTree */
271 static void SetSelectedOnAll( SmNode
* pSubTree
, bool IsSelected
= true );
273 /** Visit a selectable pNode
274 * Can be used to handle pNodes that can be selected, that doesn't have more SmCaretPos'
275 * than 0 and 1 inside them. SmTextNode should be handle separately!
276 * Also note that pNodes such as SmBinVerNode cannot be selected, don't this method for
279 void DefaultVisit( SmNode
* pNode
);
280 void VisitCompositionNode( SmNode
* pNode
);
281 /** Caret position where the selection starts */
283 /** Caret position where the selection ends */
285 /** The current state of this visitor
286 * This property changes when the visitor meets either StartPos
287 * or EndPos. This means that anything visited in between will be
294 /////////////////////////////// SmCaretPosGraphBuildingVisitor ////////////////////////////////
297 /** A visitor for building a SmCaretPosGraph
300 * Each pNode, except SmExpressionNode, SmBinHorNode and a few others, constitues an entry
301 * in a line. Consider the line entry "H", this entry creates one carat position, here
302 * denoted by | in "H|".
304 * Parameter variables:
305 * The following variables are used to transfer parameters in to calls and results out
307 * pRightMost : SmCaretPosGraphEntry*
309 * Prior to a Visit call:
310 * pRightMost: A pointer to right most position in front of the current line entry.
312 * After a Visit call:
313 * pRightMost: A pointer to the right most position in the called line entry, if no there's
314 * no caret positions in called line entry don't change this variable.
316 class SmCaretPosGraphBuildingVisitor
: public SmVisitor
319 /** Builds a caret position graph for pRootNode */
320 SmCaretPosGraphBuildingVisitor( SmNode
* pRootNode
);
321 virtual ~SmCaretPosGraphBuildingVisitor() {}
322 void Visit( SmTableNode
* pNode
);
323 void Visit( SmBraceNode
* pNode
);
324 void Visit( SmBracebodyNode
* pNode
);
325 void Visit( SmOperNode
* pNode
);
326 void Visit( SmAlignNode
* pNode
);
327 void Visit( SmAttributNode
* pNode
);
328 void Visit( SmFontNode
* pNode
);
329 void Visit( SmUnHorNode
* pNode
);
330 void Visit( SmBinHorNode
* pNode
);
331 void Visit( SmBinVerNode
* pNode
);
332 void Visit( SmBinDiagonalNode
* pNode
);
333 void Visit( SmSubSupNode
* pNode
);
334 void Visit( SmMatrixNode
* pNode
);
335 void Visit( SmPlaceNode
* pNode
);
336 void Visit( SmTextNode
* pNode
);
337 void Visit( SmSpecialNode
* pNode
);
338 void Visit( SmGlyphSpecialNode
* pNode
);
339 void Visit( SmMathSymbolNode
* pNode
);
340 void Visit( SmBlankNode
* pNode
);
341 void Visit( SmErrorNode
* pNode
);
342 void Visit( SmLineNode
* pNode
);
343 void Visit( SmExpressionNode
* pNode
);
344 void Visit( SmPolyLineNode
* pNode
);
345 void Visit( SmRootNode
* pNode
);
346 void Visit( SmRootSymbolNode
* pNode
);
347 void Visit( SmRectangleNode
* pNode
);
348 void Visit( SmVerticalBraceNode
* pNode
);
349 SmCaretPosGraph
* Graph( ){
353 SmCaretPosGraphEntry
* pRightMost
;
354 SmCaretPosGraph
* pGraph
;
357 /////////////////////////////// SmCloningVisitor ///////////////////////////////
359 /** Visitor for cloning a pNode
361 * This visitor creates deep clones.
363 class SmCloningVisitor
: public SmVisitor
366 SmCloningVisitor( ){ pResult
= NULL
; }
367 virtual ~SmCloningVisitor() {}
368 void Visit( SmTableNode
* pNode
);
369 void Visit( SmBraceNode
* pNode
);
370 void Visit( SmBracebodyNode
* pNode
);
371 void Visit( SmOperNode
* pNode
);
372 void Visit( SmAlignNode
* pNode
);
373 void Visit( SmAttributNode
* pNode
);
374 void Visit( SmFontNode
* pNode
);
375 void Visit( SmUnHorNode
* pNode
);
376 void Visit( SmBinHorNode
* pNode
);
377 void Visit( SmBinVerNode
* pNode
);
378 void Visit( SmBinDiagonalNode
* pNode
);
379 void Visit( SmSubSupNode
* pNode
);
380 void Visit( SmMatrixNode
* pNode
);
381 void Visit( SmPlaceNode
* pNode
);
382 void Visit( SmTextNode
* pNode
);
383 void Visit( SmSpecialNode
* pNode
);
384 void Visit( SmGlyphSpecialNode
* pNode
);
385 void Visit( SmMathSymbolNode
* pNode
);
386 void Visit( SmBlankNode
* pNode
);
387 void Visit( SmErrorNode
* pNode
);
388 void Visit( SmLineNode
* pNode
);
389 void Visit( SmExpressionNode
* pNode
);
390 void Visit( SmPolyLineNode
* pNode
);
391 void Visit( SmRootNode
* pNode
);
392 void Visit( SmRootSymbolNode
* pNode
);
393 void Visit( SmRectangleNode
* pNode
);
394 void Visit( SmVerticalBraceNode
* pNode
);
396 SmNode
* Clone( SmNode
* pNode
);
399 /** Clone children of pSource and give them to pTarget */
400 void CloneKids( SmStructureNode
* pSource
, SmStructureNode
* pTarget
);
401 /** Clone attributes on a pNode */
402 void CloneNodeAttr( SmNode
* pSource
, SmNode
* pTarget
);
406 /////////////////////////////// SmSelectionDrawingVisitor ///////////////////////////////
408 class SmSelectionDrawingVisitor
: public SmDefaultingVisitor
411 /** Draws a selection on rDevice for the selection on pTree */
412 SmSelectionDrawingVisitor( OutputDevice
& rDevice
, SmNode
* pTree
, Point Offset
);
413 virtual ~SmSelectionDrawingVisitor() {}
414 void Visit( SmTextNode
* pNode
);
415 using SmDefaultingVisitor::Visit
;
417 /** Reference to drawing device */
419 /** True if aSelectionArea have been initialized */
420 bool bHasSelectionArea
;
421 /** The current area that is selected */
422 Rectangle aSelectionArea
;
423 /** Extend the area that must be selected */
424 void ExtendSelectionArea( Rectangle aArea
);
425 /** Default visiting method */
426 void DefaultVisit( SmNode
* pNode
);
427 /** Visit the children of a given pNode */
428 void VisitChildren( SmNode
* pNode
);
431 /////////////////////////////// SmNodeToTextVisitor ///////////////////////////////
433 /** Extract command text from pNodes */
434 class SmNodeToTextVisitor
: public SmVisitor
437 SmNodeToTextVisitor( SmNode
* pNode
, OUString
&rText
);
438 virtual ~SmNodeToTextVisitor() {}
440 void Visit( SmTableNode
* pNode
);
441 void Visit( SmBraceNode
* pNode
);
442 void Visit( SmBracebodyNode
* pNode
);
443 void Visit( SmOperNode
* pNode
);
444 void Visit( SmAlignNode
* pNode
);
445 void Visit( SmAttributNode
* pNode
);
446 void Visit( SmFontNode
* pNode
);
447 void Visit( SmUnHorNode
* pNode
);
448 void Visit( SmBinHorNode
* pNode
);
449 void Visit( SmBinVerNode
* pNode
);
450 void Visit( SmBinDiagonalNode
* pNode
);
451 void Visit( SmSubSupNode
* pNode
);
452 void Visit( SmMatrixNode
* pNode
);
453 void Visit( SmPlaceNode
* pNode
);
454 void Visit( SmTextNode
* pNode
);
455 void Visit( SmSpecialNode
* pNode
);
456 void Visit( SmGlyphSpecialNode
* pNode
);
457 void Visit( SmMathSymbolNode
* pNode
);
458 void Visit( SmBlankNode
* pNode
);
459 void Visit( SmErrorNode
* pNode
);
460 void Visit( SmLineNode
* pNode
);
461 void Visit( SmExpressionNode
* pNode
);
462 void Visit( SmPolyLineNode
* pNode
);
463 void Visit( SmRootNode
* pNode
);
464 void Visit( SmRootSymbolNode
* pNode
);
465 void Visit( SmRectangleNode
* pNode
);
466 void Visit( SmVerticalBraceNode
* pNode
);
468 /** Extract text from a pNode that constitues a line */
469 void LineToText( SmNode
* pNode
) {
472 pNode
->Accept( this );
475 void Append( const OUString
&rText
) {
476 aCmdText
.append( rText
);
478 /** Append a blank for separation, if needed */
479 inline void Separate( ){
480 if( !aCmdText
.getLength() || aCmdText
[ aCmdText
.getLength() - 1 ] != ' ' )
481 aCmdText
.append(' ');
483 /** Output text generated from the pNodes */
484 OUStringBuffer aCmdText
;
487 #endif /* SMVISITORS_H */
489 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */