filter/CppunitTest_filter_pdf.mk | 6 ++++ filter/qa/pdf.cxx | 37 +++++++++++++++++++++++++++- sw/inc/PostItMgr.hxx | 3 ++ sw/source/core/view/vprint.cxx | 2 + sw/source/uibase/docvw/AnnotationWin2.cxx | 39 +++++++++++++++++++++--------- sw/source/uibase/docvw/PostItMgr.cxx | 26 +++++++++++++++----- 6 files changed, 95 insertions(+), 18 deletions(-)
New commits: commit 2d2166759e9bfd8e942b996ee94dc8babc6ddd48 Author: Jaume Pujantell <[email protected]> AuthorDate: Wed Aug 13 14:31:31 2025 +0200 Commit: Jaume Pujantell <[email protected]> CommitDate: Mon Oct 20 17:33:05 2025 +0200 lok: pdf export comments in margin Enable print comments in margin for PDF in LOK without tiled comments. Right now comments are only printed if they are being shown in the LO document which excludes LOK without tiled comments. Also the post-it manager and annotation window assume in some places that MapMode is used and correctly set, which is not the case in LOK. Adapted an existing test about printing comments in margin to test also for LOK. Change-Id: I362cb89ade6d4f53832fd9a722196d214360aae6 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/189511 Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-by: Miklos Vajna <[email protected]> (cherry picked from commit 3a633abe5c6a884d152c73737debe215a980c79d) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/192728 Tested-by: Jenkins Reviewed-by: Jaume Pujantell <[email protected]> diff --git a/filter/CppunitTest_filter_pdf.mk b/filter/CppunitTest_filter_pdf.mk index 912b84e0edb4..36437555c795 100644 --- a/filter/CppunitTest_filter_pdf.mk +++ b/filter/CppunitTest_filter_pdf.mk @@ -26,6 +26,7 @@ $(eval $(call gb_CppunitTest_use_libraries,filter_pdf, \ cppuhelper \ sal \ subsequenttest \ + sw \ test \ tl \ unotest \ @@ -35,6 +36,11 @@ $(eval $(call gb_CppunitTest_use_libraries,filter_pdf, \ $(eval $(call gb_CppunitTest_use_sdk_api,filter_pdf)) +$(eval $(call gb_CppunitTest_set_include,filter_pdf,\ + -I$(SRCDIR)/sw/inc \ + $$(INCLUDE) \ +)) + $(eval $(call gb_CppunitTest_use_ure,filter_pdf)) $(eval $(call gb_CppunitTest_use_vcl,filter_pdf)) diff --git a/filter/qa/pdf.cxx b/filter/qa/pdf.cxx index 1fdd75baf886..c62b9aa17e8a 100644 --- a/filter/qa/pdf.cxx +++ b/filter/qa/pdf.cxx @@ -16,9 +16,11 @@ #include <com/sun/star/beans/XPropertySet.hpp> #include <com/sun/star/graphic/XGraphic.hpp> +#include <comphelper/lok.hxx> #include <comphelper/propertyvalue.hxx> #include <tools/stream.hxx> #include <unotools/streamwrap.hxx> +#include <unotxdoc.hxx> #include <vcl/filter/PDFiumLibrary.hxx> #include <tools/helpers.hxx> @@ -36,6 +38,7 @@ public: } void setUp() override; + void tearDown() override; void doTestCommentsInMargin(bool commentsInMarginEnabled); }; @@ -46,6 +49,14 @@ void Test::setUp() MacrosTest::setUpX509(m_directories, u"filter_pdf"_ustr); } +void Test::tearDown() +{ + UnoApiTest::tearDown(); + + if (comphelper::LibreOfficeKit::isActive()) + comphelper::LibreOfficeKit::setActive(false); +} + CPPUNIT_TEST_FIXTURE(Test, testSignCertificateSubjectName) { std::shared_ptr<vcl::pdf::PDFium> pPDFium = vcl::pdf::PDFiumLibrary::get(); @@ -144,6 +155,11 @@ void Test::doTestCommentsInMargin(bool commentsInMarginEnabled) return; loadFromFile(u"commentsInMargin.odt"); + if (comphelper::LibreOfficeKit::isActive()) + { + SwXTextDocument* pTextDocument = dynamic_cast<SwXTextDocument*>(mxComponent.get()); + pTextDocument->initializeForTiledRendering(uno::Sequence<beans::PropertyValue>()); + } uno::Reference<css::lang::XMultiServiceFactory> xFactory = getMultiServiceFactory(); uno::Reference<document::XFilter> xFilter( xFactory->createInstance(u"com.sun.star.document.PDFFilter"_ustr), uno::UNO_QUERY); @@ -168,7 +184,19 @@ void Test::doTestCommentsInMargin(bool commentsInMarginEnabled) { // Unfortunately, the comment box is DPI dependent, and the lines there may split // at higher DPIs, creating additional objects on import, hence the "_GREATER" - CPPUNIT_ASSERT_GREATER(8, pPdfDocument->openPage(0)->getObjectCount()); + auto pPage = pPdfDocument->openPage(0); + int nObjs = pPage->getObjectCount(); + CPPUNIT_ASSERT_GREATER(8, nObjs); + bool bFound = false; + int i = 0; + for (; i < nObjs && !bFound; ++i) + { + auto pObj = pPage->getObject(i); + if (pObj->getText(pPage->getTextPage()) == "Nice comment over here.") + bFound = true; + } + CPPUNIT_ASSERT_MESSAGE("The comment text was not found.", bFound); + CPPUNIT_ASSERT_GREATER(400., pPage->getObject(i - 1)->getBounds().getMinX()); } else CPPUNIT_ASSERT_EQUAL(1, pPdfDocument->openPage(0)->getObjectCount()); @@ -179,6 +207,13 @@ CPPUNIT_TEST_FIXTURE(Test, testCommentsInMargin) // Test that setting/unsetting the "ExportNotesInMargin" property works correctly doTestCommentsInMargin(true); doTestCommentsInMargin(false); + comphelper::LibreOfficeKit::setActive(true); + comphelper::LibreOfficeKit::setTiledAnnotations(true); + doTestCommentsInMargin(true); + doTestCommentsInMargin(false); + comphelper::LibreOfficeKit::setTiledAnnotations(false); + doTestCommentsInMargin(true); + doTestCommentsInMargin(false); } CPPUNIT_TEST_FIXTURE(Test, testWatermarkColor) diff --git a/sw/inc/PostItMgr.hxx b/sw/inc/PostItMgr.hxx index 9ea58c7fa1d5..7ff84952c887 100644 --- a/sw/inc/PostItMgr.hxx +++ b/sw/inc/PostItMgr.hxx @@ -99,6 +99,7 @@ class SAL_DLLPUBLIC_RTTI SwPostItMgr final : public SfxListener, FieldShadowState mShadowState; std::optional<OutlinerParaObject> mpAnswer; OUString maAnswerText; + bool mbForceShow = false; // data structure to collect the <SwAnnotationWin> instances for certain <SwFrame> instances. std::unique_ptr<sw::sidebarwindows::SwFrameSidebarWinContainer> mpFrameSidebarWinContainer; @@ -254,6 +255,8 @@ class SAL_DLLPUBLIC_RTTI SwPostItMgr final : public SfxListener, sw::sidebarwindows::SidebarPosition GetSidebarPos(const Point& rPointLogic); + void SetForceShow(bool bForce) { mbForceShow = bForce; } + // The commands that directly delete comments (as opposed to deletion of the text that the // comments are anchored to) behave differently, depending on the document type, when the // change tracking is on. For ODF, we allow comments to be marked as deleted; for external diff --git a/sw/source/core/view/vprint.cxx b/sw/source/core/view/vprint.cxx index 45b51169fb99..ac4d85997fd0 100644 --- a/sw/source/core/view/vprint.cxx +++ b/sw/source/core/view/vprint.cxx @@ -520,10 +520,12 @@ bool SwViewShell::PrintOrPDFExport( if (pPostItManager) { + pPostItManager->SetForceShow(true); pPostItManager->CalcRects(); pPostItManager->LayoutPostIts(); pPostItManager->DrawNotesForPage(pOutDev, nPage-1); oOrigHeight.emplace(pStPage->getFrameArea().Height()); + pPostItManager->SetForceShow(false); } } diff --git a/sw/source/uibase/docvw/AnnotationWin2.cxx b/sw/source/uibase/docvw/AnnotationWin2.cxx index 431cdbbe2e5f..c42194786f78 100644 --- a/sw/source/uibase/docvw/AnnotationWin2.cxx +++ b/sw/source/uibase/docvw/AnnotationWin2.cxx @@ -174,6 +174,26 @@ void SwAnnotationWin::DrawForPage(OutputDevice* pDev, const Point& rPt) pPDFExtOutDevData->WrapBeginStructureElement(vcl::pdf::StructElement::NonStructElement, OUString()); } + auto lclSizePixelToLogic = [this](Size szs) { + // In LOK without tiled annotations, SwAnnotationWin desn't have the + // right conversion when printing to PDF but mxSidebarTextControl does + if (comphelper::LibreOfficeKit::isActive() + && !comphelper::LibreOfficeKit::isTiledAnnotations()) + return mxSidebarTextControl->GetDrawingArea()->get_ref_device().PixelToLogic(szs); + else + return PixelToLogic(szs); + }; + + auto lclPointPixelToLogic = [this](Point pnt) { + // In LOK without tiled annotations, SwAnnotationWin desn't have the + // right conversion when printing to PDF but mxSidebarTextControl does + if (comphelper::LibreOfficeKit::isActive() + && !comphelper::LibreOfficeKit::isTiledAnnotations()) + return mxSidebarTextControl->GetDrawingArea()->get_ref_device().PixelToLogic(pnt); + else + return PixelToLogic(pnt); + }; + pDev->Push(); pDev->SetFillColor(mColorDark); @@ -184,7 +204,7 @@ void SwAnnotationWin::DrawForPage(OutputDevice* pDev, const Point& rPt) aFont.SetFontHeight(aFont.GetFontHeight() * 20); pDev->SetFont(aFont); - Size aSz = PixelToLogic(GetSizePixel()); + Size aSz = lclSizePixelToLogic(GetSizePixel()); pDev->DrawRect(tools::Rectangle(rPt, aSz)); @@ -192,8 +212,8 @@ void SwAnnotationWin::DrawForPage(OutputDevice* pDev, const Point& rPt) { int x, y, width, height; mxMetadataAuthor->get_extents_relative_to(*m_xContainer, x, y, width, height); - Point aPos(rPt + PixelToLogic(Point(x, y))); - Size aSize(PixelToLogic(Size(width, height))); + Point aPos(rPt + lclPointPixelToLogic(Point(x, y))); + Size aSize(lclSizePixelToLogic(Size(width, height))); auto popIt1 = pDev->ScopedPush(vcl::PushFlags::CLIPREGION); pDev->IntersectClipRegion(tools::Rectangle(aPos, aSize)); @@ -204,8 +224,8 @@ void SwAnnotationWin::DrawForPage(OutputDevice* pDev, const Point& rPt) { int x, y, width, height; mxMetadataDate->get_extents_relative_to(*m_xContainer, x, y, width, height); - Point aPos(rPt + PixelToLogic(Point(x, y))); - Size aSize(PixelToLogic(Size(width, height))); + Point aPos(rPt + lclPointPixelToLogic(Point(x, y))); + Size aSize(lclSizePixelToLogic(Size(width, height))); auto popIt1 = pDev->ScopedPush(vcl::PushFlags::CLIPREGION); pDev->IntersectClipRegion(tools::Rectangle(aPos, aSize)); @@ -216,8 +236,8 @@ void SwAnnotationWin::DrawForPage(OutputDevice* pDev, const Point& rPt) { int x, y, width, height; mxMetadataResolved->get_extents_relative_to(*m_xContainer, x, y, width, height); - Point aPos(rPt + PixelToLogic(Point(x, y))); - Size aSize(PixelToLogic(Size(width, height))); + Point aPos(rPt + lclPointPixelToLogic(Point(x, y))); + Size aSize(lclSizePixelToLogic(Size(width, height))); auto popIt1 = pDev->ScopedPush(vcl::PushFlags::CLIPREGION); pDev->IntersectClipRegion(tools::Rectangle(aPos, aSize)); @@ -243,7 +263,7 @@ void SwAnnotationWin::DrawForPage(OutputDevice* pDev, const Point& rPt) // completely shown int x, y, width, height; mxMenuButton->get_extents_relative_to(*m_xContainer, x, y, width, height); - Point aPos(rPt + PixelToLogic(Point(x, y))); + Point aPos(rPt + lclPointPixelToLogic(Point(x, y))); pDev->DrawText(aPos, u"..."_ustr); } @@ -835,9 +855,6 @@ void SwAnnotationWin::DoResize() void SwAnnotationWin::SetSizePixel( const Size& rNewSize ) { - if (comphelper::LibreOfficeKit::isActive()) - return; - InterimItemWindow::SetSizePixel(rNewSize); if (mpShadow) diff --git a/sw/source/uibase/docvw/PostItMgr.cxx b/sw/source/uibase/docvw/PostItMgr.cxx index cbfe8c625316..f5edf6fb607e 100644 --- a/sw/source/uibase/docvw/PostItMgr.cxx +++ b/sw/source/uibase/docvw/PostItMgr.cxx @@ -1039,10 +1039,18 @@ void SwPostItMgr::LayoutPostIts() tools::Long Y = mpEditWin->LogicToPixel( Point(0,pItem->maLayoutInfo.mPosition.Bottom())).Y(); - aPostItHeight = ( pPostIt->GetPostItTextHeight() < pPostIt->GetMinimumSizeWithoutMeta() - ? pPostIt->GetMinimumSizeWithoutMeta() - : pPostIt->GetPostItTextHeight() ) - + pPostIt->GetMetaHeight(); + tools::Long postItPixelTextHeight + = (comphelper::LibreOfficeKit::isActive() + ? mpEditWin + ->LogicToPixel( + Point(0, pPostIt->GetPostItTextHeight())) + .Y() + : pPostIt->GetPostItTextHeight()); + aPostItHeight + = (postItPixelTextHeight < pPostIt->GetMinimumSizeWithoutMeta() + ? pPostIt->GetMinimumSizeWithoutMeta() + : postItPixelTextHeight) + + pPostIt->GetMetaHeight(); pPostIt->SetPosSizePixelRect( mlPageBorder , Y - GetInitialAnchorDistance(), GetSidebarWidth(true), @@ -1076,7 +1084,7 @@ void SwPostItMgr::LayoutPostIts() this->Broadcast(SwFormatFieldHint(pFormatField, nWhich, mpView)); } - if (!aVisiblePostItList.empty() && ShowNotes()) + if (!aVisiblePostItList.empty() && bShowNotes) { bool bOldScrollbar = pPage->bScrollbar; pPage->bScrollbar = LayoutByPage(aVisiblePostItList, pPage->mPageRect.SVRect(), lNeededHeight); @@ -1256,6 +1264,10 @@ void SwPostItMgr::DrawNotesForPage(OutputDevice *pOutDev, sal_uInt32 nPage) assert(nPage < mPages.size()); if (nPage >= mPages.size()) return; + const bool bEnableMapMode + = comphelper::LibreOfficeKit::isActive() && !mpEditWin->IsMapModeEnabled(); + if (bEnableMapMode) + mpEditWin->EnableMapMode(); for (auto const& pItem : mPages[nPage]->mvSidebarItems) { SwAnnotationWin* pPostIt = pItem->mpPostIt; @@ -1264,6 +1276,8 @@ void SwPostItMgr::DrawNotesForPage(OutputDevice *pOutDev, sal_uInt32 nPage) Point aPoint(mpEditWin->PixelToLogic(pPostIt->GetPosPixel())); pPostIt->DrawForPage(pOutDev, aPoint); } + if (bEnableMapMode) + mpEditWin->EnableMapMode(false); } void SwPostItMgr::PaintTile(OutputDevice& rRenderContext) @@ -2404,7 +2418,7 @@ void SwPostItMgr::CorrectPositions() bool SwPostItMgr::ShowNotes() const { // we only want to see notes if Options - Writer - View - Notes is ticked - return mpWrtShell->GetViewOptions()->IsPostIts(); + return mbForceShow || mpWrtShell->GetViewOptions()->IsPostIts(); } bool SwPostItMgr::HasNotes() const
