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

Reply via email to