/** Factor to multiple the squared horizontal distance with *UsedforUpandDownmovement.
*/ #define HORIZONTICAL_DISTANCE_FACTOR 10
/** Enum of direction for movement */ enum SmMovementDirection
{
MoveUp,
MoveDown,
MoveLeft,
MoveRight
};
/** Enum of elements that can inserted into a formula */ enum SmFormulaElement
{
BlankElement,
FactorialElement,
PlusElement,
MinusElement,
CDotElement,
EqualElement,
LessThanElement,
GreaterThanElement,
PercentElement
};
/** Bracket types that can be inserted */ enumclass SmBracketType
{ /** Round brackets, left command "(" */
Round, /**Square brackets, left command "[" */
Square, /** Curly brackets, left command "lbrace" */
Curly,
};
/** A list of nodes */ typedef std::list<SmNode*> SmNodeList;
/** Get position */ const SmCaretPos& GetPosition() const { return mpPosition->CaretPos; }
/** True, if the cursor has a selection */ bool HasSelection() const { return mpAnchor != mpPosition; }
/** Move the position of this cursor */ void Move(OutputDevice* pDev, SmMovementDirection direction, bool bMoveAnchor = true);
/** Move to the caret position closest to a given point */ void MoveTo(OutputDevice* pDev, const Point& pos, bool bMoveAnchor);
/** Delete the current selection or do nothing */ voidDelete();
/** Delete selection, previous element or merge lines * *Thismethodimplementsthebehaviourofbackspace.
*/ void DeletePrev(OutputDevice* pDev);
/** Insert text at the current position */ void InsertText(const OUString& aString);
/** Insert an element into the formula */ void InsertElement(SmFormulaElement element);
/** Insert command text translated into line entries at position * *Note:Thismethodusestheparsertotranslateacommandtextintoa *tree,thenitcopieslineentriesfromthistreeintothecurrenttree. *Willnotworkforcommandssuchasnewlineor##,ifpositionisinamatrix. *Thiswillworkforstufflike"AintersectionB".Butstuffspanningmultiplelines *ordependentonthecontextwhichpositionisplacedinwillnotwork!
*/ void InsertCommandText(const OUString& aCommandText);
/** Insert a special node created from aString * *Usedforhandlinginsertrequestfromthe"catalog"dialog. *Theprovidedstringshouldbeformattedasthedesiredcommand:%phi *Note:thismethodONLYsupportscommandsdefinedinMath.xcu * *FormorecomplexexpressionsuseInsertCommandText,thismethoddoesn't *useSmParser,thismeansthatit'sfaster,butnotasstrong.
*/ void InsertSpecial(std::u16string_view aString);
/** Insert a new row or newline * *Insertsanewrowifpositionisinamatrixorstackcommand. *Otherwiseanewlineisinsertedifwe'reinatoplevelline. * *@returnsTrue,ifanewrow/linecouldbeinserted. * *@remarksIfthecaretisplacedinasublineofacommandthatdoesn'tsupport *thisoperatorthemethodreturnsFALSE,anddoesn'tdoanything.
*/ bool InsertRow();
/** Insert a fraction, use selection as numerator */ void InsertFraction();
/** Create brackets around current selection, or new SmPlaceNode */ void InsertBrackets(SmBracketType eBracketType);
/** Copy the current selection */ void Copy(vcl::Window* pWindow = nullptr); /** Cut the current selection */ void Cut(vcl::Window* pWindow = nullptr)
{
Copy(pWindow); Delete();
} /** Paste the clipboard */ void Paste(vcl::Window* pWindow = nullptr);
/** Returns true if more than one node is selected * *Thismethodisusedforimplementingbackspaceanddelete. *Ifoneofthesecausesacomplexselection,e.g.anodewith *subnodesorsimilar,thisshouldnotbedeletedimmediately.
*/ bool HasComplexSelection();
/** Finds the topmost node in a visual line * *IfMoveUpIfSelectedistrue,thiswillmoveuptotheparentline *iftheparentofthecurrentlineisselected.
*/ static SmNode* FindTopMostNodeInLine(SmNode* pSNode, bool MoveUpIfSelected = false);
/** Draw the caret */ void Draw(OutputDevice& pDev, Point Offset, bool isCaretVisible);
SmCaretPosGraphEntry *mpAnchor, *mpPosition; /** Formula tree */
SmNode* mpTree; /** Owner of the formula tree */
SmDocShell* mpDocShell; /** Graph over caret position in the current tree */
std::unique_ptr<SmCaretPosGraph> mpGraph;
/** Returns a node that is selected, if any could be found */
SmNode* FindSelectedNode(SmNode* pNode);
/** Is this one of the nodes used to compose a line * *TheseareSmExpression,SmBinHorNode,SmUnHorNodeetc.
*/ staticbool IsLineCompositionNode(SmNode const* pNode);
/** Count number of selected nodes, excluding line composition nodes * *Notethisfunctiondoesn'tcountlinecompositionnodesandit *doescountallsubnodesaswellastheownernodes. * *UsedbySmCursor::HasComplexSelection()
*/ int CountSelectedNodes(SmNode* pNode);
/** Convert a visual line to a list * *Notethismethodwilldeleteallthenodesthatwillnolongerbeneeded. *thatincludespLine! *ThismethodalsodeletesSmErrorNode'sasthey'rejustmetainfointheline.
*/ staticvoid LineToList(SmStructureNode* pLine, SmNodeList& rList);
/** Auxiliary function for calling LineToList on a node * *ThismethodsetspNode=NULLandremoveitfromitsparent. *(Assumingithasaparent,andisachildofit).
*/ staticvoid NodeToList(SmNode*& rpNode, SmNodeList& rList)
{ //Remove from parent and NULL rpNode
SmNode* pNode = rpNode; if (rpNode && rpNode->GetParent())
{ //Don't remove this, correctness relies on it int index = rpNode->GetParent()->IndexOfSubNode(rpNode);
assert(index >= 0);
rpNode->GetParent()->SetSubNode(index, nullptr);
}
rpNode = nullptr; //Create line from node if (pNode && IsLineCompositionNode(pNode))
{
LineToList(static_cast<SmStructureNode*>(pNode), rList); return;
} if (pNode)
rList.push_front(pNode);
}
/** Clone a visual line to a clipboard * *...buttheselectedpartonly. *Doesn'tcloneSmErrorNodes,whichareignoredastheyarecontextdependentmetadata.
*/ staticvoid CloneLineToClipboard(SmStructureNode* pLine, SmClipboard* pClipboard);
/** Build pGraph over caret positions */ void BuildGraph();
/** Insert new nodes in the tree after position */ void InsertNodes(std::unique_ptr<SmNodeList> pNewNodes);
/** tries to set position to a specific SmCaretPos * *@returnsfalseonfailuretofindthepositioninpGraph.
*/ bool SetCaretPosition(SmCaretPos pos);
/** Set selected on nodes of the tree */ void AnnotateSelection() const;
/** Clone list of nodes in a clipboard (creates a deep clone) */ static std::unique_ptr<SmNodeList> CloneList(SmClipboard& rClipboard);
/** Find an iterator pointing to the node in pLineList following rCaretPos * *IfrCaretPos.pSelectedNodecannotbefounditisassumedthatit'sinfrontofpLineList, *thusnotanelementinpLineList.Inthiscasethismethodreturnsaniteratortothe *firstelementinpLineList. * *IfthecurrentpositionisinsideanSmTextNode,thisnodewillbesplitintwo,forthis *reasonyoushouldbeawarethatiteratorstoelementsinpLineListmaybeinvalidated,and *thatyoushouldcallPatchLineList()withthisiteratorifnoactionistaken.
*/ static SmNodeList::iterator FindPositionInLineList(SmNodeList* pLineList, const SmCaretPos& rCaretPos);
/** Patch a line list after modification, merge SmTextNode, remove SmPlaceNode etc. * *@parampLineListThelinelisttopatch *@paramaIterIteratorpointingtotheelementthatneedstobepatchedwithitsprevious. * *WhenthelistispatchedtextnodesbeforeandafteraIterwillbemerged. *Ifthere'san,inthecontext,inappropriateSmPlaceNodebeforeorafteraIteritwillalsobe *removed. * *@returnsAcaretpositionequivalenttooneselectingthenodebeforeaIter,themethodreturns *aninvalidSmCaretPostoindicateplacementinfrontoftheline.
*/ static SmCaretPos PatchLineList(SmNodeList* pLineList, SmNodeList::iterator aIter);
/** Take selected nodes from a list * *PutstheselectednodesintopSelectedNodes,orifpSelectedNodesisNULLdeletes *theselectednodes. *Note:Ifthere'saselectioninsideanSmTextNodethisnodewillbesplit,andit *willnotbemergedwhentheselectionhavebeentaken.UsePatchLineListonthe *iteratorreturnstofixthis. * *@returnsAniteratorpointingtotheelementfollowingtheselectiontaken.
*/ static SmNodeList::iterator TakeSelectedNodesFromList(SmNodeList* pLineList,
SmNodeList* pSelectedNodes = nullptr);
/** Create an instance of SmMathSymbolNode usable for brackets */ static SmNode* CreateBracket(SmBracketType eBracketType, bool bIsLeft);
/** The number of times BeginEdit have been called *UsedtoallownestingofBeginEdit()andEndEdit()sections
*/ int mnEditSections; /** Holds data for BeginEdit() and EndEdit() */ bool mbIsEnabledSetModifiedSmDocShell; /** Begin edit section where the tree will be modified */ void BeginEdit(); /** End edit section where the tree will be modified */ void EndEdit(); /** Finish editing * *FinisheseditingbyparsingpLineListandinsertingbackintopParentatnParentIndex. *Thismethodalsorebuildsthegraph,annotatestheselection,setscaretpositionand *CallsEndEdit. * *@remarksPleasenotethatthismethodwilldeletepLineList,astheelementsaretaken. * *@parampLineListListtheconstitutestheeditedline. *@parampParentParenttowhichthelineshouldbeinserted. *@paramnParentIndexIndexinparentwherethelineshouldbeinserted. *@paramPosAfterEditCaretpositiontolookforafterrebuildinggraph. *@parampStartLineLinetotakefirstpositionin,ifPosAfterEditcannotbefound, *leaveitNULLforpLineList.
*/ void FinishEdit(std::unique_ptr<SmNodeList> pLineList, SmStructureNode* pParent, int nParentIndex, SmCaretPos PosAfterEdit, SmNode* pStartLine = nullptr); /** Request the formula is repainted */ void RequestRepaint();
};
/** Minimalistic recursive decent SmNodeList parser * *Thisparserisusedtotakealistofnodesthatconstitutesaline *andparsethemtoatreeofSmBinHorNode,SmUnHorNodeandSmExpression. * *Pleasenote,thiswillnothandleallkindsofnodes,onlynodesthat *constitutesandentryinaline. * *BelowisanEBNFrepresentationofthegrammarusedforthisparser: *\code *Expression->Relation* *Relation->Sum[(=|<|>|...)Sum]* *Sum->Product[(+|-)Product]* *Product->Factor[(*|/)Factor]* *Factor->[+|-|-+|...]*Factor|Postfix *Postfix->node[!]* *\endcode
*/ class SmNodeListParser
{ public: /** Create an instance of SmNodeListParser */
SmNodeListParser() { pList = nullptr; } /** Parse a list of nodes to an expression. * *Olderrornodeswillbedeleted.
*/
SmNode* Parse(SmNodeList* list); /** True, if the token is an operator */ staticbool IsOperator(const SmToken& token); /** True, if the token is a relation operator */ staticbool IsRelationOperator(const SmToken& token); /** True, if the token is a sum operator */ staticbool IsSumOperator(const SmToken& token); /** True, if the token is a product operator */ staticbool IsProductOperator(const SmToken& token); /** True, if the token is a unary operator */ staticbool IsUnaryOperator(const SmToken& token); /** True, if the token is a postfix operator */ staticbool IsPostfixOperator(const SmToken& token);
private:
SmNodeList* pList; /** Get the current terminal */
SmNode* Terminal()
{ if (!pList->empty()) return pList->front(); return nullptr;
} /** Move to next terminal */
SmNode* Next()
{
pList->pop_front(); return Terminal();
} /** Take the current terminal */
SmNode* Take()
{
SmNode* pRetVal = Terminal();
Next(); return pRetVal;
}
SmNode* Expression();
SmNode* Relation();
SmNode* Sum();
SmNode* Product();
SmNode* Factor();
SmNode* Postfix(); static SmNode* Error();
};
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.