From 5fe7b7561aa78e87f90e8a9436cb674e53ef8f4e Mon Sep 17 00:00:00 2001 From: Winfried Donkers Date: Mon, 28 Jan 2013 18:42:38 +0100 Subject: fdo#56098 paste special shift options incorrect/incomplete Change-Id: Ic84ec07f4e0963ad1759036f1d7cbfa295289375 Reviewed-on: https://gerrit.libreoffice.org/1903 Reviewed-by: Noel Power Tested-by: Noel Power Tested-by: LibreOffice gerrit bot --- sc/source/ui/view/cellsh1.cxx | 74 +++++++++++++++++++++++++++++++------------ 1 file changed, 54 insertions(+), 20 deletions(-) (limited to 'sc') 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 ); } } } -- cgit