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 (size_t nObject
= 0; nObject
< pPage
->GetObjCount(); ++nObject
)
67 SdrObject
* pObject
= pPage
->GetObj(nObject
);
70 for (auto& pNodeHandler
: m_pNodeHandler
)
72 pNodeHandler
->handleSdrObject(pObject
);
80 void addNodeHandler(std::shared_ptr
<ModelTraverseHandler
> pHandler
)
82 m_pNodeHandler
.push_back(pHandler
);
87 GraphicSizeViolation::GraphicSizeViolation(sal_Int32 nDPI
, SdrGrafObj
* pGraphicObject
)
88 : m_pGraphicObject(pGraphicObject
)
90 constexpr double fLowPercentage
= 110;
91 constexpr double fHighPercentage
= 50;
93 m_nLowDPILimit
= sal_Int32(100.0 / fLowPercentage
* nDPI
);
94 m_nHighDPILimit
= sal_Int32(100.0 / fHighPercentage
* nDPI
);
97 bool GraphicSizeViolation::check()
99 Graphic aGraphic
= m_pGraphicObject
->GetGraphic();
100 Size aSizePixel
= aGraphic
.GetSizePixel();
101 Size aGraphicSize
= m_pGraphicObject
->GetLogicRect().GetSize();
104 = o3tl::convert(double(aGraphicSize
.Width()), o3tl::Length::mm100
, o3tl::Length::in
);
106 = o3tl::convert(double(aGraphicSize
.Height()), o3tl::Length::mm100
, o3tl::Length::in
);
108 m_nDPIX
= sal_Int32(aSizePixel
.Width() / nSizeXInch
);
109 m_nDPIY
= sal_Int32(aSizePixel
.Height() / nSizeYInch
);
111 return isDPITooLow() || isDPITooHigh();
114 const OUString
& GraphicSizeViolation::getGraphicName() { return m_pGraphicObject
->GetName(); }
118 class GraphicSizeCheckHandler
: public ModelTraverseHandler
121 std::vector
<std::unique_ptr
<GraphicSizeViolation
>>& m_rGraphicSizeViolationList
;
124 GraphicSizeCheckHandler(
126 std::vector
<std::unique_ptr
<GraphicSizeViolation
>>& rGraphicSizeViolationList
)
128 , m_rGraphicSizeViolationList(rGraphicSizeViolationList
)
132 void handleSdrObject(SdrObject
* pObject
) override
134 auto* pGraphicObject
= dynamic_cast<SdrGrafObj
*>(pObject
);
138 auto pEntry
= std::make_unique
<GraphicSizeViolation
>(m_nDPI
, pGraphicObject
);
141 m_rGraphicSizeViolationList
.push_back(std::move(pEntry
));
146 } // end anonymous namespace
148 void GraphicSizeCheck::check()
153 sal_Int32 nDPI
= m_pDocument
->getImagePreferredDPI();
157 auto pHandler
= std::make_shared
<GraphicSizeCheckHandler
>(nDPI
, m_aGraphicSizeViolationList
);
159 ModelTraverser
aModelTraverser(m_pDocument
);
160 aModelTraverser
.addNodeHandler(pHandler
);
161 aModelTraverser
.traverse();
164 OUString
GraphicSizeCheckGUIEntry::getText()
168 if (m_pViolation
->isDPITooLow())
170 sText
= SdResId(STR_WARNING_GRAPHIC_PIXEL_COUNT_LOW
);
172 else if (m_pViolation
->isDPITooHigh())
174 sText
= SdResId(STR_WARNING_GRAPHIC_PIXEL_COUNT_HIGH
);
177 sText
= sText
.replaceAll("%NAME%", m_pViolation
->getGraphicName());
178 sText
= sText
.replaceAll("%DPIX%", OUString::number(m_pViolation
->getDPIX()));
179 sText
= sText
.replaceAll("%DPIY%", OUString::number(m_pViolation
->getDPIY()));
184 void GraphicSizeCheckGUIEntry::markObject()
186 sd::ViewShell
* pViewShell
= m_pDocument
->GetDocSh()->GetViewShell();
187 SdrView
* pView
= pViewShell
->GetView();
188 pView
->ShowSdrPage(m_pViolation
->getObject()->getSdrPageFromSdrObject());
190 pView
->MarkObj(m_pViolation
->getObject(), pView
->GetSdrPageView());
193 void GraphicSizeCheckGUIEntry::runProperties()
196 sd::ViewShell
* pViewShell
= m_pDocument
->GetDocSh()->GetViewShell();
197 pViewShell
->GetDispatcher()->Execute(SID_ATTR_GRAF_CROP
, SfxCallMode::SYNCHRON
);
200 GraphicSizeCheckGUIResult::GraphicSizeCheckGUIResult(SdDrawDocument
* pDocument
)
202 GraphicSizeCheck
aCheck(pDocument
);
205 auto& rCollection
= getCollection();
206 for (auto& rpViolation
: aCheck
.getViolationList())
209 = std::make_unique
<GraphicSizeCheckGUIEntry
>(pDocument
, std::move(rpViolation
));
210 rCollection
.push_back(std::move(rGUIEntry
));
214 OUString
GraphicSizeCheckGUIResult::getTitle()
216 return SdResId(STR_GRAPHIC_SIZE_CHECK_DIALOG_TITLE
);
219 } // end of namespace sd
221 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */