diff options
author | Kohei Yoshida <kohei.yoshida@suse.com> | 2012-02-15 14:06:48 -0500 |
---|---|---|
committer | Kohei Yoshida <kohei.yoshida@suse.com> | 2012-02-15 14:08:08 -0500 |
commit | ab0096ed68cdc08906f518d3499a8e1afc5ba80c (patch) | |
tree | ddcf6aec5572df28904ae114c2b6ec4f010f607b | |
parent | 843eafc765a3d1d0ea4c9a89855c73e81784aa8b (diff) |
fdo#46070: Allow copying of adjacent cells via Fill Down/Up/Left/Right.
-rw-r--r-- | sc/source/ui/docshell/docfunc.cxx | 100 | ||||
-rw-r--r-- | sc/source/ui/inc/docfunc.hxx | 4 | ||||
-rw-r--r-- | sc/source/ui/inc/viewfunc.hxx | 2 | ||||
-rw-r--r-- | sc/source/ui/view/cellsh.cxx | 57 | ||||
-rw-r--r-- | sc/source/ui/view/viewfun2.cxx | 4 |
5 files changed, 124 insertions, 43 deletions
diff --git a/sc/source/ui/docshell/docfunc.cxx b/sc/source/ui/docshell/docfunc.cxx index 8b9d0688f275..58041904a991 100644 --- a/sc/source/ui/docshell/docfunc.cxx +++ b/sc/source/ui/docshell/docfunc.cxx @@ -3933,19 +3933,91 @@ inline ScDirection DirFromFillDir( FillDir eDir ) return DIR_LEFT; } -sal_Bool ScDocFunc::FillSimple( const ScRange& rRange, const ScMarkData* pTabMark, - FillDir eDir, sal_Bool bRecord, sal_Bool bApi ) +namespace { + +/** + * Expand the fill range as necessary, to allow copying of adjacent cell(s) + * even when those cells are not in the original range. + */ +void adjustFillRangeForAdjacentCopy(ScRange& rRange, FillDir eDir) { - ScDocShellModificator aModificator( rDocShell ); + switch (eDir) + { + case FILL_TO_BOTTOM: + { + if (rRange.aStart.Row() == 0) + return; - sal_Bool bSuccess = false; + if (rRange.aStart.Row() != rRange.aEnd.Row()) + return; + + // Include the above row. + ScAddress& s = rRange.aStart; + s.SetRow(s.Row()-1); + } + break; + case FILL_TO_TOP: + { + if (rRange.aStart.Row() == MAXROW) + return; + + if (rRange.aStart.Row() != rRange.aEnd.Row()) + return; + + // Include the row below. + ScAddress& e = rRange.aEnd; + e.SetRow(e.Row()+1); + } + break; + case FILL_TO_LEFT: + { + if (rRange.aStart.Col() == MAXCOL) + return; + + if (rRange.aStart.Col() != rRange.aEnd.Col()) + return; + + // Include the column to the right. + ScAddress& e = rRange.aEnd; + e.SetCol(e.Col()+1); + } + break; + case FILL_TO_RIGHT: + { + if (rRange.aStart.Col() == 0) + return; + + if (rRange.aStart.Col() != rRange.aEnd.Col()) + return; + + // Include the column to the left. + ScAddress& s = rRange.aStart; + s.SetCol(s.Col()-1); + } + break; + default: + ; + } +} + +} + +bool ScDocFunc::FillSimple( const ScRange& rRange, const ScMarkData* pTabMark, + FillDir eDir, bool bRecord, bool bApi ) +{ + ScDocShellModificator aModificator( rDocShell ); ScDocument* pDoc = rDocShell.GetDocument(); - SCCOL nStartCol = rRange.aStart.Col(); - SCROW nStartRow = rRange.aStart.Row(); - SCTAB nStartTab = rRange.aStart.Tab(); - SCCOL nEndCol = rRange.aEnd.Col(); - SCROW nEndRow = rRange.aEnd.Row(); - SCTAB nEndTab = rRange.aEnd.Tab(); + + bool bSuccess = false; + ScRange aRange = rRange; + adjustFillRangeForAdjacentCopy(aRange, eDir); + + SCCOL nStartCol = aRange.aStart.Col(); + SCROW nStartRow = aRange.aStart.Row(); + SCTAB nStartTab = aRange.aStart.Tab(); + SCCOL nEndCol = aRange.aEnd.Col(); + SCROW nEndRow = aRange.aEnd.Row(); + SCTAB nEndTab = aRange.aEnd.Tab(); if (bRecord && !pDoc->IsUndoEnabled()) bRecord = false; @@ -3964,8 +4036,8 @@ sal_Bool ScDocFunc::FillSimple( const ScRange& rRange, const ScMarkData* pTabMar { WaitObject aWait( rDocShell.GetActiveDialogParent() ); - ScRange aSourceArea = rRange; - ScRange aDestArea = rRange; + ScRange aSourceArea = aRange; + ScRange aDestArea = aRange; SCCOLROW nCount = 0; switch (eDir) @@ -4010,7 +4082,7 @@ sal_Bool ScDocFunc::FillSimple( const ScRange& rRange, const ScMarkData* pTabMar pDoc->Fill( aSourceArea.aStart.Col(), aSourceArea.aStart.Row(), aSourceArea.aEnd.Col(), aSourceArea.aEnd.Row(), aMark, nCount, eDir, FILL_SIMPLE ); - AdjustRowHeight(rRange); + AdjustRowHeight(aRange); if ( bRecord ) // Draw-Undo erst jetzt verfuegbar { @@ -4022,7 +4094,7 @@ sal_Bool ScDocFunc::FillSimple( const ScRange& rRange, const ScMarkData* pTabMar rDocShell.PostPaintGridAll(); aModificator.SetDocumentModified(); - bSuccess = sal_True; + bSuccess = true; } else if (!bApi) rDocShell.ErrorMessage(aTester.GetMessageId()); diff --git a/sc/source/ui/inc/docfunc.hxx b/sc/source/ui/inc/docfunc.hxx index 63cbc3975f66..a2e6fd2093c8 100644 --- a/sc/source/ui/inc/docfunc.hxx +++ b/sc/source/ui/inc/docfunc.hxx @@ -163,8 +163,8 @@ public: sal_Bool TabOp( const ScRange& rRange, const ScMarkData* pTabMark, const ScTabOpParam& rParam, sal_Bool bRecord, sal_Bool bApi ); - sal_Bool FillSimple( const ScRange& rRange, const ScMarkData* pTabMark, - FillDir eDir, sal_Bool bRecord, sal_Bool bApi ); + bool FillSimple( const ScRange& rRange, const ScMarkData* pTabMark, + FillDir eDir, bool bRecord, bool bApi ); sal_Bool FillSeries( const ScRange& rRange, const ScMarkData* pTabMark, FillDir eDir, FillCmd eCmd, FillDateCmd eDateCmd, double fStart, double fStep, double fMax, diff --git a/sc/source/ui/inc/viewfunc.hxx b/sc/source/ui/inc/viewfunc.hxx index f1273cf04310..e6be63c71bfe 100644 --- a/sc/source/ui/inc/viewfunc.hxx +++ b/sc/source/ui/inc/viewfunc.hxx @@ -236,7 +236,7 @@ public: sal_Bool MergeCells( sal_Bool bApi, sal_Bool& rDoContents, sal_Bool bRecord = true, sal_Bool bCenter = false ); sal_Bool RemoveMerge( sal_Bool bRecord = true ); - void FillSimple( FillDir eDir, sal_Bool bRecord = sal_True ); + void FillSimple( FillDir eDir, bool bRecord = true ); void FillSeries( FillDir eDir, FillCmd eCmd, FillDateCmd eDateCmd, double fStart, double fStep, double fMax, sal_Bool bRecord = sal_True ); void FillAuto( FillDir eDir, SCCOL nStartCol, SCROW nStartRow, diff --git a/sc/source/ui/view/cellsh.cxx b/sc/source/ui/view/cellsh.cxx index d029da5c4310..66a8839b7c29 100644 --- a/sc/source/ui/view/cellsh.cxx +++ b/sc/source/ui/view/cellsh.cxx @@ -118,9 +118,9 @@ void ScCellShell::GetBlockState( SfxItemSet& rSet ) ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell(); ScRange aMarkRange; ScMarkType eMarkType = GetViewData()->GetSimpleArea( aMarkRange ); - sal_Bool bSimpleArea = (eMarkType == SC_MARK_SIMPLE); + bool bSimpleArea = (eMarkType == SC_MARK_SIMPLE); bool bOnlyNotBecauseOfMatrix; - sal_Bool bEditable = pTabViewShell->SelectionEditable( &bOnlyNotBecauseOfMatrix ); + bool bEditable = pTabViewShell->SelectionEditable( &bOnlyNotBecauseOfMatrix ); ScDocument* pDoc = GetViewData()->GetDocument(); ScDocShell* pDocShell = GetViewData()->GetDocShell(); ScMarkData& rMark = GetViewData()->GetMarkData(); @@ -135,38 +135,47 @@ void ScCellShell::GetBlockState( SfxItemSet& rSet ) sal_uInt16 nWhich = aIter.FirstWhich(); while ( nWhich ) { - sal_Bool bDisable = false; - sal_Bool bNeedEdit = sal_True; // need selection be editable? + bool bDisable = false; + bool bNeedEdit = true; // need selection be editable? switch ( nWhich ) { case FID_FILL_TO_BOTTOM: // fill to top / bottom - case FID_FILL_TO_TOP: // are at least 2 rows marked? - bDisable = (!bSimpleArea) || (nRow1 == nRow2); + { + bDisable = !bSimpleArea || (nRow1 == 0 && nRow2 == 0); if ( !bDisable && bEditable ) { // do not damage matrix - if ( nWhich == FID_FILL_TO_BOTTOM ) - bDisable = pDoc->HasSelectedBlockMatrixFragment( - nCol1, nRow1, nCol2, nRow1, rMark ); // first row - else - bDisable = pDoc->HasSelectedBlockMatrixFragment( - nCol1, nRow2, nCol2, nRow2, rMark ); // last row + bDisable = pDoc->HasSelectedBlockMatrixFragment( + nCol1, nRow1, nCol2, nRow1, rMark ); // first row } - break; - + } + break; + case FID_FILL_TO_TOP: + { + bDisable = (!bSimpleArea) || (nRow1 == MAXROW && nRow2 == MAXROW); + if ( !bDisable && bEditable ) + { // do not damage matrix + bDisable = pDoc->HasSelectedBlockMatrixFragment( + nCol1, nRow2, nCol2, nRow2, rMark ); // last row + } + } + break; case FID_FILL_TO_RIGHT: // fill to left / right - case FID_FILL_TO_LEFT: // are at least 2 columns marked? - bDisable = (!bSimpleArea) || (nCol1 == nCol2); + { + bDisable = !bSimpleArea || (nCol1 == 0 && nCol2 == 0); + bDisable = pDoc->HasSelectedBlockMatrixFragment( + nCol1, nRow1, nCol1, nRow2, rMark ); // first column + } + break; + case FID_FILL_TO_LEFT: + { + bDisable = (!bSimpleArea) || (nCol1 == MAXCOL && nCol2 == MAXCOL); if ( !bDisable && bEditable ) { // Matrix nicht zerreissen - if ( nWhich == FID_FILL_TO_RIGHT ) - bDisable = pDoc->HasSelectedBlockMatrixFragment( - nCol1, nRow1, nCol1, nRow2, rMark ); // first column - else - bDisable = pDoc->HasSelectedBlockMatrixFragment( - nCol2, nRow1, nCol2, nRow2, rMark ); // last column + bDisable = pDoc->HasSelectedBlockMatrixFragment( + nCol2, nRow1, nCol2, nRow2, rMark ); // last column } - break; - + } + break; case FID_FILL_SERIES: // fill block case SID_OPENDLG_TABOP: // multiple-cell operations, are at least 2 cells marked? if (pDoc->GetChangeTrack()!=NULL &&nWhich ==SID_OPENDLG_TABOP) diff --git a/sc/source/ui/view/viewfun2.cxx b/sc/source/ui/view/viewfun2.cxx index 3cb218d20867..a2a7fe16bbb4 100644 --- a/sc/source/ui/view/viewfun2.cxx +++ b/sc/source/ui/view/viewfun2.cxx @@ -1264,14 +1264,14 @@ sal_Bool ScViewFunc::RemoveMerge( sal_Bool bRecord ) //---------------------------------------------------------------------------- -void ScViewFunc::FillSimple( FillDir eDir, sal_Bool bRecord ) +void ScViewFunc::FillSimple( FillDir eDir, bool bRecord ) { ScRange aRange; if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE) { ScDocShell* pDocSh = GetViewData()->GetDocShell(); const ScMarkData& rMark = GetViewData()->GetMarkData(); - sal_Bool bSuccess = pDocSh->GetDocFunc().FillSimple( aRange, &rMark, eDir, bRecord, false ); + bool bSuccess = pDocSh->GetDocFunc().FillSimple( aRange, &rMark, eDir, bRecord, false ); if (bSuccess) { pDocSh->UpdateOle(GetViewData()); |