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 43e511e642a2ce7026b30ea5c212940ff3eb522e
Author:     Tibor Nagy <[email protected]>
AuthorDate: Fri Nov 29 02:10:21 2024 +0100
Commit:     Nagy Tibor <[email protected]>
CommitDate: Wed Dec 4 10:17:24 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 <[email protected]>
    Tested-by: Jenkins

diff --git a/editeng/source/editeng/editeng.cxx 
b/editeng/source/editeng/editeng.cxx
index 15dcc2d7dc5a..ee4f23275377 100644
--- a/editeng/source/editeng/editeng.cxx
+++ b/editeng/source/editeng/editeng.cxx
@@ -439,10 +439,10 @@ 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.
-    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 0e791eee9a36..a0e384d1388f 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 9636a260ccac..a5dde05c00c7 100644
--- a/include/editeng/editeng.hxx
+++ b/include/editeng/editeng.hxx
@@ -294,7 +294,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 9a57b6c6aef1..b18690050037 100644
--- a/include/editeng/outliner.hxx
+++ b/include/editeng/outliner.hxx
@@ -868,7 +868,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 f511af70d977..962308e327dc 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 4607a5f3aa65..04d0f020ebbc 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 e062b79259f3..467c3fba4bc9 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 9833aa125771..f0308a5ec686 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 73b70a37ded8..934a80fe991a 100644
--- a/vcl/source/gdi/print3.cxx
+++ b/vcl/source/gdi/print3.cxx
@@ -1683,6 +1683,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 1bad80864979..46bd7df183f5 100644
--- a/vcl/source/window/printdlg.cxx
+++ b/vcl/source/window/printdlg.cxx
@@ -659,6 +659,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();
 
@@ -1205,10 +1207,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
         {
@@ -2069,6 +2084,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();
     }
 }
@@ -2186,8 +2205,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

Reply via email to