From cc46e7b9c75ddbcaaefde5f396ba76b0b866fa58 Mon Sep 17 00:00:00 2001 From: Mike Kaganski Date: Wed, 13 Jun 2018 15:53:49 +0200 Subject: tdf#116537: use page #s excluding empty pages when they are ignored Since commit 3c1a343f6936f1dcefdf79a677f8c26ce29676e6, SwDoc::CalculatePagesForPrinting expects that PageRange contains page numbers that don't include empty pages' numbers, when the org.openoffice.Office.Writer/Print/EmptyPages is false. Change-Id: I4057d6e36765707affbd5f3a4507ae03f4a27171 Reviewed-on: https://gerrit.libreoffice.org/55756 Tested-by: Jenkins Reviewed-by: Mike Kaganski --- sw/inc/crsrsh.hxx | 3 +++ sw/source/core/crsr/crsrsh.cxx | 24 +++++++++++++++++ sw/source/ui/dbui/mmresultdialogs.cxx | 51 ++++++++++++++++++++--------------- 3 files changed, 57 insertions(+), 21 deletions(-) (limited to 'sw') diff --git a/sw/inc/crsrsh.hxx b/sw/inc/crsrsh.hxx index 98a83f08b1f2..531452561fe9 100644 --- a/sw/inc/crsrsh.hxx +++ b/sw/inc/crsrsh.hxx @@ -512,6 +512,9 @@ public: // false: which is visible at the upper margin. void GetPageNum( sal_uInt16 &rnPhyNum, sal_uInt16 &rnVirtNum, bool bAtCursorPos = true, const bool bCalcFrame = true ); + // Returns current page's sequential number (1-based), ignoring autoinserted empty pages + // Returns 0 on error + sal_uInt16 GetPageNumSeqNonEmpty(bool bAtCursorPos, bool bCalcFrame); // Determine how "empty pages" are handled // (used in PhyPage). sal_uInt16 GetNextPrevPageNum( bool bNext = true ); diff --git a/sw/source/core/crsr/crsrsh.cxx b/sw/source/core/crsr/crsrsh.cxx index ebc34e0692ca..6c64ad10a0d1 100644 --- a/sw/source/core/crsr/crsrsh.cxx +++ b/sw/source/core/crsr/crsrsh.cxx @@ -1106,6 +1106,30 @@ void SwCursorShell::GetPageNum( sal_uInt16 &rnPhyNum, sal_uInt16 &rnVirtNum, rnVirtNum = pPg? pPg->GetVirtPageNum() : 1; } +sal_uInt16 SwCursorShell::GetPageNumSeqNonEmpty(bool bAtCursorPos, bool bCalcFrame) +{ + SET_CURR_SHELL(this); + // page number: first visible page or the one at the cursor + const SwContentFrame* pCFrame = GetCurrFrame(bCalcFrame); + const SwPageFrame* pPg = nullptr; + + if (!bAtCursorPos || !pCFrame || nullptr == (pPg = pCFrame->FindPageFrame())) + { + pPg = Imp()->GetFirstVisPage(GetOut()); + while (pPg && pPg->IsEmptyPage()) + pPg = static_cast(pPg->GetNext()); + } + + sal_uInt16 nPageNo = 0; + while (pPg) + { + if (!pPg->IsEmptyPage()) + ++nPageNo; + pPg = static_cast(pPg->GetPrev()); + } + return nPageNo; +} + sal_uInt16 SwCursorShell::GetNextPrevPageNum( bool bNext ) { SET_CURR_SHELL( this ); diff --git a/sw/source/ui/dbui/mmresultdialogs.cxx b/sw/source/ui/dbui/mmresultdialogs.cxx index a558f12712ac..0e2d1bf4d533 100644 --- a/sw/source/ui/dbui/mmresultdialogs.cxx +++ b/sw/source/ui/dbui/mmresultdialogs.cxx @@ -34,6 +34,8 @@ #include #include +#include +#include #include #include #include @@ -464,46 +466,47 @@ IMPL_LINK_NOARG(SwMMResultEmailDialog, CopyToHdl_Impl, Button*, void) namespace { -int documentStartPageNumber(SwMailMergeConfigItem* pConfigItem, int document) +int documentStartPageNumber(SwMailMergeConfigItem* pConfigItem, int document, bool bIgnoreEmpty) { SwView* pTargetView = pConfigItem->GetTargetView(); assert( pTargetView ); SwCursorShell& shell = pTargetView->GetWrtShell(); const SwDocMergeInfo& info = pConfigItem->GetDocumentMergeInfo(document); - sal_uInt16 page, dummy; + sal_uInt16 page; shell.Push(); shell.GotoMark( info.startPageInTarget ); - shell.GetPageNum( page, dummy ); + if (!bIgnoreEmpty) + shell.GetPageNum(page, o3tl::temporary(sal_uInt16())); + else + page = shell.GetPageNumSeqNonEmpty(true, true); shell.Pop(SwCursorShell::PopMode::DeleteCurrent); return page; } -int documentEndPageNumber(SwMailMergeConfigItem* pConfigItem, int document) +int documentEndPageNumber(SwMailMergeConfigItem* pConfigItem, int document, bool bIgnoreEmpty) { SwView* pTargetView = pConfigItem->GetTargetView(); assert( pTargetView ); SwWrtShell& shell = pTargetView->GetWrtShell(); + shell.Push(); if (document < int(pConfigItem->GetMergedDocumentCount()) - 1) { // Go to the page before the starting page of the next merged document. const SwDocMergeInfo& info = pConfigItem->GetDocumentMergeInfo( document + 1 ); - sal_uInt16 page, dummy; - shell.Push(); shell.GotoMark( info.startPageInTarget ); shell.EndPrvPg(); - shell.GetPageNum( page, dummy ); - shell.Pop(SwCursorShell::PopMode::DeleteCurrent); - return page; } else { // This is the last merged document, so it ends on the page at which the document ends. - sal_uInt16 page, dummy; - shell.Push(); shell.SttEndDoc( false ); // go to doc end - shell.GetPageNum( page, dummy ); - shell.Pop(SwCursorShell::PopMode::DeleteCurrent); - return page; } + sal_uInt16 page; + if (!bIgnoreEmpty) + shell.GetPageNum(page, o3tl::temporary(sal_uInt16())); + else + page = shell.GetPageNumSeqNonEmpty(true, true); + shell.Pop(SwCursorShell::PopMode::DeleteCurrent); + return page; } void endDialog(Button* pButton) @@ -661,8 +664,9 @@ IMPL_LINK_NOARG(SwMMResultSaveDialog, SaveOutputHdl_Impl, weld::Button&, void) pTempView->GetDocShell()->GetDoc()->ReplaceDefaults( *pTargetView->GetDocShell()->GetDoc()); pTempView->GetDocShell()->GetDoc()->ReplaceDocumentProperties( *pTargetView->GetDocShell()->GetDoc(), true ); - pTargetView->GetWrtShell().PastePages(pTempView->GetWrtShell(), - documentStartPageNumber(xConfigItem.get(), nDoc), documentEndPageNumber(xConfigItem.get(), nDoc)); + pTargetView->GetWrtShell().PastePages( + pTempView->GetWrtShell(), documentStartPageNumber(xConfigItem.get(), nDoc, false), + documentEndPageNumber(xConfigItem.get(), nDoc, false)); pTargetView->GetWrtShell().EndAction(); //then save it OUString sOutPath = aURL.GetMainURL(INetURLObject::DecodeMechanism::ToIUri); @@ -777,9 +781,13 @@ IMPL_LINK_NOARG(SwMMResultPrintDialog, PrintHdl_Impl, weld::Button&, void) nEnd = documentCount; } - OUString sPages(OUString::number(documentStartPageNumber(xConfigItem.get(), nBegin))); - sPages += " - "; - sPages += OUString::number(documentEndPageNumber(xConfigItem.get(), nEnd - 1)); + // If we skip autoinserted blanks, then the page numbers used in the print range string + // refer to the non-blank pages as they appear in the document (see tdf#89708). + const bool bIgnoreEmptyPages = !officecfg::Office::Writer::Print::EmptyPages::get(); + const int nStartPage = documentStartPageNumber(xConfigItem.get(), nBegin, bIgnoreEmptyPages); + const int nEndPage = documentEndPageNumber(xConfigItem.get(), nEnd - 1, bIgnoreEmptyPages); + + const OUString sPages(OUString::number(nStartPage) + "-" + OUString::number(nEndPage)); pTargetView->SetMailMergeConfigItem(xConfigItem); if(m_pTempPrinter) @@ -1071,8 +1079,9 @@ IMPL_LINK(SwMMResultEmailDialog, SendDocumentsHdl_Impl, Button*, pButton, void) pTempView->GetDocShell()->GetDoc()->ReplaceCompatibilityOptions( *pTargetView->GetDocShell()->GetDoc()); pTempView->GetDocShell()->GetDoc()->ReplaceDefaults( *pTargetView->GetDocShell()->GetDoc()); pTempView->GetDocShell()->GetDoc()->ReplaceDocumentProperties( *pTargetView->GetDocShell()->GetDoc(), true ); - pTargetView->GetWrtShell().PastePages(pTempView->GetWrtShell(), - documentStartPageNumber(xConfigItem.get(), nDoc), documentEndPageNumber(xConfigItem.get(), nDoc)); + pTargetView->GetWrtShell().PastePages( + pTempView->GetWrtShell(), documentStartPageNumber(xConfigItem.get(), nDoc, false), + documentEndPageNumber(xConfigItem.get(), nDoc, false)); pTargetView->GetWrtShell().EndAction(); //then save it -- cgit