nss: upgrade to release 3.73
[LibreOffice.git] / starmath / inc / visitors.hxx
blobff9ca79261ecf53c2befec29aa41ff1e88d9dc8e
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 */
10 /** Visitors are an easy way to automating operations with nodes.
12 * The available visitors are:
13 * SmVisitor base class
14 * SmDefaultingVisitor default visitor
15 * SmDrawingVisitor draws formula
16 * SmCaretPosGraphBuildingVisitor position of the node inside starmath code
17 * SmCloningVisitor duplicate nodes
18 * SmNodeToTextVisitor create code from nodes
22 #ifndef INCLUDED_STARMATH_INC_VISITORS_HXX
23 #define INCLUDED_STARMATH_INC_VISITORS_HXX
25 #include <sal/config.h>
27 #include <sal/log.hxx>
29 #include "node.hxx"
30 #include "caret.hxx"
31 #include <memory>
33 /** Base class for visitors that visits a tree of SmNodes
34 * @remarks all methods have been left abstract to ensure that implementers
35 * don't forget to implement one.
37 class SmVisitor
39 public:
40 virtual void Visit( SmTableNode* pNode ) = 0;
41 virtual void Visit( SmBraceNode* pNode ) = 0;
42 virtual void Visit( SmBracebodyNode* pNode ) = 0;
43 virtual void Visit( SmOperNode* pNode ) = 0;
44 virtual void Visit( SmAlignNode* pNode ) = 0;
45 virtual void Visit( SmAttributNode* pNode ) = 0;
46 virtual void Visit( SmFontNode* pNode ) = 0;
47 virtual void Visit( SmUnHorNode* pNode ) = 0;
48 virtual void Visit( SmBinHorNode* pNode ) = 0;
49 virtual void Visit( SmBinVerNode* pNode ) = 0;
50 virtual void Visit( SmBinDiagonalNode* pNode ) = 0;
51 virtual void Visit( SmSubSupNode* pNode ) = 0;
52 virtual void Visit( SmMatrixNode* pNode ) = 0;
53 virtual void Visit( SmPlaceNode* pNode ) = 0;
54 virtual void Visit( SmTextNode* pNode ) = 0;
55 virtual void Visit( SmSpecialNode* pNode ) = 0;
56 virtual void Visit( SmGlyphSpecialNode* pNode ) = 0;
57 virtual void Visit( SmMathSymbolNode* pNode ) = 0;
58 virtual void Visit( SmBlankNode* pNode ) = 0;
59 virtual void Visit( SmErrorNode* pNode ) = 0;
60 virtual void Visit( SmLineNode* pNode ) = 0;
61 virtual void Visit( SmExpressionNode* pNode ) = 0;
62 virtual void Visit( SmPolyLineNode* pNode ) = 0;
63 virtual void Visit( SmRootNode* pNode ) = 0;
64 virtual void Visit( SmRootSymbolNode* pNode ) = 0;
65 virtual void Visit( SmRectangleNode* pNode ) = 0;
66 virtual void Visit( SmVerticalBraceNode* pNode ) = 0;
68 protected:
69 ~SmVisitor() {}
72 // SmDefaultingVisitor
75 /** Visitor that uses DefaultVisit for handling visits by default
77 * This abstract baseclass is useful for visitors where many methods share the same
78 * implementation.
80 class SmDefaultingVisitor : public SmVisitor
82 public:
83 void Visit( SmTableNode* pNode ) override;
84 void Visit( SmBraceNode* pNode ) override;
85 void Visit( SmBracebodyNode* pNode ) override;
86 void Visit( SmOperNode* pNode ) override;
87 void Visit( SmAlignNode* pNode ) override;
88 void Visit( SmAttributNode* pNode ) override;
89 void Visit( SmFontNode* pNode ) override;
90 void Visit( SmUnHorNode* pNode ) override;
91 void Visit( SmBinHorNode* pNode ) override;
92 void Visit( SmBinVerNode* pNode ) override;
93 void Visit( SmBinDiagonalNode* pNode ) override;
94 void Visit( SmSubSupNode* pNode ) override;
95 void Visit( SmMatrixNode* pNode ) override;
96 void Visit( SmPlaceNode* pNode ) override;
97 void Visit( SmTextNode* pNode ) override;
98 void Visit( SmSpecialNode* pNode ) override;
99 void Visit( SmGlyphSpecialNode* pNode ) override;
100 void Visit( SmMathSymbolNode* pNode ) override;
101 void Visit( SmBlankNode* pNode ) override;
102 void Visit( SmErrorNode* pNode ) override;
103 void Visit( SmLineNode* pNode ) override;
104 void Visit( SmExpressionNode* pNode ) override;
105 void Visit( SmPolyLineNode* pNode ) override;
106 void Visit( SmRootNode* pNode ) override;
107 void Visit( SmRootSymbolNode* pNode ) override;
108 void Visit( SmRectangleNode* pNode ) override;
109 void Visit( SmVerticalBraceNode* pNode ) override;
110 protected:
111 ~SmDefaultingVisitor() {}
113 /** Method invoked by Visit methods by default */
114 virtual void DefaultVisit( SmNode* pNode ) = 0;
117 // SmCaretDrawingVisitor
119 /** Visitor for drawing a caret position */
120 class SmCaretDrawingVisitor final : public SmDefaultingVisitor
122 public:
123 /** Given position and device this constructor will draw the caret */
124 SmCaretDrawingVisitor( OutputDevice& rDevice, SmCaretPos position, Point offset, bool caretVisible );
125 virtual ~SmCaretDrawingVisitor() {}
126 void Visit( SmTextNode* pNode ) override;
127 using SmDefaultingVisitor::Visit;
128 private:
129 OutputDevice &mrDev;
130 SmCaretPos maPos;
131 /** Offset to draw from */
132 Point maOffset;
133 bool mbCaretVisible;
135 /** Default method for drawing pNodes */
136 void DefaultVisit( SmNode* pNode ) override;
139 // SmCaretPos2LineVisitor
141 /** Visitor getting a line from a caret position */
142 class SmCaretPos2LineVisitor final : public SmDefaultingVisitor
144 public:
145 /** Given position and device this constructor will compute a line for the caret */
146 SmCaretPos2LineVisitor( OutputDevice *pDevice, SmCaretPos position )
147 : mpDev( pDevice )
148 , maPos( position )
150 SAL_WARN_IF( !position.IsValid(), "starmath", "Cannot draw invalid position!" );
152 maPos.pSelectedNode->Accept( this );
154 virtual ~SmCaretPos2LineVisitor() {}
155 void Visit( SmTextNode* pNode ) override;
156 using SmDefaultingVisitor::Visit;
157 const SmCaretLine& GetResult( ) const {
158 return maLine;
160 private:
161 SmCaretLine maLine;
162 VclPtr<OutputDevice> mpDev;
163 SmCaretPos maPos;
165 /** Default method for computing lines for pNodes */
166 void DefaultVisit( SmNode* pNode ) override;
169 // SmDrawingVisitor
171 /** Visitor for drawing SmNodes to OutputDevice */
172 class SmDrawingVisitor final : public SmVisitor
174 public:
175 /** Create an instance of SmDrawingVisitor, and use it to draw a formula
176 * @param rDevice Device to draw on
177 * @param position Offset on device to draw the formula
178 * @param pTree Formula tree to draw
179 * @remarks This constructor will do the drawing, no need to anything more.
181 SmDrawingVisitor( OutputDevice &rDevice, Point position, SmNode* pTree )
182 : mrDev( rDevice )
183 , maPosition( position )
185 pTree->Accept( this );
187 virtual ~SmDrawingVisitor() {}
188 void Visit( SmTableNode* pNode ) override;
189 void Visit( SmBraceNode* pNode ) override;
190 void Visit( SmBracebodyNode* pNode ) override;
191 void Visit( SmOperNode* pNode ) override;
192 void Visit( SmAlignNode* pNode ) override;
193 void Visit( SmAttributNode* pNode ) override;
194 void Visit( SmFontNode* pNode ) override;
195 void Visit( SmUnHorNode* pNode ) override;
196 void Visit( SmBinHorNode* pNode ) override;
197 void Visit( SmBinVerNode* pNode ) override;
198 void Visit( SmBinDiagonalNode* pNode ) override;
199 void Visit( SmSubSupNode* pNode ) override;
200 void Visit( SmMatrixNode* pNode ) override;
201 void Visit( SmPlaceNode* pNode ) override;
202 void Visit( SmTextNode* pNode ) override;
203 void Visit( SmSpecialNode* pNode ) override;
204 void Visit( SmGlyphSpecialNode* pNode ) override;
205 void Visit( SmMathSymbolNode* pNode ) override;
206 void Visit( SmBlankNode* pNode ) override;
207 void Visit( SmErrorNode* pNode ) override;
208 void Visit( SmLineNode* pNode ) override;
209 void Visit( SmExpressionNode* pNode ) override;
210 void Visit( SmPolyLineNode* pNode ) override;
211 void Visit( SmRootNode* pNode ) override;
212 void Visit( SmRootSymbolNode* pNode ) override;
213 void Visit( SmRectangleNode* pNode ) override;
214 void Visit( SmVerticalBraceNode* pNode ) override;
215 private:
216 /** Draw the children of a pNode
217 * This the default method, use by most pNodes
219 void DrawChildren( SmStructureNode* pNode );
221 /** Draw an SmTextNode or a subclass of this */
222 void DrawTextNode( SmTextNode* pNode );
223 /** Draw an SmSpecialNode or a subclass of this */
224 void DrawSpecialNode( SmSpecialNode* pNode );
225 /** OutputDevice to draw on */
226 OutputDevice& mrDev;
227 /** Position to draw on the mrDev
228 * @remarks This variable is used to pass parameters in DrawChildren( ), this means
229 that after a call to DrawChildren( ) the contents of this method is undefined
230 so if needed cache it locally on the stack.
232 Point maPosition;
235 // SmSetSelectionVisitor
237 /** Set Selection Visitor
238 * Sets the IsSelected( ) property on all SmNodes of the tree
240 class SmSetSelectionVisitor final : public SmDefaultingVisitor
242 public:
243 SmSetSelectionVisitor( SmCaretPos startPos, SmCaretPos endPos, SmNode* pNode);
244 virtual ~SmSetSelectionVisitor() {}
245 void Visit( SmBinHorNode* pNode ) override;
246 void Visit( SmUnHorNode* pNode ) override;
247 void Visit( SmFontNode* pNode ) override;
248 void Visit( SmTextNode* pNode ) override;
249 void Visit( SmExpressionNode* pNode ) override;
250 void Visit( SmLineNode* pNode ) override;
251 void Visit( SmAlignNode* pNode ) override;
252 using SmDefaultingVisitor::Visit;
253 /** Set IsSelected on all pNodes of pSubTree */
254 static void SetSelectedOnAll( SmNode* pSubTree, bool IsSelected = true );
255 private:
256 /** Visit a selectable pNode
257 * Can be used to handle pNodes that can be selected, that doesn't have more SmCaretPos'
258 * than 0 and 1 inside them. SmTextNode should be handle separately!
259 * Also note that pNodes such as SmBinVerNode cannot be selected, don't this method for
260 * it.
262 void DefaultVisit( SmNode* pNode ) override;
263 void VisitCompositionNode( SmStructureNode* pNode );
264 /** Caret position where the selection starts */
265 SmCaretPos maStartPos;
266 /** Caret position where the selection ends */
267 SmCaretPos maEndPos;
268 /** The current state of this visitor
269 * This property changes when the visitor meets either maStartPos
270 * or maEndPos. This means that anything visited in between will be
271 * selected.
273 bool mbSelecting;
277 // SmCaretPosGraphBuildingVisitor
280 /** A visitor for building a SmCaretPosGraph
282 * Visit invariant:
283 * Each pNode, except SmExpressionNode, SmBinHorNode and a few others, constitutes an entry
284 * in a line. Consider the line entry "H", this entry creates one carat position, here
285 * denoted by | in "H|".
287 * Parameter variables:
288 * The following variables are used to transfer parameters into calls and results out
289 * of calls.
290 * pRightMost : SmCaretPosGraphEntry*
292 * Prior to a Visit call:
293 * pRightMost: A pointer to right most position in front of the current line entry.
295 * After a Visit call:
296 * pRightMost: A pointer to the right most position in the called line entry, if no there's
297 * no caret positions in called line entry don't change this variable.
299 class SmCaretPosGraphBuildingVisitor final : public SmVisitor
301 public:
302 /** Builds a caret position graph for pRootNode */
303 explicit SmCaretPosGraphBuildingVisitor( SmNode* pRootNode );
304 virtual ~SmCaretPosGraphBuildingVisitor();
305 void Visit( SmTableNode* pNode ) override;
306 void Visit( SmBraceNode* pNode ) override;
307 void Visit( SmBracebodyNode* pNode ) override;
308 void Visit( SmOperNode* pNode ) override;
309 void Visit( SmAlignNode* pNode ) override;
310 void Visit( SmAttributNode* pNode ) override;
311 void Visit( SmFontNode* pNode ) override;
312 void Visit( SmUnHorNode* pNode ) override;
313 void Visit( SmBinHorNode* pNode ) override;
314 void Visit( SmBinVerNode* pNode ) override;
315 void Visit( SmBinDiagonalNode* pNode ) override;
316 void Visit( SmSubSupNode* pNode ) override;
317 void Visit( SmMatrixNode* pNode ) override;
318 void Visit( SmPlaceNode* pNode ) override;
319 void Visit( SmTextNode* pNode ) override;
320 void Visit( SmSpecialNode* pNode ) override;
321 void Visit( SmGlyphSpecialNode* pNode ) override;
322 void Visit( SmMathSymbolNode* pNode ) override;
323 void Visit( SmBlankNode* pNode ) override;
324 void Visit( SmErrorNode* pNode ) override;
325 void Visit( SmLineNode* pNode ) override;
326 void Visit( SmExpressionNode* pNode ) override;
327 void Visit( SmPolyLineNode* pNode ) override;
328 void Visit( SmRootNode* pNode ) override;
329 void Visit( SmRootSymbolNode* pNode ) override;
330 void Visit( SmRectangleNode* pNode ) override;
331 void Visit( SmVerticalBraceNode* pNode ) override;
332 SmCaretPosGraph* takeGraph()
334 return mpGraph.release();
336 private:
337 SmCaretPosGraphEntry* mpRightMost;
338 std::unique_ptr<SmCaretPosGraph> mpGraph;
341 // SmCloningVisitor
343 /** Visitor for cloning a pNode
345 * This visitor creates deep clones.
347 class SmCloningVisitor final : public SmVisitor
349 public:
350 SmCloningVisitor()
351 : mpResult(nullptr)
353 virtual ~SmCloningVisitor() {}
354 void Visit( SmTableNode* pNode ) override;
355 void Visit( SmBraceNode* pNode ) override;
356 void Visit( SmBracebodyNode* pNode ) override;
357 void Visit( SmOperNode* pNode ) override;
358 void Visit( SmAlignNode* pNode ) override;
359 void Visit( SmAttributNode* pNode ) override;
360 void Visit( SmFontNode* pNode ) override;
361 void Visit( SmUnHorNode* pNode ) override;
362 void Visit( SmBinHorNode* pNode ) override;
363 void Visit( SmBinVerNode* pNode ) override;
364 void Visit( SmBinDiagonalNode* pNode ) override;
365 void Visit( SmSubSupNode* pNode ) override;
366 void Visit( SmMatrixNode* pNode ) override;
367 void Visit( SmPlaceNode* pNode ) override;
368 void Visit( SmTextNode* pNode ) override;
369 void Visit( SmSpecialNode* pNode ) override;
370 void Visit( SmGlyphSpecialNode* pNode ) override;
371 void Visit( SmMathSymbolNode* pNode ) override;
372 void Visit( SmBlankNode* pNode ) override;
373 void Visit( SmErrorNode* pNode ) override;
374 void Visit( SmLineNode* pNode ) override;
375 void Visit( SmExpressionNode* pNode ) override;
376 void Visit( SmPolyLineNode* pNode ) override;
377 void Visit( SmRootNode* pNode ) override;
378 void Visit( SmRootSymbolNode* pNode ) override;
379 void Visit( SmRectangleNode* pNode ) override;
380 void Visit( SmVerticalBraceNode* pNode ) override;
381 /** Clone a pNode */
382 SmNode* Clone( SmNode* pNode );
383 private:
384 SmNode* mpResult;
385 /** Clone children of pSource and give them to pTarget */
386 void CloneKids( SmStructureNode* pSource, SmStructureNode* pTarget );
387 /** Clone attributes on a pNode */
388 static void CloneNodeAttr( SmNode const * pSource, SmNode* pTarget );
392 // SmSelectionDrawingVisitor
394 class SmSelectionDrawingVisitor final : public SmDefaultingVisitor
396 public:
397 /** Draws a selection on rDevice for the selection on pTree */
398 SmSelectionDrawingVisitor( OutputDevice& rDevice, SmNode* pTree, const Point& rOffset );
399 virtual ~SmSelectionDrawingVisitor() {}
400 void Visit( SmTextNode* pNode ) override;
401 using SmDefaultingVisitor::Visit;
402 private:
403 /** Reference to drawing device */
404 OutputDevice& mrDev;
405 /** True if aSelectionArea have been initialized */
406 bool mbHasSelectionArea;
407 /** The current area that is selected */
408 tools::Rectangle maSelectionArea;
409 /** Extend the area that must be selected */
410 void ExtendSelectionArea(const tools::Rectangle& rArea);
411 /** Default visiting method */
412 void DefaultVisit( SmNode* pNode ) override;
413 /** Visit the children of a given pNode */
414 void VisitChildren( SmNode* pNode );
417 // SmNodeToTextVisitor
419 /** Extract command text from pNodes */
420 class SmNodeToTextVisitor final : public SmVisitor
422 public:
423 SmNodeToTextVisitor( SmNode* pNode, OUString &rText );
424 virtual ~SmNodeToTextVisitor() {}
426 void Visit( SmTableNode* pNode ) override;
427 void Visit( SmBraceNode* pNode ) override;
428 void Visit( SmBracebodyNode* pNode ) override;
429 void Visit( SmOperNode* pNode ) override;
430 void Visit( SmAlignNode* pNode ) override;
431 void Visit( SmAttributNode* pNode ) override;
432 void Visit( SmFontNode* pNode ) override;
433 void Visit( SmUnHorNode* pNode ) override;
434 void Visit( SmBinHorNode* pNode ) override;
435 void Visit( SmBinVerNode* pNode ) override;
436 void Visit( SmBinDiagonalNode* pNode ) override;
437 void Visit( SmSubSupNode* pNode ) override;
438 void Visit( SmMatrixNode* pNode ) override;
439 void Visit( SmPlaceNode* pNode ) override;
440 void Visit( SmTextNode* pNode ) override;
441 void Visit( SmSpecialNode* pNode ) override;
442 void Visit( SmGlyphSpecialNode* pNode ) override;
443 void Visit( SmMathSymbolNode* pNode ) override;
444 void Visit( SmBlankNode* pNode ) override;
445 void Visit( SmErrorNode* pNode ) override;
446 void Visit( SmLineNode* pNode ) override;
447 void Visit( SmExpressionNode* pNode ) override;
448 void Visit( SmPolyLineNode* pNode ) override;
449 void Visit( SmRootNode* pNode ) override;
450 void Visit( SmRootSymbolNode* pNode ) override;
451 void Visit( SmRectangleNode* pNode ) override;
452 void Visit( SmVerticalBraceNode* pNode ) override;
453 private:
456 * Extract text from a pNode that constitutes a line.
457 * @param pNode
458 * @return
460 void LineToText( SmNode* pNode ) {
461 Separate( );
462 if( pNode ) pNode->Accept( this );
463 Separate( );
467 * Appends rText to the OUStringBuffer ( maCmdText ).
468 * @param rText
469 * @return
471 void Append( const OUString &rText ) {
472 maCmdText.append( rText );
476 * Appends rText to the OUStringBuffer ( maCmdText ).
477 * @param rText
478 * @return
480 void Append( const char* rText ) {
481 maCmdText.append( OUString::createFromAscii(rText) );
485 * Append a blank for separation, if needed.
486 * It is needed if last char is not ' '.
487 * @return
489 void Separate( ){
490 if( !maCmdText.isEmpty() && maCmdText[ maCmdText.getLength() - 1 ] != ' ' )
491 maCmdText.append(' ');
494 /** Output text generated from the pNodes */
495 OUStringBuffer maCmdText;
498 #endif // INCLUDED_STARMATH_INC_VISITORS_HXX
500 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */