summaryrefslogtreecommitdiff
path: root/sd/source
diff options
context:
space:
mode:
authorTomaž Vajngerl <tomaz.vajngerl@collabora.co.uk>2021-12-07 23:25:54 +0100
committerAndras Timar <andras.timar@collabora.com>2022-02-14 11:25:42 +0100
commitf394488de84048627644b19ab962c24b501a8caf (patch)
treed4f785d9ece20d7cad99c9db3247852550ac1d45 /sd/source
parent3b268a9eba49947316fc4591c5ec19926f09299e (diff)
Add graphic size checker for the preferred document DPI
This change adds a graphic size checker, which checks all the images in the document, if they largely differ (outside of 50% and 110% of the image size) from the set preferred image DPI document setting. For all images that don't fall under this bounds, list them in the dialog and offer the posibility to select/goto the image and pop-up the properties dialog for the image to change its size. Change-Id: I06efce77c291fdb6ec3864d72c2f4d15dba9c42b Reviewed-on: https://gerrit.libreoffice.org/c/core/+/127094 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
Diffstat (limited to 'sd/source')
-rw-r--r--sd/source/ui/inc/tools/GraphicSizeCheck.hxx103
-rw-r--r--sd/source/ui/tools/GraphicSizeCheck.cxx213
-rw-r--r--sd/source/ui/view/drviews2.cxx12
-rw-r--r--sd/source/ui/view/drviewsj.cxx4
4 files changed, 332 insertions, 0 deletions
diff --git a/sd/source/ui/inc/tools/GraphicSizeCheck.hxx b/sd/source/ui/inc/tools/GraphicSizeCheck.hxx
new file mode 100644
index 000000000000..9da3d569bd3a
--- /dev/null
+++ b/sd/source/ui/inc/tools/GraphicSizeCheck.hxx
@@ -0,0 +1,103 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ */
+
+#pragma once
+
+#include <memory>
+#include <drawdoc.hxx>
+#include <svx/GenericCheckDialog.hxx>
+#include <svx/svdograf.hxx>
+
+namespace sd
+{
+class GraphicSizeViolation final
+{
+private:
+ SdrGrafObj* m_pGraphicObject;
+
+ sal_Int32 m_nLowDPILimit = 0;
+ sal_Int32 m_nHighDPILimit = 0;
+
+ sal_Int32 m_nDPIX = 0;
+ sal_Int32 m_nDPIY = 0;
+
+public:
+ GraphicSizeViolation(sal_Int32 nDPI, SdrGrafObj* pGraphicObject);
+ bool check();
+
+ OUString getGraphicName();
+
+ SdrGrafObj* getObject() const { return m_pGraphicObject; }
+
+ bool isDPITooLow() { return m_nDPIX < m_nLowDPILimit || m_nDPIY < m_nLowDPILimit; }
+
+ bool isDPITooHigh() { return m_nDPIX > m_nHighDPILimit || m_nDPIY > m_nHighDPILimit; }
+
+ sal_Int32 getDPIX() { return m_nDPIX; }
+
+ sal_Int32 getDPIY() { return m_nDPIY; }
+};
+
+class GraphicSizeCheck final
+{
+private:
+ SdDrawDocument* m_pDocument;
+ std::vector<std::unique_ptr<GraphicSizeViolation>> m_aGraphicSizeViolationList;
+
+public:
+ GraphicSizeCheck(SdDrawDocument* pDocument)
+ : m_pDocument(pDocument)
+ {
+ }
+
+ void check();
+
+ std::vector<std::unique_ptr<GraphicSizeViolation>>& getViolationList()
+ {
+ return m_aGraphicSizeViolationList;
+ }
+};
+
+class GraphicSizeCheckGUIEntry : public svx::CheckData
+{
+private:
+ SdDrawDocument* m_pDocument;
+ std::unique_ptr<GraphicSizeViolation> m_pViolation;
+
+public:
+ GraphicSizeCheckGUIEntry(SdDrawDocument* pDocument,
+ std::unique_ptr<GraphicSizeViolation>&& pViolation)
+ : m_pDocument(pDocument)
+ , m_pViolation(std::move(pViolation))
+ {
+ }
+
+ OUString getText() override;
+
+ bool canMarkObject() override { return true; }
+
+ void markObject() override;
+
+ bool hasProperties() override { return true; }
+
+ void runProperties() override;
+};
+
+class GraphicSizeCheckGUIResult : public svx::CheckDataCollection
+{
+public:
+ GraphicSizeCheckGUIResult(SdDrawDocument* m_pDocument);
+
+ OUString getTitle() override;
+};
+
+} // end of namespace sd
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/tools/GraphicSizeCheck.cxx b/sd/source/ui/tools/GraphicSizeCheck.cxx
new file mode 100644
index 000000000000..14bfcf3353b9
--- /dev/null
+++ b/sd/source/ui/tools/GraphicSizeCheck.cxx
@@ -0,0 +1,213 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ */
+
+#include <memory>
+#include <tools/GraphicSizeCheck.hxx>
+#include <svx/strings.hrc>
+#include <svx/svdobj.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svxids.hrc>
+#include <sfx2/dispatch.hxx>
+
+#include <sdresid.hxx>
+#include <DrawViewShell.hxx>
+#include <DrawDocShell.hxx>
+
+namespace sd
+{
+namespace
+{
+class ModelTraverseHandler
+{
+public:
+ virtual ~ModelTraverseHandler() {}
+
+ virtual void handleSdrObject(SdrObject* pObject) = 0;
+};
+
+class ModelTraverser
+{
+private:
+ std::vector<std::shared_ptr<ModelTraverseHandler>> m_pNodeHandler;
+ SdDrawDocument* m_pDocument;
+
+public:
+ ModelTraverser(SdDrawDocument* pDocument)
+ : m_pDocument(pDocument)
+ {
+ }
+
+ void traverse()
+ {
+ if (!m_pDocument)
+ return;
+
+ for (sal_uInt16 nPage = 0; nPage < m_pDocument->GetPageCount(); ++nPage)
+ {
+ SdrPage* pPage = m_pDocument->GetPage(nPage);
+ if (pPage)
+ {
+ for (size_t nObject = 0; nObject < pPage->GetObjCount(); ++nObject)
+ {
+ SdrObject* pObject = pPage->GetObj(nObject);
+ if (pObject)
+ {
+ for (auto& pNodeHandler : m_pNodeHandler)
+ {
+ pNodeHandler->handleSdrObject(pObject);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ void addNodeHandler(std::shared_ptr<ModelTraverseHandler> pHandler)
+ {
+ m_pNodeHandler.push_back(pHandler);
+ }
+};
+}
+
+GraphicSizeViolation::GraphicSizeViolation(sal_Int32 nDPI, SdrGrafObj* pGraphicObject)
+ : m_pGraphicObject(pGraphicObject)
+{
+ constexpr double fLowPercentage = 110;
+ constexpr double fHighPercentage = 50;
+
+ m_nLowDPILimit = sal_Int32(100.0 / fLowPercentage * nDPI);
+ m_nHighDPILimit = sal_Int32(100.0 / fHighPercentage * nDPI);
+}
+
+bool GraphicSizeViolation::check()
+{
+ Graphic aGraphic = m_pGraphicObject->GetGraphic();
+ Size aSizePixel = aGraphic.GetSizePixel();
+ Size aGraphicSize = m_pGraphicObject->GetLogicRect().GetSize();
+
+ double nSizeXInch
+ = o3tl::convert(double(aGraphicSize.Width()), o3tl::Length::mm100, o3tl::Length::in);
+ double nSizeYInch
+ = o3tl::convert(double(aGraphicSize.Height()), o3tl::Length::mm100, o3tl::Length::in);
+
+ m_nDPIX = sal_Int32(aSizePixel.Width() / nSizeXInch);
+ m_nDPIY = sal_Int32(aSizePixel.Height() / nSizeYInch);
+
+ return isDPITooLow() || isDPITooHigh();
+}
+
+OUString GraphicSizeViolation::getGraphicName() { return m_pGraphicObject->GetName(); }
+
+namespace
+{
+class GraphicSizeCheckHandler : public ModelTraverseHandler
+{
+ sal_Int32 m_nDPI;
+ std::vector<std::unique_ptr<GraphicSizeViolation>>& m_rGraphicSizeViolationList;
+
+public:
+ GraphicSizeCheckHandler(
+ sal_Int32 nDPI,
+ std::vector<std::unique_ptr<GraphicSizeViolation>>& rGraphicSizeViolationList)
+ : m_nDPI(nDPI)
+ , m_rGraphicSizeViolationList(rGraphicSizeViolationList)
+ {
+ }
+
+ void handleSdrObject(SdrObject* pObject) override
+ {
+ auto* pGraphicObject = dynamic_cast<SdrGrafObj*>(pObject);
+ if (!pGraphicObject)
+ return;
+
+ auto pEntry = std::make_unique<GraphicSizeViolation>(m_nDPI, pGraphicObject);
+ if (pEntry->check())
+ {
+ m_rGraphicSizeViolationList.push_back(std::move(pEntry));
+ }
+ }
+};
+
+} // end anonymous namespace
+
+void GraphicSizeCheck::check()
+{
+ if (!m_pDocument)
+ return;
+
+ sal_Int32 nDPI = m_pDocument->getImagePreferredDPI();
+ if (nDPI == 0)
+ return;
+
+ auto pHandler = std::make_shared<GraphicSizeCheckHandler>(nDPI, m_aGraphicSizeViolationList);
+
+ ModelTraverser aModelTraverser(m_pDocument);
+ aModelTraverser.addNodeHandler(pHandler);
+ aModelTraverser.traverse();
+}
+
+OUString GraphicSizeCheckGUIEntry::getText()
+{
+ OUString sText;
+
+ if (m_pViolation->isDPITooLow())
+ {
+ sText = SdResId(STR_WARNING_GRAPHIC_PIXEL_COUNT_LOW);
+ }
+ else if (m_pViolation->isDPITooHigh())
+ {
+ sText = SdResId(STR_WARNING_GRAPHIC_PIXEL_COUNT_HIGH);
+ }
+
+ sText = sText.replaceAll("%NAME%", m_pViolation->getGraphicName());
+ sText = sText.replaceAll("%DPIX%", OUString::number(m_pViolation->getDPIX()));
+ sText = sText.replaceAll("%DPIY%", OUString::number(m_pViolation->getDPIY()));
+
+ return sText;
+}
+
+void GraphicSizeCheckGUIEntry::markObject()
+{
+ sd::ViewShell* pViewShell = m_pDocument->GetDocSh()->GetViewShell();
+ SdrView* pView = pViewShell->GetView();
+ pView->ShowSdrPage(m_pViolation->getObject()->getSdrPageFromSdrObject());
+ pView->UnmarkAll();
+ pView->MarkObj(m_pViolation->getObject(), pView->GetSdrPageView());
+}
+
+void GraphicSizeCheckGUIEntry::runProperties()
+{
+ markObject();
+ sd::ViewShell* pViewShell = m_pDocument->GetDocSh()->GetViewShell();
+ pViewShell->GetDispatcher()->Execute(SID_ATTR_GRAF_CROP, SfxCallMode::SYNCHRON);
+}
+
+GraphicSizeCheckGUIResult::GraphicSizeCheckGUIResult(SdDrawDocument* pDocument)
+{
+ GraphicSizeCheck aCheck(pDocument);
+ aCheck.check();
+
+ auto& rCollection = getCollection();
+ for (auto& rpViolation : aCheck.getViolationList())
+ {
+ auto rGUIEntry
+ = std::make_unique<GraphicSizeCheckGUIEntry>(pDocument, std::move(rpViolation));
+ rCollection.push_back(std::move(rGUIEntry));
+ }
+}
+
+OUString GraphicSizeCheckGUIResult::getTitle()
+{
+ return SdResId(STR_GRAPHIC_SIZE_CHECK_DIALOG_TITLE);
+}
+
+} // end of namespace sd
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/view/drviews2.cxx b/sd/source/ui/view/drviews2.cxx
index b951231f2c5b..87d1a34e2ebe 100644
--- a/sd/source/ui/view/drviews2.cxx
+++ b/sd/source/ui/view/drviews2.cxx
@@ -183,6 +183,7 @@
#include <SlideSorterViewShell.hxx>
#include <controller/SlideSorterController.hxx>
#include <controller/SlsPageSelector.hxx>
+#include <tools/GraphicSizeCheck.hxx>
#include <ViewShellBase.hxx>
#include <memory>
@@ -1462,6 +1463,17 @@ void DrawViewShell::FuTemporary(SfxRequest& rReq)
}
break;
+ case SID_GRAPHIC_SIZE_CHECK:
+ {
+ sd::GraphicSizeCheckGUIResult aResult(GetDoc());
+ svx::GenericCheckDialog aDialog(GetFrameWeld(), aResult);
+ aDialog.run();
+
+ Cancel();
+ rReq.Ignore();
+ }
+ break;
+
case SID_ATTRIBUTES_LINE: // BASIC
{
SetCurrentFunction( FuLine::Create( this, GetActiveWindow(), mpDrawView.get(), GetDoc(), rReq ) );
diff --git a/sd/source/ui/view/drviewsj.cxx b/sd/source/ui/view/drviewsj.cxx
index 9eebdbc57c29..6bbf88338f06 100644
--- a/sd/source/ui/view/drviewsj.cxx
+++ b/sd/source/ui/view/drviewsj.cxx
@@ -539,6 +539,10 @@ void DrawViewShell::GetMenuStateSel( SfxItemSet &rSet )
rSet.DisableItem(SID_SAVE_GRAPHIC);
rSet.DisableItem(SID_EXTERNAL_EDIT);
}
+ if (GetDoc()->getImagePreferredDPI() <= 0)
+ {
+ rSet.DisableItem(SID_GRAPHIC_SIZE_CHECK);
+ }
}
} // end of namespace sd