Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : */
9 : #ifndef SMVISITORS_H
10 : #define SMVISITORS_H
11 :
12 : #include "node.hxx"
13 : #include "caret.hxx"
14 :
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.
18 : */
19 3511 : class SmVisitor
20 : {
21 : public:
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;
49 :
50 : protected:
51 3511 : ~SmVisitor() {}
52 : };
53 :
54 : /** Simple visitor for testing SmVisitor */
55 : class SmVisitorTest : public SmVisitor
56 : {
57 : public:
58 0 : 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 );
86 : private:
87 : /** Auxiliary method for visiting the children of a pNode */
88 : void VisitChildren( SmNode* pNode );
89 : };
90 :
91 : /////////////////////////////// SmDefaultingVisitor ////////////////////////////////
92 :
93 :
94 : /** Visitor that uses DefaultVisit for handling visits by default
95 : *
96 : * This abstract baseclass is useful for visitors where many methods share the same
97 : * implementation.
98 : */
99 33 : class SmDefaultingVisitor : public SmVisitor
100 : {
101 : public:
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 );
129 : protected:
130 33 : ~SmDefaultingVisitor() {}
131 :
132 : /** Method invoked by Visit methods by default */
133 : virtual void DefaultVisit( SmNode* pNode ) = 0;
134 : };
135 :
136 : /////////////////////////////// SmCaretDrawingVisitor ////////////////////////////////
137 :
138 : /** Visitor for drawing a caret position */
139 : class SmCaretDrawingVisitor : public SmDefaultingVisitor
140 : {
141 : public:
142 : /** Given position and device this constructor will draw the caret */
143 : SmCaretDrawingVisitor( OutputDevice& rDevice, SmCaretPos position, Point offset, bool caretVisible );
144 0 : virtual ~SmCaretDrawingVisitor() {}
145 : void Visit( SmTextNode* pNode );
146 : using SmDefaultingVisitor::Visit;
147 : private:
148 : OutputDevice &rDev;
149 : SmCaretPos pos;
150 : /** Offset to draw from */
151 : Point Offset;
152 : bool isCaretVisible;
153 : protected:
154 : /** Default method for drawing pNodes */
155 : void DefaultVisit( SmNode* pNode );
156 : };
157 :
158 : /////////////////////////////// SmCaretPos2LineVisitor ////////////////////////////////
159 :
160 : /** Visitor getting a line from a caret position */
161 : class SmCaretPos2LineVisitor : public SmDefaultingVisitor
162 : {
163 : public:
164 : /** Given position and device this constructor will compute a line for the caret */
165 14 : SmCaretPos2LineVisitor( OutputDevice *pDevice, SmCaretPos position ) {
166 14 : pDev = pDevice;
167 14 : pos = position;
168 : OSL_ENSURE( position.IsValid( ), "Cannot draw invalid position!" );
169 :
170 14 : pos.pSelectedNode->Accept( this );
171 14 : }
172 14 : virtual ~SmCaretPos2LineVisitor() {}
173 : void Visit( SmTextNode* pNode );
174 : using SmDefaultingVisitor::Visit;
175 14 : SmCaretLine GetResult( ){
176 14 : return line;
177 : }
178 : private:
179 : SmCaretLine line;
180 : OutputDevice *pDev;
181 : SmCaretPos pos;
182 : protected:
183 : /** Default method for computing lines for pNodes */
184 : void DefaultVisit( SmNode* pNode );
185 : };
186 :
187 : /////////////////////////////// SmDrawingVisitor ////////////////////////////////
188 :
189 : /** Visitor for drawing SmNodes to OutputDevice */
190 : class SmDrawingVisitor : public SmVisitor
191 : {
192 : public:
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.
198 : */
199 2915 : SmDrawingVisitor( OutputDevice &rDevice, Point position, SmNode* pTree )
200 2915 : : rDev( rDevice ) {
201 2915 : this->Position = position;
202 2915 : pTree->Accept( this );
203 2915 : }
204 2915 : 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 );
232 : private:
233 : /** Draw the children of a pNode
234 : * This the default method, use by most pNodes
235 : */
236 : void DrawChildren( SmNode* pNode );
237 :
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 */
243 : OutputDevice& rDev;
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.
248 : */
249 : Point Position;
250 : };
251 :
252 : /////////////////////////////// SmSetSelectionVisitor ////////////////////////////////
253 :
254 : /** Set Selection Visitor
255 : * Sets the IsSelected( ) property on all SmNodes of the tree
256 : */
257 : class SmSetSelectionVisitor : public SmDefaultingVisitor
258 : {
259 : public:
260 : SmSetSelectionVisitor( SmCaretPos startPos, SmCaretPos endPos, SmNode* pNode);
261 19 : 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 );
272 : private:
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
277 : * it.
278 : */
279 : void DefaultVisit( SmNode* pNode );
280 : void VisitCompositionNode( SmNode* pNode );
281 : /** Caret position where the selection starts */
282 : SmCaretPos StartPos;
283 : /** Caret position where the selection ends */
284 : SmCaretPos EndPos;
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
288 : * selected.
289 : */
290 : bool IsSelecting;
291 : };
292 :
293 :
294 : /////////////////////////////// SmCaretPosGraphBuildingVisitor ////////////////////////////////
295 :
296 :
297 : /** A visitor for building a SmCaretPosGraph
298 : *
299 : * Visit invariant:
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|".
303 : *
304 : * Parameter variables:
305 : * The following variables are used to transfer parameters in to calls and results out
306 : * of calls.
307 : * pRightMost : SmCaretPosGraphEntry*
308 : *
309 : * Prior to a Visit call:
310 : * pRightMost: A pointer to right most position in front of the current line entry.
311 : *
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.
315 : */
316 : class SmCaretPosGraphBuildingVisitor : public SmVisitor
317 : {
318 : public:
319 : /** Builds a caret position graph for pRootNode */
320 : SmCaretPosGraphBuildingVisitor( SmNode* pRootNode );
321 20 : 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 20 : SmCaretPosGraph* Graph( ){
350 20 : return pGraph;
351 : }
352 : private:
353 : SmCaretPosGraphEntry* pRightMost;
354 : SmCaretPosGraph* pGraph;
355 : };
356 :
357 : /////////////////////////////// SmCloningVisitor ///////////////////////////////
358 :
359 : /** Visitor for cloning a pNode
360 : *
361 : * This visitor creates deep clones.
362 : */
363 : class SmCloningVisitor : public SmVisitor
364 : {
365 : public:
366 0 : SmCloningVisitor( ){ pResult = NULL; }
367 0 : 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 );
395 : /** Clone a pNode */
396 : SmNode* Clone( SmNode* pNode );
397 : private:
398 : SmNode* pResult;
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 );
403 : };
404 :
405 :
406 : /////////////////////////////// SmSelectionDrawingVisitor ///////////////////////////////
407 :
408 : class SmSelectionDrawingVisitor : public SmDefaultingVisitor
409 : {
410 : public:
411 : /** Draws a selection on rDevice for the selection on pTree */
412 : SmSelectionDrawingVisitor( OutputDevice& rDevice, SmNode* pTree, Point Offset );
413 0 : virtual ~SmSelectionDrawingVisitor() {}
414 : void Visit( SmTextNode* pNode );
415 : using SmDefaultingVisitor::Visit;
416 : private:
417 : /** Reference to drawing device */
418 : OutputDevice& rDev;
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 );
429 : };
430 :
431 : /////////////////////////////// SmNodeToTextVisitor ///////////////////////////////
432 :
433 : /** Extract command text from pNodes */
434 : class SmNodeToTextVisitor : public SmVisitor
435 : {
436 : public:
437 : SmNodeToTextVisitor( SmNode* pNode, OUString &rText );
438 543 : virtual ~SmNodeToTextVisitor() {}
439 :
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 );
467 : private:
468 : /** Extract text from a pNode that constitues a line */
469 272 : void LineToText( SmNode* pNode ) {
470 272 : Separate( );
471 272 : if( pNode )
472 272 : pNode->Accept( this );
473 272 : Separate( );
474 272 : }
475 1683 : void Append( const OUString &rText ) {
476 1683 : aCmdText.append( rText );
477 1683 : }
478 : /** Append a blank for separation, if needed */
479 1658 : inline void Separate( ){
480 1658 : if( aCmdText.isEmpty() || aCmdText[ aCmdText.getLength() - 1 ] != ' ' )
481 1196 : aCmdText.append(' ');
482 1658 : }
483 : /** Output text generated from the pNodes */
484 : OUStringBuffer aCmdText;
485 : };
486 :
487 : #endif /* SMVISITORS_H */
488 :
489 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|