diff options
author | Daisuke Nishino <niboshi000@gmail.com> | 2011-11-15 19:42:35 +0900 |
---|---|---|
committer | Noel Power <noel.power@novell.com> | 2011-11-16 14:54:21 +0000 |
commit | 20dde3737f250ab48b80a28c9c03d348e486dd8b (patch) | |
tree | 03324ac0aac8af25f8b98019d45415698c28979d | |
parent | fix SDK database version number (diff) | |
download | core-20dde3737f250ab48b80a28c9c03d348e486dd8b.tar.gz core-20dde3737f250ab48b80a28c9c03d348e486dd8b.zip |
Move cursor to the right of brace when the closing brace is typed.
-rw-r--r-- | starmath/inc/caret.hxx | 2 | ||||
-rw-r--r-- | starmath/inc/cursor.hxx | 5 | ||||
-rw-r--r-- | starmath/inc/node.hxx | 7 | ||||
-rw-r--r-- | starmath/source/cursor.cxx | 89 | ||||
-rw-r--r-- | starmath/source/node.cxx | 15 | ||||
-rw-r--r-- | starmath/source/view.cxx | 8 |
6 files changed, 122 insertions, 4 deletions
diff --git a/starmath/inc/caret.hxx b/starmath/inc/caret.hxx index cec8bd722482..76e25279fb55 100644 --- a/starmath/inc/caret.hxx +++ b/starmath/inc/caret.hxx @@ -50,7 +50,7 @@ struct SmCaretPos{ //TODO: Consider forgetting about the todo above... As it's really unpleasent. int Index; /** True, if this is a valid caret position */ - bool IsValid() { return pSelectedNode != NULL; } + bool IsValid() const { return pSelectedNode != NULL; } bool operator!=(SmCaretPos pos) const { return pos.pSelectedNode != pSelectedNode || Index != pos.Index; } diff --git a/starmath/inc/cursor.hxx b/starmath/inc/cursor.hxx index 6b6e7168a59c..dcfea886736d 100644 --- a/starmath/inc/cursor.hxx +++ b/starmath/inc/cursor.hxx @@ -118,7 +118,7 @@ public: SmCaretPos GetAnchor(){ return anchor->CaretPos; } /** Get position */ - SmCaretPos GetPosition() { return position->CaretPos; } + SmCaretPos GetPosition() const { return position->CaretPos; } /** True, if the cursor has a selection */ bool HasSelection() { return anchor != position; } @@ -236,6 +236,9 @@ public: /** Draw the caret */ void Draw(OutputDevice& pDev, Point Offset, bool isCaretVisible); + bool IsAtTailOfBracket(SmBracketType eBracketType, SmBraceNode** ppBraceNode = NULL) const; + void MoveAfterBracket(SmBraceNode* pBraceNode, bool bMoveAnchor = true); + private: friend class SmDocShell; diff --git a/starmath/inc/node.hxx b/starmath/inc/node.hxx index 07aca32eaa29..1ecde44b406e 100644 --- a/starmath/inc/node.hxx +++ b/starmath/inc/node.hxx @@ -119,13 +119,13 @@ public: virtual SmNode * GetSubNode(sal_uInt16 nIndex); const SmNode * GetSubNode(sal_uInt16 nIndex) const { - return ((SmNode *) this)->GetSubNode(nIndex); + return const_cast<SmNode *>(this)->GetSubNode(nIndex); } virtual SmNode * GetLeftMost(); const SmNode * GetLeftMost() const { - return ((SmNode *) this)->GetLeftMost(); + return const_cast<SmNode *>(this)->GetLeftMost(); } sal_uInt16 & Flags() { return nFlags; } @@ -149,6 +149,8 @@ public: virtual void Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell); virtual void PrepareAttributes(); + sal_uInt16 FindIndex() const; + #if OSL_DEBUG_LEVEL void ToggleDebug() const; #endif @@ -206,6 +208,7 @@ public: /** Get the parent node of this node */ SmStructureNode* GetParent(){ return aParentNode; } + const SmStructureNode* GetParent() const { return aParentNode; } /** Set the parent node */ void SetParent(SmStructureNode* parent){ aParentNode = parent; diff --git a/starmath/source/cursor.cxx b/starmath/source/cursor.cxx index 5d92d44691c3..ab4094ab03e2 100644 --- a/starmath/source/cursor.cxx +++ b/starmath/source/cursor.cxx @@ -1474,6 +1474,95 @@ void SmCursor::RequestRepaint(){ } } +bool SmCursor::IsAtTailOfBracket(SmBracketType eBracketType, SmBraceNode** ppBraceNode) const { + const SmCaretPos pos = GetPosition(); + if (!pos.IsValid()) { + return false; + } + + SmNode* pNode = pos.pSelectedNode; + + if (pNode->GetType() == NTEXT) { + SmTextNode* pTextNode = static_cast<SmTextNode*>(pNode); + if (pos.Index < pTextNode->GetText().Len()) { + // The cursor is on a text node and at the middle of it. + return false; + } + } else { + if (pos.Index < 1) { + return false; + } + } + + while (true) { + SmStructureNode* pParentNode = pNode->GetParent(); + if (!pParentNode) { + // There's no brace body node in the ancestors. + return false; + } + + sal_uInt16 index = pNode->FindIndex(); + if (index + 1 != pParentNode->GetNumSubNodes()) { + // The cursor is not at the tail at one of ancestor nodes. + return false; + } + + pNode = pParentNode; + if (pNode->GetType() == NBRACEBODY) { + // Found the brace body node. + break; + } + } + + SmStructureNode* pBraceNodeTmp = pNode->GetParent(); + if (!pBraceNodeTmp || pBraceNodeTmp->GetType() != NBRACE) { + // Brace node is invalid. + return false; + } + + SmBraceNode* pBraceNode = static_cast<SmBraceNode*>(pBraceNodeTmp); + SmMathSymbolNode* pClosingNode = pBraceNode->ClosingBrace(); + if (!pClosingNode) { + // Couldn't get closing symbol node. + return false; + } + + // Check if the closing brace matches eBracketType. + SmTokenType eClosingTokenType = pClosingNode->GetToken().eType; + switch (eBracketType) { + case NoneBrackets: if (eClosingTokenType != TNONE) { return false; } break; + case RoundBrackets: if (eClosingTokenType != TRPARENT) { return false; } break; + case SquareBrackets: if (eClosingTokenType != TRBRACKET) { return false; } break; + case DoubleSquareBrackets: if (eClosingTokenType != TRDBRACKET) { return false; } break; + case LineBrackets: if (eClosingTokenType != TRLINE) { return false; } break; + case DoubleLineBrackets: if (eClosingTokenType != TRDLINE) { return false; } break; + case CurlyBrackets: if (eClosingTokenType != TRBRACE) { return false; } break; + case AngleBrackets: if (eClosingTokenType != TRANGLE) { return false; } break; + case CeilBrackets: if (eClosingTokenType != TRCEIL) { return false; } break; + case FloorBrackets: if (eClosingTokenType != TRFLOOR) { return false; } break; + default: + return false; + } + + if (ppBraceNode) { + *ppBraceNode = static_cast<SmBraceNode*>(pBraceNode); + } + + return true; +} + +void SmCursor::MoveAfterBracket(SmBraceNode* pBraceNode, bool bMoveAnchor) +{ + position->CaretPos.pSelectedNode = pBraceNode; + position->CaretPos.Index = 1; + if (bMoveAnchor) { + anchor->CaretPos.pSelectedNode = pBraceNode; + anchor->CaretPos.Index = 1; + } + RequestRepaint(); +} + + /////////////////////////////////////// SmNodeListParser /////////////////////////////////////// SmNode* SmNodeListParser::Parse(SmNodeList* list, bool bDeleteErrorNodes){ diff --git a/starmath/source/node.cxx b/starmath/source/node.cxx index 93dbedf73ea5..29ed2837980a 100644 --- a/starmath/source/node.cxx +++ b/starmath/source/node.cxx @@ -381,6 +381,21 @@ void SmNode::Prepare(const SmFormat &rFormat, const SmDocShell &rDocShell) pNode->Prepare(rFormat, rDocShell); } +sal_uInt16 SmNode::FindIndex() const +{ + const SmStructureNode* pParent = GetParent(); + if (!pParent) { return 0; } + + for (sal_uInt16 i = 0; i < pParent->GetNumSubNodes(); ++i) { + if (pParent->GetSubNode(i) == this) { + return i; + } + } + + DBG_ASSERT(false, "Connection between parent and child is inconsistent."); + return 0; +} + #if OSL_DEBUG_LEVEL > 1 void SmNode::ToggleDebug() const diff --git a/starmath/source/view.cxx b/starmath/source/view.cxx index 0dec05a7bf38..a77a32a92e77 100644 --- a/starmath/source/view.cxx +++ b/starmath/source/view.cxx @@ -504,6 +504,8 @@ void SmGraphicWindow::KeyInput(const KeyEvent& rKEvt) default: { sal_Unicode code = rKEvt.GetCharCode(); + SmBraceNode* pBraceNode = NULL; + if(code == ' ') { rCursor.InsertElement(BlankElement); }else if(code == 'c' && rKEvt.GetKeyCode().IsMod1()) { @@ -524,6 +526,12 @@ void SmGraphicWindow::KeyInput(const KeyEvent& rKEvt) rCursor.InsertElement(FactorialElement); }else if(code == '%') { rCursor.InsertElement(PercentElement); + }else if(code == ')' && rCursor.IsAtTailOfBracket(RoundBrackets, &pBraceNode)) { + rCursor.MoveAfterBracket(pBraceNode); + }else if(code == ']' && rCursor.IsAtTailOfBracket(SquareBrackets, &pBraceNode)) { + rCursor.MoveAfterBracket(pBraceNode); + }else if(code == '}' && rCursor.IsAtTailOfBracket(CurlyBrackets, &pBraceNode)) { + rCursor.MoveAfterBracket(pBraceNode); }else{ if(code != 0){ rCursor.InsertText(code); |