[Libreoffice-commits] core.git: sc/source

Winfried Donkers osc at dci-electronics.nl
Sat Feb 9 21:11:48 PST 2013


 sc/source/ui/view/cellsh1.cxx |   74 ++++++++++++++++++++++++++++++------------
 1 file changed, 54 insertions(+), 20 deletions(-)

New commits:
commit 5fe7b7561aa78e87f90e8a9436cb674e53ef8f4e
Author: Winfried Donkers <osc at dci-electronics.nl>
Date:   Mon Jan 28 18:42:38 2013 +0100

    fdo#56098 paste special shift options incorrect/incomplete
    
    Change-Id: Ic84ec07f4e0963ad1759036f1d7cbfa295289375
    Reviewed-on: https://gerrit.libreoffice.org/1903
    Reviewed-by: Noel Power <noel.power at suse.com>
    Tested-by: Noel Power <noel.power at suse.com>
    Tested-by: LibreOffice gerrit bot <gerrit at libreoffice.org>

diff --git a/sc/source/ui/view/cellsh1.cxx b/sc/source/ui/view/cellsh1.cxx
index c22d91d..c32ed5d 100644
--- a/sc/source/ui/view/cellsh1.cxx
+++ b/sc/source/ui/view/cellsh1.cxx
@@ -1259,29 +1259,63 @@ void ScCellShell::ExecuteEdit( SfxRequest& rReq )
                             pDlg->SetOtherDoc( bOtherDoc );
                             // if ChangeTrack MoveMode disable
                             pDlg->SetChangeTrack( pDoc->GetChangeTrack() != NULL );
-                            // cut/move references may disable shift
-                            // directions if source and destination ranges intersect
-                            if ( !bOtherDoc )
+                            // fdo#56098  disable shift if necessary
+                            if ( !bOtherDoc  && pOwnClip )
                             {
-                                if ( pOwnClip && pOwnClip->GetDocument()->IsCutMode() )
+                                ScViewData* pData = GetViewData();
+                                if ( pData->GetMarkData().GetTableSelect( pData->GetTabNo() ) )
                                 {
-                                    ScViewData* pData = GetViewData();
-                                    if ( pData->GetMarkData().GetTableSelect(
-                                            pData->GetTabNo() ) )
+                                    SCCOL nStartX, nEndX, nClipStartX, nClipSizeX, nRangeSizeX;
+                                    SCROW nStartY, nEndY, nClipStartY, nClipSizeY, nRangeSizeY;
+                                    SCTAB nStartTab, nEndTab;
+                                    pOwnClip->GetDocument()->GetClipStart( nClipStartX, nClipStartY );
+                                    pOwnClip->GetDocument()->GetClipArea( nClipSizeX, nClipSizeY, sal_True );
+
+                                    if ( !( pData->GetSimpleArea( nStartX, nStartY, nStartTab,
+                                                   nEndX, nEndY, nEndTab ) == SC_MARK_SIMPLE &&
+                                                   nStartTab == nEndTab ) )
                                     {
-                                        SCCOL nPosX = pData->GetCurX();
-                                        SCROW nPosY = pData->GetCurY();
-                                        SCCOL nClipSizeX;
-                                        SCROW  nClipSizeY;
-                                        // for CutMode, filtered rows can always be included
-                                        pOwnClip->GetDocument()->GetClipArea( nClipSizeX, nClipSizeY, sal_True );
-                                        int nDisableShift = 0;
-                                        if ( nPosX + 2 * nClipSizeX + 1 > MAXCOL )  // fdo#56098
-                                             nDisableShift |= SC_CELL_SHIFT_DISABLE_RIGHT;
-                                        if ( nPosY + 2 * nClipSizeY + 1 > MAXROW )  // fdo#56098
-                                            nDisableShift |= SC_CELL_SHIFT_DISABLE_DOWN;
-                                        if ( nDisableShift )
-                                            pDlg->SetCellShiftDisabled( nDisableShift );
+                                        // the destination is not a simple range,
+                                        // assume the destination as the current cell
+                                        nStartX = nEndX = pData->GetCurX();
+                                        nStartY = nEndY = pData->GetCurY();
+                                        nStartTab = pData->GetTabNo();
+                                    }
+                                    // we now have clip- and range dimensions
+                                    // the size of the destination area is the larger of the two
+                                    nRangeSizeX = nClipSizeX >= nEndX - nStartX ? nClipSizeX : nEndX - nStartX;
+                                    nRangeSizeY = nClipSizeY >= nEndY - nStartY ? nClipSizeY : nEndY - nStartY;
+                                    // When the source and destination areas intersect things may go wrong,
+                                    // especially if the area contains references. This may produce data loss
+                                    // (e.g. formulas that get wrong references), this scenario _must_ be avoided.
+                                    ScRange aSource( nClipStartX, nClipStartY, nStartTab,
+                                                     nClipStartX + nClipSizeX, nClipStartY + nClipSizeY, nStartTab );
+                                    ScRange aDest( nStartX, nStartY, nStartTab,
+                                                   nStartX + nRangeSizeX, nStartY + nRangeSizeY, nStartTab );
+                                    if ( aSource.Intersects( aDest ) )
+                                        pDlg->SetCellShiftDisabled( SC_CELL_SHIFT_DISABLE_DOWN | SC_CELL_SHIFT_DISABLE_RIGHT );
+                                    else
+                                    {
+                                        //no conflict with intersecting ranges,
+                                        //check if paste plus shift will fit on sheet
+                                        //and disable shift-option if no fit
+                                        int nDisableShiftX = 0;
+                                        int nDisableShiftY = 0;
+
+                                        //check if horizontal shift will fit
+                                        if ( !pData->GetDocument()->IsBlockEmpty( nStartTab,
+                                                    MAXCOL - nRangeSizeX, nStartY,
+                                                    MAXCOL, nStartY + nRangeSizeY, false ) )
+                                            nDisableShiftX = SC_CELL_SHIFT_DISABLE_RIGHT;
+
+                                        //check if vertical shift will fit
+                                        if ( !pData->GetDocument()->IsBlockEmpty( nStartTab,
+                                                    nStartX, MAXROW - nRangeSizeY,
+                                                    nStartX + nRangeSizeX, MAXROW, false ) )
+                                            nDisableShiftY = SC_CELL_SHIFT_DISABLE_DOWN;
+
+                                        if ( nDisableShiftX || nDisableShiftY )
+                                            pDlg->SetCellShiftDisabled( nDisableShiftX | nDisableShiftY );
                                     }
                                 }
                             }


More information about the Libreoffice-commits mailing list