Kaydet (Commit) c808802e authored tarafından Jan-Marek Glogowski's avatar Jan-Marek Glogowski Kaydeden (comit) Björn Michaelsen

MM: introduce SwDoc::Append helper function

This drops all the specialized, workaround code from MM, introduced
to use the SwFEShell::Paste function and additionally merges
and renames SwDoc::Paste into SwDoc::Append.

There is still a little common codepath, therefore this adds
comments to always update both functions.

Change-Id: I704b3ef3257dd977dac95e16e25049ff8ade97ed
Reviewed-on: https://gerrit.libreoffice.org/10967Reviewed-by: 's avatarBjörn Michaelsen <bjoern.michaelsen@canonical.com>
Tested-by: 's avatarBjörn Michaelsen <bjoern.michaelsen@canonical.com>
üst 8e174eab
......@@ -460,7 +460,6 @@ private:
OUString msDocAccTitle;
void InitTOXTypes();
void Paste( const SwDoc& );
public:
enum DocumentType {
......@@ -1646,7 +1645,10 @@ public:
::sw::MetaFieldManager & GetMetaFieldManager();
::sw::UndoManager & GetUndoManager();
::sw::UndoManager const& GetUndoManager() const;
SfxObjectShell* CreateCopy(bool bCallInitNew) const;
void Append( const SwDoc& rSource, sal_uInt16 nStartPageNumber,
SwPageDesc* pTargetPageDesc, bool bDeletePrevious = false );
/**
* Dumps the entire nodes structure to the given destination (file nodes.xml in the current directory by default)
......
......@@ -3138,8 +3138,10 @@ void DocumentContentOperationsManager::CopyWithFlyInFly(
!rRg.aStart.GetNode().IsSectionNode() &&
!aTmpI.GetNode().IsEndNode() )
{
// If the range starts with a SwStartNode, it isn't copied
sal_uInt16 offset = (rRg.aStart.GetNode().GetNodeType() != ND_STARTNODE) ? 1 : 0;
OSL_ENSURE( rInsPos.GetIndex() - aSavePos.GetIndex() ==
rRg.aEnd.GetIndex() - rRg.aStart.GetIndex(),
rRg.aEnd.GetIndex() - rRg.aStart.GetIndex() - 1 + offset,
"An insufficient number of nodes were copied!" );
}
}
......
......@@ -106,6 +106,7 @@
#include <DocumentExternalDataManager.hxx>
#include <unochart.hxx>
#include <fldbas.hxx>
#include <wrtsh.hxx>
#include <cmdid.h>
......@@ -900,7 +901,8 @@ SfxObjectShell* SwDoc::CreateCopy(bool bCallInitNew ) const
SfxObjectShell* pRetShell = new SwDocShell( pRet, SFX_CREATE_MODE_STANDARD );
if( bCallInitNew )
{
// it could happen that DoInitNew creates model, that increases the refcount of the object
// it could happen that DoInitNew creates model,
// that increases the refcount of the object
pRetShell->DoInitNew();
}
......@@ -912,14 +914,7 @@ SfxObjectShell* SwDoc::CreateCopy(bool bCallInitNew ) const
pRet->ReplaceStyles(*this);
// copy content
pRet->Paste( *this );
if ( bCallInitNew ) {
// delete leading page / initial content from target document
SwNodeIndex aDeleteIdx( pRet->GetNodes().GetEndOfExtras(), 2 );
pRet->GetNodes().Delete( aDeleteIdx, 1 );
}
pRet->Append(*this, 0, NULL, bCallInitNew);
// remove the temporary shell if it is there as it was done before
pRet->SetTmpDocShell( (SfxObjectShell*)NULL );
......@@ -929,29 +924,64 @@ SfxObjectShell* SwDoc::CreateCopy(bool bCallInitNew ) const
return pRetShell;
}
// copy document content - code from SwFEShell::Paste( SwDoc* )
void SwDoc::Paste( const SwDoc& rSource )
// appends all pages of source SwDoc - based on SwFEShell::Paste( SwDoc* )
void SwDoc::Append( const SwDoc& rSource, sal_uInt16 nStartPageNumber,
SwPageDesc* pTargetPageDesc, bool bDeletePrevious )
{
// GetEndOfExtras + 1 = StartOfContent == no content node!
// this ensures, that we have at least two nodes in the SwPaM.
// @see IDocumentContentOperations::CopyRange
SwNodeIndex aSourceIdx( rSource.GetNodes().GetEndOfExtras(), 1 );
SwNodeIndex aSourceEndIdx( rSource.GetNodes().GetEndOfContent(), -1 );
SwPaM aCpyPam( aSourceIdx );
if ( aSourceEndIdx.GetNode().IsTxtNode() ) {
aCpyPam.SetMark();
// moves to the last content node before EOC; for single paragraph
// documents this would result in [n, n], which is considered empty
aCpyPam.Move( fnMoveForward, fnGoDoc );
}
else
aCpyPam = SwPaM( aSourceIdx, aSourceEndIdx );
SwWrtShell* pTargetShell = GetDocShell()->GetWrtShell();
sal_uInt16 nPhysPageNumber = 0;
if ( pTargetShell ) {
pTargetShell->StartAllAction();
// Otherwise we have to handle SwDummySectionNodes as first node
if ( pTargetPageDesc ) {
OUString name = pTargetPageDesc->GetName();
pTargetShell->InsertPageBreak( &name, nStartPageNumber );
}
// -1 for the page break + -1, becauce it's an offset
nPhysPageNumber = pTargetShell->GetPhyPageNum() - 2;
if (bDeletePrevious)
nPhysPageNumber--;
// We always start on an odd physical page number
if (1 == nPhysPageNumber % 2)
nPhysPageNumber++;
}
// -1, otherwise aFixupIdx would move to new EOC
SwNodeIndex aFixupIdx( GetNodes().GetEndOfContent(), -1 );
// append at the end of document / content
SwNodeIndex aTargetIdx( GetNodes().GetEndOfContent() );
SwPaM aInsertPam( aTargetIdx );
aCpyPam.SetMark();
aCpyPam.Move( fnMoveForward, fnGoDoc );
this->GetIDocumentUndoRedo().StartUndo( UNDO_INSGLOSSARY, NULL );
this->getIDocumentFieldsAccess().LockExpFlds();
{
// **
// ** refer to SwFEShell::Paste, if you change the following code **
// **
SwPosition& rInsPos = *aInsertPam.GetPoint();
//find out if the clipboard document starts with a table
bool bStartWithTable = 0 != aCpyPam.Start()->nNode.GetNode().FindTableNode();
SwPosition aInsertPosition( rInsPos );
{
SwNodeIndex aIndexBefore(rInsPos.nNode);
......@@ -967,31 +997,88 @@ void SwDoc::Paste( const SwDoc& rSource )
aPaM.GetDoc()->MakeUniqueNumRules(aPaM);
// No need to update the rsid, as this is an empty doc
}
// Update the rsid of each pasted text node
SwNodes &rDestNodes = GetNodes();
sal_uLong const nEndIdx = aPaM.End()->nNode.GetIndex();
//TODO: Is this necessary here? SaveTblBoxCntnt( &rInsPos );
if(/*bIncludingPageFrames && */bStartWithTable)
{
//remove the paragraph in front of the table
SwPaM aPara(aInsertPosition);
this->getIDocumentContentOperations().DelFullPara(aPara);
for (sal_uLong nIdx = aPaM.Start()->nNode.GetIndex();
nIdx <= nEndIdx; ++nIdx)
{
SwTxtNode *const pTxtNode = rDestNodes[nIdx]->GetTxtNode();
if ( pTxtNode )
UpdateParRsid( pTxtNode );
}
}
//additionally copy page bound frames
if( /*bIncludingPageFrames && */rSource.GetSpzFrmFmts()->size() )
{
for ( sal_uInt16 i = 0; i < rSource.GetSpzFrmFmts()->size(); ++i )
{
const SwFrmFmt& rCpyFmt = *(*rSource.GetSpzFrmFmts())[i];
SwFmtAnchor aAnchor( rCpyFmt.GetAnchor() );
if (FLY_AT_PAGE == aAnchor.GetAnchorId())
{
aAnchor.SetPageNum( aAnchor.GetPageNum() /*+ nStartPageNumber - */);
sal_uInt16 iDelNodes = 0;
SwNodeIndex aDelIdx( aFixupIdx );
// we just need to set the new page description and reset numbering
// this keeps all other settings as in the pasted document
if ( nStartPageNumber || pTargetPageDesc ) {
SfxPoolItem *pNewItem;
SwTxtNode *aTxtNd = 0;
SwFmt *pFmt = 0;
// find the first node allowed to contain a RES_PAGEDESC
while (1) {
aFixupIdx++;
SwNode &node = aFixupIdx.GetNode();
if ( node.IsTxtNode() ) {
// every document contains at least one text node!
aTxtNd = node.GetTxtNode();
pNewItem = aTxtNd->GetAttr( RES_PAGEDESC ).Clone();
break;
}
else if ( node.IsTableNode() ) {
pFmt = node.GetTableNode()->GetTable().GetFrmFmt();
pNewItem = pFmt->GetFmtAttr( RES_PAGEDESC ).Clone();
break;
}
else
continue;
this->getIDocumentLayoutAccess().CopyLayoutFmt( rCpyFmt, aAnchor, true, true );
}
// just update the original instead of overwriting
SwFmtPageDesc *aDesc = static_cast< SwFmtPageDesc* >( pNewItem );
if ( nStartPageNumber )
aDesc->SetNumOffset( nStartPageNumber );
if ( pTargetPageDesc )
aDesc->RegisterToPageDesc( *pTargetPageDesc );
if ( aTxtNd )
aTxtNd->SetAttr( *aDesc );
else
pFmt->SetFmtAttr( *aDesc );
delete pNewItem;
iDelNodes++;
}
if ( bDeletePrevious )
iDelNodes++;
if ( iDelNodes ) {
// delete leading empty page(s), e.g. from InsertPageBreak or
// new SwDoc. this has to be done before copying the page bound
// frames, otherwise the drawing layer gets confused.
if ( pTargetShell )
pTargetShell->SttEndDoc( false );
aDelIdx -= (iDelNodes - 1);
GetNodes().Delete( aDelIdx, iDelNodes );
}
}
// finally copy page bound frames
const SwFrmFmts *pSpzFrmFmts = rSource.GetSpzFrmFmts();
for ( sal_uInt16 i = 0; i < pSpzFrmFmts->size(); ++i )
{
const SwFrmFmt& rCpyFmt = *(*pSpzFrmFmts)[i];
SwFmtAnchor aAnchor( rCpyFmt.GetAnchor() );
if (FLY_AT_PAGE != aAnchor.GetAnchorId())
continue;
if ( nPhysPageNumber )
aAnchor.SetPageNum( aAnchor.GetPageNum() + nPhysPageNumber );
this->getIDocumentLayoutAccess().CopyLayoutFmt( rCpyFmt, aAnchor, true, true );
}
}
......@@ -999,6 +1086,9 @@ void SwDoc::Paste( const SwDoc& rSource )
getIDocumentFieldsAccess().UnlockExpFlds();
getIDocumentFieldsAccess().UpdateFlds(NULL, false);
if ( pTargetShell )
pTargetShell->EndAllAction();
}
sal_uInt16 SwTxtFmtColls::GetPos(const SwTxtFmtColl* p) const
......
......@@ -1028,6 +1028,10 @@ bool SwFEShell::Paste( SwDoc* pClpDoc, bool bIncludingPageFrames )
GetDoc()->ClearBoxNumAttrs( rInsPos.nNode );
}
// **
// ** Update SwDoc::Append, if you change the following code **
// **
// find out if the clipboard document starts with a table
bool bStartWithTable = 0 != aCpyPam.Start()->nNode.GetNode().FindTableNode();
SwPosition aInsertPosition( rInsPos );
......
This diff is collapsed.
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