diff options
author | Winfried Donkers <osc@dci-electronics.nl> | 2013-01-28 18:42:38 +0100 |
---|---|---|
committer | Norbert Thiebaud <nthiebaud@gmail.com> | 2013-02-10 05:11:29 +0000 |
commit | 5fe7b7561aa78e87f90e8a9436cb674e53ef8f4e (patch) | |
tree | 505b84a8d36cb580e0320ddb0e110798d5795309 /sc | |
parent | 5a65ca67d9acefed399ed8706efa402c543bed87 (diff) |
fdo#56098 paste special shift options incorrect/incomplete
Change-Id: Ic84ec07f4e0963ad1759036f1d7cbfa295289375
Reviewed-on: https://gerrit.libreoffice.org/1903
Reviewed-by: Noel Power <noel.power@suse.com>
Tested-by: Noel Power <noel.power@suse.com>
Tested-by: LibreOffice gerrit bot <gerrit@libreoffice.org>
Diffstat (limited to 'sc')
-rw-r--r-- | sc/source/ui/view/cellsh1.cxx | 74 |
1 files changed, 54 insertions, 20 deletions
diff --git a/sc/source/ui/view/cellsh1.cxx b/sc/source/ui/view/cellsh1.cxx index c22d91d3c7b2..c32ed5de0572 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 ); } } } |