2f731e7a19
Change-Id: I55d3f4546f40a321ebf4b08db33536592f451944 Reviewed-on: https://gerrit.libreoffice.org/4318 Reviewed-by: Marcos Souza <marcos.souza.org@gmail.com> Reviewed-by: Noel Power <noel.power@suse.com> Tested-by: Noel Power <noel.power@suse.com>
489 lines
17 KiB
C++
489 lines
17 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*
|
|
* This file is part of the LibreOffice project.
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*/
|
|
#ifndef SMVISITORS_H
|
|
#define SMVISITORS_H
|
|
|
|
#include "node.hxx"
|
|
#include "caret.hxx"
|
|
|
|
/** Base class for visitors that visits a tree of SmNodes
|
|
* @remarks all methods have been left abstract to ensure that implementers
|
|
* don't forget to implement one.
|
|
*/
|
|
class SmVisitor
|
|
{
|
|
public:
|
|
virtual void Visit( SmTableNode* pNode ) = 0;
|
|
virtual void Visit( SmBraceNode* pNode ) = 0;
|
|
virtual void Visit( SmBracebodyNode* pNode ) = 0;
|
|
virtual void Visit( SmOperNode* pNode ) = 0;
|
|
virtual void Visit( SmAlignNode* pNode ) = 0;
|
|
virtual void Visit( SmAttributNode* pNode ) = 0;
|
|
virtual void Visit( SmFontNode* pNode ) = 0;
|
|
virtual void Visit( SmUnHorNode* pNode ) = 0;
|
|
virtual void Visit( SmBinHorNode* pNode ) = 0;
|
|
virtual void Visit( SmBinVerNode* pNode ) = 0;
|
|
virtual void Visit( SmBinDiagonalNode* pNode ) = 0;
|
|
virtual void Visit( SmSubSupNode* pNode ) = 0;
|
|
virtual void Visit( SmMatrixNode* pNode ) = 0;
|
|
virtual void Visit( SmPlaceNode* pNode ) = 0;
|
|
virtual void Visit( SmTextNode* pNode ) = 0;
|
|
virtual void Visit( SmSpecialNode* pNode ) = 0;
|
|
virtual void Visit( SmGlyphSpecialNode* pNode ) = 0;
|
|
virtual void Visit( SmMathSymbolNode* pNode ) = 0;
|
|
virtual void Visit( SmBlankNode* pNode ) = 0;
|
|
virtual void Visit( SmErrorNode* pNode ) = 0;
|
|
virtual void Visit( SmLineNode* pNode ) = 0;
|
|
virtual void Visit( SmExpressionNode* pNode ) = 0;
|
|
virtual void Visit( SmPolyLineNode* pNode ) = 0;
|
|
virtual void Visit( SmRootNode* pNode ) = 0;
|
|
virtual void Visit( SmRootSymbolNode* pNode ) = 0;
|
|
virtual void Visit( SmRectangleNode* pNode ) = 0;
|
|
virtual void Visit( SmVerticalBraceNode* pNode ) = 0;
|
|
|
|
protected:
|
|
~SmVisitor() {}
|
|
};
|
|
|
|
/** Simple visitor for testing SmVisitor */
|
|
class SmVisitorTest : public SmVisitor
|
|
{
|
|
public:
|
|
virtual ~SmVisitorTest() {}
|
|
void Visit( SmTableNode* pNode );
|
|
void Visit( SmBraceNode* pNode );
|
|
void Visit( SmBracebodyNode* pNode );
|
|
void Visit( SmOperNode* pNode );
|
|
void Visit( SmAlignNode* pNode );
|
|
void Visit( SmAttributNode* pNode );
|
|
void Visit( SmFontNode* pNode );
|
|
void Visit( SmUnHorNode* pNode );
|
|
void Visit( SmBinHorNode* pNode );
|
|
void Visit( SmBinVerNode* pNode );
|
|
void Visit( SmBinDiagonalNode* pNode );
|
|
void Visit( SmSubSupNode* pNode );
|
|
void Visit( SmMatrixNode* pNode );
|
|
void Visit( SmPlaceNode* pNode );
|
|
void Visit( SmTextNode* pNode );
|
|
void Visit( SmSpecialNode* pNode );
|
|
void Visit( SmGlyphSpecialNode* pNode );
|
|
void Visit( SmMathSymbolNode* pNode );
|
|
void Visit( SmBlankNode* pNode );
|
|
void Visit( SmErrorNode* pNode );
|
|
void Visit( SmLineNode* pNode );
|
|
void Visit( SmExpressionNode* pNode );
|
|
void Visit( SmPolyLineNode* pNode );
|
|
void Visit( SmRootNode* pNode );
|
|
void Visit( SmRootSymbolNode* pNode );
|
|
void Visit( SmRectangleNode* pNode );
|
|
void Visit( SmVerticalBraceNode* pNode );
|
|
private:
|
|
/** Auxiliary method for visiting the children of a pNode */
|
|
void VisitChildren( SmNode* pNode );
|
|
};
|
|
|
|
/////////////////////////////// SmDefaultingVisitor ////////////////////////////////
|
|
|
|
|
|
/** Visitor that uses DefaultVisit for handling visits by default
|
|
*
|
|
* This abstract baseclass is useful for visitors where many methods share the same
|
|
* implementation.
|
|
*/
|
|
class SmDefaultingVisitor : public SmVisitor
|
|
{
|
|
public:
|
|
void Visit( SmTableNode* pNode );
|
|
void Visit( SmBraceNode* pNode );
|
|
void Visit( SmBracebodyNode* pNode );
|
|
void Visit( SmOperNode* pNode );
|
|
void Visit( SmAlignNode* pNode );
|
|
void Visit( SmAttributNode* pNode );
|
|
void Visit( SmFontNode* pNode );
|
|
void Visit( SmUnHorNode* pNode );
|
|
void Visit( SmBinHorNode* pNode );
|
|
void Visit( SmBinVerNode* pNode );
|
|
void Visit( SmBinDiagonalNode* pNode );
|
|
void Visit( SmSubSupNode* pNode );
|
|
void Visit( SmMatrixNode* pNode );
|
|
void Visit( SmPlaceNode* pNode );
|
|
void Visit( SmTextNode* pNode );
|
|
void Visit( SmSpecialNode* pNode );
|
|
void Visit( SmGlyphSpecialNode* pNode );
|
|
void Visit( SmMathSymbolNode* pNode );
|
|
void Visit( SmBlankNode* pNode );
|
|
void Visit( SmErrorNode* pNode );
|
|
void Visit( SmLineNode* pNode );
|
|
void Visit( SmExpressionNode* pNode );
|
|
void Visit( SmPolyLineNode* pNode );
|
|
void Visit( SmRootNode* pNode );
|
|
void Visit( SmRootSymbolNode* pNode );
|
|
void Visit( SmRectangleNode* pNode );
|
|
void Visit( SmVerticalBraceNode* pNode );
|
|
protected:
|
|
~SmDefaultingVisitor() {}
|
|
|
|
/** Method invoked by Visit methods by default */
|
|
virtual void DefaultVisit( SmNode* pNode ) = 0;
|
|
};
|
|
|
|
/////////////////////////////// SmCaretDrawingVisitor ////////////////////////////////
|
|
|
|
/** Visitor for drawing a caret position */
|
|
class SmCaretDrawingVisitor : public SmDefaultingVisitor
|
|
{
|
|
public:
|
|
/** Given position and device this constructor will draw the caret */
|
|
SmCaretDrawingVisitor( OutputDevice& rDevice, SmCaretPos position, Point offset, bool caretVisible );
|
|
virtual ~SmCaretDrawingVisitor() {}
|
|
void Visit( SmTextNode* pNode );
|
|
using SmDefaultingVisitor::Visit;
|
|
private:
|
|
OutputDevice &rDev;
|
|
SmCaretPos pos;
|
|
/** Offset to draw from */
|
|
Point Offset;
|
|
bool isCaretVisible;
|
|
protected:
|
|
/** Default method for drawing pNodes */
|
|
void DefaultVisit( SmNode* pNode );
|
|
};
|
|
|
|
/////////////////////////////// SmCaretPos2LineVisitor ////////////////////////////////
|
|
|
|
/** Visitor getting a line from a caret position */
|
|
class SmCaretPos2LineVisitor : public SmDefaultingVisitor
|
|
{
|
|
public:
|
|
/** Given position and device this constructor will compute a line for the caret */
|
|
SmCaretPos2LineVisitor( OutputDevice *pDevice, SmCaretPos position ) {
|
|
pDev = pDevice;
|
|
pos = position;
|
|
OSL_ENSURE( position.IsValid( ), "Cannot draw invalid position!" );
|
|
|
|
pos.pSelectedNode->Accept( this );
|
|
}
|
|
virtual ~SmCaretPos2LineVisitor() {}
|
|
void Visit( SmTextNode* pNode );
|
|
using SmDefaultingVisitor::Visit;
|
|
SmCaretLine GetResult( ){
|
|
return line;
|
|
}
|
|
private:
|
|
SmCaretLine line;
|
|
OutputDevice *pDev;
|
|
SmCaretPos pos;
|
|
protected:
|
|
/** Default method for computing lines for pNodes */
|
|
void DefaultVisit( SmNode* pNode );
|
|
};
|
|
|
|
/////////////////////////////// SmDrawingVisitor ////////////////////////////////
|
|
|
|
/** Visitor for drawing SmNodes to OutputDevice */
|
|
class SmDrawingVisitor : public SmVisitor
|
|
{
|
|
public:
|
|
/** Create an instance of SmDrawingVisitor, and use it to draw a formula
|
|
* @param rDevice Device to draw on
|
|
* @param position Offset on device to draw the formula
|
|
* @param pTree Formula tree to draw
|
|
* @remarks This constructor will do the drawing, no need to anything more.
|
|
*/
|
|
SmDrawingVisitor( OutputDevice &rDevice, Point position, SmNode* pTree )
|
|
: rDev( rDevice ) {
|
|
this->Position = position;
|
|
pTree->Accept( this );
|
|
}
|
|
virtual ~SmDrawingVisitor() {}
|
|
void Visit( SmTableNode* pNode );
|
|
void Visit( SmBraceNode* pNode );
|
|
void Visit( SmBracebodyNode* pNode );
|
|
void Visit( SmOperNode* pNode );
|
|
void Visit( SmAlignNode* pNode );
|
|
void Visit( SmAttributNode* pNode );
|
|
void Visit( SmFontNode* pNode );
|
|
void Visit( SmUnHorNode* pNode );
|
|
void Visit( SmBinHorNode* pNode );
|
|
void Visit( SmBinVerNode* pNode );
|
|
void Visit( SmBinDiagonalNode* pNode );
|
|
void Visit( SmSubSupNode* pNode );
|
|
void Visit( SmMatrixNode* pNode );
|
|
void Visit( SmPlaceNode* pNode );
|
|
void Visit( SmTextNode* pNode );
|
|
void Visit( SmSpecialNode* pNode );
|
|
void Visit( SmGlyphSpecialNode* pNode );
|
|
void Visit( SmMathSymbolNode* pNode );
|
|
void Visit( SmBlankNode* pNode );
|
|
void Visit( SmErrorNode* pNode );
|
|
void Visit( SmLineNode* pNode );
|
|
void Visit( SmExpressionNode* pNode );
|
|
void Visit( SmPolyLineNode* pNode );
|
|
void Visit( SmRootNode* pNode );
|
|
void Visit( SmRootSymbolNode* pNode );
|
|
void Visit( SmRectangleNode* pNode );
|
|
void Visit( SmVerticalBraceNode* pNode );
|
|
private:
|
|
/** Draw the children of a pNode
|
|
* This the default method, use by most pNodes
|
|
*/
|
|
void DrawChildren( SmNode* pNode );
|
|
|
|
/** Draw an SmTextNode or a subclass of this */
|
|
void DrawTextNode( SmTextNode* pNode );
|
|
/** Draw an SmSpecialNode or a subclass of this */
|
|
void DrawSpecialNode( SmSpecialNode* pNode );
|
|
/** OutputDevice to draw on */
|
|
OutputDevice& rDev;
|
|
/** Position to draw on the rDev
|
|
* @remarks This variable is used to pass parameters in DrawChildren( ), this means
|
|
that after a call to DrawChildren( ) the contents of this method is undefined
|
|
so if needed cache it locally on the stack.
|
|
*/
|
|
Point Position;
|
|
};
|
|
|
|
/////////////////////////////// SmSetSelectionVisitor ////////////////////////////////
|
|
|
|
/** Set Selection Visitor
|
|
* Sets the IsSelected( ) property on all SmNodes of the tree
|
|
*/
|
|
class SmSetSelectionVisitor : public SmDefaultingVisitor
|
|
{
|
|
public:
|
|
SmSetSelectionVisitor( SmCaretPos startPos, SmCaretPos endPos, SmNode* pNode);
|
|
virtual ~SmSetSelectionVisitor() {}
|
|
void Visit( SmBinHorNode* pNode );
|
|
void Visit( SmUnHorNode* pNode );
|
|
void Visit( SmFontNode* pNode );
|
|
void Visit( SmTextNode* pNode );
|
|
void Visit( SmExpressionNode* pNode );
|
|
void Visit( SmLineNode* pNode );
|
|
void Visit( SmAlignNode* pNode );
|
|
using SmDefaultingVisitor::Visit;
|
|
/** Set IsSelected on all pNodes of pSubTree */
|
|
static void SetSelectedOnAll( SmNode* pSubTree, bool IsSelected = true );
|
|
private:
|
|
/** Visit a selectable pNode
|
|
* Can be used to handle pNodes that can be selected, that doesn't have more SmCaretPos'
|
|
* than 0 and 1 inside them. SmTextNode should be handle separately!
|
|
* Also note that pNodes such as SmBinVerNode cannot be selected, don't this method for
|
|
* it.
|
|
*/
|
|
void DefaultVisit( SmNode* pNode );
|
|
void VisitCompositionNode( SmNode* pNode );
|
|
/** Caret position where the selection starts */
|
|
SmCaretPos StartPos;
|
|
/** Caret position where the selection ends */
|
|
SmCaretPos EndPos;
|
|
/** The current state of this visitor
|
|
* This property changes when the visitor meets either StartPos
|
|
* or EndPos. This means that anything visited in between will be
|
|
* selected.
|
|
*/
|
|
bool IsSelecting;
|
|
};
|
|
|
|
|
|
/////////////////////////////// SmCaretPosGraphBuildingVisitor ////////////////////////////////
|
|
|
|
|
|
/** A visitor for building a SmCaretPosGraph
|
|
*
|
|
* Visit invariant:
|
|
* Each pNode, except SmExpressionNode, SmBinHorNode and a few others, constitues an entry
|
|
* in a line. Consider the line entry "H", this entry creates one carat position, here
|
|
* denoted by | in "H|".
|
|
*
|
|
* Parameter variables:
|
|
* The following variables are used to transfer parameters in to calls and results out
|
|
* of calls.
|
|
* pRightMost : SmCaretPosGraphEntry*
|
|
*
|
|
* Prior to a Visit call:
|
|
* pRightMost: A pointer to right most position in front of the current line entry.
|
|
*
|
|
* After a Visit call:
|
|
* pRightMost: A pointer to the right most position in the called line entry, if no there's
|
|
* no caret positions in called line entry don't change this variable.
|
|
*/
|
|
class SmCaretPosGraphBuildingVisitor : public SmVisitor
|
|
{
|
|
public:
|
|
/** Builds a caret position graph for pRootNode */
|
|
SmCaretPosGraphBuildingVisitor( SmNode* pRootNode );
|
|
virtual ~SmCaretPosGraphBuildingVisitor() {}
|
|
void Visit( SmTableNode* pNode );
|
|
void Visit( SmBraceNode* pNode );
|
|
void Visit( SmBracebodyNode* pNode );
|
|
void Visit( SmOperNode* pNode );
|
|
void Visit( SmAlignNode* pNode );
|
|
void Visit( SmAttributNode* pNode );
|
|
void Visit( SmFontNode* pNode );
|
|
void Visit( SmUnHorNode* pNode );
|
|
void Visit( SmBinHorNode* pNode );
|
|
void Visit( SmBinVerNode* pNode );
|
|
void Visit( SmBinDiagonalNode* pNode );
|
|
void Visit( SmSubSupNode* pNode );
|
|
void Visit( SmMatrixNode* pNode );
|
|
void Visit( SmPlaceNode* pNode );
|
|
void Visit( SmTextNode* pNode );
|
|
void Visit( SmSpecialNode* pNode );
|
|
void Visit( SmGlyphSpecialNode* pNode );
|
|
void Visit( SmMathSymbolNode* pNode );
|
|
void Visit( SmBlankNode* pNode );
|
|
void Visit( SmErrorNode* pNode );
|
|
void Visit( SmLineNode* pNode );
|
|
void Visit( SmExpressionNode* pNode );
|
|
void Visit( SmPolyLineNode* pNode );
|
|
void Visit( SmRootNode* pNode );
|
|
void Visit( SmRootSymbolNode* pNode );
|
|
void Visit( SmRectangleNode* pNode );
|
|
void Visit( SmVerticalBraceNode* pNode );
|
|
SmCaretPosGraph* Graph( ){
|
|
return pGraph;
|
|
}
|
|
private:
|
|
SmCaretPosGraphEntry* pRightMost;
|
|
SmCaretPosGraph* pGraph;
|
|
};
|
|
|
|
/////////////////////////////// SmCloningVisitor ///////////////////////////////
|
|
|
|
/** Visitor for cloning a pNode
|
|
*
|
|
* This visitor creates deep clones.
|
|
*/
|
|
class SmCloningVisitor : public SmVisitor
|
|
{
|
|
public:
|
|
SmCloningVisitor( ){ pResult = NULL; }
|
|
virtual ~SmCloningVisitor() {}
|
|
void Visit( SmTableNode* pNode );
|
|
void Visit( SmBraceNode* pNode );
|
|
void Visit( SmBracebodyNode* pNode );
|
|
void Visit( SmOperNode* pNode );
|
|
void Visit( SmAlignNode* pNode );
|
|
void Visit( SmAttributNode* pNode );
|
|
void Visit( SmFontNode* pNode );
|
|
void Visit( SmUnHorNode* pNode );
|
|
void Visit( SmBinHorNode* pNode );
|
|
void Visit( SmBinVerNode* pNode );
|
|
void Visit( SmBinDiagonalNode* pNode );
|
|
void Visit( SmSubSupNode* pNode );
|
|
void Visit( SmMatrixNode* pNode );
|
|
void Visit( SmPlaceNode* pNode );
|
|
void Visit( SmTextNode* pNode );
|
|
void Visit( SmSpecialNode* pNode );
|
|
void Visit( SmGlyphSpecialNode* pNode );
|
|
void Visit( SmMathSymbolNode* pNode );
|
|
void Visit( SmBlankNode* pNode );
|
|
void Visit( SmErrorNode* pNode );
|
|
void Visit( SmLineNode* pNode );
|
|
void Visit( SmExpressionNode* pNode );
|
|
void Visit( SmPolyLineNode* pNode );
|
|
void Visit( SmRootNode* pNode );
|
|
void Visit( SmRootSymbolNode* pNode );
|
|
void Visit( SmRectangleNode* pNode );
|
|
void Visit( SmVerticalBraceNode* pNode );
|
|
/** Clone a pNode */
|
|
SmNode* Clone( SmNode* pNode );
|
|
private:
|
|
SmNode* pResult;
|
|
/** Clone children of pSource and give them to pTarget */
|
|
void CloneKids( SmStructureNode* pSource, SmStructureNode* pTarget );
|
|
/** Clone attributes on a pNode */
|
|
void CloneNodeAttr( SmNode* pSource, SmNode* pTarget );
|
|
};
|
|
|
|
|
|
/////////////////////////////// SmSelectionDrawingVisitor ///////////////////////////////
|
|
|
|
class SmSelectionDrawingVisitor : public SmDefaultingVisitor
|
|
{
|
|
public:
|
|
/** Draws a selection on rDevice for the selection on pTree */
|
|
SmSelectionDrawingVisitor( OutputDevice& rDevice, SmNode* pTree, Point Offset );
|
|
virtual ~SmSelectionDrawingVisitor() {}
|
|
void Visit( SmTextNode* pNode );
|
|
using SmDefaultingVisitor::Visit;
|
|
private:
|
|
/** Reference to drawing device */
|
|
OutputDevice& rDev;
|
|
/** True if aSelectionArea have been initialized */
|
|
bool bHasSelectionArea;
|
|
/** The current area that is selected */
|
|
Rectangle aSelectionArea;
|
|
/** Extend the area that must be selected */
|
|
void ExtendSelectionArea( Rectangle aArea );
|
|
/** Default visiting method */
|
|
void DefaultVisit( SmNode* pNode );
|
|
/** Visit the children of a given pNode */
|
|
void VisitChildren( SmNode* pNode );
|
|
};
|
|
|
|
/////////////////////////////// SmNodeToTextVisitor ///////////////////////////////
|
|
|
|
/** Extract command text from pNodes */
|
|
class SmNodeToTextVisitor : public SmVisitor
|
|
{
|
|
public:
|
|
SmNodeToTextVisitor( SmNode* pNode, OUString &rText );
|
|
virtual ~SmNodeToTextVisitor() {}
|
|
|
|
void Visit( SmTableNode* pNode );
|
|
void Visit( SmBraceNode* pNode );
|
|
void Visit( SmBracebodyNode* pNode );
|
|
void Visit( SmOperNode* pNode );
|
|
void Visit( SmAlignNode* pNode );
|
|
void Visit( SmAttributNode* pNode );
|
|
void Visit( SmFontNode* pNode );
|
|
void Visit( SmUnHorNode* pNode );
|
|
void Visit( SmBinHorNode* pNode );
|
|
void Visit( SmBinVerNode* pNode );
|
|
void Visit( SmBinDiagonalNode* pNode );
|
|
void Visit( SmSubSupNode* pNode );
|
|
void Visit( SmMatrixNode* pNode );
|
|
void Visit( SmPlaceNode* pNode );
|
|
void Visit( SmTextNode* pNode );
|
|
void Visit( SmSpecialNode* pNode );
|
|
void Visit( SmGlyphSpecialNode* pNode );
|
|
void Visit( SmMathSymbolNode* pNode );
|
|
void Visit( SmBlankNode* pNode );
|
|
void Visit( SmErrorNode* pNode );
|
|
void Visit( SmLineNode* pNode );
|
|
void Visit( SmExpressionNode* pNode );
|
|
void Visit( SmPolyLineNode* pNode );
|
|
void Visit( SmRootNode* pNode );
|
|
void Visit( SmRootSymbolNode* pNode );
|
|
void Visit( SmRectangleNode* pNode );
|
|
void Visit( SmVerticalBraceNode* pNode );
|
|
private:
|
|
/** Extract text from a pNode that constitues a line */
|
|
void LineToText( SmNode* pNode ) {
|
|
Separate( );
|
|
if( pNode )
|
|
pNode->Accept( this );
|
|
Separate( );
|
|
}
|
|
void Append( const OUString &rText ) {
|
|
aCmdText.append( rText );
|
|
}
|
|
/** Append a blank for separation, if needed */
|
|
inline void Separate( ){
|
|
if( aCmdText.isEmpty() || aCmdText[ aCmdText.getLength() - 1 ] != ' ' )
|
|
aCmdText.append(' ');
|
|
}
|
|
/** Output text generated from the pNodes */
|
|
OUStringBuffer aCmdText;
|
|
};
|
|
|
|
#endif /* SMVISITORS_H */
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|