1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/.
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>
28 * Interface for the visitor class, which handles each visited SdrObject
31 class ModelTraverseHandler
34 virtual ~ModelTraverseHandler() {}
36 virtual void handleSdrObject(SdrObject
* pObject
) = 0;
40 * Traverses the DOM and calls a handler for each object (SdrObject) it
46 std::vector
<std::shared_ptr
<ModelTraverseHandler
>> m_pNodeHandler
;
47 SdDrawDocument
* m_pDocument
;
50 ModelTraverser(SdDrawDocument
* pDocument
)
51 : m_pDocument(pDocument
)
60 for (sal_uInt16 nPage
= 0; nPage
< m_pDocument
->GetPageCount(); ++nPage
)
62 SdrPage
* pPage
= m_pDocument
->GetPage(nPage
);
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();
100 = o3tl::convert(double(aGraphicSize
.Width()), o3tl::Length::mm100
, o3tl::Length::in
);
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(); }
114 class GraphicSizeCheckHandler
: public ModelTraverseHandler
117 std::vector
<std::unique_ptr
<GraphicSizeViolation
>>& m_rGraphicSizeViolationList
;
120 GraphicSizeCheckHandler(
122 std::vector
<std::unique_ptr
<GraphicSizeViolation
>>& rGraphicSizeViolationList
)
124 , m_rGraphicSizeViolationList(rGraphicSizeViolationList
)
128 void handleSdrObject(SdrObject
* pObject
) override
130 auto* pGraphicObject
= dynamic_cast<SdrGrafObj
*>(pObject
);
134 auto pEntry
= std::make_unique
<GraphicSizeViolation
>(m_nDPI
, pGraphicObject
);
137 m_rGraphicSizeViolationList
.push_back(std::move(pEntry
));
142 } // end anonymous namespace
144 void GraphicSizeCheck::check()
149 sal_Int32 nDPI
= m_pDocument
->getImagePreferredDPI();
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()
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()));
180 void GraphicSizeCheckGUIEntry::markObject()
182 sd::ViewShell
* pViewShell
= m_pDocument
->GetDocSh()->GetViewShell();
183 SdrView
* pView
= pViewShell
->GetView();
184 pView
->ShowSdrPage(m_pViolation
->getObject()->getSdrPageFromSdrObject());
186 pView
->MarkObj(m_pViolation
->getObject(), pView
->GetSdrPageView());
189 void GraphicSizeCheckGUIEntry::runProperties()
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
);
201 auto& rCollection
= getCollection();
202 for (auto& rpViolation
: aCheck
.getViolationList())
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: */