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 : #ifndef SMVISITORS_H
29 : #define SMVISITORS_H
30 :
31 : #include "node.hxx"
32 : #include "caret.hxx"
33 :
34 : /** Base class for visitors that visits a tree of SmNodes
35 : * @remarks all methods have been left abstract to ensure that implementers
36 : * don't forget to implement one.
37 : */
38 2884 : class SmVisitor
39 : {
40 : public:
41 : virtual void Visit( SmTableNode* pNode ) = 0;
42 : virtual void Visit( SmBraceNode* pNode ) = 0;
43 : virtual void Visit( SmBracebodyNode* pNode ) = 0;
44 : virtual void Visit( SmOperNode* pNode ) = 0;
45 : virtual void Visit( SmAlignNode* pNode ) = 0;
46 : virtual void Visit( SmAttributNode* pNode ) = 0;
47 : virtual void Visit( SmFontNode* pNode ) = 0;
48 : virtual void Visit( SmUnHorNode* pNode ) = 0;
49 : virtual void Visit( SmBinHorNode* pNode ) = 0;
50 : virtual void Visit( SmBinVerNode* pNode ) = 0;
51 : virtual void Visit( SmBinDiagonalNode* pNode ) = 0;
52 : virtual void Visit( SmSubSupNode* pNode ) = 0;
53 : virtual void Visit( SmMatrixNode* pNode ) = 0;
54 : virtual void Visit( SmPlaceNode* pNode ) = 0;
55 : virtual void Visit( SmTextNode* pNode ) = 0;
56 : virtual void Visit( SmSpecialNode* pNode ) = 0;
57 : virtual void Visit( SmGlyphSpecialNode* pNode ) = 0;
58 : virtual void Visit( SmMathSymbolNode* pNode ) = 0;
59 : virtual void Visit( SmBlankNode* pNode ) = 0;
60 : virtual void Visit( SmErrorNode* pNode ) = 0;
61 : virtual void Visit( SmLineNode* pNode ) = 0;
62 : virtual void Visit( SmExpressionNode* pNode ) = 0;
63 : virtual void Visit( SmPolyLineNode* pNode ) = 0;
64 : virtual void Visit( SmRootNode* pNode ) = 0;
65 : virtual void Visit( SmRootSymbolNode* pNode ) = 0;
66 : virtual void Visit( SmRectangleNode* pNode ) = 0;
67 : virtual void Visit( SmVerticalBraceNode* pNode ) = 0;
68 :
69 : protected:
70 2884 : ~SmVisitor() {}
71 : };
72 :
73 : /** Simple visitor for testing SmVisitor */
74 : class SmVisitorTest : public SmVisitor
75 : {
76 : public:
77 0 : virtual ~SmVisitorTest() {}
78 : void Visit( SmTableNode* pNode );
79 : void Visit( SmBraceNode* pNode );
80 : void Visit( SmBracebodyNode* pNode );
81 : void Visit( SmOperNode* pNode );
82 : void Visit( SmAlignNode* pNode );
83 : void Visit( SmAttributNode* pNode );
84 : void Visit( SmFontNode* pNode );
85 : void Visit( SmUnHorNode* pNode );
86 : void Visit( SmBinHorNode* pNode );
87 : void Visit( SmBinVerNode* pNode );
88 : void Visit( SmBinDiagonalNode* pNode );
89 : void Visit( SmSubSupNode* pNode );
90 : void Visit( SmMatrixNode* pNode );
91 : void Visit( SmPlaceNode* pNode );
92 : void Visit( SmTextNode* pNode );
93 : void Visit( SmSpecialNode* pNode );
94 : void Visit( SmGlyphSpecialNode* pNode );
95 : void Visit( SmMathSymbolNode* pNode );
96 : void Visit( SmBlankNode* pNode );
97 : void Visit( SmErrorNode* pNode );
98 : void Visit( SmLineNode* pNode );
99 : void Visit( SmExpressionNode* pNode );
100 : void Visit( SmPolyLineNode* pNode );
101 : void Visit( SmRootNode* pNode );
102 : void Visit( SmRootSymbolNode* pNode );
103 : void Visit( SmRectangleNode* pNode );
104 : void Visit( SmVerticalBraceNode* pNode );
105 : private:
106 : /** Auxiliary method for visiting the children of a pNode */
107 : void VisitChildren( SmNode* pNode );
108 : };
109 :
110 : /////////////////////////////// SmDefaultingVisitor ////////////////////////////////
111 :
112 :
113 : /** Visitor that uses DefaultVisit for handling visits by default
114 : *
115 : * This abstract baseclass is useful for visitors where many methods share the same
116 : * implementation.
117 : */
118 33 : class SmDefaultingVisitor : public SmVisitor
119 : {
120 : public:
121 : void Visit( SmTableNode* pNode );
122 : void Visit( SmBraceNode* pNode );
123 : void Visit( SmBracebodyNode* pNode );
124 : void Visit( SmOperNode* pNode );
125 : void Visit( SmAlignNode* pNode );
126 : void Visit( SmAttributNode* pNode );
127 : void Visit( SmFontNode* pNode );
128 : void Visit( SmUnHorNode* pNode );
129 : void Visit( SmBinHorNode* pNode );
130 : void Visit( SmBinVerNode* pNode );
131 : void Visit( SmBinDiagonalNode* pNode );
132 : void Visit( SmSubSupNode* pNode );
133 : void Visit( SmMatrixNode* pNode );
134 : void Visit( SmPlaceNode* pNode );
135 : void Visit( SmTextNode* pNode );
136 : void Visit( SmSpecialNode* pNode );
137 : void Visit( SmGlyphSpecialNode* pNode );
138 : void Visit( SmMathSymbolNode* pNode );
139 : void Visit( SmBlankNode* pNode );
140 : void Visit( SmErrorNode* pNode );
141 : void Visit( SmLineNode* pNode );
142 : void Visit( SmExpressionNode* pNode );
143 : void Visit( SmPolyLineNode* pNode );
144 : void Visit( SmRootNode* pNode );
145 : void Visit( SmRootSymbolNode* pNode );
146 : void Visit( SmRectangleNode* pNode );
147 : void Visit( SmVerticalBraceNode* pNode );
148 : protected:
149 33 : ~SmDefaultingVisitor() {}
150 :
151 : /** Method invoked by Visit methods by default */
152 : virtual void DefaultVisit( SmNode* pNode ) = 0;
153 : };
154 :
155 : /////////////////////////////// SmCaretDrawingVisitor ////////////////////////////////
156 :
157 : /** Visitor for drawing a caret position */
158 : class SmCaretDrawingVisitor : public SmDefaultingVisitor
159 : {
160 : public:
161 : /** Given position and device this constructor will draw the caret */
162 : SmCaretDrawingVisitor( OutputDevice& rDevice, SmCaretPos position, Point offset, bool caretVisible );
163 0 : virtual ~SmCaretDrawingVisitor() {}
164 : void Visit( SmTextNode* pNode );
165 : using SmDefaultingVisitor::Visit;
166 : private:
167 : OutputDevice &rDev;
168 : SmCaretPos pos;
169 : /** Offset to draw from */
170 : Point Offset;
171 : bool isCaretVisible;
172 : protected:
173 : /** Default method for drawing pNodes */
174 : void DefaultVisit( SmNode* pNode );
175 : };
176 :
177 : /////////////////////////////// SmCaretPos2LineVisitor ////////////////////////////////
178 :
179 : /** Visitor getting a line from a caret position */
180 : class SmCaretPos2LineVisitor : public SmDefaultingVisitor
181 : {
182 : public:
183 : /** Given position and device this constructor will compute a line for the caret */
184 14 : SmCaretPos2LineVisitor( OutputDevice *pDevice, SmCaretPos position ) {
185 14 : pDev = pDevice;
186 14 : pos = position;
187 : OSL_ENSURE( position.IsValid( ), "Cannot draw invalid position!" );
188 :
189 14 : pos.pSelectedNode->Accept( this );
190 14 : }
191 14 : virtual ~SmCaretPos2LineVisitor() {}
192 : void Visit( SmTextNode* pNode );
193 : using SmDefaultingVisitor::Visit;
194 14 : SmCaretLine GetResult( ){
195 14 : return line;
196 : }
197 : private:
198 : SmCaretLine line;
199 : OutputDevice *pDev;
200 : SmCaretPos pos;
201 : protected:
202 : /** Default method for computing lines for pNodes */
203 : void DefaultVisit( SmNode* pNode );
204 : };
205 :
206 : /////////////////////////////// SmDrawingVisitor ////////////////////////////////
207 :
208 : /** Visitor for drawing SmNodes to OutputDevice */
209 : class SmDrawingVisitor : public SmVisitor
210 : {
211 : public:
212 : /** Create an instance of SmDrawingVisitor, and use it to draw a formula
213 : * @param rDevice Device to draw on
214 : * @param position Offset on device to draw the formula
215 : * @param pTree Formula tree to draw
216 : * @remarks This constructor will do the drawing, no need to anything more.
217 : */
218 2288 : SmDrawingVisitor( OutputDevice &rDevice, Point position, SmNode* pTree )
219 2288 : : rDev( rDevice ) {
220 2288 : this->Position = position;
221 2288 : pTree->Accept( this );
222 2288 : }
223 2288 : virtual ~SmDrawingVisitor() {}
224 : void Visit( SmTableNode* pNode );
225 : void Visit( SmBraceNode* pNode );
226 : void Visit( SmBracebodyNode* pNode );
227 : void Visit( SmOperNode* pNode );
228 : void Visit( SmAlignNode* pNode );
229 : void Visit( SmAttributNode* pNode );
230 : void Visit( SmFontNode* pNode );
231 : void Visit( SmUnHorNode* pNode );
232 : void Visit( SmBinHorNode* pNode );
233 : void Visit( SmBinVerNode* pNode );
234 : void Visit( SmBinDiagonalNode* pNode );
235 : void Visit( SmSubSupNode* pNode );
236 : void Visit( SmMatrixNode* pNode );
237 : void Visit( SmPlaceNode* pNode );
238 : void Visit( SmTextNode* pNode );
239 : void Visit( SmSpecialNode* pNode );
240 : void Visit( SmGlyphSpecialNode* pNode );
241 : void Visit( SmMathSymbolNode* pNode );
242 : void Visit( SmBlankNode* pNode );
243 : void Visit( SmErrorNode* pNode );
244 : void Visit( SmLineNode* pNode );
245 : void Visit( SmExpressionNode* pNode );
246 : void Visit( SmPolyLineNode* pNode );
247 : void Visit( SmRootNode* pNode );
248 : void Visit( SmRootSymbolNode* pNode );
249 : void Visit( SmRectangleNode* pNode );
250 : void Visit( SmVerticalBraceNode* pNode );
251 : private:
252 : /** Draw the children of a pNode
253 : * This the default method, use by most pNodes
254 : */
255 : void DrawChildren( SmNode* pNode );
256 :
257 : /** Draw an SmTextNode or a subclass of this */
258 : void DrawTextNode( SmTextNode* pNode );
259 : /** Draw an SmSpecialNode or a subclass of this */
260 : void DrawSpecialNode( SmSpecialNode* pNode );
261 : /** OutputDevice to draw on */
262 : OutputDevice& rDev;
263 : /** Position to draw on the rDev
264 : * @remarks This variable is used to pass parameters in DrawChildren( ), this means
265 : that after a call to DrawChildren( ) the contents of this method is undefined
266 : so if needed cache it locally on the stack.
267 : */
268 : Point Position;
269 : };
270 :
271 : /////////////////////////////// SmSetSelectionVisitor ////////////////////////////////
272 :
273 : /** Set Selection Visitor
274 : * Sets the IsSelected( ) property on all SmNodes of the tree
275 : */
276 : class SmSetSelectionVisitor : public SmDefaultingVisitor
277 : {
278 : public:
279 : SmSetSelectionVisitor( SmCaretPos startPos, SmCaretPos endPos, SmNode* pNode);
280 19 : virtual ~SmSetSelectionVisitor() {}
281 : void Visit( SmBinHorNode* pNode );
282 : void Visit( SmUnHorNode* pNode );
283 : void Visit( SmFontNode* pNode );
284 : void Visit( SmTextNode* pNode );
285 : void Visit( SmExpressionNode* pNode );
286 : void Visit( SmLineNode* pNode );
287 : void Visit( SmAlignNode* pNode );
288 : using SmDefaultingVisitor::Visit;
289 : /** Set IsSelected on all pNodes of pSubTree */
290 : static void SetSelectedOnAll( SmNode* pSubTree, bool IsSelected = true );
291 : private:
292 : /** Visit a selectable pNode
293 : * Can be used to handle pNodes that can be selected, that doesn't have more SmCaretPos'
294 : * than 0 and 1 inside them. SmTextNode should be handle seperately!
295 : * Also note that pNodes such as SmBinVerNode cannot be selected, don't this method for
296 : * it.
297 : */
298 : void DefaultVisit( SmNode* pNode );
299 : void VisitCompositionNode( SmNode* pNode );
300 : /** Caret position where the selection starts */
301 : SmCaretPos StartPos;
302 : /** Caret position where the selection ends */
303 : SmCaretPos EndPos;
304 : /** The current state of this visitor
305 : * This property changes when the visitor meets either StartPos
306 : * or EndPos. This means that anything visited in between will be
307 : * selected.
308 : */
309 : bool IsSelecting;
310 : };
311 :
312 :
313 : /////////////////////////////// SmCaretPosGraphBuildingVisitor ////////////////////////////////
314 :
315 :
316 : /** A visitor for building a SmCaretPosGraph
317 : *
318 : * Visit invariant:
319 : * Each pNode, except SmExpressionNode, SmBinHorNode and a few others, constitues an entry
320 : * in a line. Consider the line entry "H", this entry creates one carat position, here
321 : * denoted by | in "H|".
322 : *
323 : * Parameter variables:
324 : * The following variables are used to transfer parameters in to calls and results out
325 : * of calls.
326 : * pRightMost : SmCaretPosGraphEntry*
327 : *
328 : * Prior to a Visit call:
329 : * pRightMost: A pointer to right most position in front of the current line entry.
330 : *
331 : * After a Visit call:
332 : * pRightMost: A pointer to the right most position in the called line entry, if no there's
333 : * no caret positions in called line entry don't change this variable.
334 : */
335 : class SmCaretPosGraphBuildingVisitor : public SmVisitor
336 : {
337 : public:
338 : /** Builds a caret position graph for pRootNode */
339 : SmCaretPosGraphBuildingVisitor( SmNode* pRootNode );
340 20 : virtual ~SmCaretPosGraphBuildingVisitor() {}
341 : void Visit( SmTableNode* pNode );
342 : void Visit( SmBraceNode* pNode );
343 : void Visit( SmBracebodyNode* pNode );
344 : void Visit( SmOperNode* pNode );
345 : void Visit( SmAlignNode* pNode );
346 : void Visit( SmAttributNode* pNode );
347 : void Visit( SmFontNode* pNode );
348 : void Visit( SmUnHorNode* pNode );
349 : void Visit( SmBinHorNode* pNode );
350 : void Visit( SmBinVerNode* pNode );
351 : void Visit( SmBinDiagonalNode* pNode );
352 : void Visit( SmSubSupNode* pNode );
353 : void Visit( SmMatrixNode* pNode );
354 : void Visit( SmPlaceNode* pNode );
355 : void Visit( SmTextNode* pNode );
356 : void Visit( SmSpecialNode* pNode );
357 : void Visit( SmGlyphSpecialNode* pNode );
358 : void Visit( SmMathSymbolNode* pNode );
359 : void Visit( SmBlankNode* pNode );
360 : void Visit( SmErrorNode* pNode );
361 : void Visit( SmLineNode* pNode );
362 : void Visit( SmExpressionNode* pNode );
363 : void Visit( SmPolyLineNode* pNode );
364 : void Visit( SmRootNode* pNode );
365 : void Visit( SmRootSymbolNode* pNode );
366 : void Visit( SmRectangleNode* pNode );
367 : void Visit( SmVerticalBraceNode* pNode );
368 20 : SmCaretPosGraph* Graph( ){
369 20 : return pGraph;
370 : }
371 : private:
372 : SmCaretPosGraphEntry* pRightMost;
373 : SmCaretPosGraph* pGraph;
374 : };
375 :
376 : /////////////////////////////// SmCloningVisitor ///////////////////////////////
377 :
378 : /** Visitor for cloning a pNode
379 : *
380 : * This visitor creates deep clones.
381 : */
382 : class SmCloningVisitor : public SmVisitor
383 : {
384 : public:
385 0 : SmCloningVisitor( ){ pResult = NULL; }
386 0 : virtual ~SmCloningVisitor() {}
387 : void Visit( SmTableNode* pNode );
388 : void Visit( SmBraceNode* pNode );
389 : void Visit( SmBracebodyNode* pNode );
390 : void Visit( SmOperNode* pNode );
391 : void Visit( SmAlignNode* pNode );
392 : void Visit( SmAttributNode* pNode );
393 : void Visit( SmFontNode* pNode );
394 : void Visit( SmUnHorNode* pNode );
395 : void Visit( SmBinHorNode* pNode );
396 : void Visit( SmBinVerNode* pNode );
397 : void Visit( SmBinDiagonalNode* pNode );
398 : void Visit( SmSubSupNode* pNode );
399 : void Visit( SmMatrixNode* pNode );
400 : void Visit( SmPlaceNode* pNode );
401 : void Visit( SmTextNode* pNode );
402 : void Visit( SmSpecialNode* pNode );
403 : void Visit( SmGlyphSpecialNode* pNode );
404 : void Visit( SmMathSymbolNode* pNode );
405 : void Visit( SmBlankNode* pNode );
406 : void Visit( SmErrorNode* pNode );
407 : void Visit( SmLineNode* pNode );
408 : void Visit( SmExpressionNode* pNode );
409 : void Visit( SmPolyLineNode* pNode );
410 : void Visit( SmRootNode* pNode );
411 : void Visit( SmRootSymbolNode* pNode );
412 : void Visit( SmRectangleNode* pNode );
413 : void Visit( SmVerticalBraceNode* pNode );
414 : /** Clone a pNode */
415 : SmNode* Clone( SmNode* pNode );
416 : private:
417 : SmNode* pResult;
418 : /** Clone children of pSource and give them to pTarget */
419 : void CloneKids( SmStructureNode* pSource, SmStructureNode* pTarget );
420 : /** Clone attributes on a pNode */
421 : void CloneNodeAttr( SmNode* pSource, SmNode* pTarget );
422 : };
423 :
424 :
425 : /////////////////////////////// SmSelectionDrawingVisitor ///////////////////////////////
426 :
427 : class SmSelectionDrawingVisitor : public SmDefaultingVisitor
428 : {
429 : public:
430 : /** Draws a selection on rDevice for the selection on pTree */
431 : SmSelectionDrawingVisitor( OutputDevice& rDevice, SmNode* pTree, Point Offset );
432 0 : virtual ~SmSelectionDrawingVisitor() {}
433 : void Visit( SmTextNode* pNode );
434 : using SmDefaultingVisitor::Visit;
435 : private:
436 : /** Reference to drawing device */
437 : OutputDevice& rDev;
438 : /** True if aSelectionArea have been initialized */
439 : bool bHasSelectionArea;
440 : /** The current area that is selected */
441 : Rectangle aSelectionArea;
442 : /** Extend the area that must be selected */
443 : void ExtendSelectionArea( Rectangle aArea );
444 : /** Default visiting method */
445 : void DefaultVisit( SmNode* pNode );
446 : /** Visit the children of a given pNode */
447 : void VisitChildren( SmNode* pNode );
448 : };
449 :
450 : /////////////////////////////// SmNodeToTextVisitor ///////////////////////////////
451 :
452 : /** Extract command text from pNodes */
453 : class SmNodeToTextVisitor : public SmVisitor
454 : {
455 : public:
456 : SmNodeToTextVisitor( SmNode* pNode, OUString &rText );
457 543 : virtual ~SmNodeToTextVisitor() {}
458 :
459 : void Visit( SmTableNode* pNode );
460 : void Visit( SmBraceNode* pNode );
461 : void Visit( SmBracebodyNode* pNode );
462 : void Visit( SmOperNode* pNode );
463 : void Visit( SmAlignNode* pNode );
464 : void Visit( SmAttributNode* pNode );
465 : void Visit( SmFontNode* pNode );
466 : void Visit( SmUnHorNode* pNode );
467 : void Visit( SmBinHorNode* pNode );
468 : void Visit( SmBinVerNode* pNode );
469 : void Visit( SmBinDiagonalNode* pNode );
470 : void Visit( SmSubSupNode* pNode );
471 : void Visit( SmMatrixNode* pNode );
472 : void Visit( SmPlaceNode* pNode );
473 : void Visit( SmTextNode* pNode );
474 : void Visit( SmSpecialNode* pNode );
475 : void Visit( SmGlyphSpecialNode* pNode );
476 : void Visit( SmMathSymbolNode* pNode );
477 : void Visit( SmBlankNode* pNode );
478 : void Visit( SmErrorNode* pNode );
479 : void Visit( SmLineNode* pNode );
480 : void Visit( SmExpressionNode* pNode );
481 : void Visit( SmPolyLineNode* pNode );
482 : void Visit( SmRootNode* pNode );
483 : void Visit( SmRootSymbolNode* pNode );
484 : void Visit( SmRectangleNode* pNode );
485 : void Visit( SmVerticalBraceNode* pNode );
486 : private:
487 : /** Extract text from a pNode that constitues a line */
488 272 : void LineToText( SmNode* pNode ) {
489 272 : Separate( );
490 272 : if( pNode )
491 272 : pNode->Accept( this );
492 272 : Separate( );
493 272 : }
494 1875 : void Append( const OUString &rText ) {
495 1875 : aCmdText.append( rText );
496 1875 : }
497 : /** Append a blank for separation, if needed */
498 2394 : inline void Separate( ){
499 2394 : if( !aCmdText.getLength() || aCmdText[ aCmdText.getLength() - 1 ] != ' ' )
500 1356 : aCmdText.append(' ');
501 2394 : }
502 : /** Output text generated from the pNodes */
503 : OUStringBuffer aCmdText;
504 : };
505 :
506 : #endif /* SMVISITORS_H */
507 :
508 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|