[Libreoffice-commits] .: starmath/inc starmath/source
Jonas Finnemann Jensen
jopsen at kemper.freedesktop.org
Sat Nov 6 10:56:33 PDT 2010
starmath/inc/caret.hxx | 6 ++
starmath/inc/visitors.hxx | 8 ---
starmath/source/caret.cxx | 4 +
starmath/source/cursor.cxx | 23 +++++------
starmath/source/visitors.cxx | 89 +++++++++++++++++++++++++++----------------
5 files changed, 80 insertions(+), 50 deletions(-)
New commits:
commit ed84b764fc384d934e1281f2d5ed2038bdad82da
Author: Jonas Finnemann Jensen <jopsen at gmail.com>
Date: Sat Oct 16 20:57:58 2010 +0200
Fixed bug when deleting multiple lines
With this fix only one line can be selected in the visual formula
editor, it's not perfect as caret can still be moved to another line
while selecting, which causes the topmost line to be selected. Anyway,
it works and addresses the bug. Better workaround might be possible
later.
diff --git a/starmath/inc/caret.hxx b/starmath/inc/caret.hxx
index df8abaf..bc22f03 100644
--- a/starmath/inc/caret.hxx
+++ b/starmath/inc/caret.hxx
@@ -177,7 +177,13 @@ public:
nOffset = 0;
}
~SmCaretPosGraph();
+ /** Add a caret position
+ * @remarks If Left and/or Right are set NULL, they will point back to the entry.
+ */
SmCaretPosGraphEntry* Add(SmCaretPosGraphEntry entry);
+ /** Add a caret position
+ * @remarks If left and/or right are set NULL, they will point back to the entry.
+ */
SmCaretPosGraphEntry* Add(SmCaretPos pos,
SmCaretPosGraphEntry* left = NULL,
SmCaretPosGraphEntry* right = NULL){
diff --git a/starmath/inc/visitors.hxx b/starmath/inc/visitors.hxx
index d63bc13..f5f4638 100644
--- a/starmath/inc/visitors.hxx
+++ b/starmath/inc/visitors.hxx
@@ -263,17 +263,13 @@ private:
class SmSetSelectionVisitor : public SmDefaultingVisitor
{
public:
- SmSetSelectionVisitor( SmCaretPos startPos,
- SmCaretPos endPos ){
- StartPos = startPos;
- EndPos = endPos;
- IsSelecting = false;
- }
+ SmSetSelectionVisitor( SmCaretPos startPos, SmCaretPos endPos, SmNode* pNode);
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 );
/** Set IsSelected on all pNodes of pSubTree */
static void SetSelectedOnAll( SmNode* pSubTree, bool IsSelected = true );
diff --git a/starmath/source/caret.cxx b/starmath/source/caret.cxx
index 128c427..a847d13 100644
--- a/starmath/source/caret.cxx
+++ b/starmath/source/caret.cxx
@@ -47,6 +47,10 @@ SmCaretPosGraphEntry* SmCaretPosGraph::Add(SmCaretPosGraphEntry entry){
pNext = new SmCaretPosGraph();
return pNext->Add(entry);
}else{
+ //Set Left and Right to point to the entry itself if they are NULL
+ entry.Left = entry.Left ? entry.Left : Graph + nOffset;
+ entry.Right = entry.Right ? entry.Right : Graph + nOffset;
+ //Save the entry
Graph[nOffset] = entry;
return Graph + nOffset++;
}
diff --git a/starmath/source/cursor.cxx b/starmath/source/cursor.cxx
index 5613c3b..95811bd 100644
--- a/starmath/source/cursor.cxx
+++ b/starmath/source/cursor.cxx
@@ -35,13 +35,13 @@ void SmCursor::Move(OutputDevice* pDev, SmMovementDirection direction, bool bMov
switch(direction){
case MoveLeft:
{
- //If position->Left is NULL, we want NewPos = NULL anyway...
NewPos = position->Left;
+ j_assert(NewPos, "NewPos shouldn't be NULL here!");
}break;
case MoveRight:
{
- //If position->Right is NULL, we want NewPos = NULL anyway...
NewPos = position->Right;
+ j_assert(NewPos, "NewPos shouldn't be NULL here!");
}break;
case MoveUp:
//Implementation is practically identical to MoveDown, except for a single if statement
@@ -177,8 +177,7 @@ bool SmCursor::SetCaretPosition(SmCaretPos pos, bool moveAnchor){
void SmCursor::AnnotateSelection(){
//TODO: Manage a state, reset it upon modification and optimize this call
- SmSetSelectionVisitor SSV(anchor->CaretPos, position->CaretPos);
- pTree->Accept(&SSV);
+ SmSetSelectionVisitor(anchor->CaretPos, position->CaretPos, pTree);
}
void SmCursor::Draw(OutputDevice& pDev, Point Offset){
@@ -202,6 +201,7 @@ void SmCursor::Delete(){
//Find the topmost node of the line that holds the selection
SmNode* pLine = FindTopMostNodeInLine(pSNode, true);
+ j_assert(pLine != pTree, "Shouldn't be able to select the entire tree");
//Get the parent of the line
SmStructureNode* pLineParent = pLine->GetParent();
@@ -1226,19 +1226,18 @@ SmNode* SmCursor::FindTopMostNodeInLine(SmNode* pSNode, bool MoveUpIfSelected){
return NULL;
//Move up parent untill we find a node who's
- //parent isn't selected and not a type of:
+ //parent is NULL or isn't selected and not a type of:
// SmExpressionNode
+ // SmLineNode
// SmBinHorNode
// SmUnHorNode
// SmAlignNode
// SmFontNode
- while((MoveUpIfSelected && pSNode->GetParent()->IsSelected()) ||
- IsLineCompositionNode(pSNode->GetParent())){
+ while(pSNode->GetParent() &&
+ ((MoveUpIfSelected &&
+ pSNode->GetParent()->IsSelected()) ||
+ IsLineCompositionNode(pSNode->GetParent())))
pSNode = pSNode->GetParent();
- j_assert(pSNode, "pSNode shouldn't be NULL, have we hit root node if so, this is bad!");
- if(!pSNode) //I've got to do something, nothing is probably the best solution :)
- return NULL;
- }
//Now we have the selection line node
return pSNode;
}
@@ -1259,6 +1258,7 @@ SmNodeList* SmCursor::LineToList(SmStructureNode* pLine, SmNodeList* list){
SmNodeIterator it(pLine);
while(it.Next()){
switch(it->GetType()){
+ case NLINE:
case NUNHOR:
case NEXPRESSION:
case NBINHOR:
@@ -1304,6 +1304,7 @@ SmNodeList* SmCursor::CloneLineToList(SmStructureNode* pLine, bool bOnlyIfSelect
bool SmCursor::IsLineCompositionNode(SmNode* pNode){
switch(pNode->GetType()){
+ case NLINE:
case NUNHOR:
case NEXPRESSION:
case NBINHOR:
diff --git a/starmath/source/visitors.cxx b/starmath/source/visitors.cxx
index dc5dd38..c385b3b 100644
--- a/starmath/source/visitors.cxx
+++ b/starmath/source/visitors.cxx
@@ -335,7 +335,6 @@ void SmDefaultingVisitor::Visit( SmVerticalBraceNode* pNode )
DefaultVisit( pNode );
}
-
/////////////////////////////// SmCaretDrawingVisitor ////////////////////////////////
SmCaretDrawingVisitor::SmCaretDrawingVisitor( OutputDevice& rDevice,
@@ -435,7 +434,6 @@ void SmCaretPos2LineVisitor::DefaultVisit( SmNode* pNode )
/////////////////////////////// Nasty temporary device!!! ////////////////////////////////
-
#include <tools/gen.hxx>
#include <tools/fract.hxx>
#include <rtl/math.hxx>
@@ -470,7 +468,6 @@ public:
operator OutputDevice & ( ) { return rOutDev; }
};
-
SmTmpDevice2::SmTmpDevice2( OutputDevice &rTheDev, BOOL bUseMap100th_mm ) :
rOutDev( rTheDev )
{
@@ -483,7 +480,6 @@ SmTmpDevice2::SmTmpDevice2( OutputDevice &rTheDev, BOOL bUseMap100th_mm ) :
}
}
-
Color SmTmpDevice2::Impl_GetColor( const Color& rColor )
{
ColorData nNewCol = rColor.GetColor( );
@@ -509,7 +505,6 @@ Color SmTmpDevice2::Impl_GetColor( const Color& rColor )
return Color( nNewCol );
}
-
void SmTmpDevice2::SetFont( const Font &rNewFont )
{
rOutDev.SetFont( rNewFont );
@@ -646,7 +641,6 @@ void SmDrawingVisitor::Visit( SmRootSymbolNode* pNode )
// draw root-sign itself
DrawSpecialNode( pNode );
-
SmTmpDevice2 aTmpDev( ( OutputDevice & ) rDev, TRUE );
aTmpDev.SetFillColor( pNode->GetFont( ).GetColor( ) );
rDev.SetLineColor( );
@@ -809,8 +803,46 @@ void SmDrawingVisitor::DrawChildren( SmNode* pNode )
/////////////////////////////// SmSetSelectionVisitor ////////////////////////////////
-void SmSetSelectionVisitor::SetSelectedOnAll( SmNode* pSubTree, bool IsSelected )
-{
+SmSetSelectionVisitor::SmSetSelectionVisitor( SmCaretPos startPos, SmCaretPos endPos, SmNode* pTree) {
+ StartPos = startPos;
+ EndPos = endPos;
+ IsSelecting = false;
+
+ //Assume that pTree is a SmTableNode
+ j_assert(pTree->GetType() == NTABLE, "pTree should be a SmTableNode!");
+ //Visit root node, this is special as this node cannot be selected, but it's children can!
+ if(pTree->GetType() == NTABLE){
+ //Change state if StartPos is infront of this node
+ if( StartPos.pSelectedNode == pTree && StartPos.Index == 0 )
+ IsSelecting = !IsSelecting;
+ //Change state if EndPos is infront of this node
+ if( EndPos.pSelectedNode == pTree && EndPos.Index == 0 )
+ IsSelecting = !IsSelecting;
+ j_assert(!IsSelecting, "Caret positions needed to set IsSelecting about, shouldn't be possible!");
+
+ //Visit lines
+ SmNodeIterator it( pTree );
+ while( it.Next( ) ) {
+ it->Accept( this );
+ //If we started a selection in this line and it haven't ended, we do that now!
+ if(IsSelecting) {
+ IsSelecting = false;
+ SetSelectedOnAll(it.Current(), true);
+ //Set StartPos and EndPos to invalid positions, this ensures that an unused
+ //start or end (because we forced end above), doesn't start a new selection.
+ StartPos = EndPos = SmCaretPos();
+ }
+ }
+ //Check if pTree isn't selected
+ j_assert(!pTree->IsSelected(), "pTree should never be selected!");
+ //Discard the selection if there's a bug (it's better than crashing)
+ if(pTree->IsSelected())
+ SetSelectedOnAll(pTree, false);
+ }else //This shouldn't happen, but I don't see any reason to die if it does
+ pTree->Accept(this);
+}
+
+void SmSetSelectionVisitor::SetSelectedOnAll( SmNode* pSubTree, bool IsSelected ) {
pSubTree->SetSelected( IsSelected );
//Quick BFS to set all selections
@@ -819,8 +851,7 @@ void SmSetSelectionVisitor::SetSelectedOnAll( SmNode* pSubTree, bool IsSelected
SetSelectedOnAll( it.Current( ), IsSelected );
}
-void SmSetSelectionVisitor::DefaultVisit( SmNode* pNode )
-{
+void SmSetSelectionVisitor::DefaultVisit( SmNode* pNode ) {
//Change state if StartPos is infront of this node
if( StartPos.pSelectedNode == pNode && StartPos.Index == 0 )
IsSelecting = !IsSelecting;
@@ -875,8 +906,7 @@ void SmSetSelectionVisitor::DefaultVisit( SmNode* pNode )
}
}
-void SmSetSelectionVisitor::VisitCompositionNode( SmNode* pNode )
-{
+void SmSetSelectionVisitor::VisitCompositionNode( SmNode* pNode ) {
//Change state if StartPos is infront of this node
if( StartPos.pSelectedNode == pNode && StartPos.Index == 0 )
IsSelecting = !IsSelecting;
@@ -903,8 +933,7 @@ void SmSetSelectionVisitor::VisitCompositionNode( SmNode* pNode )
IsSelecting = !IsSelecting;
}
-void SmSetSelectionVisitor::Visit( SmTextNode* pNode )
-{
+void SmSetSelectionVisitor::Visit( SmTextNode* pNode ) {
long i1 = -1,
i2 = -1;
if( StartPos.pSelectedNode == pNode )
@@ -946,36 +975,33 @@ void SmSetSelectionVisitor::Visit( SmTextNode* pNode )
pNode->SetSelectionEnd( end );
}
-void SmSetSelectionVisitor::Visit( SmExpressionNode* pNode )
-{
+void SmSetSelectionVisitor::Visit( SmExpressionNode* pNode ) {
VisitCompositionNode( pNode );
}
-void SmSetSelectionVisitor::Visit( SmAlignNode* pNode )
-{
+void SmSetSelectionVisitor::Visit( SmLineNode* pNode ) {
VisitCompositionNode( pNode );
}
-void SmSetSelectionVisitor::Visit( SmBinHorNode* pNode )
-{
+void SmSetSelectionVisitor::Visit( SmAlignNode* pNode ) {
VisitCompositionNode( pNode );
}
-void SmSetSelectionVisitor::Visit( SmUnHorNode* pNode )
-{
+void SmSetSelectionVisitor::Visit( SmBinHorNode* pNode ) {
VisitCompositionNode( pNode );
}
-void SmSetSelectionVisitor::Visit( SmFontNode* pNode )
-{
+void SmSetSelectionVisitor::Visit( SmUnHorNode* pNode ) {
VisitCompositionNode( pNode );
}
-
+void SmSetSelectionVisitor::Visit( SmFontNode* pNode ) {
+ VisitCompositionNode( pNode );
+}
/////////////////////////////// SmCaretPosGraphBuildingVisitor ////////////////////////////////
-SmCaretPosGraphBuildingVisitor::SmCaretPosGraphBuildingVisitor( SmNode* pRootNode ){
+SmCaretPosGraphBuildingVisitor::SmCaretPosGraphBuildingVisitor( SmNode* pRootNode ) {
pRightMost = NULL;
pGraph = new SmCaretPosGraph( );
//pRootNode should always be a table
@@ -995,7 +1021,7 @@ SmCaretPosGraphBuildingVisitor::SmCaretPosGraphBuildingVisitor( SmNode* pRootNod
//The argument for doing this is that we now don't have to worry about SmLineNode
//being a visual line composition node. Thus, no need for yet another special case
//in SmCursor::IsLineCompositionNode and everywhere this method is used.
- if( it->GetType( ) != NLINE )
+ //if( it->GetType( ) != NLINE )
pRightMost = pGraph->Add( SmCaretPos( it.Current( ), 0 ) );
it->Accept( this );
}
@@ -1004,11 +1030,11 @@ SmCaretPosGraphBuildingVisitor::SmCaretPosGraphBuildingVisitor( SmNode* pRootNod
}
void SmCaretPosGraphBuildingVisitor::Visit( SmLineNode* pNode ){
- pRightMost = NULL;
+ //pRightMost = NULL;
SmNodeIterator it( pNode );
while( it.Next( ) ){
- if( !pRightMost )
- pRightMost = pGraph->Add( SmCaretPos( it.Current( ), 0 ) );
+ //if( !pRightMost )
+ // pRightMost = pGraph->Add( SmCaretPos( it.Current( ), 0 ) );
it->Accept( this );
}
}
@@ -1489,7 +1515,6 @@ void SmCaretPosGraphBuildingVisitor::Visit( SmBinDiagonalNode* pNode )
pRightMost = right;
}
-
//Straigt forward ( I think )
void SmCaretPosGraphBuildingVisitor::Visit( SmBinHorNode* pNode )
{
@@ -1853,7 +1878,6 @@ void SmCloningVisitor::Visit( SmBraceNode* pNode )
pResult = pClone;
}
-
void SmCloningVisitor::Visit( SmBracebodyNode* pNode )
{
SmBracebodyNode* pClone = new SmBracebodyNode( pNode->GetToken( ) );
@@ -2114,7 +2138,6 @@ void SmSelectionDrawingVisitor::Visit( SmTextNode* pNode )
}
}
-
/////////////////////////////// SmNodeToTextVisitor ///////////////////////////////
void SmNodeToTextVisitor::Visit( SmTableNode* pNode )
More information about the Libreoffice-commits
mailing list