bump product version to 5.0.4.1
[LibreOffice.git] / starmath / inc / visitors.hxx
blob25b4d17e9dc081115a793c0484f5432f7e511d43
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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/.
8 */
9 #ifndef INCLUDED_STARMATH_INC_VISITORS_HXX
10 #define INCLUDED_STARMATH_INC_VISITORS_HXX
12 #include <sal/config.h>
14 #include <sal/log.hxx>
16 #include "node.hxx"
17 #include "caret.hxx"
18 #include <memory>
20 /** Base class for visitors that visits a tree of SmNodes
21 * @remarks all methods have been left abstract to ensure that implementers
22 * don't forget to implement one.
24 class SmVisitor
26 public:
27 virtual void Visit( SmTableNode* pNode ) = 0;
28 virtual void Visit( SmBraceNode* pNode ) = 0;
29 virtual void Visit( SmBracebodyNode* pNode ) = 0;
30 virtual void Visit( SmOperNode* pNode ) = 0;
31 virtual void Visit( SmAlignNode* pNode ) = 0;
32 virtual void Visit( SmAttributNode* pNode ) = 0;
33 virtual void Visit( SmFontNode* pNode ) = 0;
34 virtual void Visit( SmUnHorNode* pNode ) = 0;
35 virtual void Visit( SmBinHorNode* pNode ) = 0;
36 virtual void Visit( SmBinVerNode* pNode ) = 0;
37 virtual void Visit( SmBinDiagonalNode* pNode ) = 0;
38 virtual void Visit( SmSubSupNode* pNode ) = 0;
39 virtual void Visit( SmMatrixNode* pNode ) = 0;
40 virtual void Visit( SmPlaceNode* pNode ) = 0;
41 virtual void Visit( SmTextNode* pNode ) = 0;
42 virtual void Visit( SmSpecialNode* pNode ) = 0;
43 virtual void Visit( SmGlyphSpecialNode* pNode ) = 0;
44 virtual void Visit( SmMathSymbolNode* pNode ) = 0;
45 virtual void Visit( SmBlankNode* pNode ) = 0;
46 virtual void Visit( SmErrorNode* pNode ) = 0;
47 virtual void Visit( SmLineNode* pNode ) = 0;
48 virtual void Visit( SmExpressionNode* pNode ) = 0;
49 virtual void Visit( SmPolyLineNode* pNode ) = 0;
50 virtual void Visit( SmDynIntegralNode* pNode ) = 0;
51 virtual void Visit( SmDynIntegralSymbolNode* pNode ) = 0;
52 virtual void Visit( SmRootNode* pNode ) = 0;
53 virtual void Visit( SmRootSymbolNode* pNode ) = 0;
54 virtual void Visit( SmRectangleNode* pNode ) = 0;
55 virtual void Visit( SmVerticalBraceNode* pNode ) = 0;
57 protected:
58 ~SmVisitor() {}
61 // SmDefaultingVisitor
64 /** Visitor that uses DefaultVisit for handling visits by default
66 * This abstract baseclass is useful for visitors where many methods share the same
67 * implementation.
69 class SmDefaultingVisitor : public SmVisitor
71 public:
72 void Visit( SmTableNode* pNode ) SAL_OVERRIDE;
73 void Visit( SmBraceNode* pNode ) SAL_OVERRIDE;
74 void Visit( SmBracebodyNode* pNode ) SAL_OVERRIDE;
75 void Visit( SmOperNode* pNode ) SAL_OVERRIDE;
76 void Visit( SmAlignNode* pNode ) SAL_OVERRIDE;
77 void Visit( SmAttributNode* pNode ) SAL_OVERRIDE;
78 void Visit( SmFontNode* pNode ) SAL_OVERRIDE;
79 void Visit( SmUnHorNode* pNode ) SAL_OVERRIDE;
80 void Visit( SmBinHorNode* pNode ) SAL_OVERRIDE;
81 void Visit( SmBinVerNode* pNode ) SAL_OVERRIDE;
82 void Visit( SmBinDiagonalNode* pNode ) SAL_OVERRIDE;
83 void Visit( SmSubSupNode* pNode ) SAL_OVERRIDE;
84 void Visit( SmMatrixNode* pNode ) SAL_OVERRIDE;
85 void Visit( SmPlaceNode* pNode ) SAL_OVERRIDE;
86 void Visit( SmTextNode* pNode ) SAL_OVERRIDE;
87 void Visit( SmSpecialNode* pNode ) SAL_OVERRIDE;
88 void Visit( SmGlyphSpecialNode* pNode ) SAL_OVERRIDE;
89 void Visit( SmMathSymbolNode* pNode ) SAL_OVERRIDE;
90 void Visit( SmBlankNode* pNode ) SAL_OVERRIDE;
91 void Visit( SmErrorNode* pNode ) SAL_OVERRIDE;
92 void Visit( SmLineNode* pNode ) SAL_OVERRIDE;
93 void Visit( SmExpressionNode* pNode ) SAL_OVERRIDE;
94 void Visit( SmPolyLineNode* pNode ) SAL_OVERRIDE;
95 void Visit( SmRootNode* pNode ) SAL_OVERRIDE;
96 void Visit( SmRootSymbolNode* pNode ) SAL_OVERRIDE;
97 void Visit( SmDynIntegralNode* pNode ) SAL_OVERRIDE;
98 void Visit( SmDynIntegralSymbolNode* pNode ) SAL_OVERRIDE;
99 void Visit( SmRectangleNode* pNode ) SAL_OVERRIDE;
100 void Visit( SmVerticalBraceNode* pNode ) SAL_OVERRIDE;
101 protected:
102 ~SmDefaultingVisitor() {}
104 /** Method invoked by Visit methods by default */
105 virtual void DefaultVisit( SmNode* pNode ) = 0;
108 // SmCaretDrawingVisitor
110 /** Visitor for drawing a caret position */
111 class SmCaretDrawingVisitor : public SmDefaultingVisitor
113 public:
114 /** Given position and device this constructor will draw the caret */
115 SmCaretDrawingVisitor( OutputDevice& rDevice, SmCaretPos position, Point offset, bool caretVisible );
116 virtual ~SmCaretDrawingVisitor() {}
117 void Visit( SmTextNode* pNode ) SAL_OVERRIDE;
118 using SmDefaultingVisitor::Visit;
119 private:
120 OutputDevice &rDev;
121 SmCaretPos pos;
122 /** Offset to draw from */
123 Point Offset;
124 bool isCaretVisible;
125 protected:
126 /** Default method for drawing pNodes */
127 void DefaultVisit( SmNode* pNode ) SAL_OVERRIDE;
130 // SmCaretPos2LineVisitor
132 /** Visitor getting a line from a caret position */
133 class SmCaretPos2LineVisitor : public SmDefaultingVisitor
135 public:
136 /** Given position and device this constructor will compute a line for the caret */
137 SmCaretPos2LineVisitor( OutputDevice *pDevice, SmCaretPos position ) {
138 pDev = pDevice;
139 pos = position;
140 SAL_WARN_IF( !position.IsValid(), "starmath", "Cannot draw invalid position!" );
142 pos.pSelectedNode->Accept( this );
144 virtual ~SmCaretPos2LineVisitor() {}
145 void Visit( SmTextNode* pNode ) SAL_OVERRIDE;
146 using SmDefaultingVisitor::Visit;
147 SmCaretLine GetResult( ){
148 return line;
150 private:
151 SmCaretLine line;
152 VclPtr<OutputDevice> pDev;
153 SmCaretPos pos;
154 protected:
155 /** Default method for computing lines for pNodes */
156 void DefaultVisit( SmNode* pNode ) SAL_OVERRIDE;
159 // SmDrawingVisitor
161 /** Visitor for drawing SmNodes to OutputDevice */
162 class SmDrawingVisitor : public SmVisitor
164 public:
165 /** Create an instance of SmDrawingVisitor, and use it to draw a formula
166 * @param rDevice Device to draw on
167 * @param position Offset on device to draw the formula
168 * @param pTree Formula tree to draw
169 * @remarks This constructor will do the drawing, no need to anything more.
171 SmDrawingVisitor( OutputDevice &rDevice, Point position, SmNode* pTree )
172 : rDev( rDevice ) {
173 this->Position = position;
174 pTree->Accept( this );
176 virtual ~SmDrawingVisitor() {}
177 void Visit( SmTableNode* pNode ) SAL_OVERRIDE;
178 void Visit( SmBraceNode* pNode ) SAL_OVERRIDE;
179 void Visit( SmBracebodyNode* pNode ) SAL_OVERRIDE;
180 void Visit( SmOperNode* pNode ) SAL_OVERRIDE;
181 void Visit( SmAlignNode* pNode ) SAL_OVERRIDE;
182 void Visit( SmAttributNode* pNode ) SAL_OVERRIDE;
183 void Visit( SmFontNode* pNode ) SAL_OVERRIDE;
184 void Visit( SmUnHorNode* pNode ) SAL_OVERRIDE;
185 void Visit( SmBinHorNode* pNode ) SAL_OVERRIDE;
186 void Visit( SmBinVerNode* pNode ) SAL_OVERRIDE;
187 void Visit( SmBinDiagonalNode* pNode ) SAL_OVERRIDE;
188 void Visit( SmSubSupNode* pNode ) SAL_OVERRIDE;
189 void Visit( SmMatrixNode* pNode ) SAL_OVERRIDE;
190 void Visit( SmPlaceNode* pNode ) SAL_OVERRIDE;
191 void Visit( SmTextNode* pNode ) SAL_OVERRIDE;
192 void Visit( SmSpecialNode* pNode ) SAL_OVERRIDE;
193 void Visit( SmGlyphSpecialNode* pNode ) SAL_OVERRIDE;
194 void Visit( SmMathSymbolNode* pNode ) SAL_OVERRIDE;
195 void Visit( SmBlankNode* pNode ) SAL_OVERRIDE;
196 void Visit( SmErrorNode* pNode ) SAL_OVERRIDE;
197 void Visit( SmLineNode* pNode ) SAL_OVERRIDE;
198 void Visit( SmExpressionNode* pNode ) SAL_OVERRIDE;
199 void Visit( SmPolyLineNode* pNode ) SAL_OVERRIDE;
200 void Visit( SmRootNode* pNode ) SAL_OVERRIDE;
201 void Visit( SmRootSymbolNode* pNode ) SAL_OVERRIDE;
202 void Visit( SmDynIntegralNode* pNode ) SAL_OVERRIDE;
203 void Visit( SmDynIntegralSymbolNode* pNode ) SAL_OVERRIDE;
204 void Visit( SmRectangleNode* pNode ) SAL_OVERRIDE;
205 void Visit( SmVerticalBraceNode* pNode ) SAL_OVERRIDE;
206 private:
207 /** Draw the children of a pNode
208 * This the default method, use by most pNodes
210 void DrawChildren( SmNode* pNode );
212 /** Draw an SmTextNode or a subclass of this */
213 void DrawTextNode( SmTextNode* pNode );
214 /** Draw an SmSpecialNode or a subclass of this */
215 void DrawSpecialNode( SmSpecialNode* pNode );
216 /** OutputDevice to draw on */
217 OutputDevice& rDev;
218 /** Position to draw on the rDev
219 * @remarks This variable is used to pass parameters in DrawChildren( ), this means
220 that after a call to DrawChildren( ) the contents of this method is undefined
221 so if needed cache it locally on the stack.
223 Point Position;
226 // SmSetSelectionVisitor
228 /** Set Selection Visitor
229 * Sets the IsSelected( ) property on all SmNodes of the tree
231 class SmSetSelectionVisitor : public SmDefaultingVisitor
233 public:
234 SmSetSelectionVisitor( SmCaretPos startPos, SmCaretPos endPos, SmNode* pNode);
235 virtual ~SmSetSelectionVisitor() {}
236 void Visit( SmBinHorNode* pNode ) SAL_OVERRIDE;
237 void Visit( SmUnHorNode* pNode ) SAL_OVERRIDE;
238 void Visit( SmFontNode* pNode ) SAL_OVERRIDE;
239 void Visit( SmTextNode* pNode ) SAL_OVERRIDE;
240 void Visit( SmExpressionNode* pNode ) SAL_OVERRIDE;
241 void Visit( SmLineNode* pNode ) SAL_OVERRIDE;
242 void Visit( SmAlignNode* pNode ) SAL_OVERRIDE;
243 using SmDefaultingVisitor::Visit;
244 /** Set IsSelected on all pNodes of pSubTree */
245 static void SetSelectedOnAll( SmNode* pSubTree, bool IsSelected = true );
246 private:
247 /** Visit a selectable pNode
248 * Can be used to handle pNodes that can be selected, that doesn't have more SmCaretPos'
249 * than 0 and 1 inside them. SmTextNode should be handle separately!
250 * Also note that pNodes such as SmBinVerNode cannot be selected, don't this method for
251 * it.
253 void DefaultVisit( SmNode* pNode ) SAL_OVERRIDE;
254 void VisitCompositionNode( SmNode* pNode );
255 /** Caret position where the selection starts */
256 SmCaretPos StartPos;
257 /** Caret position where the selection ends */
258 SmCaretPos EndPos;
259 /** The current state of this visitor
260 * This property changes when the visitor meets either StartPos
261 * or EndPos. This means that anything visited in between will be
262 * selected.
264 bool IsSelecting;
268 // SmCaretPosGraphBuildingVisitor
271 /** A visitor for building a SmCaretPosGraph
273 * Visit invariant:
274 * Each pNode, except SmExpressionNode, SmBinHorNode and a few others, constitutes an entry
275 * in a line. Consider the line entry "H", this entry creates one carat position, here
276 * denoted by | in "H|".
278 * Parameter variables:
279 * The following variables are used to transfer parameters in to calls and results out
280 * of calls.
281 * pRightMost : SmCaretPosGraphEntry*
283 * Prior to a Visit call:
284 * pRightMost: A pointer to right most position in front of the current line entry.
286 * After a Visit call:
287 * pRightMost: A pointer to the right most position in the called line entry, if no there's
288 * no caret positions in called line entry don't change this variable.
290 class SmCaretPosGraphBuildingVisitor : public SmVisitor
292 public:
293 /** Builds a caret position graph for pRootNode */
294 SmCaretPosGraphBuildingVisitor( SmNode* pRootNode );
295 virtual ~SmCaretPosGraphBuildingVisitor();
296 void Visit( SmTableNode* pNode ) SAL_OVERRIDE;
297 void Visit( SmBraceNode* pNode ) SAL_OVERRIDE;
298 void Visit( SmBracebodyNode* pNode ) SAL_OVERRIDE;
299 void Visit( SmOperNode* pNode ) SAL_OVERRIDE;
300 void Visit( SmAlignNode* pNode ) SAL_OVERRIDE;
301 void Visit( SmAttributNode* pNode ) SAL_OVERRIDE;
302 void Visit( SmFontNode* pNode ) SAL_OVERRIDE;
303 void Visit( SmUnHorNode* pNode ) SAL_OVERRIDE;
304 void Visit( SmBinHorNode* pNode ) SAL_OVERRIDE;
305 void Visit( SmBinVerNode* pNode ) SAL_OVERRIDE;
306 void Visit( SmBinDiagonalNode* pNode ) SAL_OVERRIDE;
307 void Visit( SmSubSupNode* pNode ) SAL_OVERRIDE;
308 void Visit( SmMatrixNode* pNode ) SAL_OVERRIDE;
309 void Visit( SmPlaceNode* pNode ) SAL_OVERRIDE;
310 void Visit( SmTextNode* pNode ) SAL_OVERRIDE;
311 void Visit( SmSpecialNode* pNode ) SAL_OVERRIDE;
312 void Visit( SmGlyphSpecialNode* pNode ) SAL_OVERRIDE;
313 void Visit( SmMathSymbolNode* pNode ) SAL_OVERRIDE;
314 void Visit( SmBlankNode* pNode ) SAL_OVERRIDE;
315 void Visit( SmErrorNode* pNode ) SAL_OVERRIDE;
316 void Visit( SmLineNode* pNode ) SAL_OVERRIDE;
317 void Visit( SmExpressionNode* pNode ) SAL_OVERRIDE;
318 void Visit( SmPolyLineNode* pNode ) SAL_OVERRIDE;
319 void Visit( SmRootNode* pNode ) SAL_OVERRIDE;
320 void Visit( SmRootSymbolNode* pNode ) SAL_OVERRIDE;
321 void Visit( SmDynIntegralNode* pNode ) SAL_OVERRIDE;
322 void Visit( SmDynIntegralSymbolNode* pNode ) SAL_OVERRIDE;
323 void Visit( SmRectangleNode* pNode ) SAL_OVERRIDE;
324 void Visit( SmVerticalBraceNode* pNode ) SAL_OVERRIDE;
325 SmCaretPosGraph* takeGraph()
327 return mpGraph.release();
329 private:
330 SmCaretPosGraphEntry* mpRightMost;
331 std::unique_ptr<SmCaretPosGraph> mpGraph;
334 // SmCloningVisitor
336 /** Visitor for cloning a pNode
338 * This visitor creates deep clones.
340 class SmCloningVisitor : public SmVisitor
342 public:
343 SmCloningVisitor( ){ pResult = NULL; }
344 virtual ~SmCloningVisitor() {}
345 void Visit( SmTableNode* pNode ) SAL_OVERRIDE;
346 void Visit( SmBraceNode* pNode ) SAL_OVERRIDE;
347 void Visit( SmBracebodyNode* pNode ) SAL_OVERRIDE;
348 void Visit( SmOperNode* pNode ) SAL_OVERRIDE;
349 void Visit( SmAlignNode* pNode ) SAL_OVERRIDE;
350 void Visit( SmAttributNode* pNode ) SAL_OVERRIDE;
351 void Visit( SmFontNode* pNode ) SAL_OVERRIDE;
352 void Visit( SmUnHorNode* pNode ) SAL_OVERRIDE;
353 void Visit( SmBinHorNode* pNode ) SAL_OVERRIDE;
354 void Visit( SmBinVerNode* pNode ) SAL_OVERRIDE;
355 void Visit( SmBinDiagonalNode* pNode ) SAL_OVERRIDE;
356 void Visit( SmSubSupNode* pNode ) SAL_OVERRIDE;
357 void Visit( SmMatrixNode* pNode ) SAL_OVERRIDE;
358 void Visit( SmPlaceNode* pNode ) SAL_OVERRIDE;
359 void Visit( SmTextNode* pNode ) SAL_OVERRIDE;
360 void Visit( SmSpecialNode* pNode ) SAL_OVERRIDE;
361 void Visit( SmGlyphSpecialNode* pNode ) SAL_OVERRIDE;
362 void Visit( SmMathSymbolNode* pNode ) SAL_OVERRIDE;
363 void Visit( SmBlankNode* pNode ) SAL_OVERRIDE;
364 void Visit( SmErrorNode* pNode ) SAL_OVERRIDE;
365 void Visit( SmLineNode* pNode ) SAL_OVERRIDE;
366 void Visit( SmExpressionNode* pNode ) SAL_OVERRIDE;
367 void Visit( SmPolyLineNode* pNode ) SAL_OVERRIDE;
368 void Visit( SmRootNode* pNode ) SAL_OVERRIDE;
369 void Visit( SmRootSymbolNode* pNode ) SAL_OVERRIDE;
370 void Visit( SmDynIntegralNode* pNode ) SAL_OVERRIDE;
371 void Visit( SmDynIntegralSymbolNode* pNode ) SAL_OVERRIDE;
372 void Visit( SmRectangleNode* pNode ) SAL_OVERRIDE;
373 void Visit( SmVerticalBraceNode* pNode ) SAL_OVERRIDE;
374 /** Clone a pNode */
375 SmNode* Clone( SmNode* pNode );
376 private:
377 SmNode* pResult;
378 /** Clone children of pSource and give them to pTarget */
379 void CloneKids( SmStructureNode* pSource, SmStructureNode* pTarget );
380 /** Clone attributes on a pNode */
381 static void CloneNodeAttr( SmNode* pSource, SmNode* pTarget );
385 // SmSelectionDrawingVisitor
387 class SmSelectionDrawingVisitor : public SmDefaultingVisitor
389 public:
390 /** Draws a selection on rDevice for the selection on pTree */
391 SmSelectionDrawingVisitor( OutputDevice& rDevice, SmNode* pTree, Point Offset );
392 virtual ~SmSelectionDrawingVisitor() {}
393 void Visit( SmTextNode* pNode ) SAL_OVERRIDE;
394 using SmDefaultingVisitor::Visit;
395 private:
396 /** Reference to drawing device */
397 OutputDevice& rDev;
398 /** True if aSelectionArea have been initialized */
399 bool bHasSelectionArea;
400 /** The current area that is selected */
401 Rectangle aSelectionArea;
402 /** Extend the area that must be selected */
403 void ExtendSelectionArea(const Rectangle& rArea);
404 /** Default visiting method */
405 void DefaultVisit( SmNode* pNode ) SAL_OVERRIDE;
406 /** Visit the children of a given pNode */
407 void VisitChildren( SmNode* pNode );
410 // SmNodeToTextVisitor
412 /** Extract command text from pNodes */
413 class SmNodeToTextVisitor : public SmVisitor
415 public:
416 SmNodeToTextVisitor( SmNode* pNode, OUString &rText );
417 virtual ~SmNodeToTextVisitor() {}
419 void Visit( SmTableNode* pNode ) SAL_OVERRIDE;
420 void Visit( SmBraceNode* pNode ) SAL_OVERRIDE;
421 void Visit( SmBracebodyNode* pNode ) SAL_OVERRIDE;
422 void Visit( SmOperNode* pNode ) SAL_OVERRIDE;
423 void Visit( SmAlignNode* pNode ) SAL_OVERRIDE;
424 void Visit( SmAttributNode* pNode ) SAL_OVERRIDE;
425 void Visit( SmFontNode* pNode ) SAL_OVERRIDE;
426 void Visit( SmUnHorNode* pNode ) SAL_OVERRIDE;
427 void Visit( SmBinHorNode* pNode ) SAL_OVERRIDE;
428 void Visit( SmBinVerNode* pNode ) SAL_OVERRIDE;
429 void Visit( SmBinDiagonalNode* pNode ) SAL_OVERRIDE;
430 void Visit( SmSubSupNode* pNode ) SAL_OVERRIDE;
431 void Visit( SmMatrixNode* pNode ) SAL_OVERRIDE;
432 void Visit( SmPlaceNode* pNode ) SAL_OVERRIDE;
433 void Visit( SmTextNode* pNode ) SAL_OVERRIDE;
434 void Visit( SmSpecialNode* pNode ) SAL_OVERRIDE;
435 void Visit( SmGlyphSpecialNode* pNode ) SAL_OVERRIDE;
436 void Visit( SmMathSymbolNode* pNode ) SAL_OVERRIDE;
437 void Visit( SmBlankNode* pNode ) SAL_OVERRIDE;
438 void Visit( SmErrorNode* pNode ) SAL_OVERRIDE;
439 void Visit( SmLineNode* pNode ) SAL_OVERRIDE;
440 void Visit( SmExpressionNode* pNode ) SAL_OVERRIDE;
441 void Visit( SmPolyLineNode* pNode ) SAL_OVERRIDE;
442 void Visit( SmRootNode* pNode ) SAL_OVERRIDE;
443 void Visit( SmRootSymbolNode* pNode ) SAL_OVERRIDE;
444 void Visit( SmDynIntegralNode* pNode ) SAL_OVERRIDE;
445 void Visit( SmDynIntegralSymbolNode* pNode ) SAL_OVERRIDE;
446 void Visit( SmRectangleNode* pNode ) SAL_OVERRIDE;
447 void Visit( SmVerticalBraceNode* pNode ) SAL_OVERRIDE;
448 private:
449 /** Extract text from a pNode that constitutes a line */
450 void LineToText( SmNode* pNode ) {
451 Separate( );
452 if( pNode )
453 pNode->Accept( this );
454 Separate( );
456 void Append( const OUString &rText ) {
457 aCmdText.append( rText );
459 /** Append a blank for separation, if needed */
460 inline void Separate( ){
461 if( aCmdText.isEmpty() || aCmdText[ aCmdText.getLength() - 1 ] != ' ' )
462 aCmdText.append(' ');
464 /** Output text generated from the pNodes */
465 OUStringBuffer aCmdText;
468 #endif // INCLUDED_STARMATH_INC_VISITORS_HXX
470 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */