[ooo-build-commit] .: 3 commits - sc/inc sc/source

Fridrich Strba fridrich at kemper.freedesktop.org
Thu Sep 16 02:15:13 PDT 2010


 sc/inc/document.hxx              |    1 
 sc/source/core/data/document.cxx |    7 
 sc/source/ui/inc/cellsh.hxx      |    1 
 sc/source/ui/inc/tabview.hxx     |   14 +
 sc/source/ui/view/cellsh4.cxx    |  128 ++++++++++++----
 sc/source/ui/view/gridwin.cxx    |   17 +-
 sc/source/ui/view/select.cxx     |    5 
 sc/source/ui/view/tabview.cxx    |    3 
 sc/source/ui/view/tabview2.cxx   |  307 ++++++++++++++++++++++++++++++++++++++-
 sc/source/ui/view/tabview3.cxx   |  111 ++++----------
 sc/source/ui/view/tabvwsh3.cxx   |   19 +-
 sc/source/ui/view/viewdata.cxx   |   11 -
 12 files changed, 483 insertions(+), 141 deletions(-)

New commits:
commit 9b2c8e0cd13c2a90237dfb9d0cf15952cc2d931b
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Thu Sep 16 11:12:39 2010 +0200

    calc-selection-fixed-cursor-fix.diff: Migrated
    
    n#595822, when making selection, don't move the cursor position.

diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx
index 9cd5155..da7bfb4 100644
--- a/sc/source/ui/view/gridwin.cxx
+++ b/sc/source/ui/view/gridwin.cxx
@@ -2189,7 +2189,7 @@ void __EXPORT ScGridWindow::MouseButtonUp( const MouseEvent& rMEvt )
     if ( rMEvt.IsLeft() && pViewData->GetView()->GetSelEngine()->SelMouseButtonUp( rMEvt ) )
     {
 //		rMark.MarkToSimple();
-        pViewData->GetView()->UpdateAutoFillMark();
+        pViewData->GetView()->SelectionChanged();
 
         SfxDispatcher* pDisp = pViewData->GetViewShell()->GetDispatcher();
         BOOL bFormulaMode = pScMod->IsFormulaMode();
commit d3091706329af9b5ccb9e2f92682325238c1ec0a
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Thu Sep 16 11:09:29 2010 +0200

    calc-selection-fixed-cursor.diff: Migrated
    
    n#502717, i#21869, i#97093, when making selection, don't move the cursor position

diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 80eaf2c..bbe9640 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -866,6 +866,7 @@ public:
                                                 ScRange* pLastRange = NULL,
                                                 Rectangle* pLastMM = NULL ) const;
 
+    void            SkipOverlapped( SCCOL& rCol, SCROW& rRow, SCTAB nTab ) const;
     BOOL			IsHorOverlapped( SCCOL nCol, SCROW nRow, SCTAB nTab ) const;
     BOOL			IsVerOverlapped( SCCOL nCol, SCROW nRow, SCTAB nTab ) const;
 
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 2d1ea48..0aa44d7 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -4766,6 +4766,13 @@ BOOL ScDocument::RefreshAutoFilter( SCCOL nStartCol, SCROW nStartRow,
     return bChange;
 }
 
+void ScDocument::SkipOverlapped( SCCOL& rCol, SCROW& rRow, SCTAB nTab ) const
+{
+    while (IsHorOverlapped(rCol, rRow, nTab))
+        --rCol;
+    while (IsVerOverlapped(rCol, rRow, nTab))
+        --rRow;
+}
 
 BOOL ScDocument::IsHorOverlapped( SCCOL nCol, SCROW nRow, SCTAB nTab ) const
 {
diff --git a/sc/source/ui/inc/cellsh.hxx b/sc/source/ui/inc/cellsh.hxx
index 9202c39..0149334 100644
--- a/sc/source/ui/inc/cellsh.hxx
+++ b/sc/source/ui/inc/cellsh.hxx
@@ -34,6 +34,7 @@
 #include <svx/svdmark.hxx>
 #include <tools/link.hxx>
 #include "formatsh.hxx"
+#include "address.hxx"
 
 class SvxClipboardFmtItem;
 class TransferableDataHelper;
diff --git a/sc/source/ui/inc/tabview.hxx b/sc/source/ui/inc/tabview.hxx
index d97a600..bee47de 100644
--- a/sc/source/ui/inc/tabview.hxx
+++ b/sc/source/ui/inc/tabview.hxx
@@ -176,7 +176,6 @@ private:
     BOOL				bInActivatePart;
     BOOL				bInZoomUpdate;
     BOOL				bMoveIsShift;
-    BOOL				bNewStartIfMarking;
 
     void			Init();
 
@@ -197,6 +196,10 @@ private:
     static void		SetScrollBar( ScrollBar& rScroll, long nRangeMax, long nVisible, long nPos, BOOL bLayoutRTL );
     static long		GetScrollBarPos( ScrollBar& rScroll, BOOL bLayoutRTL );
 
+    void            GetPageMoveEndPosition(SCsCOL nMovX, SCsROW nMovY, SCsCOL& rPageX, SCsROW& rPageY);
+    void            GetAreaMoveEndPosition(SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode,
+                                           SCsCOL& rAreaX, SCsROW& rAreaY, ScFollowMode& rMode);
+
 protected:
     void			UpdateHeaderWidth( const ScVSplitPos* pWhich = NULL,
                                         const SCROW* pPosY = NULL );
@@ -385,12 +388,7 @@ public:
 
     void			FindNextUnprot( BOOL bShift, BOOL bInSelection = TRUE );
 
-    void			SetNewStartIfMarking();
-
-    //<!--Added by PengYunQuan for Validity Cell Range Picker
-    //void            SetTabNo( SCTAB nTab, BOOL bNew = FALSE, BOOL bExtendSelection = FALSE );
     SC_DLLPUBLIC void            SetTabNo( SCTAB nTab, BOOL bNew = FALSE, BOOL bExtendSelection = FALSE );
-    //-->Added by PengYunQuan for Validity Cell Range Picker
     void            SelectNextTab( short nDir, BOOL bExtendSelection = FALSE );
 
     void			ActivateView( BOOL bActivate, BOOL bFirst );
@@ -481,6 +479,10 @@ public:
 
     BOOL			IsBlockMode() const		{ return bIsBlockMode; }
 
+    void            ExpandBlock(SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode);
+    void            ExpandBlockPage(SCsCOL nMovX, SCsROW nMovY);
+    void            ExpandBlockArea(SCsCOL nMovX, SCsROW nMovY);
+
     void			MarkColumns();
     void			MarkRows();
     void			MarkDataArea( BOOL bIncludeCursor = TRUE );
diff --git a/sc/source/ui/view/cellsh4.cxx b/sc/source/ui/view/cellsh4.cxx
index 2c451fb..1a3b9d9 100644
--- a/sc/source/ui/view/cellsh4.cxx
+++ b/sc/source/ui/view/cellsh4.cxx
@@ -49,6 +49,7 @@
 #include "document.hxx"
 #include "sc.hrc"
 
+#include "vcl/svapp.hxx"
 
 //------------------------------------------------------------------
 
@@ -85,10 +86,56 @@ void ScCellShell::ExecuteCursor( SfxRequest& rReq )
         {
             // ADD mode: keep the selection, start a new block when marking with shift again
             bKeep = TRUE;
-            pTabViewShell->SetNewStartIfMarking();
         }
     }
 
+    if (bSel)
+    {
+        switch (nSlotId)
+        {
+            case SID_CURSORDOWN:
+                rReq.SetSlot(SID_CURSORDOWN_SEL);
+            break;
+            case SID_CURSORUP:
+                rReq.SetSlot(SID_CURSORUP_SEL);
+            break;
+            case SID_CURSORRIGHT:
+                rReq.SetSlot(SID_CURSORRIGHT_SEL);
+            break;
+            case SID_CURSORLEFT:
+                rReq.SetSlot(SID_CURSORLEFT_SEL);
+            break;
+            case SID_CURSORPAGEDOWN:
+                rReq.SetSlot(SID_CURSORPAGEDOWN_SEL);
+            break;
+            case SID_CURSORPAGEUP:
+                rReq.SetSlot(SID_CURSORPAGEUP_SEL);
+            break;
+            case SID_CURSORPAGERIGHT:
+                rReq.SetSlot(SID_CURSORPAGERIGHT_SEL);
+            break;
+            case SID_CURSORPAGELEFT:
+                rReq.SetSlot(SID_CURSORPAGELEFT_SEL);
+            break;
+            case SID_CURSORBLKDOWN:
+                rReq.SetSlot(SID_CURSORBLKDOWN_SEL);
+            break;
+            case SID_CURSORBLKUP:
+                rReq.SetSlot(SID_CURSORBLKUP_SEL);
+            break;
+            case SID_CURSORBLKRIGHT:
+                rReq.SetSlot(SID_CURSORBLKRIGHT_SEL);
+            break;
+            case SID_CURSORBLKLEFT:
+                rReq.SetSlot(SID_CURSORBLKLEFT_SEL);
+            break;
+            default:
+                ;
+        }
+        ExecuteCursorSel(rReq);
+        return;
+    }
+
     SCsCOLROW nRTLSign = 1;
     if ( pData->GetDocument()->IsLayoutRTL( pData->GetTabNo() ) )
     {
@@ -169,38 +216,64 @@ void ScCellShell::GetStateCursor( SfxItemSet& /* rSet */ )
 
 void ScCellShell::ExecuteCursorSel( SfxRequest& rReq )
 {
-    const SfxItemSet*	pReqArgs = rReq.GetArgs();
-    USHORT				nSlotId  = rReq.GetSlot();
-    short				nRepeat = 1;
-
-    if ( pReqArgs != NULL )
+    sal_uInt16 nSlotId  = rReq.GetSlot();
+    ScTabViewShell* pViewShell = GetViewData()->GetViewShell();
+    ScInputHandler* pInputHdl = pViewShell->GetInputHandler();
+    pViewShell->HideAllCursors();
+    if (pInputHdl && pInputHdl->IsInputMode())
     {
-        const	SfxPoolItem* pItem;
-        if( IS_AVAILABLE( FN_PARAM_1, &pItem ) )
-            nRepeat = ((const SfxInt16Item*)pItem)->GetValue();
+        // the current cell is in edit mode.  Commit the text before moving on.
+        pViewShell->ExecuteInputDirect();
     }
 
-    switch ( nSlotId )
+    // Horizontal direction depends on whether or not the UI language is RTL.
+    SCsCOL nMovX = 1;
+    if (GetViewData()->GetDocument()->IsLayoutRTL(GetViewData()->GetTabNo()))
+        // mirror horizontal movement for right-to-left mode.
+        nMovX = -1;
+
+    switch (nSlotId)
     {
-        case SID_CURSORDOWN_SEL:		rReq.SetSlot( SID_CURSORDOWN );  break;
-        case SID_CURSORBLKDOWN_SEL:		rReq.SetSlot( SID_CURSORBLKDOWN );  break;
-        case SID_CURSORUP_SEL:			rReq.SetSlot( SID_CURSORUP );  break;
-        case SID_CURSORBLKUP_SEL:		rReq.SetSlot( SID_CURSORBLKUP );  break;
-        case SID_CURSORLEFT_SEL:		rReq.SetSlot( SID_CURSORLEFT );  break;
-        case SID_CURSORBLKLEFT_SEL:		rReq.SetSlot( SID_CURSORBLKLEFT );  break;
-        case SID_CURSORRIGHT_SEL:		rReq.SetSlot( SID_CURSORRIGHT );  break;
-        case SID_CURSORBLKRIGHT_SEL:	rReq.SetSlot( SID_CURSORBLKRIGHT );  break;
-        case SID_CURSORPAGEDOWN_SEL:	rReq.SetSlot( SID_CURSORPAGEDOWN );  break;
-        case SID_CURSORPAGEUP_SEL:		rReq.SetSlot( SID_CURSORPAGEUP );  break;
-        case SID_CURSORPAGERIGHT_SEL:	rReq.SetSlot( SID_CURSORPAGERIGHT_ );  break;
-        case SID_CURSORPAGELEFT_SEL:	rReq.SetSlot( SID_CURSORPAGELEFT_ );  break;
+        case SID_CURSORDOWN_SEL:
+            pViewShell->ExpandBlock(0, 1, SC_FOLLOW_LINE);
+        break;
+        case SID_CURSORUP_SEL:
+            pViewShell->ExpandBlock(0, -1, SC_FOLLOW_LINE);
+        break;
+        case SID_CURSORRIGHT_SEL:
+            pViewShell->ExpandBlock(nMovX, 0, SC_FOLLOW_LINE);
+        break;
+        case SID_CURSORLEFT_SEL:
+            pViewShell->ExpandBlock(-nMovX, 0, SC_FOLLOW_LINE);
+        break;
+        case SID_CURSORPAGEUP_SEL:
+            pViewShell->ExpandBlockPage(0, -1);
+        break;
+        case SID_CURSORPAGEDOWN_SEL:
+            pViewShell->ExpandBlockPage(0, 1);
+        break;
+        case SID_CURSORPAGERIGHT_SEL:
+            pViewShell->ExpandBlockPage(nMovX, 0);
+        break;
+        case SID_CURSORPAGELEFT_SEL:
+            pViewShell->ExpandBlockPage(-nMovX, 0);
+        break;
+        case SID_CURSORBLKDOWN_SEL:
+            pViewShell->ExpandBlockArea(0, 1);
+        break;
+        case SID_CURSORBLKUP_SEL:
+            pViewShell->ExpandBlockArea(0, -1);
+        break;
+        case SID_CURSORBLKRIGHT_SEL:
+            pViewShell->ExpandBlockArea(nMovX, 0);
+        break;
+        case SID_CURSORBLKLEFT_SEL:
+            pViewShell->ExpandBlockArea(-nMovX, 0);
+        break;
         default:
-            DBG_ERROR("Unbekannte Message bei ViewShell (CursorSel)");
-            return;
+            ;
     }
-    rReq.AppendItem( SfxInt16Item(FN_PARAM_1, nRepeat ) );
-    rReq.AppendItem( SfxBoolItem(FN_PARAM_2, TRUE) );
-    ExecuteSlot( rReq, GetInterface() );
+    pViewShell->ShowAllCursors();
 }
 
 void ScCellShell::ExecuteMove( SfxRequest& rReq )
@@ -345,7 +418,6 @@ void ScCellShell::ExecutePage( SfxRequest& rReq )
         {
             // ADD mode: keep the selection, start a new block when marking with shift again
             bKeep = TRUE;
-            pTabViewShell->SetNewStartIfMarking();
         }
     }
 
diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx
index 9715f18..9cd5155 100644
--- a/sc/source/ui/view/gridwin.cxx
+++ b/sc/source/ui/view/gridwin.cxx
@@ -2228,8 +2228,12 @@ void __EXPORT ScGridWindow::MouseButtonUp( const MouseEvent& rMEvt )
             }
 
             SfxStringItem aPosItem( SID_CURRENTCELL, aAddr );
+            // We don't want to align to the cursor position because if the
+            // cell cursor isn't visible after making selection, it would jump
+            // back to the origin of the selection where the cell cursor is.
+            SfxBoolItem aAlignCursorItem( FN_PARAM_2, false );
             pDisp->Execute( SID_CURRENTCELL, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD,
-                                        &aPosItem, (void*)0L );
+                                        &aPosItem, &aAlignCursorItem, (void*)0L );
 
             pViewData->GetView()->InvalidateAttribs();
         }
@@ -3981,7 +3985,10 @@ sal_Int8 ScGridWindow::DropTransferObj( ScTransferObj* pTransObj, SCCOL nDestPos
                 if ( bDone )
                 {
                     pView->MarkRange( aDest, FALSE, FALSE );
-                    pView->SetCursor( aDest.aEnd.Col(), aDest.aEnd.Row() );
+
+                    SCCOL nDCol = pViewData->GetCurX() - aSource.aStart.Col();
+                    SCROW nDRow = pViewData->GetCurY() - aSource.aStart.Row();
+                    pView->SetCursor( aDest.aStart.Col() + nDCol, aDest.aStart.Row() + nDRow );
                 }
 
                 pDocSh->GetUndoManager()->LeaveListAction();
@@ -4089,7 +4096,7 @@ sal_Int8 ScGridWindow::DropTransferObj( ScTransferObj* pTransObj, SCCOL nDestPos
                     pView->EnterMatrix( aFormula );
 
                     pView->MarkRange( aDest, FALSE, FALSE );
-                    pView->SetCursor( aDest.aEnd.Col(), aDest.aEnd.Row() );
+                    pView->SetCursor( aDest.aStart.Col(), aDest.aStart.Row() );
                 }
 
                 pDocSh->GetUndoManager()->LeaveListAction();
@@ -4123,7 +4130,7 @@ sal_Int8 ScGridWindow::DropTransferObj( ScTransferObj* pTransObj, SCCOL nDestPos
                 if ( bDone )
                 {
                     pView->MarkRange( aDest, FALSE, FALSE );
-                    pView->SetCursor( aDest.aEnd.Col(), aDest.aEnd.Row() );
+                    pView->SetCursor( aDest.aStart.Col(), aDest.aStart.Row() );
                 }
             }
 
diff --git a/sc/source/ui/view/select.cxx b/sc/source/ui/view/select.cxx
index a72d378..cfe5cfe 100644
--- a/sc/source/ui/view/select.cxx
+++ b/sc/source/ui/view/select.cxx
@@ -583,7 +583,10 @@ BOOL ScViewFunctionSet::SetCursorAtCell( SCsCOL nPosX, SCsROW nPosY, BOOL bScrol
                 }
             }
             if (bStarted)
+                // If the selection is already started, don't set the cursor.
                 pView->MarkCursor( (SCCOL) nPosX, (SCROW) nPosY, nTab, FALSE, FALSE, TRUE );
+            else
+                pView->SetCursor( (SCCOL) nPosX, (SCROW) nPosY );
         }
         else
         {
@@ -619,9 +622,9 @@ BOOL ScViewFunctionSet::SetCursorAtCell( SCsCOL nPosX, SCsROW nPosY, BOOL bScrol
                 
                 bStarted = TRUE;
             }
+            pView->SetCursor( (SCCOL) nPosX, (SCROW) nPosY );
         }
 
-        pView->SetCursor( (SCCOL) nPosX, (SCROW) nPosY );
         pViewData->SetRefStart( nPosX, nPosY, nTab );
         if (bHideCur)
             pView->ShowAllCursors();
diff --git a/sc/source/ui/view/tabview.cxx b/sc/source/ui/view/tabview.cxx
index 898c66d..f192d7b 100644
--- a/sc/source/ui/view/tabview.cxx
+++ b/sc/source/ui/view/tabview.cxx
@@ -384,8 +384,7 @@ BOOL lcl_HasRowOutline( const ScViewData& rViewData )
             bInUpdateHeader( FALSE ),										\
             bInActivatePart( FALSE ),										\
             bInZoomUpdate( FALSE ),											\
-            bMoveIsShift( FALSE ),											\
-            bNewStartIfMarking( FALSE )
+             bMoveIsShift( FALSE )
 
 
 ScTabView::ScTabView( Window* pParent, ScDocShell& rDocSh, ScTabViewShell* pViewShell ) :
diff --git a/sc/source/ui/view/tabview2.cxx b/sc/source/ui/view/tabview2.cxx
index 27c0f7d..ebb6dbd 100644
--- a/sc/source/ui/view/tabview2.cxx
+++ b/sc/source/ui/view/tabview2.cxx
@@ -59,6 +59,7 @@
 #include "waitoff.hxx"
 #include "globstr.hrc"
 #include "scmod.hxx"
+#include "tabprotection.hxx"
 
 #define SC_BLOCKMODE_NONE		0
 #define SC_BLOCKMODE_NORMAL		1
@@ -175,16 +176,9 @@ void ScTabView::InitBlockMode( SCCOL nCurX, SCROW nCurY, SCTAB nCurZ,
         InvertBlockMark( nBlockStartX,nBlockStartY,nBlockEndX,nBlockEndY );
 #endif
         UpdateSelectionOverlay();
-
-        bNewStartIfMarking = FALSE;		// use only once
     }
 }
 
-void ScTabView::SetNewStartIfMarking()
-{
-    bNewStartIfMarking = TRUE;
-}
-
 void ScTabView::DoneBlockMode( BOOL bContinue )            // Default FALSE
 {
     //	Wenn zwischen Tabellen- und Header SelectionEngine gewechselt wird,
@@ -411,6 +405,305 @@ void ScTabView::MarkCursor( SCCOL nCurX, SCROW nCurY, SCTAB nCurZ,
         aHdrFunc.SetAnchorFlag( FALSE );
 }
 
+void ScTabView::GetPageMoveEndPosition(SCsCOL nMovX, SCsROW nMovY, SCsCOL& rPageX, SCsROW& rPageY)
+{
+    SCCOL nCurX;
+    SCROW nCurY;
+    aViewData.GetMoveCursor( nCurX,nCurY );
+
+    ScSplitPos eWhich = aViewData.GetActivePart();
+    ScHSplitPos eWhichX = WhichH( eWhich );
+    ScVSplitPos eWhichY = WhichV( eWhich );
+
+    SCsCOL nPageX;
+    SCsROW nPageY;
+    if (nMovX >= 0)
+        nPageX = ((SCsCOL) aViewData.CellsAtX( nCurX, 1, eWhichX )) * nMovX;
+    else
+        nPageX = ((SCsCOL) aViewData.CellsAtX( nCurX, -1, eWhichX )) * nMovX;
+
+    if (nMovY >= 0)
+        nPageY = ((SCsROW) aViewData.CellsAtY( nCurY, 1, eWhichY )) * nMovY;
+    else
+        nPageY = ((SCsROW) aViewData.CellsAtY( nCurY, -1, eWhichY )) * nMovY;
+
+    if (nMovX != 0 && nPageX == 0) nPageX = (nMovX>0) ? 1 : -1;
+    if (nMovY != 0 && nPageY == 0) nPageY = (nMovY>0) ? 1 : -1;
+
+    rPageX = nPageX;
+    rPageY = nPageY;
+}
+
+void ScTabView::GetAreaMoveEndPosition(SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode,
+                                       SCsCOL& rAreaX, SCsROW& rAreaY, ScFollowMode& rMode)
+{
+    SCCOL nNewX = -1;
+    SCROW nNewY = -1;
+    SCCOL nCurX = -1;
+    SCROW nCurY = -1;
+
+    if (aViewData.IsRefMode())
+    {
+        nNewX = aViewData.GetRefEndX();
+        nNewY = aViewData.GetRefEndY();
+    }
+    else if (IsBlockMode())
+    {
+        nNewX = nBlockEndX;
+        nNewY = nBlockEndY;
+    }
+    else
+    {
+        nNewX = nCurX = aViewData.GetCurX();
+        nNewY = nCurY = aViewData.GetCurY();
+    }
+
+    ScDocument* pDoc = aViewData.GetDocument();
+    SCTAB nTab = aViewData.GetTabNo();
+
+    //  FindAreaPos kennt nur -1 oder 1 als Richtung
+
+    SCsCOLROW i;
+    if ( nMovX > 0 )
+        for ( i=0; i<nMovX; i++ )
+            pDoc->FindAreaPos( nNewX, nNewY, nTab,  1,  0 );
+    if ( nMovX < 0 )
+        for ( i=0; i<-nMovX; i++ )
+            pDoc->FindAreaPos( nNewX, nNewY, nTab, -1,  0 );
+    if ( nMovY > 0 )
+        for ( i=0; i<nMovY; i++ )
+            pDoc->FindAreaPos( nNewX, nNewY, nTab,  0,  1 );
+    if ( nMovY < 0 )
+        for ( i=0; i<-nMovY; i++ )
+            pDoc->FindAreaPos( nNewX, nNewY, nTab,  0, -1 );
+
+    if (eMode==SC_FOLLOW_JUMP)                  // unten/rechts nicht zuviel grau anzeigen
+    {
+        if (nMovX != 0 && nNewX == MAXCOL)
+            eMode = SC_FOLLOW_LINE;
+        if (nMovY != 0 && nNewY == MAXROW)
+            eMode = SC_FOLLOW_LINE;
+    }
+
+    if (aViewData.IsRefMode())
+    {
+        rAreaX = nNewX - aViewData.GetRefEndX();
+        rAreaY = nNewY - aViewData.GetRefEndY();
+    }
+    else if (IsBlockMode())
+    {
+        rAreaX = nNewX - nBlockEndX;
+        rAreaY = nNewY - nBlockEndY;
+    }
+    else
+    {
+        rAreaX = nNewX - nCurX;
+        rAreaY = nNewY - nCurY;
+    }
+    rMode = eMode;
+}
+
+namespace {
+
+bool lcl_isCellQualified(ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab, bool bSelectLocked, bool bSelectUnlocked)
+{
+    bool bCellProtected = pDoc->HasAttrib(
+        nCol, nRow, nTab, nCol, nRow, nTab, HASATTR_PROTECTED);
+
+    if (bCellProtected && !bSelectLocked)
+        return false;
+
+    if (!bCellProtected && !bSelectUnlocked)
+        return false;
+
+    return true;
+}
+
+void lcl_moveCursorByProtRule(
+    SCCOL& rCol, SCROW& rRow, SCsCOL nMovX, SCsROW nMovY, SCTAB nTab, ScDocument* pDoc)
+{
+    bool bSelectLocked = true;
+    bool bSelectUnlocked = true;
+    ScTableProtection* pTabProtection = pDoc->GetTabProtection(nTab);
+    if (pTabProtection && pTabProtection->isProtected())
+    {
+        bSelectLocked   = pTabProtection->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS);
+        bSelectUnlocked = pTabProtection->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS);
+    }
+
+    if (nMovX > 0)
+    {
+        if (rCol < MAXCOL)
+        {
+            for (SCCOL i = 0; i < nMovX; ++i)
+            {
+                if (!lcl_isCellQualified(pDoc, rCol+1, rRow, nTab, bSelectLocked, bSelectUnlocked))
+                    break;
+                ++rCol;
+            }
+        }
+    }
+    else if (nMovX < 0)
+    {
+        if (rCol > 0)
+        {
+            nMovX = -nMovX;
+            for (SCCOL i = 0; i < nMovX; ++i)
+            {
+                if (!lcl_isCellQualified(pDoc, rCol-1, rRow, nTab, bSelectLocked, bSelectUnlocked))
+                    break;
+                --rCol;
+            }
+        }
+    }
+
+    if (nMovY > 0)
+    {
+        if (rRow < MAXROW)
+        {
+            for (SCROW i = 0; i < nMovY; ++i)
+            {
+                if (!lcl_isCellQualified(pDoc, rCol, rRow+1, nTab, bSelectLocked, bSelectUnlocked))
+                    break;
+                ++rRow;
+            }
+        }
+    }
+    else if (nMovY < 0)
+    {
+        if (rRow > 0)
+        {
+            nMovY = -nMovY;
+            for (SCROW i = 0; i < nMovY; ++i)
+            {
+                if (!lcl_isCellQualified(pDoc, rCol, rRow-1, nTab, bSelectLocked, bSelectUnlocked))
+                    break;
+                --rRow;
+            }
+        }
+    }
+}
+
+}
+
+void ScTabView::ExpandBlock(SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode)
+{
+    if (!nMovX && !nMovY)
+        // Nothing to do.  Bail out.
+        return;
+
+    ScTabViewShell* pViewShell = aViewData.GetViewShell();
+    bool bRefInputMode = pViewShell && pViewShell->IsRefInputMode();
+    if (bRefInputMode && !aViewData.IsRefMode())
+        // initialize formula reference mode if it hasn't already.
+        InitRefMode(aViewData.GetCurX(), aViewData.GetCurY(), aViewData.GetTabNo(), SC_REFTYPE_REF);
+
+    ScDocument* pDoc = aViewData.GetDocument();
+
+    if (aViewData.IsRefMode())
+    {
+        // formula reference mode
+
+        SCCOL nNewX = aViewData.GetRefEndX();
+        SCROW nNewY = aViewData.GetRefEndY();
+        SCTAB nRefTab = aViewData.GetRefEndZ();
+
+        bool bSelectLocked = true;
+        bool bSelectUnlocked = true;
+        ScTableProtection* pTabProtection = pDoc->GetTabProtection(nRefTab);
+        if (pTabProtection && pTabProtection->isProtected())
+        {
+            bSelectLocked   = pTabProtection->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS);
+            bSelectUnlocked = pTabProtection->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS);
+        }
+
+        lcl_moveCursorByProtRule(nNewX, nNewY, nMovX, nMovY, nRefTab, pDoc);
+
+        if (nMovX)
+        {
+            SCCOL nTempX = nNewX;
+            while (pDoc->IsHorOverlapped(nTempX, nNewY, nRefTab))
+            {
+                if (nMovX > 0)
+                    ++nTempX;
+                else
+                    --nTempX;
+            }
+            if (lcl_isCellQualified(pDoc, nTempX, nNewY, nRefTab, bSelectLocked, bSelectUnlocked))
+                nNewX = nTempX;
+        }
+
+        if (nMovY)
+        {
+            SCROW nTempY = nNewY;
+            while (pDoc->IsVerOverlapped(nNewX, nTempY, nRefTab))
+            {
+                if (nMovY > 0)
+                    ++nTempY;
+                else
+                    --nTempY;
+            }
+            if (lcl_isCellQualified(pDoc, nNewX, nTempY, nRefTab, bSelectLocked, bSelectUnlocked))
+                nNewY = nTempY;
+        }
+
+        pDoc->SkipOverlapped(nNewX, nNewY, nRefTab);
+        UpdateRef(nNewX, nNewY, nRefTab);
+        AlignToCursor(nNewX, nNewY, eMode);
+    }
+    else
+    {
+        // normal selection mode
+
+        SCTAB nTab = aViewData.GetTabNo();
+
+        if (!IsBlockMode())
+            InitBlockMode(aViewData.GetCurX(), aViewData.GetCurY(), nTab, true);
+
+        lcl_moveCursorByProtRule(nBlockEndX, nBlockEndY, nMovX, nMovY, nTab, pDoc);
+
+        if (nBlockEndX < 0)
+            nBlockEndX = 0;
+        else if (nBlockEndX > MAXCOL)
+            nBlockEndX = MAXCOL;
+
+        if (nBlockEndY < 0)
+            nBlockEndY = 0;
+        else if (nBlockEndY > MAXROW)
+            nBlockEndY = MAXROW;
+
+        pDoc->SkipOverlapped(nBlockEndX, nBlockEndY, nTab);
+        MarkCursor(nBlockEndX, nBlockEndY, nTab, false, false, true);
+
+        // Check if the entire row(s) or column(s) are selected.
+        ScSplitPos eActive = aViewData.GetActivePart();
+        bool bRowSelected = (nBlockStartX == 0 && nBlockEndX == MAXCOL);
+        bool bColSelected = (nBlockStartY == 0 && nBlockEndY == MAXROW);
+        SCsCOL nAlignX = bRowSelected ? aViewData.GetPosX(WhichH(eActive)) : nBlockEndX;
+        SCsROW nAlignY = bColSelected ? aViewData.GetPosY(WhichV(eActive)) : nBlockEndY;
+        AlignToCursor(nAlignX, nAlignY, eMode);
+
+        SelectionChanged();
+    }
+}
+
+void ScTabView::ExpandBlockPage(SCsCOL nMovX, SCsROW nMovY)
+{
+    SCsCOL nPageX;
+    SCsROW nPageY;
+    GetPageMoveEndPosition(nMovX, nMovY, nPageX, nPageY);
+    ExpandBlock(nPageX, nPageY, SC_FOLLOW_FIX);
+}
+
+void ScTabView::ExpandBlockArea(SCsCOL nMovX, SCsROW nMovY)
+{
+    SCsCOL nAreaX;
+    SCsROW nAreaY;
+    ScFollowMode eMode;
+    GetAreaMoveEndPosition(nMovX, nMovY, SC_FOLLOW_JUMP, nAreaX, nAreaY, eMode);
+    ExpandBlock(nAreaX, nAreaY, eMode);
+}
+
 void ScTabView::UpdateSelectionOverlay()
 {
     for (USHORT i=0; i<4; i++)
diff --git a/sc/source/ui/view/tabview3.cxx b/sc/source/ui/view/tabview3.cxx
index cd4d70b..9c75cd4 100644
--- a/sc/source/ui/view/tabview3.cxx
+++ b/sc/source/ui/view/tabview3.cxx
@@ -119,10 +119,7 @@ void ScTabView::ClickCursor( SCCOL nPosX, SCROW nPosY, BOOL bControl )
 {
     ScDocument* pDoc = aViewData.GetDocument();
     SCTAB nTab = aViewData.GetTabNo();
-    while (pDoc->IsHorOverlapped( nPosX, nPosY, nTab ))		//! ViewData !!!
-        --nPosX;
-    while (pDoc->IsVerOverlapped( nPosX, nPosY, nTab ))
-        --nPosY;
+    pDoc->SkipOverlapped(nPosX, nPosY, nTab);
 
     BOOL bRefMode = SC_MOD()->IsFormulaMode();
 
@@ -901,22 +898,36 @@ void ScTabView::MoveCursorAbs( SCsCOL nCurX, SCsROW nCurY, ScFollowMode eMode,
 
     HideAllCursors();
 
-    if ( bShift && bNewStartIfMarking && IsBlockMode() )
-    {
-        //	used for ADD selection mode: start a new block from the cursor position
-        DoneBlockMode( TRUE );
-        InitBlockMode( aViewData.GetCurX(), aViewData.GetCurY(), aViewData.GetTabNo(), TRUE );
-    }
-
         //	aktiven Teil umschalten jetzt in AlignToCursor
 
     AlignToCursor( nCurX, nCurY, eMode );
     //!		auf OS/2: SC_FOLLOW_JUMP statt SC_FOLLOW_LINE, um Nachlaufen zu verhindern ???
 
     if (bKeepSel)
+    {
         SetCursor( nCurX, nCurY );		// Markierung stehenlassen
+
+        // If the cursor is in existing selection, it's a cursor movement by
+        // ENTER or TAB.  If not, then it's a new selection during ADD
+        // selection mode.
+
+        const ScMarkData& rMark = aViewData.GetMarkData();
+        ScRangeList aSelList;
+        rMark.FillRangeListWithMarks(&aSelList, false);
+        if (!aSelList.In(ScRange(nCurX, nCurY, aViewData.GetTabNo())))
+            // Cursor not in existing selection.  Start a new selection.
+            DoneBlockMode(true);
+    }
     else
     {
+        if (!bShift)
+        {
+            // Remove all marked data on cursor movement unless the Shift is locked.
+            ScMarkData aData(aViewData.GetMarkData());
+            aData.ResetMark();
+            SetMarkData(aData);
+        }
+
         BOOL bSame = ( nCurX == aViewData.GetCurX() && nCurY == aViewData.GetCurY() );
         bMoveIsShift = bShift;
         pSelEngine->CursorPosChanging( bShift, bControl );
@@ -1060,68 +1071,18 @@ void ScTabView::MoveCursorRel( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode,
 
 void ScTabView::MoveCursorPage( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode, BOOL bShift, BOOL bKeepSel )
 {
-    SCCOL nCurX;
-    SCROW nCurY;
-    aViewData.GetMoveCursor( nCurX,nCurY );
-
-    ScSplitPos eWhich = aViewData.GetActivePart();
-    ScHSplitPos eWhichX = WhichH( eWhich );
-    ScVSplitPos eWhichY = WhichV( eWhich );
-
     SCsCOL nPageX;
     SCsROW nPageY;
-    if (nMovX >= 0)
-        nPageX = ((SCsCOL) aViewData.CellsAtX( nCurX, 1, eWhichX )) * nMovX;
-    else
-        nPageX = ((SCsCOL) aViewData.CellsAtX( nCurX, -1, eWhichX )) * nMovX;
-
-    if (nMovY >= 0)
-        nPageY = ((SCsROW) aViewData.CellsAtY( nCurY, 1, eWhichY )) * nMovY;
-    else
-        nPageY = ((SCsROW) aViewData.CellsAtY( nCurY, -1, eWhichY )) * nMovY;
-
-    if (nMovX != 0 && nPageX == 0) nPageX = (nMovX>0) ? 1 : -1;
-    if (nMovY != 0 && nPageY == 0) nPageY = (nMovY>0) ? 1 : -1;
-
+    GetPageMoveEndPosition(nMovX, nMovY, nPageX, nPageY);
     MoveCursorRel( nPageX, nPageY, eMode, bShift, bKeepSel );
 }
 
 void ScTabView::MoveCursorArea( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode, BOOL bShift, BOOL bKeepSel )
 {
-    SCCOL nCurX;
-    SCROW nCurY;
-    aViewData.GetMoveCursor( nCurX,nCurY );
-    SCCOL nNewX = nCurX;
-    SCROW nNewY = nCurY;
-
-    ScDocument* pDoc = aViewData.GetDocument();
-    SCTAB nTab = aViewData.GetTabNo();
-
-    //	FindAreaPos kennt nur -1 oder 1 als Richtung
-
-    SCsCOLROW i;
-    if ( nMovX > 0 )
-        for ( i=0; i<nMovX; i++ )
-            pDoc->FindAreaPos( nNewX, nNewY, nTab,  1,  0 );
-    if ( nMovX < 0 )
-        for ( i=0; i<-nMovX; i++ )
-            pDoc->FindAreaPos( nNewX, nNewY, nTab, -1,  0 );
-    if ( nMovY > 0 )
-        for ( i=0; i<nMovY; i++ )
-            pDoc->FindAreaPos( nNewX, nNewY, nTab,  0,  1 );
-    if ( nMovY < 0 )
-        for ( i=0; i<-nMovY; i++ )
-            pDoc->FindAreaPos( nNewX, nNewY, nTab,  0, -1 );
-
-    if (eMode==SC_FOLLOW_JUMP)					// unten/rechts nicht zuviel grau anzeigen
-    {
-        if (nMovX != 0 && nNewX == MAXCOL)
-            eMode = SC_FOLLOW_LINE;
-        if (nMovY != 0 && nNewY == MAXROW)
-            eMode = SC_FOLLOW_LINE;
-    }
-
-    MoveCursorRel( ((SCsCOL)nNewX)-(SCsCOL)nCurX, ((SCsROW)nNewY)-(SCsROW)nCurY, eMode, bShift, bKeepSel );
+    SCsCOL nNewX;
+    SCsROW nNewY;
+    GetAreaMoveEndPosition(nMovX, nMovY, eMode, nNewX, nNewY, eMode);
+    MoveCursorRel(nNewX, nNewY, eMode, bShift, bKeepSel);
 }
 
 void ScTabView::MoveCursorEnd( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode, BOOL bShift, BOOL bKeepSel )
@@ -1186,14 +1147,8 @@ void ScTabView::MoveCursorScreen( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode
     else if (nMovY>0)
         nNewY=nPosY+nAddY;
 
-//	aViewData.ResetOldCursor();
     aViewData.SetOldCursor( nNewX,nNewY );
-
-    while (pDoc->IsHorOverlapped( nNewX, nNewY, nTab ))
-        --nNewX;
-    while (pDoc->IsVerOverlapped( nNewX, nNewY, nTab ))
-        --nNewY;
-
+    pDoc->SkipOverlapped(nNewX, nNewY, nTab);
     MoveCursorAbs( nNewX, nNewY, eMode, bShift, FALSE, TRUE );
 }
 
@@ -1477,11 +1432,7 @@ void ScTabView::MarkRange( const ScRange& rRange, BOOL bSetCursor, BOOL bContinu
         SCCOL nPosX = rRange.aStart.Col();
         SCROW nPosY = rRange.aStart.Row();
         ScDocument* pDoc = aViewData.GetDocument();
-
-        while (pDoc->IsHorOverlapped( nPosX, nPosY, nTab ))		//! ViewData !!!
-            --nPosX;
-        while (pDoc->IsVerOverlapped( nPosX, nPosY, nTab ))
-            --nPosY;
+        pDoc->SkipOverlapped(nPosX, nPosY, nTab);
 
         aViewData.ResetOldCursor();
         SetCursor( nPosX, nPosY );
diff --git a/sc/source/ui/view/tabvwsh3.cxx b/sc/source/ui/view/tabvwsh3.cxx
index c09f44a..88eecb9 100644
--- a/sc/source/ui/view/tabvwsh3.cxx
+++ b/sc/source/ui/view/tabvwsh3.cxx
@@ -265,6 +265,10 @@ void ScTabViewShell::Execute( SfxRequest& rReq )
                 if ( pReqArgs->GetItemState( FN_PARAM_1, TRUE, &pItem ) == SFX_ITEM_SET )
                     bUnmark = ((const SfxBoolItem*)pItem)->GetValue();
 
+                bool bAlignToCursor = true;
+                if (pReqArgs->GetItemState(FN_PARAM_2, true, &pItem) == SFX_ITEM_SET)
+                    bAlignToCursor = static_cast<const SfxBoolItem*>(pItem)->GetValue();
+
                 if ( nSlot == SID_JUMPTOMARK )
                 {
                     //	#106586# URL has to be decoded for escaped characters (%20)
@@ -385,10 +389,7 @@ void ScTabViewShell::Execute( SfxRequest& rReq )
                     // und Cursor setzen
 
                     // zusammengefasste Zellen beruecksichtigen:
-                    while ( pDoc->IsHorOverlapped( nCol, nRow, nTab ) )		//! ViewData !!!
-                        --nCol;
-                    while ( pDoc->IsVerOverlapped( nCol, nRow, nTab ) )
-                        --nRow;
+                    pDoc->SkipOverlapped(nCol, nRow, nTab);
 
                     //	Navigator-Aufrufe sind nicht API!!!
 
@@ -409,9 +410,13 @@ void ScTabViewShell::Execute( SfxRequest& rReq )
                         if (!rReq.IsAPI())
                             rReq.Done();
                     }
-                    // align to cursor even if the cursor position hasn't changed,
-                    // because the cursor may be set outside the visible area.
-                    AlignToCursor( nCol, nRow, SC_FOLLOW_JUMP );
+
+                    if (bAlignToCursor)
+                    {
+                        // align to cursor even if the cursor position hasn't changed,
+                        // because the cursor may be set outside the visible area.
+                        AlignToCursor( nCol, nRow, SC_FOLLOW_JUMP );
+                    }
 
                     rReq.SetReturnValue( SfxStringItem( SID_CURRENTCELL, aAddress ) );
                 }
diff --git a/sc/source/ui/view/viewdata.cxx b/sc/source/ui/view/viewdata.cxx
index d435ea1..96866dd 100644
--- a/sc/source/ui/view/viewdata.cxx
+++ b/sc/source/ui/view/viewdata.cxx
@@ -1905,12 +1905,11 @@ BOOL ScViewData::GetPosFromPixel( long nClickX, long nClickY, ScSplitPos eWhich,
     {
         //!	public Methode um Position anzupassen
 
-        BOOL bHOver = FALSE;
-        while (pDoc->IsHorOverlapped( rPosX, rPosY, nTabNo ))
-            { --rPosX; bHOver=TRUE; }
-        BOOL bVOver = FALSE;
-        while (pDoc->IsVerOverlapped( rPosX, rPosY, nTabNo ))
-            { --rPosY; bVOver=TRUE; }
+        SCCOL nOrigX = rPosX;
+        SCROW nOrigY = rPosY;
+        pDoc->SkipOverlapped(rPosX, rPosY, nTabNo);
+        bool bHOver = (nOrigX != rPosX);
+        bool bVOver = (nOrigY != rPosY);
 
         if ( bRepair && ( bHOver || bVOver ) )
         {
commit d1b875b6f76d47a70e1e33ef252e1aa7c3a24889
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Thu Sep 16 11:03:28 2010 +0200

    chart-highlight-selection-fix.diff: Migrated
    
    n#568016, correctly highlight disjoint ranges in chart mode

diff --git a/sc/source/ui/view/tabview3.cxx b/sc/source/ui/view/tabview3.cxx
index 0429368..cd4d70b 100644
--- a/sc/source/ui/view/tabview3.cxx
+++ b/sc/source/ui/view/tabview3.cxx
@@ -77,6 +77,7 @@
 #include "rangeutl.hxx"
 #include "client.hxx"
 #include "tabprotection.hxx"
+#include "formula/FormulaCompiler.hxx"
 
 #include <com/sun/star/chart2/data/HighlightedRange.hpp>
 
@@ -2188,6 +2189,7 @@ void ScTabView::DoChartSelection(
     const uno::Sequence< chart2::data::HighlightedRange > & rHilightRanges )
 {
     ClearHighlightRanges();
+    const sal_Unicode sep = ::formula::FormulaCompiler::GetNativeSymbol(ocSep).GetChar(0);
 
     for( sal_Int32 i=0; i<rHilightRanges.getLength(); ++i )
     {
@@ -2195,7 +2197,7 @@ void ScTabView::DoChartSelection(
         ScRangeList aRangeList;
         ScDocument* pDoc = aViewData.GetDocShell()->GetDocument();
         if( ScRangeStringConverter::GetRangeListFromString(
-                aRangeList, rHilightRanges[i].RangeRepresentation, pDoc, pDoc->GetAddressConvention(), ';' ))
+                aRangeList, rHilightRanges[i].RangeRepresentation, pDoc, pDoc->GetAddressConvention(), sep ))
         {
             for ( ScRangePtr p = aRangeList.First(); p; p = aRangeList.Next())
             {


More information about the ooo-build-commit mailing list