[Libreoffice-commits] .: starmath/inc starmath/source

Jonas Finnemann Jensen jopsen at kemper.freedesktop.org
Sun Jan 30 11:22:01 PST 2011


 starmath/inc/cursor.hxx    |   28 ++++++++
 starmath/source/cursor.cxx |  152 ++++++++++++++++++++++++---------------------
 starmath/source/view.cxx   |    5 +
 3 files changed, 115 insertions(+), 70 deletions(-)

New commits:
commit 93f8e59094fbca480030d719c9de8be783205427
Author: Jonas Finnemann Jensen <jopsen at gmail.com>
Date:   Wed Nov 24 09:36:21 2010 +0100

    Enable line deletion in starmath
    
    * Implemented SmCursor::DeletePrev, for deletion of lines
    * Fixed nasty bug in SmCursor::InsertRow
    * Code cleanup in cursor.cxx

diff --git a/starmath/inc/cursor.hxx b/starmath/inc/cursor.hxx
index 49f1e0c..b5fbd13 100644
--- a/starmath/inc/cursor.hxx
+++ b/starmath/inc/cursor.hxx
@@ -132,6 +132,12 @@ public:
     /** Delete the current selection or do nothing */
     void Delete();
 
+    /** Delete selection, previous element or merge lines
+     *
+     * This method implements the behaviour of backspace.
+     */
+    void DeletePrev(OutputDevice* pDev);
+
     /** Insert text at the current position */
     void InsertText(XubString aString);
 
@@ -270,6 +276,28 @@ private:
      */
     static SmNodeList* LineToList(SmStructureNode* pLine, SmNodeList* pList = new SmNodeList());
 
+    /** Auxiliary function for calling LineToList on a node
+     *
+     * This method sets pNode = NULL and remove it from it's parent.
+     * (Assuming it has a parent, and is a child of it).
+     */
+    static SmNodeList* NodeToList(SmNode*& rpNode, SmNodeList* pList = new SmNodeList()){
+        //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);
+            if(index != -1)
+                rpNode->GetParent()->SetSubNode(index, NULL);
+        }
+        rpNode = NULL;
+        //Create line from node
+        if(pNode && IsLineCompositionNode(pNode))
+            return LineToList((SmStructureNode*)pNode, pList);
+        if(pNode)
+            pList->push_front(pNode);
+        return pList;
+    }
+
     /** Clone a visual line to a list
      *
      * Doesn't clone SmErrorNode's these are ignored, as they are context dependent metadata.
diff --git a/starmath/source/cursor.cxx b/starmath/source/cursor.cxx
index 25c4522..c530366 100644
--- a/starmath/source/cursor.cxx
+++ b/starmath/source/cursor.cxx
@@ -186,6 +186,76 @@ void SmCursor::Draw(OutputDevice& pDev, Point Offset, bool isCaretVisible){
     SmCaretDrawingVisitor(pDev, GetPosition(), Offset, isCaretVisible);
 }
 
+void SmCursor::DeletePrev(OutputDevice* pDev){
+    //Delete only a selection if there's a selection
+    if(HasSelection()){
+        Delete();
+        return;
+    }
+
+    SmNode* pLine = FindTopMostNodeInLine(position->CaretPos.pSelectedNode);
+    SmStructureNode* pLineParent = pLine->GetParent();
+    int nLineOffset = pLineParent->IndexOfSubNode(pLine);
+
+    //If we're in front of a node who's parent is a TABLE
+    if(pLineParent->GetType() == NTABLE && position->CaretPos.Index == 0 && nLineOffset > 0){
+        //Now we can merge with nLineOffset - 1
+        BeginEdit();
+        //Line to merge things into, so we can delete pLine
+        SmNode* pMergeLine = pLineParent->GetSubNode(nLineOffset-1);
+        j_assert(pMergeLine, "pMergeLine cannot be NULL!");
+        //Convert first line to list
+        SmNodeList *pLineList = NodeToList(pMergeLine);
+        //Find iterator to patch
+        SmNodeList::iterator patchPoint = pLineList->end();
+        patchPoint--;
+        //Convert second line to list
+        NodeToList(pLine, pLineList);
+        //Patch the line list
+        patchPoint++;
+        SmCaretPos PosAfterDelete = PatchLineList(pLineList, patchPoint);
+        //Parse the line
+        pLine = SmNodeListParser().Parse(pLineList);
+        delete pLineList;
+        pLineParent->SetSubNode(nLineOffset-1, pLine);
+        //Delete the removed line slot
+        SmNodeArray lines(pLineParent->GetNumSubNodes()-1);
+        for(int i = 0; i < pLineParent->GetNumSubNodes(); i++){
+            if(i < nLineOffset)
+                lines[i] = pLineParent->GetSubNode(i);
+            else if(i > nLineOffset)
+                lines[i-1] = pLineParent->GetSubNode(i);
+        }
+        pLineParent->SetSubNodes(lines);
+        //Rebuild graph
+        anchor = NULL;
+        position = NULL;
+        BuildGraph();
+        AnnotateSelection();
+        //Set caret position
+        if(!SetCaretPosition(PosAfterDelete, true))
+            SetCaretPosition(SmCaretPos(pLine, 0), true);
+        //Finish editing
+        EndEdit();
+
+    //TODO: If we're in an empty (sub/super/*) script
+    /*}else if(pLineParent->GetType() == NSUBSUP &&
+             nLineOffset != 0 &&
+             pLine->GetType() == NEXPRESSION &&
+             pLine->GetNumSubNodes() == 0){
+        //There's a (sub/super/*) script we can delete
+    //Consider selecting the entire script if GetNumSubNodes() != 0 or pLine->GetType() != NEXPRESSION
+    //TODO: Handle case where we delete a limit
+    */
+
+    //Else move select, and delete if not complex
+    }else{
+        this->Move(pDev, MoveLeft, false);
+        if(!this->HasComplexSelection())
+            Delete();
+    }
+}
+
 void SmCursor::Delete(){
     //Return if we don't have a selection to delete
     if(!HasSelection())
@@ -214,13 +284,7 @@ void SmCursor::Delete(){
     //Position after delete
     SmCaretPos PosAfterDelete;
 
-    SmNodeList* pLineList;
-    if(IsLineCompositionNode(pLine))
-        pLineList = LineToList((SmStructureNode*)pLine);
-    else {
-        pLineList = new SmNodeList();
-        pLineList->push_back(pLine);
-    }
+    SmNodeList* pLineList = NodeToList(pLine);
 
     //Take the selected nodes and delete them...
     SmNodeList::iterator patchIt = TakeSelectedNodesFromList(pLineList);
@@ -256,13 +320,7 @@ void SmCursor::InsertNodes(SmNodeList* pNewNodes){
     j_assert(nParentIndex != -1, "pLine must be a subnode of pLineParent!");
 
     //Convert line to list
-    SmNodeList* pLineList;
-    if(IsLineCompositionNode(pLine))
-        pLineList = LineToList((SmStructureNode*)pLine);
-    else {
-        pLineList = new SmNodeList();
-        pLineList->push_front(pLine);
-    }
+    SmNodeList* pLineList = NodeToList(pLine);
 
     //Find iterator for place to insert nodes
     SmNodeList::iterator it = FindPositionInLineList(pLineList, pos);
@@ -465,13 +523,7 @@ void SmCursor::InsertSubSup(SmSubSup eSubSup) {
     BeginEdit();
 
     //Convert line to list
-    SmNodeList* pLineList;
-    if(IsLineCompositionNode(pLine))
-        pLineList = LineToList((SmStructureNode*)pLine);
-    else {
-        pLineList = new SmNodeList();
-        pLineList->push_front(pLine);
-    }
+    SmNodeList* pLineList = NodeToList(pLine);
 
     //Take the selection, and/or find iterator for current position
     SmNodeList* pSelectedNodesList = new SmNodeList();
@@ -518,14 +570,7 @@ void SmCursor::InsertSubSup(SmSubSup eSubSup) {
 
     //Convert existing, if any, sub-/superscript line to list
     SmNode *pScriptLine = pSubSup->GetSubSup(eSubSup);
-    SmNodeList* pScriptLineList;
-    if(pScriptLine && IsLineCompositionNode(pScriptLine))
-        pScriptLineList = LineToList((SmStructureNode*)pScriptLine);
-    else{
-        pScriptLineList = new SmNodeList();
-        if(pScriptLine)
-            pScriptLineList->push_front(pScriptLine);
-    }
+    SmNodeList* pScriptLineList = NodeToList(pScriptLine);
 
     //Add selection to pScriptLineList
     unsigned int nOldSize = pScriptLineList->size();
@@ -601,13 +646,7 @@ bool SmCursor::InsertLimit(SmSubSup eSubSup, bool bMoveCaret) {
     //If it's already there... let's move the caret
     } else if(bMoveCaret){
         pLine = pSubSup->GetSubSup(eSubSup);
-        SmNodeList* pLineList;
-        if(IsLineCompositionNode(pLine))
-            pLineList = LineToList((SmStructureNode*)pLine);
-        else {
-            pLineList = new SmNodeList();
-            pLineList->push_front(pLine);
-        }
+        SmNodeList* pLineList = NodeToList(pLine);
         if(pLineList->size() > 0)
             PosAfterLimit = SmCaretPos::GetPosAfter(pLineList->back());
         pLine = SmNodeListParser().Parse(pLineList);
@@ -649,13 +688,7 @@ void SmCursor::InsertBrackets(SmBracketType eBracketType) {
     j_assert( nParentIndex != -1, "pLine must be a subnode of pLineParent!");
 
     //Convert line to list
-    SmNodeList *pLineList;
-    if(IsLineCompositionNode(pLine))
-        pLineList = LineToList((SmStructureNode*)pLine);
-    else {
-        pLineList = new SmNodeList();
-        pLineList->push_front(pLine);
-    }
+    SmNodeList *pLineList = NodeToList(pLine);
 
     //Take the selection, and/or find iterator for current position
     SmNodeList *pSelectedNodesList = new SmNodeList();
@@ -816,13 +849,7 @@ bool SmCursor::InsertRow() {
     BeginEdit();
 
     //Convert line to list
-    SmNodeList *pLineList;
-    if(IsLineCompositionNode(pLine))
-        pLineList = LineToList((SmStructureNode*)pLine);
-    else {
-        pLineList = new SmNodeList();
-        pLineList->push_front(pLine);
-    }
+    SmNodeList *pLineList = NodeToList(pLine);
 
     //Find position in line
     SmNodeList::iterator it;
@@ -849,20 +876,21 @@ bool SmCursor::InsertRow() {
         //Parse new line
         SmNode *pNewLine = SmNodeListParser().Parse(pNewLineList);
         delete pNewLineList;
-        //Get position before we wrap in SmLineNode
-        //NOTE: This should be done after, if SmLineNode ever becomes a line composition node
-        PosAfterInsert = SmCaretPos(pNewLine, 0);
         //Wrap pNewLine in SmLineNode if needed
         if(pLineParent->GetType() == NLINE) {
             SmLineNode *pNewLineNode = new SmLineNode(SmToken(TNEWLINE, '\0', "newline"));
             pNewLineNode->SetSubNodes(pNewLine, NULL);
             pNewLine = pNewLineNode;
         }
+        //Get position
+        PosAfterInsert = SmCaretPos(pNewLine, 0);
         //Move other nodes if needed
         for( int i = pTable->GetNumSubNodes(); i > nTableIndex + 1; i--)
             pTable->SetSubNode(i, pTable->GetSubNode(i-1));
+
         //Insert new line
         pTable->SetSubNode(nTableIndex + 1, pNewLine);
+
         //Check if we need to change token type:
         if(pTable->GetNumSubNodes() > 2 && pTable->GetToken().eType == TBINOM) {
             SmToken tok = pTable->GetToken();
@@ -919,13 +947,7 @@ void SmCursor::InsertFraction() {
     BeginEdit();
 
     //Convert line to list
-    SmNodeList* pLineList;
-    if(IsLineCompositionNode(pLine))
-        pLineList = LineToList((SmStructureNode*)pLine);
-    else {
-        pLineList = new SmNodeList();
-        pLineList->push_front(pLine);
-    }
+    SmNodeList* pLineList = NodeToList(pLine);
 
     //Take the selection, and/or find iterator for current position
     SmNodeList* pSelectedNodesList = new SmNodeList();
@@ -957,7 +979,6 @@ void SmCursor::InsertFraction() {
     FinishEdit(pLineList, pLineParent, nParentIndex, SmCaretPos(pDenom, 1));
 }
 
-
 void SmCursor::InsertText(XubString aString){
     BeginEdit();
 
@@ -1142,13 +1163,7 @@ void SmCursor::InsertCommandText(XubString aCommandText) {
     pSubExpr->Prepare(pDocShell->GetFormat(), *pDocShell);
 
     //Convert subtree to list
-    SmNodeList* pLineList;
-    if(IsLineCompositionNode(pSubExpr))
-        pLineList = LineToList((SmStructureNode*)pSubExpr);
-    else {
-        pLineList = new SmNodeList();
-        pLineList->push_front(pSubExpr);
-    }
+    SmNodeList* pLineList = NodeToList(pSubExpr);
 
     BeginEdit();
 
@@ -1219,7 +1234,6 @@ SmNodeList* SmCursor::CloneList(SmNodeList* pList){
     return pClones;
 }
 
-
 void SmCursor::SetClipboard(SmNodeList* pList){
     if(pClipboard){
         //Delete all nodes on the clipboard
diff --git a/starmath/source/view.cxx b/starmath/source/view.cxx
index 810ddd7..e2509dd 100644
--- a/starmath/source/view.cxx
+++ b/starmath/source/view.cxx
@@ -451,7 +451,6 @@ void SmGraphicWindow::KeyInput(const KeyEvent& rKEvt)
 #endif /* DEBUG_ENABLE_DUMPASDOT */
         }break;
         case KEY_DELETE:
-        case KEY_BACKSPACE:
         {
             if(!rCursor.HasSelection()){
                 rCursor.Move(this, nCode == KEY_DELETE ? MoveRight : MoveLeft, false);
@@ -459,6 +458,10 @@ void SmGraphicWindow::KeyInput(const KeyEvent& rKEvt)
             }
             rCursor.Delete();
         }break;
+        case KEY_BACKSPACE:
+        {
+            rCursor.DeletePrev(this);
+        }break;
         case KEY_ADD:
             rCursor.InsertElement(PlusElement);
             break;


More information about the Libreoffice-commits mailing list