Version 6.1.4.1, tag libreoffice-6.1.4.1
[LibreOffice.git] / starmath / inc / visitors.hxx
blob6f3b17e733c60fa100887b34d054269c3051dabf
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( SmRootNode* pNode ) = 0;
51 virtual void Visit( SmRootSymbolNode* pNode ) = 0;
52 virtual void Visit( SmRectangleNode* pNode ) = 0;
53 virtual void Visit( SmVerticalBraceNode* pNode ) = 0;
55 protected:
56 ~SmVisitor() {}
59 // SmDefaultingVisitor
62 /** Visitor that uses DefaultVisit for handling visits by default
64 * This abstract baseclass is useful for visitors where many methods share the same
65 * implementation.
67 class SmDefaultingVisitor : public SmVisitor
69 public:
70 void Visit( SmTableNode* pNode ) override;
71 void Visit( SmBraceNode* pNode ) override;
72 void Visit( SmBracebodyNode* pNode ) override;
73 void Visit( SmOperNode* pNode ) override;
74 void Visit( SmAlignNode* pNode ) override;
75 void Visit( SmAttributNode* pNode ) override;
76 void Visit( SmFontNode* pNode ) override;
77 void Visit( SmUnHorNode* pNode ) override;
78 void Visit( SmBinHorNode* pNode ) override;
79 void Visit( SmBinVerNode* pNode ) override;
80 void Visit( SmBinDiagonalNode* pNode ) override;
81 void Visit( SmSubSupNode* pNode ) override;
82 void Visit( SmMatrixNode* pNode ) override;
83 void Visit( SmPlaceNode* pNode ) override;
84 void Visit( SmTextNode* pNode ) override;
85 void Visit( SmSpecialNode* pNode ) override;
86 void Visit( SmGlyphSpecialNode* pNode ) override;
87 void Visit( SmMathSymbolNode* pNode ) override;
88 void Visit( SmBlankNode* pNode ) override;
89 void Visit( SmErrorNode* pNode ) override;
90 void Visit( SmLineNode* pNode ) override;
91 void Visit( SmExpressionNode* pNode ) override;
92 void Visit( SmPolyLineNode* pNode ) override;
93 void Visit( SmRootNode* pNode ) override;
94 void Visit( SmRootSymbolNode* pNode ) override;
95 void Visit( SmRectangleNode* pNode ) override;
96 void Visit( SmVerticalBraceNode* pNode ) override;
97 protected:
98 ~SmDefaultingVisitor() {}
100 /** Method invoked by Visit methods by default */
101 virtual void DefaultVisit( SmNode* pNode ) = 0;
104 // SmCaretDrawingVisitor
106 /** Visitor for drawing a caret position */
107 class SmCaretDrawingVisitor : public SmDefaultingVisitor
109 public:
110 /** Given position and device this constructor will draw the caret */
111 SmCaretDrawingVisitor( OutputDevice& rDevice, SmCaretPos position, Point offset, bool caretVisible );
112 virtual ~SmCaretDrawingVisitor() {}
113 void Visit( SmTextNode* pNode ) override;
114 using SmDefaultingVisitor::Visit;
115 private:
116 OutputDevice &mrDev;
117 SmCaretPos maPos;
118 /** Offset to draw from */
119 Point maOffset;
120 bool mbCaretVisible;
121 protected:
122 /** Default method for drawing pNodes */
123 void DefaultVisit( SmNode* pNode ) override;
126 // SmCaretPos2LineVisitor
128 /** Visitor getting a line from a caret position */
129 class SmCaretPos2LineVisitor : public SmDefaultingVisitor
131 public:
132 /** Given position and device this constructor will compute a line for the caret */
133 SmCaretPos2LineVisitor( OutputDevice *pDevice, SmCaretPos position )
134 : mpDev( pDevice )
135 , maPos( position )
137 SAL_WARN_IF( !position.IsValid(), "starmath", "Cannot draw invalid position!" );
139 maPos.pSelectedNode->Accept( this );
141 virtual ~SmCaretPos2LineVisitor() {}
142 void Visit( SmTextNode* pNode ) override;
143 using SmDefaultingVisitor::Visit;
144 const SmCaretLine& GetResult( ) {
145 return maLine;
147 private:
148 SmCaretLine maLine;
149 VclPtr<OutputDevice> mpDev;
150 SmCaretPos maPos;
151 protected:
152 /** Default method for computing lines for pNodes */
153 void DefaultVisit( SmNode* pNode ) override;
156 // SmDrawingVisitor
158 /** Visitor for drawing SmNodes to OutputDevice */
159 class SmDrawingVisitor : public SmVisitor
161 public:
162 /** Create an instance of SmDrawingVisitor, and use it to draw a formula
163 * @param rDevice Device to draw on
164 * @param position Offset on device to draw the formula
165 * @param pTree Formula tree to draw
166 * @remarks This constructor will do the drawing, no need to anything more.
168 SmDrawingVisitor( OutputDevice &rDevice, Point position, SmNode* pTree )
169 : mrDev( rDevice )
170 , maPosition( position )
172 pTree->Accept( this );
174 virtual ~SmDrawingVisitor() {}
175 void Visit( SmTableNode* pNode ) override;
176 void Visit( SmBraceNode* pNode ) override;
177 void Visit( SmBracebodyNode* pNode ) override;
178 void Visit( SmOperNode* pNode ) override;
179 void Visit( SmAlignNode* pNode ) override;
180 void Visit( SmAttributNode* pNode ) override;
181 void Visit( SmFontNode* pNode ) override;
182 void Visit( SmUnHorNode* pNode ) override;
183 void Visit( SmBinHorNode* pNode ) override;
184 void Visit( SmBinVerNode* pNode ) override;
185 void Visit( SmBinDiagonalNode* pNode ) override;
186 void Visit( SmSubSupNode* pNode ) override;
187 void Visit( SmMatrixNode* pNode ) override;
188 void Visit( SmPlaceNode* pNode ) override;
189 void Visit( SmTextNode* pNode ) override;
190 void Visit( SmSpecialNode* pNode ) override;
191 void Visit( SmGlyphSpecialNode* pNode ) override;
192 void Visit( SmMathSymbolNode* pNode ) override;
193 void Visit( SmBlankNode* pNode ) override;
194 void Visit( SmErrorNode* pNode ) override;
195 void Visit( SmLineNode* pNode ) override;
196 void Visit( SmExpressionNode* pNode ) override;
197 void Visit( SmPolyLineNode* pNode ) override;
198 void Visit( SmRootNode* pNode ) override;
199 void Visit( SmRootSymbolNode* pNode ) override;
200 void Visit( SmRectangleNode* pNode ) override;
201 void Visit( SmVerticalBraceNode* pNode ) override;
202 private:
203 /** Draw the children of a pNode
204 * This the default method, use by most pNodes
206 void DrawChildren( SmStructureNode* pNode );
208 /** Draw an SmTextNode or a subclass of this */
209 void DrawTextNode( SmTextNode* pNode );
210 /** Draw an SmSpecialNode or a subclass of this */
211 void DrawSpecialNode( SmSpecialNode* pNode );
212 /** OutputDevice to draw on */
213 OutputDevice& mrDev;
214 /** Position to draw on the mrDev
215 * @remarks This variable is used to pass parameters in DrawChildren( ), this means
216 that after a call to DrawChildren( ) the contents of this method is undefined
217 so if needed cache it locally on the stack.
219 Point maPosition;
222 // SmSetSelectionVisitor
224 /** Set Selection Visitor
225 * Sets the IsSelected( ) property on all SmNodes of the tree
227 class SmSetSelectionVisitor : public SmDefaultingVisitor
229 public:
230 SmSetSelectionVisitor( SmCaretPos startPos, SmCaretPos endPos, SmNode* pNode);
231 virtual ~SmSetSelectionVisitor() {}
232 void Visit( SmBinHorNode* pNode ) override;
233 void Visit( SmUnHorNode* pNode ) override;
234 void Visit( SmFontNode* pNode ) override;
235 void Visit( SmTextNode* pNode ) override;
236 void Visit( SmExpressionNode* pNode ) override;
237 void Visit( SmLineNode* pNode ) override;
238 void Visit( SmAlignNode* pNode ) override;
239 using SmDefaultingVisitor::Visit;
240 /** Set IsSelected on all pNodes of pSubTree */
241 static void SetSelectedOnAll( SmNode* pSubTree, bool IsSelected = true );
242 private:
243 /** Visit a selectable pNode
244 * Can be used to handle pNodes that can be selected, that doesn't have more SmCaretPos'
245 * than 0 and 1 inside them. SmTextNode should be handle separately!
246 * Also note that pNodes such as SmBinVerNode cannot be selected, don't this method for
247 * it.
249 void DefaultVisit( SmNode* pNode ) override;
250 void VisitCompositionNode( SmStructureNode* pNode );
251 /** Caret position where the selection starts */
252 SmCaretPos maStartPos;
253 /** Caret position where the selection ends */
254 SmCaretPos maEndPos;
255 /** The current state of this visitor
256 * This property changes when the visitor meets either maStartPos
257 * or maEndPos. This means that anything visited in between will be
258 * selected.
260 bool mbSelecting;
264 // SmCaretPosGraphBuildingVisitor
267 /** A visitor for building a SmCaretPosGraph
269 * Visit invariant:
270 * Each pNode, except SmExpressionNode, SmBinHorNode and a few others, constitutes an entry
271 * in a line. Consider the line entry "H", this entry creates one carat position, here
272 * denoted by | in "H|".
274 * Parameter variables:
275 * The following variables are used to transfer parameters in to calls and results out
276 * of calls.
277 * pRightMost : SmCaretPosGraphEntry*
279 * Prior to a Visit call:
280 * pRightMost: A pointer to right most position in front of the current line entry.
282 * After a Visit call:
283 * pRightMost: A pointer to the right most position in the called line entry, if no there's
284 * no caret positions in called line entry don't change this variable.
286 class SmCaretPosGraphBuildingVisitor : public SmVisitor
288 public:
289 /** Builds a caret position graph for pRootNode */
290 explicit SmCaretPosGraphBuildingVisitor( SmNode* pRootNode );
291 virtual ~SmCaretPosGraphBuildingVisitor();
292 void Visit( SmTableNode* pNode ) override;
293 void Visit( SmBraceNode* pNode ) override;
294 void Visit( SmBracebodyNode* pNode ) override;
295 void Visit( SmOperNode* pNode ) override;
296 void Visit( SmAlignNode* pNode ) override;
297 void Visit( SmAttributNode* pNode ) override;
298 void Visit( SmFontNode* pNode ) override;
299 void Visit( SmUnHorNode* pNode ) override;
300 void Visit( SmBinHorNode* pNode ) override;
301 void Visit( SmBinVerNode* pNode ) override;
302 void Visit( SmBinDiagonalNode* pNode ) override;
303 void Visit( SmSubSupNode* pNode ) override;
304 void Visit( SmMatrixNode* pNode ) override;
305 void Visit( SmPlaceNode* pNode ) override;
306 void Visit( SmTextNode* pNode ) override;
307 void Visit( SmSpecialNode* pNode ) override;
308 void Visit( SmGlyphSpecialNode* pNode ) override;
309 void Visit( SmMathSymbolNode* pNode ) override;
310 void Visit( SmBlankNode* pNode ) override;
311 void Visit( SmErrorNode* pNode ) override;
312 void Visit( SmLineNode* pNode ) override;
313 void Visit( SmExpressionNode* pNode ) override;
314 void Visit( SmPolyLineNode* pNode ) override;
315 void Visit( SmRootNode* pNode ) override;
316 void Visit( SmRootSymbolNode* pNode ) override;
317 void Visit( SmRectangleNode* pNode ) override;
318 void Visit( SmVerticalBraceNode* pNode ) override;
319 SmCaretPosGraph* takeGraph()
321 return mpGraph.release();
323 private:
324 SmCaretPosGraphEntry* mpRightMost;
325 std::unique_ptr<SmCaretPosGraph> mpGraph;
328 // SmCloningVisitor
330 /** Visitor for cloning a pNode
332 * This visitor creates deep clones.
334 class SmCloningVisitor : public SmVisitor
336 public:
337 SmCloningVisitor()
338 : mpResult(nullptr)
340 virtual ~SmCloningVisitor() {}
341 void Visit( SmTableNode* pNode ) override;
342 void Visit( SmBraceNode* pNode ) override;
343 void Visit( SmBracebodyNode* pNode ) override;
344 void Visit( SmOperNode* pNode ) override;
345 void Visit( SmAlignNode* pNode ) override;
346 void Visit( SmAttributNode* pNode ) override;
347 void Visit( SmFontNode* pNode ) override;
348 void Visit( SmUnHorNode* pNode ) override;
349 void Visit( SmBinHorNode* pNode ) override;
350 void Visit( SmBinVerNode* pNode ) override;
351 void Visit( SmBinDiagonalNode* pNode ) override;
352 void Visit( SmSubSupNode* pNode ) override;
353 void Visit( SmMatrixNode* pNode ) override;
354 void Visit( SmPlaceNode* pNode ) override;
355 void Visit( SmTextNode* pNode ) override;
356 void Visit( SmSpecialNode* pNode ) override;
357 void Visit( SmGlyphSpecialNode* pNode ) override;
358 void Visit( SmMathSymbolNode* pNode ) override;
359 void Visit( SmBlankNode* pNode ) override;
360 void Visit( SmErrorNode* pNode ) override;
361 void Visit( SmLineNode* pNode ) override;
362 void Visit( SmExpressionNode* pNode ) override;
363 void Visit( SmPolyLineNode* pNode ) override;
364 void Visit( SmRootNode* pNode ) override;
365 void Visit( SmRootSymbolNode* pNode ) override;
366 void Visit( SmRectangleNode* pNode ) override;
367 void Visit( SmVerticalBraceNode* pNode ) override;
368 /** Clone a pNode */
369 SmNode* Clone( SmNode* pNode );
370 private:
371 SmNode* mpResult;
372 /** Clone children of pSource and give them to pTarget */
373 void CloneKids( SmStructureNode* pSource, SmStructureNode* pTarget );
374 /** Clone attributes on a pNode */
375 static void CloneNodeAttr( SmNode const * pSource, SmNode* pTarget );
379 // SmSelectionDrawingVisitor
381 class SmSelectionDrawingVisitor : public SmDefaultingVisitor
383 public:
384 /** Draws a selection on rDevice for the selection on pTree */
385 SmSelectionDrawingVisitor( OutputDevice& rDevice, SmNode* pTree, const Point& rOffset );
386 virtual ~SmSelectionDrawingVisitor() {}
387 void Visit( SmTextNode* pNode ) override;
388 using SmDefaultingVisitor::Visit;
389 private:
390 /** Reference to drawing device */
391 OutputDevice& mrDev;
392 /** True if aSelectionArea have been initialized */
393 bool mbHasSelectionArea;
394 /** The current area that is selected */
395 tools::Rectangle maSelectionArea;
396 /** Extend the area that must be selected */
397 void ExtendSelectionArea(const tools::Rectangle& rArea);
398 /** Default visiting method */
399 void DefaultVisit( SmNode* pNode ) override;
400 /** Visit the children of a given pNode */
401 void VisitChildren( SmNode* pNode );
404 // SmNodeToTextVisitor
406 /** Extract command text from pNodes */
407 class SmNodeToTextVisitor : public SmVisitor
409 public:
410 SmNodeToTextVisitor( SmNode* pNode, OUString &rText );
411 virtual ~SmNodeToTextVisitor() {}
413 void Visit( SmTableNode* pNode ) override;
414 void Visit( SmBraceNode* pNode ) override;
415 void Visit( SmBracebodyNode* pNode ) override;
416 void Visit( SmOperNode* pNode ) override;
417 void Visit( SmAlignNode* pNode ) override;
418 void Visit( SmAttributNode* pNode ) override;
419 void Visit( SmFontNode* pNode ) override;
420 void Visit( SmUnHorNode* pNode ) override;
421 void Visit( SmBinHorNode* pNode ) override;
422 void Visit( SmBinVerNode* pNode ) override;
423 void Visit( SmBinDiagonalNode* pNode ) override;
424 void Visit( SmSubSupNode* pNode ) override;
425 void Visit( SmMatrixNode* pNode ) override;
426 void Visit( SmPlaceNode* pNode ) override;
427 void Visit( SmTextNode* pNode ) override;
428 void Visit( SmSpecialNode* pNode ) override;
429 void Visit( SmGlyphSpecialNode* pNode ) override;
430 void Visit( SmMathSymbolNode* pNode ) override;
431 void Visit( SmBlankNode* pNode ) override;
432 void Visit( SmErrorNode* pNode ) override;
433 void Visit( SmLineNode* pNode ) override;
434 void Visit( SmExpressionNode* pNode ) override;
435 void Visit( SmPolyLineNode* pNode ) override;
436 void Visit( SmRootNode* pNode ) override;
437 void Visit( SmRootSymbolNode* pNode ) override;
438 void Visit( SmRectangleNode* pNode ) override;
439 void Visit( SmVerticalBraceNode* pNode ) override;
440 private:
441 /** Extract text from a pNode that constitutes a line */
442 void LineToText( SmNode* pNode ) {
443 Separate( );
444 if( pNode )
445 pNode->Accept( this );
446 Separate( );
448 void Append( const OUString &rText ) {
449 maCmdText.append( rText );
451 /** Append a blank for separation, if needed */
452 void Separate( ){
453 if( maCmdText.isEmpty() || maCmdText[ maCmdText.getLength() - 1 ] != ' ' )
454 maCmdText.append(' ');
456 /** Output text generated from the pNodes */
457 OUStringBuffer maCmdText;
460 #endif // INCLUDED_STARMATH_INC_VISITORS_HXX
462 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */