editeng/source/editeng/editeng.cxx | 4 editeng/source/outliner/outlin2.cxx | 4 include/editeng/editeng.hxx | 2 include/editeng/outliner.hxx | 2 include/vcl/print.hxx | 3 sd/source/core/sdpage.cxx | 3 sd/source/ui/view/DocumentRenderer.cxx | 465 +++++++++++++++++++++++++++++++-- vcl/source/gdi/print.cxx | 9 vcl/source/gdi/print3.cxx | 5 vcl/source/window/printdlg.cxx | 29 ++ 10 files changed, 500 insertions(+), 26 deletions(-)
New commits: commit 4292d28dbc713cad20187427468ad7a361a3853a Author: Tibor Nagy <tibor.nagy.ext...@allotropia.de> AuthorDate: Fri Nov 29 02:10:21 2024 +0100 Commit: Nagy Tibor <tibor.nagy.ext...@allotropia.de> CommitDate: Wed Dec 4 22:07:56 2024 +0100 tdf#88226 sd: fix cutting off the overflow text on the notes print page This fix offers two options to preserve the overflowed text: 1: if the "Original size" option is selected for printing, the overflowed text will be displayed on a new page. 2: if the "Fit to Printable Area" option is selected for printing, notes will be scaled to fit within the available printable space. The "Multiple sheets of paper" and "Tile sheet of paper" options are disabled for notes because these options are intended for slide printing and do not make much sense for printing notes. The orientation for the notes print page has also been fixed. Change-Id: I99e56cf9aed5c32764797469a8ea7f3b25053882 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/177511 Reviewed-by: Nagy Tibor <tibor.nagy.ext...@allotropia.de> Tested-by: Jenkins (cherry picked from commit 43e511e642a2ce7026b30ea5c212940ff3eb522e) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/177776 Tested-by: allotropia jenkins <jenk...@allotropia.de> diff --git a/editeng/source/editeng/editeng.cxx b/editeng/source/editeng/editeng.cxx index 6fcb1e52ccb0..058f522385a6 100644 --- a/editeng/source/editeng/editeng.cxx +++ b/editeng/source/editeng/editeng.cxx @@ -618,11 +618,11 @@ sal_Int32 EditEngine::GetLineNumberAtIndex( sal_Int32 nPara, sal_Int32 nIndex ) return getImpl().GetLineNumberAtIndex(nPara, nIndex); } -sal_uInt32 EditEngine::GetLineHeight( sal_Int32 nParagraph ) +sal_uInt32 EditEngine::GetLineHeight( sal_Int32 nParagraph, sal_Int32 nLine ) { // If someone calls GetLineHeight() with an empty Engine. ensureDocumentFormatted(); - return getImpl().GetLineHeight( nParagraph, 0 ); + return getImpl().GetLineHeight( nParagraph, nLine ); } tools::Rectangle EditEngine::GetParaBounds( sal_Int32 nPara ) diff --git a/editeng/source/outliner/outlin2.cxx b/editeng/source/outliner/outlin2.cxx index af7fa1dd9670..22723698d994 100644 --- a/editeng/source/outliner/outlin2.cxx +++ b/editeng/source/outliner/outlin2.cxx @@ -318,9 +318,9 @@ sal_Int32 Outliner::GetLineLen( sal_Int32 nParagraph, sal_Int32 nLine ) const return pEditEngine->GetLineLen( nParagraph, nLine ); } -sal_uInt32 Outliner::GetLineHeight( sal_Int32 nParagraph ) +sal_uInt32 Outliner::GetLineHeight( sal_Int32 nParagraph, sal_Int32 nLine ) { - return pEditEngine->GetLineHeight( nParagraph ); + return pEditEngine->GetLineHeight( nParagraph, nLine ); } void Outliner::RemoveCharAttribs( sal_Int32 nPara, sal_uInt16 nWhich ) diff --git a/include/editeng/editeng.hxx b/include/editeng/editeng.hxx index 7a590f6155ab..a1c3024bb3a7 100644 --- a/include/editeng/editeng.hxx +++ b/include/editeng/editeng.hxx @@ -295,7 +295,7 @@ public: sal_Int32 GetLineLen( sal_Int32 nParagraph, sal_Int32 nLine ) const; void GetLineBoundaries( /*out*/sal_Int32& rStart, /*out*/sal_Int32& rEnd, sal_Int32 nParagraph, sal_Int32 nLine ) const; sal_Int32 GetLineNumberAtIndex( sal_Int32 nPara, sal_Int32 nIndex ) const; - SAL_DLLPRIVATE sal_uInt32 GetLineHeight( sal_Int32 nParagraph ); + SAL_DLLPRIVATE sal_uInt32 GetLineHeight( sal_Int32 nParagraph, sal_Int32 nLine = 0 ); SAL_DLLPRIVATE tools::Rectangle GetParaBounds( sal_Int32 nPara ); SAL_DLLPRIVATE ParagraphInfos GetParagraphInfos( sal_Int32 nPara ); SAL_DLLPRIVATE sal_Int32 FindParagraph( tools::Long nDocPosY ); diff --git a/include/editeng/outliner.hxx b/include/editeng/outliner.hxx index dfdc4a89f0d7..c5ed7dedd47e 100644 --- a/include/editeng/outliner.hxx +++ b/include/editeng/outliner.hxx @@ -881,7 +881,7 @@ public: sal_uInt32 GetLineCount( sal_Int32 nParagraph ) const; sal_Int32 GetLineLen( sal_Int32 nParagraph, sal_Int32 nLine ) const; - sal_uInt32 GetLineHeight( sal_Int32 nParagraph ); + sal_uInt32 GetLineHeight( sal_Int32 nParagraph, sal_Int32 nLine = 0 ); ErrCode Read( SvStream& rInput, const OUString& rBaseURL, EETextFormat, SvKeyValueIterator* pHTTPHeaderAttrs = nullptr ); diff --git a/include/vcl/print.hxx b/include/vcl/print.hxx index a1aacf8f0d90..19e4a9d7b989 100644 --- a/include/vcl/print.hxx +++ b/include/vcl/print.hxx @@ -417,6 +417,9 @@ public: bool isUIOptionEnabled( const OUString& rPropName ) const; SAL_DLLPRIVATE bool isUIChoiceEnabled( const OUString& rPropName, sal_Int32 nChoice ) const; + /// Defines which options in a UI element should be disabled or enabled. + void setUIChoicesDisabled(const OUString& rPropName, css::uno::Sequence<sal_Bool>& rChoicesDisabled); + /** MakeEnabled will change the property rPropName depends on to the value that makes rPropName enabled. If the dependency itself is also disabled, diff --git a/sd/source/core/sdpage.cxx b/sd/source/core/sdpage.cxx index 5bd30a4fbeb9..b314b3d0a917 100644 --- a/sd/source/core/sdpage.cxx +++ b/sd/source/core/sdpage.cxx @@ -460,6 +460,9 @@ SdrObject* SdPage::CreatePresObj(PresObjKind eObjKind, bool bVertical, const ::t else aTempAttr.Put( makeSdrTextMinFrameHeightItem( rRect.GetSize().Height() ) ); + if (eObjKind == PresObjKind::Notes) + aTempAttr.Put(makeSdrTextAutoGrowHeightItem(false)); + if (mbMaster) { // The size of presentation objects on the master page have to diff --git a/sd/source/ui/view/DocumentRenderer.cxx b/sd/source/ui/view/DocumentRenderer.cxx index 3b8c62994b76..3331e2463036 100644 --- a/sd/source/ui/view/DocumentRenderer.cxx +++ b/sd/source/ui/view/DocumentRenderer.cxx @@ -44,6 +44,8 @@ #include <rtl/ustrbuf.hxx> #include <editeng/editstat.hxx> #include <editeng/outlobj.hxx> +#include <svx/sdtfsitm.hxx> +#include <svx/sdooitm.hxx> #include <svx/svdetc.hxx> #include <svx/svditer.hxx> #include <svx/svdopage.hxx> @@ -75,6 +77,20 @@ namespace sd { namespace { + void lcl_AdjustPageSize(Size& rPageSize, const Size& rPrintPageSize) + { + bool bOrientationDiff = (rPageSize.Width() < rPageSize.Height() + && rPrintPageSize.Width() > rPrintPageSize.Height()) + || (rPageSize.Width() > rPageSize.Height() + && rPrintPageSize.Width() < rPrintPageSize.Height()); + if (bOrientationDiff) + { + ::tools::Long nTmp = rPageSize.Width(); + rPageSize.setWidth(rPageSize.Height()); + rPageSize.setHeight(nTmp); + } + } + /** Convenience class to extract values from the sequence of properties given to one of the XRenderable methods. */ @@ -781,6 +797,279 @@ namespace { const sal_uInt16 mnPageIndex; }; + /** The NotesPrinterPage is used for printing notes pages onto one or more printer pages + */ + class NotesPrinterPage : public PrinterPage + { + public: + NotesPrinterPage( + const sal_uInt16 nPageIndex, + const sal_Int32 nPageNumb, + const sal_Int32 nPageCount, + const bool bScaled, + const PageKind ePageKind, + const MapMode& rMapMode, + const bool bPrintMarkedOnly, + const OUString& rsPageString, + const Point& rPageStringOffset, + const DrawModeFlags nDrawMode, + const Orientation eOrientation, + const sal_uInt16 nPaperTray) + : PrinterPage(ePageKind, rMapMode, bPrintMarkedOnly, rsPageString, rPageStringOffset, + nDrawMode, eOrientation, nPaperTray), + mnPageIndex(nPageIndex), + mnPageNumb(nPageNumb), + mnPageCount(nPageCount), + mbScaled(bScaled) + { + } + + virtual void Print( + Printer& rPrinter, + SdDrawDocument& rDocument, + ViewShell&, + View* pView, + DrawView& rPrintView, + const SdrLayerIDSet& rVisibleLayers, + const SdrLayerIDSet& rPrintableLayers) const override + { + SdPage* pPageToPrint = rDocument.GetSdPage(mnPageIndex, mePageKind); + rPrinter.SetMapMode(maMap); + + // Clone the current page to create an independent instance for modifications. + // This ensures that changes made to pNotesPage do not affect the original page. + rtl::Reference<SdPage> pNotesPage + = static_cast<SdPage*>(pPageToPrint->CloneSdrPage(rDocument).get()); + + Size aPageSize; + if (mbScaled) + { + aPageSize = pNotesPage->GetSize(); + lcl_AdjustPageSize(aPageSize, rPrinter.GetPrintPageSize()); + } + else + aPageSize = rPrinter.GetPrintPageSize(); + + // Adjusts the objects on the notes page to fit the new page size. + ::tools::Rectangle aNewBorderRect(-1, -1, -1, -1); + pNotesPage->ScaleObjects(aPageSize, aNewBorderRect, true); + + SdrObject* pNotesObj = pNotesPage->GetPresObj(PresObjKind::Notes); + if (pNotesObj) + { + // new page(s) margins + sal_Int32 nLeft = 2000; + sal_Int32 nRight = 2000; + sal_Int32 nTop = 2250; + sal_Int32 nBottom = 2250; + + double nRatioX = aPageSize.Width() / 21000.0; + double nRatioY = aPageSize.Height() / 29700.0; + + nLeft *= nRatioX; + nRight *= nRatioX; + nTop *= nRatioY; + nBottom *= nRatioY; + + Point aNotesPt = pNotesObj->GetRelativePos(); + Size aNotesSize = pNotesObj->GetLogicRect().GetSize(); + + Outliner* pOut = rDocument.GetInternalOutliner(); + const OutlinerMode nSaveOutlMode(pOut->GetOutlinerMode()); + const bool bSavedUpdateMode(pOut->IsUpdateLayout()); + pOut->SetPaperSize(aNotesSize); + pOut->SetUpdateLayout(true); + pOut->Clear(); + pOut->SetText(*pNotesObj->GetOutlinerParaObject()); + + bool bAutoGrow = pNotesObj->GetMergedItem(SDRATTR_TEXT_AUTOGROWHEIGHT).GetValue(); + + // If AutoGrowHeight property is enabled and the notes page has a lower border, + // use the lower border but if there is no lower border, use the bottom margin + // to determine the first page break position. + // If AutoGrow is not enabled, the notes object defines the first page break. + ::tools::Long nNotesPageBottom + = bAutoGrow ? (pNotesPage->GetLowerBorder() != 0) + ? aPageSize.Height() - pNotesPage->GetLowerBorder() + : aPageSize.Height() - nBottom + : aNotesPt.Y() + aNotesSize.Height(); + if (mbScaled) + { + sal_Int32 nTextHeight = aNotesPt.Y() + pOut->GetTextHeight(); + if (bAutoGrow && (nTextHeight > nNotesPageBottom)) + { + pNotesObj->SetMergedItem(SdrOnOffItem(SDRATTR_TEXT_AUTOGROWHEIGHT, false)); + + ::tools::Long nObjW = aNotesSize.Width(); + ::tools::Long nObjH = aPageSize.Height() - aNotesPt.Y() - nBottom; + + pNotesObj->SetLogicRect(::tools::Rectangle(aNotesPt, Size(nObjW, nObjH))); + } + SdrTextFitToSizeTypeItem eFitToSize = drawing::TextFitToSizeType_AUTOFIT; + pNotesObj->SetMergedItem(eFitToSize); + } + else // original size + { + bool bExit = false; + sal_Int32 nPrevLineLen = 0; + sal_Int32 nPrevParaIdx = 0; + sal_uInt16 nActualPageNumb = 1; + ::tools::Long nCurrentPosY = aNotesPt.Y(); + sal_Int32 nParaCount = pOut->GetParagraphCount(); + std::vector<std::pair<sal_Int32, sal_Int32>> aPageBreaks; + + for (sal_Int32 i = 0; i < nParaCount && !bExit; ++i) + { + sal_Int32 nActualLineLen = 0; + sal_uInt32 nLineCount = pOut->GetLineCount(i); + for (sal_uInt32 j = 0; j < nLineCount; ++j) + { + nActualLineLen += pOut->GetLineLen(i, j); + sal_Int32 nLineHeight = pOut->GetLineHeight(i, j); + sal_Int32 nNextPosY = nCurrentPosY + nLineHeight; + + if (nNextPosY > nNotesPageBottom) + { + // If the current or the next page matches the print page + // calculate and add a page break, since we only want to add + // a page break if the page is relevant. + if (mnPageNumb == nActualPageNumb + || mnPageNumb == nActualPageNumb + 1) + { + if (!aPageBreaks.empty()) + { + // determine the page break at the bottom of the page + // for pages that have both a previous and a following page + aPageBreaks.emplace_back( + nPrevParaIdx - aPageBreaks[0].first, nPrevLineLen); + } + else + { + if (mnPageNumb == 1 || (nLineCount > 1 && j != 0)) + { + // first page or multi-line paragraphs + aPageBreaks.emplace_back(nPrevParaIdx, nPrevLineLen); + } + else + { // single-line paragraphs + aPageBreaks.emplace_back(nPrevParaIdx + 1, 0); + } + } + + if (mnPageNumb == nActualPageNumb || mnPageNumb == mnPageCount) + { + bExit = true; + break; + } + } + nNotesPageBottom = aPageSize.Height() - nBottom; + nCurrentPosY = nTop; + nActualPageNumb++; + nActualLineLen = 0; + } + nPrevParaIdx = i; + nPrevLineLen = nActualLineLen; + nCurrentPosY += nLineHeight; + } + } + + if (!aPageBreaks.empty()) + { + ESelection aE; + if (mnPageNumb == 1) + { + aE.start.nPara = aPageBreaks[0].first; + aE.start.nIndex = aPageBreaks[0].second; + aE.end.nPara = pOut->GetParagraphCount() - 1; + aE.end.nIndex = pOut->GetText(pOut->GetParagraph(aE.end.nPara)).getLength(); + pOut->QuickDelete(aE); + } + else + { + sal_Int16 nDepth = pOut->GetDepth(aPageBreaks[0].first); + SfxItemSet aItemSet = pOut->GetParaAttribs(aPageBreaks[0].first); + + aE.start.nPara = 0; + aE.start.nIndex = 0; + aE.end.nPara = aPageBreaks[0].first; + aE.end.nIndex = aPageBreaks[0].second; + + if (aPageBreaks[0].second != 0) // Multi-line + { + pOut->QuickInsertLineBreak(ESelection(aE.end.nPara, aE.end.nIndex, + aE.end.nPara, aE.end.nIndex)); + nTop -= pOut->GetLineHeight(0,0); + } + pOut->QuickDelete(aE); + + Paragraph* pFirstPara = pOut->GetParagraph(0); + pOut->SetDepth(pFirstPara, nDepth); + pOut->SetParaAttribs(0, aItemSet); + + if (aPageBreaks.size() > 1) + { + aE.start.nPara = aPageBreaks[1].first; + aE.start.nIndex = aPageBreaks[1].second; + aE.end.nPara = pOut->GetParagraphCount() - 1; + aE.end.nIndex = pOut->GetText(pOut->GetParagraph(aE.end.nPara)).getLength(); + pOut->QuickDelete(aE); + } + } + } + pNotesObj->SetOutlinerParaObject(pOut->CreateParaObject()); + + Size aObjSize; + if (mnPageNumb != 1) // new page(s) + { + SdrObjListIter aShapeIter(pNotesPage.get()); + while (aShapeIter.IsMore()) + { + SdrObject* pObj = aShapeIter.Next(); + if (pObj && pObj->GetObjIdentifier() != SdrObjKind::Text) + pNotesPage->RemoveObject(pObj->GetOrdNum()); + } + + aNotesPt.setX(nLeft); + aNotesPt.setY(nTop); + ::tools::Long nWidth = aPageSize.Width() - nLeft - nRight; + aObjSize = Size(nWidth, pOut->GetTextHeight()); + } + else // first page + { + if (!bAutoGrow) + aObjSize = aNotesSize; + else + aObjSize = Size(aNotesSize.Width(), pOut->GetTextHeight()); + } + pNotesObj->SetLogicRect(::tools::Rectangle(aNotesPt, aObjSize)); + } + pOut->Clear(); + pOut->SetUpdateLayout(bSavedUpdateMode); + pOut->Init(nSaveOutlMode); + } + pNotesPage->SetSize(aPageSize); + + PrintPage( + rPrinter, + rPrintView, + *pNotesPage, + pView, + mbPrintMarkedOnly, + rVisibleLayers, + rPrintableLayers); + PrintMessage( + rPrinter, + msPageString, + maPageStringOffset); + } + + private: + const sal_uInt16 mnPageIndex; + const sal_Int32 mnPageNumb; + const sal_Int32 mnPageCount; + const bool mbScaled; + }; + /** Print one slide multiple times on a printer page so that the whole printer page is covered. */ @@ -1198,7 +1487,11 @@ public: : VclPtr< OutputDevice >(); mpPrinter = dynamic_cast<Printer*>(pOut.get()); Size aPageSizePixel = mpPrinter ? mpPrinter->GetPaperSizePixel() : Size(); - if( aPageSizePixel != maPrinterPageSizePixel ) + Size aPrintPageSize = mpPrinter ? mpPrinter->GetPrintPageSize() : Size(); + + lcl_AdjustPageSize(aPageSizePixel, aPrintPageSize); + + if (aPageSizePixel != maPrinterPageSizePixel) { bIsPaperChanged = true; maPrinterPageSizePixel = aPageSizePixel; @@ -1361,11 +1654,15 @@ private: { aPaperSize.setWidth(rInfo.mpPrinter->GetPaperSize().Width()); aPaperSize.setHeight(rInfo.mpPrinter->GetPaperSize().Height()); + + if (!mpOptions->IsBooklet()) + lcl_AdjustPageSize(aPaperSize, rInfo.mpPrinter->GetPrintPageSize()); } maPrintSize = awt::Size(aPaperSize.Width(), aPaperSize.Height()); - if (mpOptions->IsPrinterPreferred(pDocument->GetDocumentType())) + if (mpOptions->IsPrinterPreferred(pDocument->GetDocumentType()) + && ePageKind == PageKind::Standard && !mpOptions->IsBooklet()) { if( (rInfo.meOrientation == Orientation::Landscape && (aPaperSize.Width() < aPaperSize.Height())) @@ -1863,7 +2160,11 @@ private: if (pDocument->GetSdPageCount(ePageKind) == 0) return; SdPage* pRefPage = pDocument->GetSdPage(0, ePageKind); - rInfo.maPageSize = pRefPage->GetSize(); + + if (!mpOptions->IsPrinterPreferred(pDocument->GetDocumentType()) && mpOptions->IsNotes()) + rInfo.maPageSize = mpPrinter->GetPrintPageSize(); + else + rInfo.maPageSize = pRefPage->GetSize(); SetupPaperOrientation(ePageKind, rInfo); @@ -1898,19 +2199,22 @@ private: continue; MapMode aMap (rInfo.maMap); - // is it possible that the page size changed? - const Size aPageSize = pPage->GetSize(); + + Size aPageSize = pPage->GetSize(); if (mpOptions->IsPageSize()) { - const double fHorz (static_cast<double>(rInfo.maPrintSize.Width()) / aPageSize.Width()); - const double fVert (static_cast<double>(rInfo.maPrintSize.Height()) / aPageSize.Height()); + Size aPrintSize = rInfo.maPrintSize; + lcl_AdjustPageSize(aPageSize, aPrintSize); + + const double fHorz(static_cast<double>(aPrintSize.Width()) / aPageSize.Width()); + const double fVert(static_cast<double>(aPrintSize.Height()) / aPageSize.Height()); Fraction aFract; if (fHorz < fVert) - aFract = Fraction(rInfo.maPrintSize.Width(), aPageSize.Width()); + aFract = Fraction(aPrintSize.Width(), aPageSize.Width()); else - aFract = Fraction(rInfo.maPrintSize.Height(), aPageSize.Height()); + aFract = Fraction(aPrintSize.Height(), aPageSize.Height()); aMap.SetScaleX(aFract); aMap.SetScaleY(aFract); @@ -2136,17 +2440,138 @@ private: // if CutPage is set then do not move it, otherwise move the // scaled page to printable area - maPrinterPages.push_back( - std::make_shared<RegularPrinterPage>( - sal::static_int_cast<sal_uInt16>(nPageIndex), - ePageKind, - aMap, - rInfo.mbPrintMarkedOnly, - rInfo.msPageString, - aPageOffset, - rInfo.mnDrawMode, - rInfo.meOrientation, - nPaperBin)); + if (ePageKind == PageKind::Standard) + { + maPrinterPages.push_back( + std::make_shared<RegularPrinterPage>( + sal::static_int_cast<sal_uInt16>(nPageIndex), + ePageKind, + aMap, + rInfo.mbPrintMarkedOnly, + rInfo.msPageString, + aPageOffset, + rInfo.mnDrawMode, + rInfo.meOrientation, + nPaperBin)); + } + else // Notes + { + SdPage* pPage = GetFilteredPage(nPageIndex, PageKind::Notes); + SdDrawDocument* pDocument = mrBase.GetMainViewShell()->GetDoc(); + + // Clone the current page to create an independent instance. + // This ensures that changes made to pNotesPage do not affect the original page. + rtl::Reference<SdPage> pNotesPage + = static_cast<SdPage*>(pPage->CloneSdrPage(*pDocument).get()); + + Size aPageSize = bScalePage ? pNotesPage->GetSize() : rInfo.mpPrinter->GetPrintPageSize(); + // Adjusts the objects on the notes page to fit the new page size. + ::tools::Rectangle aNewBorderRect(-1, -1, -1, -1); + pNotesPage->ScaleObjects(aPageSize, aNewBorderRect, true); + + SdrObject* pNotesObj = pNotesPage->GetPresObj(PresObjKind::Notes); + if (pNotesObj && bCutPage) + { + // default margins + sal_Int32 nTopMargin = 2250, nBottomMargin = 2250; + double nRatioY = aPageSize.Height() / 29700.0; + nTopMargin *= nRatioY; + nBottomMargin *= nRatioY; + + Size nNotesObjSize = pNotesObj->GetLogicRect().GetSize(); + + Outliner* pOut = pDocument->GetInternalOutliner(); + const OutlinerMode nSaveOutlMode(pOut->GetOutlinerMode()); + const bool bSavedUpdateMode(pOut->IsUpdateLayout()); + pOut->Init(OutlinerMode::OutlineView); + pOut->SetPaperSize(nNotesObjSize); + pOut->SetUpdateLayout(true); + pOut->Clear(); + pOut->SetText(*pNotesObj->GetOutlinerParaObject()); + + sal_Int32 nFirstPageBottomMargin = 0; + ::tools::Long nNotesHeight = nNotesObjSize.Height(); + bool bAutoGrow = pNotesObj->GetMergedItem(SDRATTR_TEXT_AUTOGROWHEIGHT).GetValue(); + if (bAutoGrow) + { + nNotesHeight += pNotesObj->GetRelativePos().Y(); + nFirstPageBottomMargin = (pNotesPage->GetLowerBorder() != 0) + ? pNotesPage->GetLowerBorder() + : nBottomMargin; + } + double nOverflowedTextHeight = 0; + ::tools::Long nFirstPageBottom = aPageSize.Height() - nFirstPageBottomMargin; + if (nNotesHeight > nFirstPageBottom) + { + // Calculate the height of the overflow text + // when the AutoGrowHeight property of the notes object is enabled + // and the height of the object exceeds the page height. + nOverflowedTextHeight = pNotesObj->GetRelativePos().Y() + + pOut->GetTextHeight() - nFirstPageBottom; + } + else + nOverflowedTextHeight = pOut->GetTextHeight() - nNotesObjSize.Height(); + + sal_Int32 nNotePageCount = 1; + double nNewPageHeight = aPageSize.Height() - nTopMargin - nBottomMargin; + if (nOverflowedTextHeight > 0) + { + nNotePageCount += std::ceil(nOverflowedTextHeight / nNewPageHeight); + } + + for (sal_Int32 i = 1; i <= nNotePageCount; i++) + { + // set page numbers + sal_Int32 nPageNumb = i; + OUString sPageNumb = rInfo.msPageString; + if (!sPageNumb.isEmpty() && nNotePageCount > 1) + { + OUString sTmp; + if (!rInfo.msTimeDate.isEmpty()) + { + sTmp += " "; + } + sTmp += SdResId(STR_PAGE_NAME) + " " + OUString::number(i); + sPageNumb += sTmp; + } + + maPrinterPages.push_back( + std::make_shared<NotesPrinterPage>( + sal::static_int_cast<sal_uInt16>(nPageIndex), + nPageNumb, + nNotePageCount, + bScalePage, + PageKind::Notes, + aMap, + rInfo.mbPrintMarkedOnly, + sPageNumb, + aPageOffset, + rInfo.mnDrawMode, + rInfo.meOrientation, + nPaperBin)); + } + pOut->Clear(); + pOut->SetUpdateLayout(bSavedUpdateMode); + pOut->Init(nSaveOutlMode); + } + else // scaled page + { + maPrinterPages.push_back( + std::make_shared<NotesPrinterPage>( + sal::static_int_cast<sal_uInt16>(nPageIndex), + sal_Int32(0), + sal_Int32(0), + bScalePage, + PageKind::Notes, + aMap, + rInfo.mbPrintMarkedOnly, + rInfo.msPageString, + aPageOffset, + rInfo.mnDrawMode, + rInfo.meOrientation, + nPaperBin)); + } + } } else { diff --git a/vcl/source/gdi/print.cxx b/vcl/source/gdi/print.cxx index 3b4fd7c9c8db..f1c5f93ad20a 100644 --- a/vcl/source/gdi/print.cxx +++ b/vcl/source/gdi/print.cxx @@ -1316,6 +1316,15 @@ bool Printer::SetPaperSizeUser( const Size& rSize ) bNeedToChange = maJobSetup.ImplGetConstData().GetPaperFormat() != PAPER_USER && maJobSetup.ImplGetConstData().GetPaperFormat() != aPaper; + + if (!bNeedToChange) + { + Size aPaperSize = GetPaperSizePixel(); + bNeedToChange = (aPageSize.Width() < aPageSize.Height() + && aPaperSize.Width() > aPaperSize.Height()) + || (aPageSize.Width() > aPageSize.Height() + && aPaperSize.Width() < aPaperSize.Height()); + } } if(bNeedToChange) diff --git a/vcl/source/gdi/print3.cxx b/vcl/source/gdi/print3.cxx index 1111c1e86143..baf2b221adf3 100644 --- a/vcl/source/gdi/print3.cxx +++ b/vcl/source/gdi/print3.cxx @@ -1688,6 +1688,11 @@ bool PrinterController::isUIOptionEnabled( const OUString& i_rProperty ) const return bEnabled; } +void PrinterController::setUIChoicesDisabled(const OUString& rPropName, css::uno::Sequence<sal_Bool>& rChoicesDisabled) +{ + mpImplData->maChoiceDisableMap[rPropName] = std::move(rChoicesDisabled); +} + bool PrinterController::isUIChoiceEnabled( const OUString& i_rProperty, sal_Int32 i_nValue ) const { bool bEnabled = true; diff --git a/vcl/source/window/printdlg.cxx b/vcl/source/window/printdlg.cxx index cb48bd636251..b0df9bf73c2d 100644 --- a/vcl/source/window/printdlg.cxx +++ b/vcl/source/window/printdlg.cxx @@ -661,6 +661,8 @@ PrintDialog::PrintDialog(weld::Window* i_pWindow, std::shared_ptr<PrinterControl initFromMultiPageSetup( maPController->getMultipage() ); + updatePageSize(mxOrientationBox->get_active()); + // setup optional UI options set by application setupOptionalUI(); @@ -1189,10 +1191,23 @@ void PrintDialog::updateNup( bool i_bMayUseCache ) aMPS.aPaperSize = maNupPortraitSize; else // automatic mode { + updatePageSize(mxOrientationBox->get_active()); + Size aPrintPageSize = maPController->getPrinter()->GetPrintPageSize(); + // get size of first real page to see if it is portrait or landscape // we assume same page sizes for all the pages for this Size aPageSize = getJobPageSize(); + if ((aPageSize.Width() < aPageSize.Height() + && aPrintPageSize.Width() > aPrintPageSize.Height()) + || (aPageSize.Width() > aPageSize.Height() + && aPrintPageSize.Width() < aPrintPageSize.Height())) + { + tools::Long nTmp = aPageSize.Width(); + aPageSize.setWidth(aPageSize.Height()); + aPageSize.setHeight(nTmp); + } + Size aMultiSize( aPageSize.Width() * nCols, aPageSize.Height() * nRows ); if( aMultiSize.Width() > aMultiSize.Height() ) // fits better on landscape { @@ -2049,6 +2064,10 @@ IMPL_LINK( PrintDialog, SelectHdl, weld::ComboBox&, rBox, void ) updatePageSize(mxOrientationBox->get_active()); + int nOrientation = mxOrientationBox->get_active(); + if (nOrientation != ORIENTATION_AUTOMATIC) + setPaperOrientation(static_cast<Orientation>(nOrientation - 1), true); + maUpdatePreviewNoCacheIdle.Start(); } } @@ -2166,8 +2185,18 @@ IMPL_LINK( PrintDialog, UIOption_SelectHdl, weld::ComboBox&, i_rBox, void ) //n-up print, we will assume notes are in landscape unless we throw //away maFirstPageSize when we change page content type if (pVal->Name == "PageContentType") + { maFirstPageSize = Size(); + css::uno::Sequence<sal_Bool> aChoicesDisabled{ + false, // Original size + false, // Fit to printable page + (nVal == 2) /*Notes*/ ? true : false, // disable/enable Multiple sheets of paper + (nVal == 2) /*Notes*/ ? true : false // disable/enable Tile sheet of paper + }; + maPController->setUIChoicesDisabled(u"PageOptions"_ustr, aChoicesDisabled); + } + checkOptionalControlDependencies(); // update preview and page settings