import different first page header/footer from doc
When a Word section has a different first page header/footer,
this used to be imported into LO as a chain of two page styles.
Now that LO supports a single page style with different first page
header/footer we can import to that.
This change also incidentally fixes fdo#57908.
bnc#654230 had the same underlying problem, so the workaround committed
for that (which includes comments expressing lack of understanding)
has been removed.
Change-Id: I6df7e9abc8f2a327a3b33e06322ca943f6f24605
Reviewed-on: https://gerrit.libreoffice.org/2065
Reviewed-by: Tor Lillqvist <tml@iki.fi>
Tested-by: Tor Lillqvist <tml@iki.fi>
diff --git a/sw/source/filter/ww8/wrtw8sty.cxx b/sw/source/filter/ww8/wrtw8sty.cxx
index b0e4e92..3d40f4e 100644
--- a/sw/source/filter/ww8/wrtw8sty.cxx
+++ b/sw/source/filter/ww8/wrtw8sty.cxx
@@ -1587,7 +1587,7 @@ void MSWordExportBase::SectionProperties( const WW8_SepInfo& rSepInfo, WW8_PdAtt
// a different header/footer for the first page. The same effect can be
// achieved by chaining two page styles together (SwPageDesc::GetFollow)
// which are identical except for header/footer.
// The latter method is still used by the doc/docx import filter.
// The latter method was previously used by the doc/docx import filter.
// In both of these cases, we emit a single Word section with different
// first page header/footer.
const SwFrmFmt* pPdFirstPgFmt = &pPd->GetFirst();
@@ -1622,12 +1622,6 @@ void MSWordExportBase::SectionProperties( const WW8_SepInfo& rSepInfo, WW8_PdAtt
}
}
// The code above tries to detect if this is first page headers/footers,
// but it doesn't work even for quite trivial testcases. As I don't actually
// understand that code, I'll keep it. The simple and (at least for me) reliable way
// to detect for first page seems to be just RES_POOLPAGE_FIRST.
if( pPd->GetPoolFmtId() == RES_POOLPAGE_FIRST )
titlePage = true;
if( titlePage )
AttrOutput().SectionTitlePage();
diff --git a/sw/source/filter/ww8/ww8par.cxx b/sw/source/filter/ww8/ww8par.cxx
index fdef14c..2659624 100644
--- a/sw/source/filter/ww8/ww8par.cxx
+++ b/sw/source/filter/ww8/ww8par.cxx
@@ -1932,27 +1932,11 @@ bool SwWW8ImplReader::HasOwnHeaderFooter(sal_uInt8 nWhichItems, sal_uInt8 grpfIh
return false;
}
void SwWW8ImplReader::Read_HdFt(bool bIsTitle, int nSect,
const SwPageDesc *pPrev, const wwSection &rSection)
void SwWW8ImplReader::Read_HdFt(int nSect, const SwPageDesc *pPrev,
const wwSection &rSection)
{
sal_uInt8 nWhichItems = 0;
SwPageDesc *pPD = 0;
if (!bIsTitle)
{
nWhichItems =
rSection.maSep.grpfIhdt & ~(WW8_HEADER_FIRST | WW8_FOOTER_FIRST);
pPD = rSection.mpPage;
}
else
{
// Always read title page header/footer data - it could be used by following sections
nWhichItems = ( WW8_HEADER_FIRST | WW8_FOOTER_FIRST );
pPD = rSection.mpTitlePage;
}
sal_uInt8 grpfIhdt = rSection.maSep.grpfIhdt;
SwPageDesc *pPD = rSection.mpPage;
if( pHdFt )
{
@@ -1962,7 +1946,7 @@ void SwWW8ImplReader::Read_HdFt(bool bIsTitle, int nSect,
for( sal_uInt8 nI = 0x20; nI; nI >>= 1, nNumber-- )
{
if (nI & nWhichItems)
if (nI & grpfIhdt)
{
bool bOk = true;
if( bVer67 )
@@ -1975,10 +1959,14 @@ void SwWW8ImplReader::Read_HdFt(bool bIsTitle, int nSect,
bool bUseLeft
= (nI & ( WW8_HEADER_EVEN | WW8_FOOTER_EVEN )) ? true: false;
bool bUseFirst
= (nI & ( WW8_HEADER_FIRST | WW8_FOOTER_FIRST )) ? true: false;
bool bFooter
= (nI & ( WW8_FOOTER_EVEN | WW8_FOOTER_ODD | WW8_FOOTER_FIRST )) ? true: false;
SwFrmFmt& rFmt = bUseLeft ? pPD->GetLeft() : pPD->GetMaster();
SwFrmFmt& rFmt = bUseLeft ? pPD->GetLeft()
: bUseFirst ? pPD->GetFirst()
: pPD->GetMaster();
SwFrmFmt* pHdFtFmt;
if (bFooter)
@@ -1989,6 +1977,8 @@ void SwWW8ImplReader::Read_HdFt(bool bIsTitle, int nSect,
pPD->GetMaster().SetFmtAttr(SwFmtFooter(true));
if (bUseLeft)
pPD->GetLeft().SetFmtAttr(SwFmtFooter(true));
if (bUseFirst)
pPD->GetFirst().SetFmtAttr(SwFmtFooter(true));
pHdFtFmt = const_cast<SwFrmFmt*>(rFmt.GetFooter().GetFooterFmt());
}
else
@@ -1999,6 +1989,8 @@ void SwWW8ImplReader::Read_HdFt(bool bIsTitle, int nSect,
pPD->GetMaster().SetFmtAttr(SwFmtHeader(true));
if (bUseLeft)
pPD->GetLeft().SetFmtAttr(SwFmtHeader(true));
if (bUseFirst)
pPD->GetFirst().SetFmtAttr(SwFmtHeader(true));
pHdFtFmt = const_cast<SwFrmFmt*>(rFmt.GetHeader().GetHeaderFmt());
}
@@ -2042,18 +2034,10 @@ void wwSectionManager::SetHdFt(wwSection &rSection, int nSect,
OSL_ENSURE(rSection.mpPage, "makes no sense to call with a main page");
if (rSection.mpPage)
{
mrReader.Read_HdFt(false, nSect, pPrevious ? pPrevious->mpPage : 0,
mrReader.Read_HdFt(nSect, pPrevious ? pPrevious->mpPage : 0,
rSection);
}
if (rSection.mpTitlePage)
{
// 2 Pagedescs noetig: 1.Seite und folgende
// 1. Seite einlesen
mrReader.Read_HdFt(true, nSect, pPrevious ? pPrevious->mpTitlePage : 0,
rSection);
}
// Kopf / Fuss - Index Updaten
// Damit der Index auch spaeter noch stimmt
if (mrReader.pHdFt)
@@ -3730,9 +3714,9 @@ void SwWW8ImplReader::DeleteStk(SwFltControlStack* pStck)
}
void wwSectionManager::SetSegmentToPageDesc(const wwSection &rSection,
bool bTitlePage, bool bIgnoreCols)
bool bIgnoreCols)
{
SwPageDesc &rPage = bTitlePage ? *rSection.mpTitlePage : *rSection.mpPage;
SwPageDesc &rPage = *rSection.mpPage;
SetNumberingType(rSection, rPage);
@@ -3756,26 +3740,14 @@ void wwSectionManager::SetSegmentToPageDesc(const wwSection &rSection,
}
}
wwULSpaceData aULData;
GetPageULData(rSection, bTitlePage, aULData);
GetPageULData(rSection, aULData);
SetPageULSpaceItems(rFmt, aULData, rSection);
SetPage(rPage, rFmt, rSection, bIgnoreCols);
bool bSetBorder = false;
switch (rSection.maSep.pgbApplyTo)
{
case 0:
case 3:
bSetBorder = true;
break;
case 1:
bSetBorder = bTitlePage;
break;
case 2:
bSetBorder = !bTitlePage;
break;
}
if (bSetBorder)
if (rSection.maSep.pgbApplyTo & 1)
mrReader.SetPageBorder(rPage.GetFirst(), rSection);
if (rSection.maSep.pgbApplyTo & 2)
mrReader.SetPageBorder(rFmt, rSection);
mrReader.SetDocumentGrid(rFmt, rSection);
@@ -3793,16 +3765,12 @@ void wwSectionManager::SetUseOn(wwSection &rSection)
UseOnPage eUse = eUseBase;
if (!bEven)
eUse = (UseOnPage)(eUse | nsUseOnPage::PD_HEADERSHARE | nsUseOnPage::PD_FOOTERSHARE);
eUse = (UseOnPage)(eUse | nsUseOnPage::PD_FIRSTSHARE);
if (!rSection.HasTitlePage())
eUse = (UseOnPage)(eUse | nsUseOnPage::PD_FIRSTSHARE);
OSL_ENSURE(rSection.mpPage, "Makes no sense to call me with no pages to set");
if (rSection.mpPage)
rSection.mpPage->WriteUseOn(eUse);
if (rSection.mpTitlePage)
{
rSection.mpTitlePage->WriteUseOn(
(UseOnPage) (eUseBase | nsUseOnPage::PD_HEADERSHARE | nsUseOnPage::PD_FOOTERSHARE | nsUseOnPage::PD_FIRSTSHARE));
}
}
//Set the page descriptor on this node, handle the different cases for a text
@@ -3835,32 +3803,11 @@ void GiveNodePageDesc(SwNodeIndex &rIdx, const SwFmtPageDesc &rPgDesc,
}
}
//Map a word section with to either one or two writer page descriptors
//depending on if the word section has a title page
//Map a word section to a writer page descriptor
SwFmtPageDesc wwSectionManager::SetSwFmtPageDesc(mySegIter &rIter,
mySegIter &rStart, bool bIgnoreCols)
{
SwFmtPageDesc aEmpty;
// Always read title page header/footer data - it could be used by following sections
{
if (IsNewDoc() && rIter == rStart)
{
rIter->mpTitlePage =
mrReader.rDoc.GetPageDescFromPool(RES_POOLPAGE_FIRST);
}
else
{
sal_uInt16 nPos = mrReader.rDoc.MakePageDesc(
ViewShell::GetShellRes()->GetPageDescName(mnDesc, ShellResource::FIRST_PAGE)
, 0, false);
rIter->mpTitlePage = &mrReader.rDoc.GetPageDesc(nPos);
}
OSL_ENSURE(rIter->mpTitlePage, "no page!");
if (!rIter->mpTitlePage)
return aEmpty;
SetSegmentToPageDesc(*rIter, true, bIgnoreCols);
}
if (IsNewDoc() && rIter == rStart)
{
@@ -3871,7 +3818,7 @@ SwFmtPageDesc wwSectionManager::SetSwFmtPageDesc(mySegIter &rIter,
{
sal_uInt16 nPos = mrReader.rDoc.MakePageDesc(
ViewShell::GetShellRes()->GetPageDescName(mnDesc, ShellResource::NORMAL_PAGE),
rIter->mpTitlePage, false);
0, false);
rIter->mpPage = &mrReader.rDoc.GetPageDesc(nPos);
}
OSL_ENSURE(rIter->mpPage, "no page!");
@@ -3886,18 +3833,12 @@ SwFmtPageDesc wwSectionManager::SetSwFmtPageDesc(mySegIter &rIter,
SetUseOn(*rIter);
//Set hd/ft after set page
if (rIter->mpTitlePage)
SetSegmentToPageDesc(*rIter, true, bIgnoreCols);
SetSegmentToPageDesc(*rIter, false, bIgnoreCols);
SetSegmentToPageDesc(*rIter, bIgnoreCols);
SwFmtPageDesc aRet(rIter->HasTitlePage() ?
rIter->mpTitlePage : rIter->mpPage);
SwFmtPageDesc aRet(rIter->mpPage);
rIter->mpPage->SetFollow(rIter->mpPage);
if (rIter->mpTitlePage)
rIter->mpTitlePage->SetFollow(rIter->mpPage);
if (rIter->PageRestartNo())
aRet.SetNumOffset(rIter->PageStartAt());
@@ -4077,7 +4018,6 @@ void wwSectionManager::InsertSegments()
// #i40766# Need to cache the page descriptor in case there is
// no page break in the section
SwPageDesc *pOrig = aIter->mpPage;
SwPageDesc *pOrigTitle = aIter->mpTitlePage;
bool bFailed = true;
SwFmtPageDesc aDesc(SetSwFmtPageDesc(aIter, aStart, true));
if (aDesc.GetPageDesc())
@@ -4101,7 +4041,6 @@ void wwSectionManager::InsertSegments()
if(bFailed)
{
aIter->mpPage = pOrig;
aIter->mpTitlePage = pOrigTitle;
}
}
}
diff --git a/sw/source/filter/ww8/ww8par.hxx b/sw/source/filter/ww8/ww8par.hxx
index 8ff035e..0a19e72 100644
--- a/sw/source/filter/ww8/ww8par.hxx
+++ b/sw/source/filter/ww8/ww8par.hxx
@@ -694,7 +694,6 @@ public:
WW8_BRC brc[4];
SwNodeIndex maStart;
SwSection *mpSection;
SwPageDesc *mpTitlePage;
SwPageDesc *mpPage;
SvxFrameDirection meDir;
short mLinkId;
@@ -750,10 +749,9 @@ private:
wwULSpaceData() : bHasHeader(false), bHasFooter(false) {}
};
void SetSegmentToPageDesc(const wwSection &rSection, bool bTitlePage,
bool bIgnoreCols);
void SetSegmentToPageDesc(const wwSection &rSection, bool bIgnoreCols);
void GetPageULData(const wwSection &rNewSection, bool bFirst,
void GetPageULData(const wwSection &rNewSection,
wwULSpaceData& rData) const;
void SetPageULSpaceItems(SwFrmFmt &rFmt, wwULSpaceData& rData,
const wwSection &rSection) const;
@@ -1219,7 +1217,7 @@ private:
SwWW8StyInf *GetStyle(sal_uInt16 nColl) const;
void AppendTxtNode(SwPosition& rPos);
void Read_HdFt(bool bIsTitle, int nSect, const SwPageDesc *pPrev,
void Read_HdFt(int nSect, const SwPageDesc *pPrev,
const wwSection &rSection);
void Read_HdFtText(long nStartCp, long nLen, SwFrmFmt* pHdFtFmt);
void Read_HdFtTextAsHackedFrame(long nStart, long nLen,
diff --git a/sw/source/filter/ww8/ww8par6.cxx b/sw/source/filter/ww8/ww8par6.cxx
index c4f260e..f293835 100644
--- a/sw/source/filter/ww8/ww8par6.cxx
+++ b/sw/source/filter/ww8/ww8par6.cxx
@@ -512,7 +512,7 @@ void SwWW8ImplReader::SetPageBorder(SwFrmFmt &rFmt, const wwSection &rSection) c
rFmt.SetFmtAttr(aSet);
}
void wwSectionManager::GetPageULData(const wwSection &rSection, bool bFirst,
void wwSectionManager::GetPageULData(const wwSection &rSection,
wwSectionManager::wwULSpaceData& rData) const
{
sal_Int32 nWWUp = rSection.maSep.dyaTop;
@@ -535,13 +535,8 @@ void wwSectionManager::GetPageULData(const wwSection &rSection, bool bFirst,
nWWUp += rSection.maSep.dzaGutter;
}
if( bFirst )
rData.bHasHeader = (rSection.maSep.grpfIhdt & WW8_HEADER_FIRST) !=0;
else
{
rData.bHasHeader = (rSection.maSep.grpfIhdt &
(WW8_HEADER_EVEN | WW8_HEADER_ODD)) != 0;
}
rData.bHasHeader = (rSection.maSep.grpfIhdt &
(WW8_HEADER_EVEN | WW8_HEADER_ODD | WW8_HEADER_FIRST)) != 0;
if( rData.bHasHeader )
{
@@ -562,13 +557,8 @@ void wwSectionManager::GetPageULData(const wwSection &rSection, bool bFirst,
else // kein Header -> Up einfach uebernehmen
rData.nSwUp = Abs(nWWUp);
if( bFirst )
rData.bHasFooter = (rSection.maSep.grpfIhdt & WW8_FOOTER_FIRST) !=0;
else
{
rData.bHasFooter = (rSection.maSep.grpfIhdt &
(WW8_FOOTER_EVEN | WW8_FOOTER_ODD)) != 0;
}
rData.bHasFooter = (rSection.maSep.grpfIhdt &
(WW8_FOOTER_EVEN | WW8_FOOTER_ODD | WW8_FOOTER_FIRST)) != 0;
if( rData.bHasFooter )
{
@@ -766,7 +756,7 @@ void SwWW8ImplReader::HandleLineNumbering(const wwSection &rSection)
}
wwSection::wwSection(const SwPosition &rPos) : maStart(rPos.nNode),
mpSection(0), mpTitlePage(0), mpPage(0), meDir(FRMDIR_HORI_LEFT_TOP),
mpSection(0), mpPage(0), meDir(FRMDIR_HORI_LEFT_TOP),
nPgWidth(SvxPaperInfo::GetPaperSize(PAPER_A4).Width()),
nPgLeft(MM_250), nPgRight(MM_250), mnBorders(0), mbHasFootnote(false)
{
@@ -1115,10 +1105,14 @@ void wwSectionManager::CreateSep(const long nTxtPos, bool /*bMustHaveBreak*/)
aNewSection.maSep.grpfIhdt = ReadBSprm(pSep, eVer <= ww::eWW2 ? 128 : 153, 0);
else if (mrReader.pHdFt)
{
aNewSection.maSep.grpfIhdt = WW8_HEADER_ODD | WW8_FOOTER_ODD;
aNewSection.maSep.grpfIhdt = WW8_HEADER_ODD | WW8_FOOTER_ODD
| WW8_HEADER_FIRST | WW8_FOOTER_FIRST;
if (aNewSection.HasTitlePage())
aNewSection.maSep.grpfIhdt |= WW8_HEADER_FIRST | WW8_FOOTER_FIRST;
// It is possible for a first page header to be provided
// for this section, but not actually shown in this section. In this
// case (aNewSection.maSep.grpfIhdt & WW8_HEADER_FIRST) will be nonzero
// but aNewSection.HasTitlePage() will be false.
// Likewise for first page footer.
if (mrReader.pWDop->fFacingPages)
aNewSection.maSep.grpfIhdt |= WW8_HEADER_EVEN | WW8_FOOTER_EVEN;
@@ -1161,41 +1155,41 @@ void wwSectionManager::CreateSep(const long nTxtPos, bool /*bMustHaveBreak*/)
void SwWW8ImplReader::CopyPageDescHdFt(const SwPageDesc* pOrgPageDesc,
SwPageDesc* pNewPageDesc, sal_uInt8 nCode )
{
// copy first header content section
if (nCode & WW8_HEADER_FIRST)
rDoc.CopyHeader(pOrgPageDesc->GetMaster(), pNewPageDesc->GetMaster());
// copy first footer content section
if( nCode & WW8_FOOTER_FIRST )
rDoc.CopyFooter(pOrgPageDesc->GetMaster(), pNewPageDesc->GetMaster());
if( nCode & ( WW8_HEADER_ODD | WW8_FOOTER_ODD
| WW8_HEADER_EVEN | WW8_FOOTER_EVEN ) )
// copy odd header content section
if( nCode & WW8_HEADER_ODD )
{
// copy odd header content section
if( nCode & WW8_HEADER_ODD )
{
rDoc.CopyHeader(pOrgPageDesc->GetMaster(),
pNewPageDesc->GetMaster() );
}
// copy odd footer content section
if( nCode & WW8_FOOTER_ODD )
{
rDoc.CopyFooter(pOrgPageDesc->GetMaster(),
pNewPageDesc->GetMaster());
}
// copy even header content section
if( nCode & WW8_HEADER_EVEN )
{
rDoc.CopyHeader(pOrgPageDesc->GetLeft(),
pNewPageDesc->GetLeft());
}
// copy even footer content section
if( nCode & WW8_FOOTER_EVEN )
{
rDoc.CopyFooter(pOrgPageDesc->GetLeft(),
pNewPageDesc->GetLeft());
}
rDoc.CopyHeader(pOrgPageDesc->GetMaster(),
pNewPageDesc->GetMaster() );
}
// copy odd footer content section
if( nCode & WW8_FOOTER_ODD )
{
rDoc.CopyFooter(pOrgPageDesc->GetMaster(),
pNewPageDesc->GetMaster());
}
// copy even header content section
if( nCode & WW8_HEADER_EVEN )
{
rDoc.CopyHeader(pOrgPageDesc->GetLeft(),
pNewPageDesc->GetLeft());
}
// copy even footer content section
if( nCode & WW8_FOOTER_EVEN )
{
rDoc.CopyFooter(pOrgPageDesc->GetLeft(),
pNewPageDesc->GetLeft());
}
// copy first page header content section
if( nCode & WW8_HEADER_FIRST )
{
rDoc.CopyHeader(pOrgPageDesc->GetFirst(),
pNewPageDesc->GetFirst());
}
// copy first page footer content section
if( nCode & WW8_FOOTER_FIRST )
{
rDoc.CopyFooter(pOrgPageDesc->GetFirst(),
pNewPageDesc->GetFirst());
}
}