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 <DrawViewShell.hxx>
21 #include <DrawDocShell.hxx>
22 #include <tools/UnitConversion.hxx>
28 class ModelTraverseHandler
31 virtual ~ModelTraverseHandler() {}
33 virtual void handleSdrObject(SdrObject
* pObject
) = 0;
39 std::vector
<std::shared_ptr
<ModelTraverseHandler
>> m_pNodeHandler
;
40 SdDrawDocument
* m_pDocument
;
43 ModelTraverser(SdDrawDocument
* pDocument
)
44 : m_pDocument(pDocument
)
53 for (sal_uInt16 nPage
= 0; nPage
< m_pDocument
->GetPageCount(); ++nPage
)
55 SdrPage
* pPage
= m_pDocument
->GetPage(nPage
);
58 for (size_t nObject
= 0; nObject
< pPage
->GetObjCount(); ++nObject
)
60 SdrObject
* pObject
= pPage
->GetObj(nObject
);
63 for (auto& pNodeHandler
: m_pNodeHandler
)
65 pNodeHandler
->handleSdrObject(pObject
);
73 void addNodeHandler(std::shared_ptr
<ModelTraverseHandler
> pHandler
)
75 m_pNodeHandler
.push_back(pHandler
);
80 GraphicSizeViolation::GraphicSizeViolation(sal_Int32 nDPI
, SdrGrafObj
* pGraphicObject
)
81 : m_pGraphicObject(pGraphicObject
)
83 constexpr double fLowPercentage
= 110;
84 constexpr double fHighPercentage
= 50;
86 m_nLowDPILimit
= sal_Int32(100.0 / fLowPercentage
* nDPI
);
87 m_nHighDPILimit
= sal_Int32(100.0 / fHighPercentage
* nDPI
);
90 bool GraphicSizeViolation::check()
92 Graphic aGraphic
= m_pGraphicObject
->GetGraphic();
93 Size aSizePixel
= aGraphic
.GetSizePixel();
94 Size aGraphicSize
= m_pGraphicObject
->GetLogicRect().GetSize();
96 double nSizeXInch
= double(convertMm100ToTwip(aGraphicSize
.Width())) / 1440.0;
97 double nSizeYInch
= double(convertMm100ToTwip(aGraphicSize
.Height())) / 1440.0;
99 m_nDPIX
= sal_Int32(aSizePixel
.Width() / nSizeXInch
);
100 m_nDPIY
= sal_Int32(aSizePixel
.Height() / nSizeYInch
);
102 return isDPITooLow() || isDPITooHigh();
105 OUString
GraphicSizeViolation::getGraphicName() { return m_pGraphicObject
->GetName(); }
109 class GraphicSizeCheckHandler
: public ModelTraverseHandler
112 std::vector
<std::unique_ptr
<GraphicSizeViolation
>>& m_rGraphicSizeViolationList
;
115 GraphicSizeCheckHandler(
117 std::vector
<std::unique_ptr
<GraphicSizeViolation
>>& rGraphicSizeViolationList
)
119 , m_rGraphicSizeViolationList(rGraphicSizeViolationList
)
123 void handleSdrObject(SdrObject
* pObject
) override
125 auto* pGraphicObject
= dynamic_cast<SdrGrafObj
*>(pObject
);
129 auto pEntry
= std::make_unique
<GraphicSizeViolation
>(m_nDPI
, pGraphicObject
);
132 m_rGraphicSizeViolationList
.push_back(std::move(pEntry
));
137 } // end anonymous namespace
139 void GraphicSizeCheck::check()
144 sal_Int32 nDPI
= m_pDocument
->getImagePreferredDPI();
148 auto pHandler
= std::make_shared
<GraphicSizeCheckHandler
>(nDPI
, m_aGraphicSizeViolationList
);
150 ModelTraverser
aModelTraverser(m_pDocument
);
151 aModelTraverser
.addNodeHandler(pHandler
);
152 aModelTraverser
.traverse();
155 OUString
GraphicSizeCheckGUIEntry::getText()
159 if (m_pViolation
->isDPITooLow())
161 sText
= SdResId(STR_WARNING_GRAPHIC_PIXEL_COUNT_LOW
);
163 else if (m_pViolation
->isDPITooHigh())
165 sText
= SdResId(STR_WARNING_GRAPHIC_PIXEL_COUNT_HIGH
);
168 sText
= sText
.replaceAll("%NAME%", m_pViolation
->getGraphicName());
169 sText
= sText
.replaceAll("%DPIX%", OUString::number(m_pViolation
->getDPIX()));
170 sText
= sText
.replaceAll("%DPIY%", OUString::number(m_pViolation
->getDPIY()));
175 void GraphicSizeCheckGUIEntry::markObject()
177 sd::ViewShell
* pViewShell
= m_pDocument
->GetDocSh()->GetViewShell();
178 SdrView
* pView
= pViewShell
->GetView();
179 pView
->ShowSdrPage(m_pViolation
->getObject()->getSdrPageFromSdrObject());
181 pView
->MarkObj(m_pViolation
->getObject(), pView
->GetSdrPageView());
184 void GraphicSizeCheckGUIEntry::runProperties()
187 sd::ViewShell
* pViewShell
= m_pDocument
->GetDocSh()->GetViewShell();
188 pViewShell
->GetDispatcher()->Execute(SID_ATTR_GRAF_CROP
, SfxCallMode::SYNCHRON
);
191 GraphicSizeCheckGUIResult::GraphicSizeCheckGUIResult(SdDrawDocument
* pDocument
)
193 GraphicSizeCheck
aCheck(pDocument
);
196 auto& rCollection
= getCollection();
197 for (auto& rpViolation
: aCheck
.getViolationList())
200 = std::make_unique
<GraphicSizeCheckGUIEntry
>(pDocument
, std::move(rpViolation
));
201 rCollection
.push_back(std::move(rGUIEntry
));
205 OUString
GraphicSizeCheckGUIResult::getTitle()
207 return SdResId(STR_GRAPHIC_SIZE_CHECK_DIALOG_TITLE
);
210 } // end of namespace sd
212 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */