uno grid a11y: Use ImplInheritanceHelper
[LibreOffice.git] / sd / source / ui / tools / GraphicSizeCheck.cxx
blob68bd33a3e194deb6edd4d40ea49cb6e221053c18
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 */
11 #include <memory>
12 #include <tools/GraphicSizeCheck.hxx>
13 #include <svx/strings.hrc>
14 #include <svx/svdobj.hxx>
15 #include <svx/svdpage.hxx>
16 #include <svx/svxids.hrc>
17 #include <sfx2/dispatch.hxx>
19 #include <sdresid.hxx>
20 #include <DrawDocShell.hxx>
21 #include <ViewShell.hxx>
23 namespace sd
25 namespace
27 /**
28 * Interface for the visitor class, which handles each visited SdrObject
29 * in the DOM.
31 class ModelTraverseHandler
33 public:
34 virtual ~ModelTraverseHandler() {}
36 virtual void handleSdrObject(SdrObject* pObject) = 0;
39 /**
40 * Traverses the DOM and calls a handler for each object (SdrObject) it
41 * encounters.
43 class ModelTraverser
45 private:
46 std::vector<std::shared_ptr<ModelTraverseHandler>> m_pNodeHandler;
47 SdDrawDocument* m_pDocument;
49 public:
50 ModelTraverser(SdDrawDocument* pDocument)
51 : m_pDocument(pDocument)
55 void traverse()
57 if (!m_pDocument)
58 return;
60 for (sal_uInt16 nPage = 0; nPage < m_pDocument->GetPageCount(); ++nPage)
62 SdrPage* pPage = m_pDocument->GetPage(nPage);
63 if (pPage)
65 for (const rtl::Reference<SdrObject>& pObject : *pPage)
67 for (auto& pNodeHandler : m_pNodeHandler)
69 pNodeHandler->handleSdrObject(pObject.get());
76 void addNodeHandler(std::shared_ptr<ModelTraverseHandler> pHandler)
78 m_pNodeHandler.push_back(pHandler);
83 GraphicSizeViolation::GraphicSizeViolation(sal_Int32 nDPI, SdrGrafObj* pGraphicObject)
84 : m_pGraphicObject(pGraphicObject)
86 constexpr double fLowPercentage = 110;
87 constexpr double fHighPercentage = 50;
89 m_nLowDPILimit = sal_Int32(100.0 / fLowPercentage * nDPI);
90 m_nHighDPILimit = sal_Int32(100.0 / fHighPercentage * nDPI);
93 bool GraphicSizeViolation::check()
95 Graphic aGraphic = m_pGraphicObject->GetGraphic();
96 Size aSizePixel = aGraphic.GetSizePixel();
97 Size aGraphicSize = m_pGraphicObject->GetLogicRect().GetSize();
99 double nSizeXInch
100 = o3tl::convert(double(aGraphicSize.Width()), o3tl::Length::mm100, o3tl::Length::in);
101 double nSizeYInch
102 = o3tl::convert(double(aGraphicSize.Height()), o3tl::Length::mm100, o3tl::Length::in);
104 m_nDPIX = sal_Int32(aSizePixel.Width() / nSizeXInch);
105 m_nDPIY = sal_Int32(aSizePixel.Height() / nSizeYInch);
107 return isDPITooLow() || isDPITooHigh();
110 const OUString& GraphicSizeViolation::getGraphicName() { return m_pGraphicObject->GetName(); }
112 namespace
114 class GraphicSizeCheckHandler : public ModelTraverseHandler
116 sal_Int32 m_nDPI;
117 std::vector<std::unique_ptr<GraphicSizeViolation>>& m_rGraphicSizeViolationList;
119 public:
120 GraphicSizeCheckHandler(
121 sal_Int32 nDPI,
122 std::vector<std::unique_ptr<GraphicSizeViolation>>& rGraphicSizeViolationList)
123 : m_nDPI(nDPI)
124 , m_rGraphicSizeViolationList(rGraphicSizeViolationList)
128 void handleSdrObject(SdrObject* pObject) override
130 auto* pGraphicObject = dynamic_cast<SdrGrafObj*>(pObject);
131 if (!pGraphicObject)
132 return;
134 auto pEntry = std::make_unique<GraphicSizeViolation>(m_nDPI, pGraphicObject);
135 if (pEntry->check())
137 m_rGraphicSizeViolationList.push_back(std::move(pEntry));
142 } // end anonymous namespace
144 void GraphicSizeCheck::check()
146 if (!m_pDocument)
147 return;
149 sal_Int32 nDPI = m_pDocument->getImagePreferredDPI();
150 if (nDPI == 0)
151 return;
153 auto pHandler = std::make_shared<GraphicSizeCheckHandler>(nDPI, m_aGraphicSizeViolationList);
155 ModelTraverser aModelTraverser(m_pDocument);
156 aModelTraverser.addNodeHandler(pHandler);
157 aModelTraverser.traverse();
160 OUString GraphicSizeCheckGUIEntry::getText()
162 OUString sText;
164 if (m_pViolation->isDPITooLow())
166 sText = SdResId(STR_WARNING_GRAPHIC_PIXEL_COUNT_LOW);
168 else if (m_pViolation->isDPITooHigh())
170 sText = SdResId(STR_WARNING_GRAPHIC_PIXEL_COUNT_HIGH);
173 sText = sText.replaceAll("%NAME%", m_pViolation->getGraphicName());
174 sText = sText.replaceAll("%DPIX%", OUString::number(m_pViolation->getDPIX()));
175 sText = sText.replaceAll("%DPIY%", OUString::number(m_pViolation->getDPIY()));
177 return sText;
180 void GraphicSizeCheckGUIEntry::markObject()
182 sd::ViewShell* pViewShell = m_pDocument->GetDocSh()->GetViewShell();
183 SdrView* pView = pViewShell->GetView();
184 pView->ShowSdrPage(m_pViolation->getObject()->getSdrPageFromSdrObject());
185 pView->UnmarkAll();
186 pView->MarkObj(m_pViolation->getObject(), pView->GetSdrPageView());
189 void GraphicSizeCheckGUIEntry::runProperties()
191 markObject();
192 sd::ViewShell* pViewShell = m_pDocument->GetDocSh()->GetViewShell();
193 pViewShell->GetDispatcher()->Execute(SID_ATTR_GRAF_CROP, SfxCallMode::SYNCHRON);
196 GraphicSizeCheckGUIResult::GraphicSizeCheckGUIResult(SdDrawDocument* pDocument)
198 GraphicSizeCheck aCheck(pDocument);
199 aCheck.check();
201 auto& rCollection = getCollection();
202 for (auto& rpViolation : aCheck.getViolationList())
204 auto rGUIEntry
205 = std::make_unique<GraphicSizeCheckGUIEntry>(pDocument, std::move(rpViolation));
206 rCollection.push_back(std::move(rGUIEntry));
210 OUString GraphicSizeCheckGUIResult::getTitle()
212 return SdResId(STR_GRAPHIC_SIZE_CHECK_DIALOG_TITLE);
215 } // end of namespace sd
217 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */