summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@suse.com>2012-02-15 14:06:48 -0500
committerKohei Yoshida <kohei.yoshida@suse.com>2012-02-15 14:08:08 -0500
commitab0096ed68cdc08906f518d3499a8e1afc5ba80c (patch)
treeddcf6aec5572df28904ae114c2b6ec4f010f607b
parent843eafc765a3d1d0ea4c9a89855c73e81784aa8b (diff)
fdo#46070: Allow copying of adjacent cells via Fill Down/Up/Left/Right.
-rw-r--r--sc/source/ui/docshell/docfunc.cxx100
-rw-r--r--sc/source/ui/inc/docfunc.hxx4
-rw-r--r--sc/source/ui/inc/viewfunc.hxx2
-rw-r--r--sc/source/ui/view/cellsh.cxx57
-rw-r--r--sc/source/ui/view/viewfun2.cxx4
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());