[Libreoffice-commits] core.git: Branch 'libreoffice-6-0' - sw/source
Mike Kaganski
mike.kaganski at collabora.com
Tue Jan 9 08:42:02 UTC 2018
sw/source/core/doc/doc.cxx | 105 ++++++++++++++++++++++++---------------------
1 file changed, 56 insertions(+), 49 deletions(-)
New commits:
commit f73df3fa98258fb5208a1295c0ae5c56d3c0b315
Author: Mike Kaganski <mike.kaganski at collabora.com>
Date: Sun Dec 24 00:28:30 2017 +0300
tdf#114663: consider left/right page numbers when not printing blanks
Commit 3c1a343f6936f1dcefdf79a677f8c26ce29676e6 made it possible
to use document pages' sequential number (unaffected by automatically
inserted blank pages) in Pages input box when not printing blank
pages. But the implementation didn't take into account the case when
only left/right pages were printed. In this case, it treated the
unprinted right/left pages same way as automatic blanks, i.e.,
excluded they from page numbering, so that e.g. when user entered
10-20 (when selected even pages), actually printed 11 pages from
tenth even page (#20 in original document) till twenteeth even page
(#40). Expected result (familiar from other applications, and worked
before the commit) is to print 6 pages with even numbers, that are
in the pages range 10-20 of original document (10,12,14,16,18,20).
Now we consistently use StringRangeEnumerator::getRangesFromString
after converting user input with page numbers conditionally referring
either physical pages, or pages without blanks, to equivalent range
string referring physical pages. This preprocessing of range string
also ensures correct enumerating later (when StringRangeEnumerator
is created based on this string, e.g., for processing of PostIts).
Change-Id: I2381699bc4c37841bf9ce789cdad03141dd72255
Reviewed-on: https://gerrit.libreoffice.org/47030
Tested-by: Jenkins <ci at libreoffice.org>
Reviewed-by: Mike Kaganski <mike.kaganski at collabora.com>
(cherry picked from commit 230d3d6602e80fad0ceb700da35fc0c1db28f110)
Reviewed-on: https://gerrit.libreoffice.org/47053
Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
diff --git a/sw/source/core/doc/doc.cxx b/sw/source/core/doc/doc.cxx
index 2d45bac285f0..e9cdbc8b1174 100644
--- a/sw/source/core/doc/doc.cxx
+++ b/sw/source/core/doc/doc.cxx
@@ -640,6 +640,46 @@ static sal_Int32 lcl_GetPaperBin( const SwPageFrame *pStartFrame )
return nRes;
}
+namespace
+{
+// tdf#:114663 Translates a range string from user input (with page numbering possibly not
+// taking blank pages into account) to equivalent string which references physical page numbers.
+// rUIPages2PhyPagesMap must contain a contiguous sequence of UI page numbers
+OUString UIPages2PhyPages(const OUString& rUIPageRange, const std::map< sal_Int32, sal_Int32 >& rUIPages2PhyPagesMap)
+{
+ if (rUIPages2PhyPagesMap.empty())
+ return OUString();
+ auto iMin = rUIPages2PhyPagesMap.begin();
+ const sal_Int32 nUIPageMin = iMin->first, nPhyPageMin = iMin->second;
+ auto iMax = rUIPages2PhyPagesMap.rbegin();
+ const sal_Int32 nUIPageMax = iMax->first, nPhyPageMax = iMax->second;
+ OUStringBuffer aOut(rUIPageRange.getLength());
+ OUStringBuffer aNumber(16);
+ const sal_Unicode* pInput = rUIPageRange.getStr();
+ while (*pInput)
+ {
+ while (*pInput >= '0' && *pInput <= '9')
+ aNumber.append(*pInput++);
+ if (!aNumber.isEmpty())
+ {
+ sal_Int32 nNumber = aNumber.makeStringAndClear().toInt32();
+ if (nNumber < nUIPageMin)
+ nNumber = nPhyPageMin-1;
+ else if (nNumber > nUIPageMax)
+ nNumber = nPhyPageMax+1;
+ else
+ nNumber = rUIPages2PhyPagesMap.at(nNumber);
+ aOut.append(nNumber);
+ }
+
+ while (*pInput && (*pInput < '0' || *pInput > '9'))
+ aOut.append(*pInput++);
+ }
+
+ return aOut.makeStringAndClear();
+}
+}
+
void SwDoc::CalculatePagesForPrinting(
const SwRootFrame& rLayout,
/* out */ SwRenderData &rData,
@@ -659,16 +699,19 @@ void SwDoc::CalculatePagesForPrinting(
std::map< sal_Int32, sal_Int32 > &rPrinterPaperTrays = rData.GetPrinterPaperTrays();
std::set< sal_Int32 > &rValidPages = rData.GetValidPagesSet();
+ // Map page numbers from user input (possibly ignoring blanks) to physical page numbers
+ std::map< sal_Int32, sal_Int32 > aUIPages2PhyPagesMap;
rValidPages.clear();
- sal_Int32 nPageNum = 1;
+ sal_Int32 nPageNum = 1, nUIPageNum = 1;
const SwPageFrame *pStPage = dynamic_cast<const SwPageFrame*>( rLayout.Lower() );
while (pStPage && nPageNum <= nDocPageCount)
{
+ const bool bNonEmptyPage = pStPage->getFrameArea().Height() != 0;
const bool bPrintThisPage =
( (bPrintRightPages && pStPage->OnRightPage()) ||
(bPrintLeftPages && !pStPage->OnRightPage()) ) &&
- ( bPrintEmptyPages || pStPage->getFrameArea().Height() );
+ ( bPrintEmptyPages || bNonEmptyPage );
if (bPrintThisPage)
{
@@ -676,6 +719,10 @@ void SwDoc::CalculatePagesForPrinting(
rPrinterPaperTrays[ nPageNum ] = lcl_GetPaperBin( pStPage );
}
+ if ( bPrintEmptyPages || bNonEmptyPage )
+ {
+ aUIPages2PhyPagesMap[nUIPageNum++] = nPageNum;
+ }
++nPageNum;
pStPage = static_cast<const SwPageFrame*>(pStPage->GetNext());
}
@@ -712,58 +759,18 @@ void SwDoc::CalculatePagesForPrinting(
// set page range to print to 'all pages'
aPageRange = OUString::number( 1 ) + "-" + OUString::number( nDocPageCount );
}
+ else
+ {
+ // Convert page numbers from user input to physical page numbers
+ aPageRange = UIPages2PhyPages(aPageRange, aUIPages2PhyPagesMap);
+ }
rData.SetPageRange( aPageRange );
// get vector of pages to print according to PageRange and valid pages set from above
// (result may be an empty vector, for example if the range string is not correct)
// If excluding empty pages, allow range to specify range of printable pages
- if (bPrintEmptyPages || nContent == 0)
- {
- // Use range enumerator directly
- StringRangeEnumerator::getRangesFromString(
- aPageRange, rData.GetPagesToPrint(),
- 1, nDocPageCount, 0, &rData.GetValidPagesSet() );
- }
- else // not printing blanks and not printing all
- {
- // Use range enumerator to adjust for empty pages - numbers in range are
- // essentially indexes into the valid page number set
- StringRangeEnumerator aEnum( aPageRange, 1, nDocPageCount, 0);
- rData.GetPagesToPrint().clear();
- rData.GetPagesToPrint().reserve(static_cast<size_t>(aEnum.size()));
-
- std::set<sal_Int32>::iterator valIt = rData.GetValidPagesSet().begin();
- sal_Int32 lastRangeValue = 1;
- for (StringRangeEnumerator::Iterator it = aEnum.begin(); it != aEnum.end(); ++it)
- {
- // Move valid page set iterator forward/back by diff between current
- // and previous numbers expressed in range
- if ((*it) - lastRangeValue > 0)
- {
- // Fast-forward
- for (sal_Int32 i = 0;
- i < (*it) - lastRangeValue && valIt != rData.GetValidPagesSet().end();
- ++i, ++valIt)
- ;
- }
- else if (lastRangeValue - (*it) > 0)
- {
- // Rewind
- for (sal_Int32 i = 0;
- i < lastRangeValue - (*it) && valIt != rData.GetValidPagesSet().begin();
- ++i, --valIt)
- ;
- }
-
- // Range encompasses more values than are listed as valid
- if (valIt == rData.GetValidPagesSet().end())
- break;
-
- rData.GetPagesToPrint().push_back(*valIt);
-
- lastRangeValue = *it;
- }
- }
+ StringRangeEnumerator::getRangesFromString( aPageRange, rData.GetPagesToPrint(),
+ 1, nDocPageCount, 0, &rData.GetValidPagesSet() );
}
void SwDoc::UpdatePagesForPrintingWithPostItData(
More information about the Libreoffice-commits
mailing list