Kaydet (Commit) ab0096ed authored tarafından Kohei Yoshida's avatar Kohei Yoshida

fdo#46070: Allow copying of adjacent cells via Fill Down/Up/Left/Right.

üst 843eafc7
......@@ -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());
......
......@@ -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,
......
......@@ -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,
......
......@@ -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)
......
......@@ -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());
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment