sd/inc/drawdoc.hxx | 10 +- sd/inc/pres.hxx | 1 sd/inc/sdpage.hxx | 2 sd/source/core/drawdoc2.cxx | 85 ++++++++++++++++- sd/source/core/sdpage.cxx | 20 +++- sd/source/ui/slidesorter/controller/SlsSlotManager.cxx | 2 sd/source/ui/unoidl/unopage.cxx | 3 sd/source/ui/view/drviews2.cxx | 2 8 files changed, 117 insertions(+), 8 deletions(-)
New commits: commit 62f9434a216984bcc0499549e36099bc88296f45 Author: Mohit Marathe <[email protected]> AuthorDate: Mon Oct 13 20:36:55 2025 +0530 Commit: Michael Stahl <[email protected]> CommitDate: Mon Jan 12 13:01:40 2026 +0100 sd: populate page previews grid in canvas page Signed-off-by: Mohit Marathe <[email protected]> Change-Id: I9058a857cad403b78c20e3f771e1531d7f641a38 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/192767 Reviewed-by: Michael Stahl <[email protected]> Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/196693 diff --git a/sd/inc/drawdoc.hxx b/sd/inc/drawdoc.hxx index db7656d450b1..fdb41267ab66 100644 --- a/sd/inc/drawdoc.hxx +++ b/sd/inc/drawdoc.hxx @@ -413,6 +413,8 @@ private: sal_Int32 mnImagePreferredDPI; + rtl::Reference<SdPage> mpCanvasPage; + SAL_DLLPRIVATE virtual css::uno::Reference< css::frame::XModel > createUnoModel() override; public: @@ -999,8 +1001,7 @@ public: bool bIsPageObj, const sal_Int32 nInsertPosition); - - SAL_DLLPRIVATE sal_uInt16 InsertCanvasPage (); + SAL_DLLPRIVATE sal_uInt16 GetOrInsertCanvasPage (); /** return the document fonts for latin, cjk and ctl according to the current languages set at this document */ @@ -1138,6 +1139,11 @@ private: bool bIsPageBack, bool bIsPageObj); + SAL_DLLPRIVATE bool hasCanvasPage() const { return mpCanvasPage != nullptr; } + + SAL_DLLPRIVATE void populatePagePreviewsGrid(); + SAL_DLLPRIVATE void updateCanvasPreviewsGrid(); + SAL_DLLPRIVATE virtual void PageListChanged() override; SAL_DLLPRIVATE virtual void MasterPageListChanged() override; }; diff --git a/sd/inc/pres.hxx b/sd/inc/pres.hxx index ab2b44adf6c5..b0780b9dd47d 100644 --- a/sd/inc/pres.hxx +++ b/sd/inc/pres.hxx @@ -32,6 +32,7 @@ enum class PresObjKind Page, Handout, Notes, + PagePreview, Header, Footer, DateTime, diff --git a/sd/inc/sdpage.hxx b/sd/inc/sdpage.hxx index a63a362373f3..013fecbccb56 100644 --- a/sd/inc/sdpage.hxx +++ b/sd/inc/sdpage.hxx @@ -168,7 +168,7 @@ public: sd::ShapeList& GetPresentationShapeList() { return maPresentationShapeList; } void EnsureMasterPageDefaultBackground(); - SD_DLLPUBLIC SdrObject* CreatePresObj(PresObjKind eObjKind, bool bVertical, const ::tools::Rectangle& rRect, const OUString& rCustomPrompt = OUString()); + SD_DLLPUBLIC SdrObject* CreatePresObj(PresObjKind eObjKind, bool bVertical, const ::tools::Rectangle& rRect, const OUString& rCustomPrompt = OUString(), const sal_uInt16 nPagePreviewNum = 0xffff); SD_DLLPUBLIC rtl::Reference<SdrObject> CreateDefaultPresObj(PresObjKind eObjKind); SD_DLLPUBLIC void DestroyDefaultPresObj(PresObjKind eObjKind); SD_DLLPUBLIC SdrObject* GetPresObj(PresObjKind eObjKind, int nIndex = 1, bool bFuzzySearch = false ); diff --git a/sd/source/core/drawdoc2.cxx b/sd/source/core/drawdoc2.cxx index 65efc70f84f9..19ae5cf93bcd 100644 --- a/sd/source/core/drawdoc2.cxx +++ b/sd/source/core/drawdoc2.cxx @@ -457,6 +457,9 @@ void SdDrawDocument::InsertPage(SdrPage* pPage, sal_uInt16 nPos) SdXImpressDocument* pDoc = getUnoModel(); SfxLokHelper::notifyDocumentSizeChangedAllViews(pDoc); } + + if (hasCanvasPage()) + updateCanvasPreviewsGrid(); } // Override SfxBaseModel::getUnoModel and return a more concrete type @@ -471,6 +474,9 @@ void SdDrawDocument::DeletePage(sal_uInt16 nPgNum) FmFormModel::DeletePage(nPgNum); UpdatePageObjectsInNotes(nPgNum); + + if (hasCanvasPage()) + updateCanvasPreviewsGrid(); } // Remove page @@ -494,6 +500,9 @@ rtl::Reference<SdrPage> SdDrawDocument::RemovePage(sal_uInt16 nPgNum) SfxLokHelper::notifyDocumentSizeChangedAllViews(pDoc); } + if (hasCanvasPage()) + updateCanvasPreviewsGrid(); + return pPage; } @@ -1445,8 +1454,11 @@ void SdDrawDocument::SetupNewPage ( } } -sal_uInt16 SdDrawDocument::InsertCanvasPage() +sal_uInt16 SdDrawDocument::GetOrInsertCanvasPage() { + if (hasCanvasPage()) + return mpCanvasPage->GetPageNum() / 2; + sal_uInt16 nLastPageNum = GetSdPageCount(PageKind::Standard); SdPage* pLastStandardPage = GetSdPage(nLastPageNum - 1, PageKind::Standard); @@ -1457,6 +1469,10 @@ sal_uInt16 SdDrawDocument::InsertCanvasPage() const Size aCanvasSize(500000, 500000); ResizeCurrentPage(pCanvasPage, aCanvasSize, PageKind::Standard); + pCanvasPage->SetCanvasPage(); + mpCanvasPage = pCanvasPage; + + populatePagePreviewsGrid(); return pCanvasPage->GetPageNum() / 2; } @@ -1466,4 +1482,71 @@ sd::UndoManager* SdDrawDocument::GetUndoManager() const return mpDocSh ? dynamic_cast< sd::UndoManager* >(mpDocSh->GetUndoManager()) : nullptr; } +static int calculateGridColumns(const sal_uInt16 nCnt) +{ + int n = static_cast<int>(nCnt); + int srqtN = std::round(std::sqrt(n)); + + return (n % srqtN) ? srqtN + 1 : srqtN; +} + +void SdDrawDocument::populatePagePreviewsGrid() +{ + sal_uInt16 nPageCnt = GetSdPageCount(PageKind::Standard) - 1; // don't count the canvas page + sal_uInt16 nTotalCol = static_cast<sal_uInt16>(calculateGridColumns(nPageCnt)); + sal_uInt16 nTotalRow = nPageCnt / nTotalCol + (nPageCnt % nTotalCol ? 1 : 0); + + // width and height of a standard 16:9 page + sal_uInt16 nWidth = 28000; + sal_uInt16 nHeight = 15750; + + // the factor by which width & height will be divided + sal_uInt8 nFactor = 3; + + // TODO: this should also vary based on the available space + sal_uInt16 nGapWidth = 500; + sal_uInt16 nGapHeight = 500; + + ::tools::Long nPreviewWidth; + ::tools::Long nPreviewHeight; + ::tools::Long nTotalGridWidth; + ::tools::Long nTotalGridHeight; + do + { + nTotalGridWidth = (nTotalCol - 1) * nGapWidth; + nTotalGridHeight = (nTotalRow - 1) * nGapHeight; + nPreviewWidth = (nWidth / nFactor); + nPreviewHeight = (nHeight / nFactor); + nTotalGridWidth += nPreviewWidth * nTotalCol; + nTotalGridHeight += nPreviewHeight * nTotalRow; + nFactor++; + } + while (nTotalGridWidth >= mpCanvasPage->GetWidth() || + nTotalGridHeight >= mpCanvasPage->GetHeight()); + + ::tools::Long nY = (mpCanvasPage->GetHeight() - nTotalGridHeight) / 2; + for (sal_uInt16 nRow = 0; nRow < nTotalRow; nRow++) + { + ::tools::Long nX = (mpCanvasPage->GetWidth() - nTotalGridWidth) / 2; + for (sal_uInt16 nCol = 0; nCol < nTotalCol; nCol++) + { + sal_uInt16 nCurrentPageIndex = nTotalCol * nRow + nCol; + if (nCurrentPageIndex == nPageCnt) + return; + SdPage* pPage = GetSdPage(nCurrentPageIndex, PageKind::Standard); + if (pPage->IsCanvasPage()) break; + const sal_uInt16 nPageNum = pPage->GetPageNum(); + mpCanvasPage->CreatePresObj(PresObjKind::PagePreview, true, ::tools::Rectangle(Point(nX, nY), Size(nPreviewWidth, nPreviewHeight)), OUString(), nPageNum); + nX += nPreviewWidth + nGapWidth; + } + nY += nPreviewHeight + nGapHeight; + } +} + +void SdDrawDocument::updateCanvasPreviewsGrid() +{ + SdrPage* pPage = mpCanvasPage.get(); + pPage->ClearSdrObjList(); + populatePagePreviewsGrid(); +} /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/core/sdpage.cxx b/sd/source/core/sdpage.cxx index a5cea90e493f..1918e12b2827 100644 --- a/sd/source/core/sdpage.cxx +++ b/sd/source/core/sdpage.cxx @@ -285,7 +285,7 @@ void SdPage::EnsureMasterPageDefaultBackground() /** creates a presentation object with the given PresObjKind on this page. A user call will be set */ -SdrObject* SdPage::CreatePresObj(PresObjKind eObjKind, bool bVertical, const ::tools::Rectangle& rRect, const OUString& rCustomPrompt) +SdrObject* SdPage::CreatePresObj(PresObjKind eObjKind, bool bVertical, const ::tools::Rectangle& rRect, const OUString& rCustomPrompt, const sal_uInt16 nPagePreviewNum) { SfxUndoManager* pUndoManager(static_cast< SdDrawDocument& >(getSdrModelFromSdrPage()).GetUndoManager()); const bool bUndo = pUndoManager && pUndoManager->IsInListAction() && IsInserted(); @@ -428,6 +428,22 @@ SdrObject* SdPage::CreatePresObj(PresObjKind eObjKind, bool bVertical, const ::t } break; + case PresObjKind::PagePreview: + { + if (nPagePreviewNum < getSdrModelFromSdrPage().GetPageCount()) + { + pSdrObj = new SdrPageObj(getSdrModelFromSdrPage(), getSdrModelFromSdrPage().GetPage(nPagePreviewNum)); + } + else + { + pSdrObj = new SdrPageObj(getSdrModelFromSdrPage()); + } + pSdrObj->SetMarkProtect(false); + pSdrObj->SetResizeProtect(false); + pSdrObj->SetMoveProtect(false); + } + break; + case PresObjKind::Header: case PresObjKind::Footer: case PresObjKind::DateTime: @@ -916,7 +932,7 @@ const o3tl::enumarray<PresObjKind, const char*> PresObjKindVector = { "PRESOBJ_TEXT" ,"PRESOBJ_GRAPHIC" , "PRESOBJ_OBJECT", "PRESOBJ_CHART", "PRESOBJ_ORGCHART", "PRESOBJ_TABLE", "PRESOBJ_PAGE", "PRESOBJ_HANDOUT", - "PRESOBJ_NOTES","PRESOBJ_HEADER", "PRESOBJ_FOOTER", + "PRESOBJ_NOTES", "PRESOBJ_PAGEPREVIEW", "PRESOBJ_HEADER", "PRESOBJ_FOOTER", "PRESOBJ_DATETIME", "PRESOBJ_SLIDENUMBER", "PRESOBJ_CALC", "PRESOBJ_MEDIA" }; diff --git a/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx b/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx index 04f6f57ea3ce..00976414946b 100644 --- a/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx +++ b/sd/source/ui/slidesorter/controller/SlsSlotManager.cxx @@ -251,7 +251,7 @@ void SlotManager::FuTemporary (SfxRequest& rRequest) case SID_INSERT_CANVAS_SLIDE: { SdDrawDocument* pDoc = pShell->GetDoc(); - sal_uInt16 nCanvasPageIndex = pDoc->InsertCanvasPage(); + sal_uInt16 nCanvasPageIndex = pDoc->GetOrInsertCanvasPage(); SdPage* pCanvasPage = static_cast<SdPage*>(pDoc->GetPage(nCanvasPageIndex)); view::SlideSorterView::DrawLock aDrawLock (mrSlideSorter); diff --git a/sd/source/ui/unoidl/unopage.cxx b/sd/source/ui/unoidl/unopage.cxx index 40e48670955c..201fe8eca737 100644 --- a/sd/source/ui/unoidl/unopage.cxx +++ b/sd/source/ui/unoidl/unopage.cxx @@ -1480,6 +1480,9 @@ Reference< drawing::XShape > SdGenericDrawPage::CreateShape(SdrObject *pObj) co case PresObjKind::Handout: aShapeType += "HandoutShape"; break; + case PresObjKind::PagePreview: + aShapeType += "PageShape"; + break; case PresObjKind::Notes: aShapeType += "NotesShape"; break; diff --git a/sd/source/ui/view/drviews2.cxx b/sd/source/ui/view/drviews2.cxx index 626677a63bf7..3c590da5d15a 100644 --- a/sd/source/ui/view/drviews2.cxx +++ b/sd/source/ui/view/drviews2.cxx @@ -1401,7 +1401,7 @@ void DrawViewShell::FuTemporary(SfxRequest& rReq) break; case SID_INSERT_CANVAS_SLIDE: { - sal_uInt16 nCanvasPageIndex = GetDoc()->InsertCanvasPage(); + sal_uInt16 nCanvasPageIndex = GetDoc()->GetOrInsertCanvasPage(); Cancel(); // Don't know what this does SwitchPage(nCanvasPageIndex); rReq.Done();
