summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
authorDennis Francis <dennisfrancis.in@gmail.com>2015-11-01 03:49:38 +0530
committerEike Rathke <erack@redhat.com>2015-12-07 13:49:53 +0000
commit2e512174f2116d86682037459fd5ab5164e9f510 (patch)
treef28b135f29c1246a7a1f6a766de1214ab49f3bf6 /sc
parent1a032dcfebc2702f0612c470d6b9c3e3cf4fb637 (diff)
tdf#34449 : ability of deleting borders of a cell from adjacent cell
Change-Id: Ieb13a9ea88faa220d1ee352b0e47268a7fda5f38 Reviewed-on: https://gerrit.libreoffice.org/19715 Reviewed-by: Eike Rathke <erack@redhat.com> Tested-by: Eike Rathke <erack@redhat.com>
Diffstat (limited to 'sc')
-rw-r--r--sc/inc/markdata.hxx15
-rw-r--r--sc/source/core/data/document.cxx80
-rw-r--r--sc/source/core/data/markdata.cxx267
-rw-r--r--sc/source/ui/inc/undoblk.hxx4
-rw-r--r--sc/source/ui/undo/undoblk3.cxx8
-rw-r--r--sc/source/ui/view/viewfunc.cxx22
6 files changed, 385 insertions, 11 deletions
diff --git a/sc/inc/markdata.hxx b/sc/inc/markdata.hxx
index 20777a69367f..6e3eafc3aee8 100644
--- a/sc/inc/markdata.hxx
+++ b/sc/inc/markdata.hxx
@@ -21,6 +21,7 @@
#define INCLUDED_SC_INC_MARKDATA_HXX
#include "address.hxx"
+#include "rangelst.hxx"
#include "scdllapi.h"
#include <set>
@@ -55,6 +56,11 @@ private:
bool bMarking:1; // area is being marked -> no MarkToMulti
bool bMarkIsNeg:1; // cancel if multi selection
+ ScRangeList aTopEnvelope; // list of ranges in the top envelope of the multi selection
+ ScRangeList aBottomEnvelope; // list of ranges in the bottom envelope of the multi selection
+ ScRangeList aLeftEnvelope; // list of ranges in the left envelope of the multi selection
+ ScRangeList aRightEnvelope; // list of ranges in the right envelope of the multi selection
+
public:
ScMarkData();
@@ -122,6 +128,15 @@ public:
void InsertTab( SCTAB nTab );
void DeleteTab( SCTAB nTab );
+ // Generate envelopes if mutimarked and fills the passed ScRange object with
+ // the smallest range that includes the marked area plus its envelopes.
+ void GetSelectionCover( ScRange& rRange );
+ // Get top, bottom, left and right envelopes
+ const ScRangeList& GetTopEnvelope() const { return aTopEnvelope; }
+ const ScRangeList& GetBottomEnvelope() const { return aBottomEnvelope; }
+ const ScRangeList& GetLeftEnvelope() const { return aLeftEnvelope; }
+ const ScRangeList& GetRightEnvelope() const { return aRightEnvelope; }
+
// iterators for table access
typedef std::set<SCTAB>::iterator iterator;
typedef std::set<SCTAB>::const_iterator const_iterator;
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 5225443475b2..129695ab12bb 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -5591,6 +5591,86 @@ void ScDocument::ApplySelectionFrame( const ScMarkData& rMark,
}
}
}
+ if( pLineOuter && pLineOuter->IsRemoveAdjacentCellBorder() )
+ {
+ SvxBoxItem aTmp0( *pLineOuter );
+ aTmp0.SetLine( NULL, SvxBoxItemLine::TOP );
+ aTmp0.SetLine( NULL, SvxBoxItemLine::BOTTOM );
+ aTmp0.SetLine( NULL, SvxBoxItemLine::LEFT );
+ aTmp0.SetLine( NULL, SvxBoxItemLine::RIGHT );
+ SvxBoxItem aLeft( aTmp0 );
+ SvxBoxItem aRight( aTmp0 );
+ SvxBoxItem aTop( aTmp0 );
+ SvxBoxItem aBottom( aTmp0 );
+
+ SvxBoxInfoItem aTmp1( *pLineInner );
+ aTmp1.SetTable( false );
+ aTmp1.SetLine( NULL, SvxBoxInfoItemLine::HORI );
+ aTmp1.SetLine( NULL, SvxBoxInfoItemLine::VERT );
+ aTmp1.SetValid( SvxBoxInfoItemValidFlags::ALL, false );
+ aTmp1.SetValid( SvxBoxInfoItemValidFlags::DISTANCE, true );
+ SvxBoxInfoItem aLeftInfo( aTmp1 );
+ SvxBoxInfoItem aRightInfo( aTmp1 );
+ SvxBoxInfoItem aTopInfo( aTmp1 );
+ SvxBoxInfoItem aBottomInfo( aTmp1 );
+
+ if( pLineInner->IsValid( SvxBoxInfoItemValidFlags::TOP ) && !pLineOuter->GetTop() )
+ aTopInfo.SetValid( SvxBoxInfoItemValidFlags::BOTTOM, true );
+
+ if( pLineInner->IsValid( SvxBoxInfoItemValidFlags::BOTTOM ) && !pLineOuter->GetBottom() )
+ aBottomInfo.SetValid( SvxBoxInfoItemValidFlags::TOP, true );
+
+ if( pLineInner->IsValid( SvxBoxInfoItemValidFlags::LEFT ) && !pLineOuter->GetLeft() )
+ aLeftInfo.SetValid( SvxBoxInfoItemValidFlags::RIGHT, true );
+
+ if( pLineInner->IsValid( SvxBoxInfoItemValidFlags::RIGHT ) && !pLineOuter->GetRight() )
+ aRightInfo.SetValid( SvxBoxInfoItemValidFlags::LEFT, true );
+
+ const ScRangeList& rRangeListTopEnvelope = rMark.GetTopEnvelope();
+ const ScRangeList& rRangeListBottomEnvelope = rMark.GetBottomEnvelope();
+ const ScRangeList& rRangeListLeftEnvelope = rMark.GetLeftEnvelope();
+ const ScRangeList& rRangeListRightEnvelope = rMark.GetRightEnvelope();
+
+ ScMarkData::const_iterator itr1 = rMark.begin(), itrEnd1 = rMark.end();
+ for ( ; itr1 != itrEnd1 && *itr1 < nMax; ++itr1 )
+ {
+ if ( maTabs[*itr1] )
+ {
+ size_t nEnvelopeRangeCount = rRangeListTopEnvelope.size();
+ for ( size_t j=0; j < nEnvelopeRangeCount; j++ )
+ {
+ const ScRange* pRange = rRangeListTopEnvelope[ j ];
+ maTabs[*itr1]->ApplyBlockFrame( &aTop, &aTopInfo,
+ pRange->aStart.Col(), pRange->aStart.Row(),
+ pRange->aEnd.Col(), pRange->aEnd.Row() );
+ }
+ nEnvelopeRangeCount = rRangeListBottomEnvelope.size();
+ for ( size_t j=0; j < nEnvelopeRangeCount; j++ )
+ {
+ const ScRange* pRange = rRangeListBottomEnvelope[ j ];
+ maTabs[*itr1]->ApplyBlockFrame( &aBottom, &aBottomInfo,
+ pRange->aStart.Col(), pRange->aStart.Row(),
+ pRange->aEnd.Col(), pRange->aEnd.Row() );
+ }
+ nEnvelopeRangeCount = rRangeListLeftEnvelope.size();
+ for ( size_t j=0; j < nEnvelopeRangeCount; j++ )
+ {
+ const ScRange* pRange = rRangeListLeftEnvelope[ j ];
+ maTabs[*itr1]->ApplyBlockFrame( &aLeft, &aLeftInfo,
+ pRange->aStart.Col(), pRange->aStart.Row(),
+ pRange->aEnd.Col(), pRange->aEnd.Row() );
+ }
+ nEnvelopeRangeCount = rRangeListRightEnvelope.size();
+ for ( size_t j=0; j < nEnvelopeRangeCount; j++ )
+ {
+ const ScRange* pRange = rRangeListRightEnvelope[ j ];
+ maTabs[*itr1]->ApplyBlockFrame( &aRight, &aRightInfo,
+ pRange->aStart.Col(), pRange->aStart.Row(),
+ pRange->aEnd.Col(), pRange->aEnd.Row() );
+ }
+ }
+ }
+ }
}
void ScDocument::ApplyFrameAreaTab( const ScRange& rRange,
diff --git a/sc/source/core/data/markdata.cxx b/sc/source/core/data/markdata.cxx
index 137a2e442ee7..b8eaac78d4c0 100644
--- a/sc/source/core/data/markdata.cxx
+++ b/sc/source/core/data/markdata.cxx
@@ -20,8 +20,10 @@
#include "markdata.hxx"
#include "markarr.hxx"
#include "rangelst.hxx"
+#include "segmenttree.hxx"
#include <columnspanset.hxx>
#include <fstalgorithm.hxx>
+#include <unordered_map>
#include <osl/diagnose.h>
@@ -40,7 +42,11 @@ ScMarkData::ScMarkData(const ScMarkData& rData) :
maTabMarked( rData.maTabMarked ),
aMarkRange( rData.aMarkRange ),
aMultiRange( rData.aMultiRange ),
- pMultiSel( nullptr )
+ pMultiSel( nullptr ),
+ aTopEnvelope( rData.aTopEnvelope ),
+ aBottomEnvelope( rData.aBottomEnvelope ),
+ aLeftEnvelope( rData.aLeftEnvelope ),
+ aRightEnvelope( rData.aRightEnvelope )
{
bMarked = rData.bMarked;
bMultiMarked = rData.bMultiMarked;
@@ -69,6 +75,10 @@ ScMarkData& ScMarkData::operator=(const ScMarkData& rData)
bMultiMarked = rData.bMultiMarked;
bMarking = rData.bMarking;
bMarkIsNeg = rData.bMarkIsNeg;
+ aTopEnvelope = rData.aTopEnvelope;
+ aBottomEnvelope = rData.aBottomEnvelope;
+ aLeftEnvelope = rData.aLeftEnvelope;
+ aRightEnvelope = rData.aRightEnvelope;
maTabMarked = rData.maTabMarked;
@@ -94,6 +104,10 @@ void ScMarkData::ResetMark()
bMarked = bMultiMarked = false;
bMarking = bMarkIsNeg = false;
+ aTopEnvelope.RemoveAll();
+ aBottomEnvelope.RemoveAll();
+ aLeftEnvelope.RemoveAll();
+ aRightEnvelope.RemoveAll();
}
void ScMarkData::SetMarkArea( const ScRange& rRange )
@@ -553,6 +567,257 @@ void ScMarkData::DeleteTab( SCTAB nTab )
maTabMarked.swap(tabMarked);
}
+static void lcl_AddRanges(ScRange& rRangeDest, const ScRange& rNewRange )
+{
+ SCCOL nStartCol = rNewRange.aStart.Col();
+ SCROW nStartRow = rNewRange.aStart.Row();
+ SCCOL nEndCol = rNewRange.aEnd.Col();
+ SCROW nEndRow = rNewRange.aEnd.Row();
+ PutInOrder( nStartRow, nEndRow );
+ PutInOrder( nStartCol, nEndCol );
+ if ( nStartCol < rRangeDest.aStart.Col() )
+ rRangeDest.aStart.SetCol( nStartCol );
+ if ( nStartRow < rRangeDest.aStart.Row() )
+ rRangeDest.aStart.SetRow( nStartRow );
+ if ( nEndCol > rRangeDest.aEnd.Col() )
+ rRangeDest.aEnd.SetCol( nEndCol );
+ if ( nEndRow > rRangeDest.aEnd.Row() )
+ rRangeDest.aEnd.SetRow( nEndRow );
+}
+
+void ScMarkData::GetSelectionCover( ScRange& rRange )
+{
+ if( bMultiMarked )
+ {
+ rRange = aMultiRange;
+ SCCOL nStartCol = aMultiRange.aStart.Col(), nEndCol = aMultiRange.aEnd.Col();
+ PutInOrder( nStartCol, nEndCol );
+ nStartCol = ( nStartCol == 0 ) ? nStartCol : nStartCol - 1;
+ nEndCol = ( nEndCol == MAXCOL ) ? nEndCol : nEndCol + 1;
+ std::unique_ptr<ScFlatBoolRowSegments> pPrevColMarkedRows;
+ std::unique_ptr<ScFlatBoolRowSegments> pCurColMarkedRows;
+ std::unordered_map<SCROW,ScFlatBoolColSegments> aRowToColSegmentsInTopEnvelope;
+ std::unordered_map<SCROW,ScFlatBoolColSegments> aRowToColSegmentsInBottomEnvelope;
+ ScFlatBoolRowSegments aNoRowsMarked;
+ aNoRowsMarked.setFalse( 0, MAXROW );
+
+ const ScMarkArray* pArray = pMultiSel;
+ bool bPrevColUnMarked = false;
+
+ for ( SCCOL nCol=nStartCol; nCol <= nEndCol; nCol++ )
+ {
+ SCROW nTop, nBottom;
+ bool bCurColUnMarked = !pArray[nCol].HasMarks();
+ if ( !bCurColUnMarked )
+ {
+ pCurColMarkedRows.reset( new ScFlatBoolRowSegments() );
+ pCurColMarkedRows->setFalse( 0, MAXROW );
+ ScMarkArrayIter aMarkIter( pArray + nCol );
+ ScFlatBoolRowSegments::ForwardIterator aPrevItr ( pPrevColMarkedRows.get() ? *pPrevColMarkedRows : aNoRowsMarked ); // For finding left envelope
+ ScFlatBoolRowSegments::ForwardIterator aPrevItr1( pPrevColMarkedRows.get() ? *pPrevColMarkedRows : aNoRowsMarked ); // For finding right envelope
+ SCROW nTopPrev = 0, nBottomPrev = 0; // For right envelope
+ while ( aMarkIter.Next( nTop, nBottom ) )
+ {
+ pCurColMarkedRows->setTrue( nTop, nBottom );
+ if( bPrevColUnMarked && ( nCol > nStartCol ))
+ {
+ ScRange aAddRange(nCol - 1, nTop, aMultiRange.aStart.Tab(),
+ nCol - 1, nBottom, aMultiRange.aStart.Tab());
+ lcl_AddRanges( rRange, aAddRange ); // Left envelope
+ aLeftEnvelope.Append( aAddRange );
+ }
+ else if( nCol > nStartCol )
+ {
+ SCROW nTop1 = nTop, nBottom1 = nTop;
+ while( nTop1 <= nBottom && nBottom1 <= nBottom )
+ {
+ bool bRangeMarked = false;
+ aPrevItr.getValue( nTop1, bRangeMarked );
+ if( bRangeMarked )
+ {
+ nTop1 = aPrevItr.getLastPos() + 1;
+ nBottom1 = nTop1;
+ }
+ else
+ {
+ nBottom1 = aPrevItr.getLastPos();
+ if( nBottom1 > nBottom )
+ nBottom1 = nBottom;
+ ScRange aAddRange( nCol - 1, nTop1, aMultiRange.aStart.Tab(),
+ nCol - 1, nBottom1, aMultiRange.aStart.Tab() );
+ lcl_AddRanges( rRange, aAddRange ); // Left envelope
+ aLeftEnvelope.Append( aAddRange );
+ nTop1 = ++nBottom1;
+ }
+ }
+ while( nTopPrev <= nBottom && nBottomPrev <= nBottom )
+ {
+ bool bRangeMarked;
+ aPrevItr1.getValue( nTopPrev, bRangeMarked );
+ if( bRangeMarked )
+ {
+ nBottomPrev = aPrevItr1.getLastPos();
+ if( nTopPrev < nTop )
+ {
+ if( nBottomPrev >= nTop )
+ {
+ nBottomPrev = nTop - 1;
+ ScRange aAddRange( nCol, nTopPrev, aMultiRange.aStart.Tab(),
+ nCol, nBottomPrev, aMultiRange.aStart.Tab());
+ lcl_AddRanges( rRange, aAddRange ); // Right envelope
+ aRightEnvelope.Append( aAddRange );
+ nTopPrev = nBottomPrev = (nBottom + 1);
+ }
+ else
+ {
+ ScRange aAddRange( nCol, nTopPrev, aMultiRange.aStart.Tab(),
+ nCol, nBottomPrev, aMultiRange.aStart.Tab());
+ lcl_AddRanges( rRange, aAddRange ); // Right envelope
+ aRightEnvelope.Append( aAddRange );
+ nTopPrev = ++nBottomPrev;
+ }
+ }
+ else
+ nTopPrev = nBottomPrev = ( nBottom + 1 );
+ }
+ else
+ {
+ nBottomPrev = aPrevItr1.getLastPos();
+ nTopPrev = ++nBottomPrev;
+ }
+ }
+ }
+ if( nTop )
+ {
+ ScRange aAddRange( nCol, nTop - 1, aMultiRange.aStart.Tab(),
+ nCol, nTop - 1, aMultiRange.aStart.Tab());
+ lcl_AddRanges( rRange, aAddRange ); // Top envelope
+ aRowToColSegmentsInTopEnvelope[nTop - 1].setTrue( nCol, nCol );
+ }
+ if( nBottom < MAXROW )
+ {
+ ScRange aAddRange(nCol, nBottom + 1, aMultiRange.aStart.Tab(),
+ nCol, nBottom + 1, aMultiRange.aStart.Tab());
+ lcl_AddRanges( rRange, aAddRange ); // Bottom envelope
+ aRowToColSegmentsInBottomEnvelope[nBottom + 1].setTrue( nCol, nCol );
+ }
+ }
+
+ while( nTopPrev <= MAXROW && nBottomPrev <= MAXROW && ( nCol > nStartCol ) )
+ {
+ bool bRangeMarked;
+ aPrevItr1.getValue( nTopPrev, bRangeMarked );
+ if( bRangeMarked )
+ {
+ nBottomPrev = aPrevItr1.getLastPos();
+ ScRange aAddRange(nCol, nTopPrev, aMultiRange.aStart.Tab(),
+ nCol, nBottomPrev, aMultiRange.aStart.Tab());
+ lcl_AddRanges( rRange, aAddRange ); // Right envelope
+ aRightEnvelope.Append( aAddRange );
+ nTopPrev = ++nBottomPrev;
+ }
+ else
+ {
+ nBottomPrev = aPrevItr1.getLastPos();
+ nTopPrev = ++nBottomPrev;
+ }
+ }
+ }
+ else if( nCol > nStartCol )
+ {
+ bPrevColUnMarked = true;
+ SCROW nTopPrev = 0, nBottomPrev = 0;
+ bool bRangeMarked = false;
+ ScFlatBoolRowSegments::ForwardIterator aPrevItr( pPrevColMarkedRows.get() ? *pPrevColMarkedRows : aNoRowsMarked );
+ while( nTopPrev <= MAXROW && nBottomPrev <= MAXROW )
+ {
+ aPrevItr.getValue(nTopPrev, bRangeMarked);
+ if( bRangeMarked )
+ {
+ nBottomPrev = aPrevItr.getLastPos();
+ ScRange aAddRange(nCol, nTopPrev, aMultiRange.aStart.Tab(),
+ nCol, nBottomPrev, aMultiRange.aStart.Tab());
+ lcl_AddRanges( rRange, aAddRange ); // Right envelope
+ aRightEnvelope.Append( aAddRange );
+ nTopPrev = ++nBottomPrev;
+ }
+ else
+ {
+ nBottomPrev = aPrevItr.getLastPos();
+ nTopPrev = ++nBottomPrev;
+ }
+ }
+ }
+ if ( bCurColUnMarked )
+ pPrevColMarkedRows.reset( nullptr );
+ else
+ pPrevColMarkedRows.reset( pCurColMarkedRows.release() );
+ }
+ for( auto& rKV : aRowToColSegmentsInTopEnvelope )
+ {
+ SCCOL nStart = nStartCol;
+ ScFlatBoolColSegments::RangeData aRange;
+ while( nStart <= nEndCol )
+ {
+ if( !rKV.second.getRangeData( nStart, aRange ) )
+ break;
+ if( aRange.mbValue ) // is marked
+ aTopEnvelope.Append( ScRange( aRange.mnCol1, rKV.first, aMultiRange.aStart.Tab(),
+ aRange.mnCol2, rKV.first, aMultiRange.aStart.Tab() ) );
+ nStart = aRange.mnCol2 + 1;
+ }
+ }
+ for( auto& rKV : aRowToColSegmentsInBottomEnvelope )
+ {
+ SCCOL nStart = nStartCol;
+ ScFlatBoolColSegments::RangeData aRange;
+ while( nStart <= nEndCol )
+ {
+ if( !rKV.second.getRangeData( nStart, aRange ) )
+ break;
+ if( aRange.mbValue ) // is marked
+ aBottomEnvelope.Append( ScRange( aRange.mnCol1, rKV.first, aMultiRange.aStart.Tab(),
+ aRange.mnCol2, rKV.first, aMultiRange.aStart.Tab() ) );
+ nStart = aRange.mnCol2 + 1;
+ }
+ }
+ }
+ else if( bMarked )
+ {
+ aMarkRange.PutInOrder();
+ SCROW nRow1, nRow2, nRow1New, nRow2New;
+ SCCOL nCol1, nCol2, nCol1New, nCol2New;
+ SCTAB nTab1, nTab2;
+ aMarkRange.GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
+ nCol1New = nCol1;
+ nCol2New = nCol2;
+ nRow1New = nRow1;
+ nRow2New = nRow2;
+ // Each envelope will have zero or more ranges for single rectangle selection.
+ if( nCol1 > 0 )
+ {
+ aLeftEnvelope.Append( ScRange( nCol1 - 1, nRow1, nTab1, nCol1 - 1, nRow2, nTab2 ) );
+ --nCol1New;
+ }
+ if( nRow1 > 0 )
+ {
+ aTopEnvelope.Append( ScRange( nCol1, nRow1 - 1, nTab1, nCol2, nRow1 - 1, nTab2 ) );
+ --nRow1New;
+ }
+ if( nCol2 < MAXCOL )
+ {
+ aRightEnvelope.Append( ScRange( nCol2 + 1, nRow1, nTab1, nCol2 + 1, nRow2, nTab2 ) );
+ ++nCol2New;
+ }
+ if( nRow2 < MAXROW )
+ {
+ aBottomEnvelope.Append( ScRange( nCol1, nRow2 + 1, nTab1, nCol2, nRow2 + 1, nTab2 ) );
+ ++nRow2New;
+ }
+ rRange = ScRange( nCol1New, nRow1New, nTab1, nCol2New, nRow2New, nTab2 );
+ }
+}
+
//iterators
ScMarkData::iterator ScMarkData::begin()
{
diff --git a/sc/source/ui/inc/undoblk.hxx b/sc/source/ui/inc/undoblk.hxx
index 2bafcdddfffb..3187163aefd3 100644
--- a/sc/source/ui/inc/undoblk.hxx
+++ b/sc/source/ui/inc/undoblk.hxx
@@ -322,7 +322,8 @@ public:
ScDocument* pNewUndoDoc, bool bNewMulti,
const ScPatternAttr* pNewApply,
const SvxBoxItem* pNewOuter = nullptr,
- const SvxBoxInfoItem* pNewInner = nullptr );
+ const SvxBoxInfoItem* pNewInner = nullptr,
+ const ScRange* pRangeCover = nullptr );
virtual ~ScUndoSelectionAttr();
virtual void Undo() override;
@@ -336,6 +337,7 @@ public:
private:
ScMarkData aMarkData;
ScRange aRange;
+ ScRange aRangeCover;
std::unique_ptr<ScEditDataArray> mpDataArray;
ScDocument* pUndoDoc;
bool bMulti;
diff --git a/sc/source/ui/undo/undoblk3.cxx b/sc/source/ui/undo/undoblk3.cxx
index f7e0e2846869..aa04576f6b90 100644
--- a/sc/source/ui/undo/undoblk3.cxx
+++ b/sc/source/ui/undo/undoblk3.cxx
@@ -349,7 +349,8 @@ ScUndoSelectionAttr::ScUndoSelectionAttr( ScDocShell* pNewDocShell,
SCCOL nEndX, SCROW nEndY, SCTAB nEndZ,
ScDocument* pNewUndoDoc, bool bNewMulti,
const ScPatternAttr* pNewApply,
- const SvxBoxItem* pNewOuter, const SvxBoxInfoItem* pNewInner )
+ const SvxBoxItem* pNewOuter, const SvxBoxInfoItem* pNewInner,
+ const ScRange* pRangeCover )
: ScSimpleUndo( pNewDocShell ),
aMarkData ( rMark ),
aRange ( nStartX, nStartY, nStartZ, nEndX, nEndY, nEndZ ),
@@ -361,6 +362,7 @@ ScUndoSelectionAttr::ScUndoSelectionAttr( ScDocShell* pNewDocShell,
pApplyPattern = const_cast<ScPatternAttr*>(static_cast<const ScPatternAttr*>( &pPool->Put( *pNewApply ) ));
pLineOuter = pNewOuter ? const_cast<SvxBoxItem*>(static_cast<const SvxBoxItem*>( &pPool->Put( *pNewOuter ) )) : nullptr;
pLineInner = pNewInner ? const_cast<SvxBoxInfoItem*>(static_cast<const SvxBoxInfoItem*>( &pPool->Put( *pNewInner ) )) : nullptr;
+ aRangeCover = pRangeCover ? *pRangeCover : aRange;
}
ScUndoSelectionAttr::~ScUndoSelectionAttr()
@@ -392,7 +394,7 @@ void ScUndoSelectionAttr::DoChange( const bool bUndo )
SetViewMarkData( aMarkData );
- ScRange aEffRange( aRange );
+ ScRange aEffRange( aRangeCover );
if ( rDoc.HasAttrib( aEffRange, HASATTR_MERGED ) ) // merged cells?
rDoc.ExtendMerge( aEffRange );
@@ -403,7 +405,7 @@ void ScUndoSelectionAttr::DoChange( const bool bUndo )
if (bUndo) // only for Undo
{
- ScRange aCopyRange = aRange;
+ ScRange aCopyRange = aRangeCover;
SCTAB nTabCount = rDoc.GetTableCount();
aCopyRange.aStart.SetTab(0);
aCopyRange.aEnd.SetTab(nTabCount-1);
diff --git a/sc/source/ui/view/viewfunc.cxx b/sc/source/ui/view/viewfunc.cxx
index ebcee5d1941c..cb140c8fca6c 100644
--- a/sc/source/ui/view/viewfunc.cxx
+++ b/sc/source/ui/view/viewfunc.cxx
@@ -1019,7 +1019,10 @@ void ScViewFunc::ApplyPatternLines( const ScPatternAttr& rAttr, const SvxBoxItem
if (bRecord && !pDoc->IsUndoEnabled())
bRecord = false;
- ScRange aMarkRange;
+ bool bRemoveAdjCellBorder = false;
+ if( pNewOuter )
+ bRemoveAdjCellBorder = pNewOuter->IsRemoveAdjacentCellBorder();
+ ScRange aMarkRange, aMarkRangeWithEnvelope;
aFuncMark.MarkToSimple();
bool bMulti = aFuncMark.IsMultiMarked();
if (bMulti)
@@ -1035,6 +1038,10 @@ void ScViewFunc::ApplyPatternLines( const ScPatternAttr& rAttr, const SvxBoxItem
aFuncMark.SetMarkArea(aMarkRange);
MarkDataChanged();
}
+ if( bRemoveAdjCellBorder )
+ aFuncMark.GetSelectionCover( aMarkRangeWithEnvelope );
+ else
+ aMarkRangeWithEnvelope = aMarkRange;
ScDocShell* pDocSh = GetViewData().GetDocShell();
@@ -1045,31 +1052,34 @@ void ScViewFunc::ApplyPatternLines( const ScPatternAttr& rAttr, const SvxBoxItem
ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
SCTAB nStartTab = aMarkRange.aStart.Tab();
SCTAB nTabCount = pDoc->GetTableCount();
+ bool bCopyOnlyMarked = false;
+ if( !bRemoveAdjCellBorder )
+ bCopyOnlyMarked = bMulti;
pUndoDoc->InitUndo( pDoc, nStartTab, nStartTab );
ScMarkData::iterator itr = aFuncMark.begin(), itrEnd = aFuncMark.end();
for (; itr != itrEnd; ++itr)
if (*itr != nStartTab)
pUndoDoc->AddUndoTab( *itr, *itr );
- ScRange aCopyRange = aMarkRange;
+ ScRange aCopyRange = aMarkRangeWithEnvelope;
aCopyRange.aStart.SetTab(0);
aCopyRange.aEnd.SetTab(nTabCount-1);
- pDoc->CopyToDocument( aCopyRange, InsertDeleteFlags::ATTRIB, bMulti, pUndoDoc, &aFuncMark );
+ pDoc->CopyToDocument( aCopyRange, InsertDeleteFlags::ATTRIB, bCopyOnlyMarked, pUndoDoc, &aFuncMark );
pDocSh->GetUndoManager()->AddUndoAction(
new ScUndoSelectionAttr(
pDocSh, aFuncMark,
aMarkRange.aStart.Col(), aMarkRange.aStart.Row(), aMarkRange.aStart.Tab(),
aMarkRange.aEnd.Col(), aMarkRange.aEnd.Row(), aMarkRange.aEnd.Tab(),
- pUndoDoc, bMulti, &rAttr, pNewOuter, pNewInner ) );
+ pUndoDoc, bCopyOnlyMarked, &rAttr, pNewOuter, pNewInner, &aMarkRangeWithEnvelope ) );
}
sal_uInt16 nExt = SC_PF_TESTMERGE;
- pDocSh->UpdatePaintExt( nExt, aMarkRange ); // content before the change
+ pDocSh->UpdatePaintExt( nExt, aMarkRangeWithEnvelope ); // content before the change
pDoc->ApplySelectionFrame( aFuncMark, pNewOuter, pNewInner );
- pDocSh->UpdatePaintExt( nExt, aMarkRange ); // content after the change
+ pDocSh->UpdatePaintExt( nExt, aMarkRangeWithEnvelope ); // content after the change
aFuncMark.MarkToMulti();
pDoc->ApplySelectionPattern( rAttr, aFuncMark );