1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
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/.
10 #include <sal/config.h>
12 #include <AccessibilityCheck.hxx>
19 #include <officecfg/Office/Common.hxx>
20 #include <sfx2/bindings.hxx>
21 #include <sfx2/AccessibilityIssue.hxx>
22 #include <unotools/configmgr.hxx>
23 #include <vcl/svapp.hxx>
25 #include "A11yCheckIssuesPanel.hxx"
27 #include <com/sun/star/lang/IllegalArgumentException.hpp>
31 AccessibilityCheckEntry::AccessibilityCheckEntry(
32 weld::Container
* pParent
, std::shared_ptr
<sfx::AccessibilityIssue
> const& rAccessibilityIssue
)
33 : m_xBuilder(Application::CreateBuilder(pParent
, "svx/ui/accessibilitycheckentry.ui"))
34 , m_xContainer(m_xBuilder
->weld_container("accessibilityCheckEntryBox"))
35 , m_xLabel(m_xBuilder
->weld_label("accessibilityCheckEntryLabel"))
36 , m_xGotoButton(m_xBuilder
->weld_link_button("accessibilityCheckEntryLinkButton"))
37 , m_xFixButton(m_xBuilder
->weld_button("accessibilityCheckEntryFixButton"))
38 , m_pAccessibilityIssue(rAccessibilityIssue
)
40 // lock in the height as including the button so all rows are the same height
41 m_xContainer
->set_size_request(-1, m_xContainer
->get_preferred_size().Height());
43 if (m_pAccessibilityIssue
->canGotoIssue())
45 m_xGotoButton
->set_label(m_pAccessibilityIssue
->m_aIssueText
);
47 // int nPrefWidth(m_xGotoButton->get_preferred_size().Width());
48 int nMaxWidth
= m_xGotoButton
->get_approximate_digit_width() * 10;
49 // if (nPrefWidth > nMaxWidth)
51 // tdf#156137 allow LinkButton label to wrap
52 m_xGotoButton
->set_label_wrap(true);
53 m_xGotoButton
->set_size_request(nMaxWidth
, -1);
56 m_xGotoButton
->connect_activate_link(
57 LINK(this, AccessibilityCheckEntry
, GotoButtonClicked
));
58 m_xLabel
->set_visible(false);
62 m_xLabel
->set_label(m_pAccessibilityIssue
->m_aIssueText
);
63 m_xGotoButton
->set_visible(false);
66 m_xFixButton
->set_visible(m_pAccessibilityIssue
->canQuickFixIssue());
67 m_xFixButton
->connect_clicked(LINK(this, AccessibilityCheckEntry
, FixButtonClicked
));
69 m_pAccessibilityIssue
->setParent(dynamic_cast<weld::Window
*>(get_widget()));
72 IMPL_LINK_NOARG(AccessibilityCheckEntry
, GotoButtonClicked
, weld::LinkButton
&, bool)
74 m_pAccessibilityIssue
->gotoIssue();
78 IMPL_LINK_NOARG(AccessibilityCheckEntry
, FixButtonClicked
, weld::Button
&, void)
80 m_pAccessibilityIssue
->quickFixIssue();
83 std::unique_ptr
<PanelLayout
> A11yCheckIssuesPanel::Create(weld::Widget
* pParent
,
84 SfxBindings
* pBindings
)
86 if (pParent
== nullptr)
87 throw ::com::sun::star::lang::IllegalArgumentException(
88 "no parent window given to A11yCheckIssuesPanel::Create", nullptr, 0);
89 return std::make_unique
<A11yCheckIssuesPanel
>(pParent
, pBindings
);
92 A11yCheckIssuesPanel::A11yCheckIssuesPanel(weld::Widget
* pParent
, SfxBindings
* pBindings
)
93 : PanelLayout(pParent
, "A11yCheckIssuesPanel", "modules/swriter/ui/a11ycheckissuespanel.ui")
94 , m_xExpanderDocument(m_xBuilder
->weld_expander("expand_document"))
95 , m_xExpanderStyles(m_xBuilder
->weld_expander("expand_styles"))
96 , m_xExpanderNoAlt(m_xBuilder
->weld_expander("expand_no_alt"))
97 , m_xExpanderTable(m_xBuilder
->weld_expander("expand_table"))
98 , m_xExpanderFormatting(m_xBuilder
->weld_expander("expand_formatting"))
99 , m_xExpanderHyperlink(m_xBuilder
->weld_expander("expand_hyperlink"))
100 , m_xExpanderFakes(m_xBuilder
->weld_expander("expand_fakes"))
101 , m_xExpanderNumbering(m_xBuilder
->weld_expander("expand_numbering"))
102 , m_xExpanderOther(m_xBuilder
->weld_expander("expand_other"))
103 , m_xBoxDocument(m_xBuilder
->weld_box("box_document"))
104 , m_xBoxStyles(m_xBuilder
->weld_box("box_styles"))
105 , m_xBoxNoAlt(m_xBuilder
->weld_box("box_no_alt"))
106 , m_xBoxTable(m_xBuilder
->weld_box("box_table"))
107 , m_xBoxFormatting(m_xBuilder
->weld_box("box_formatting"))
108 , m_xBoxHyperlink(m_xBuilder
->weld_box("box_hyperlink"))
109 , m_xBoxFakes(m_xBuilder
->weld_box("box_fakes"))
110 , m_xBoxNumbering(m_xBuilder
->weld_box("box_numbering"))
111 , m_xBoxOther(m_xBuilder
->weld_box("box_other"))
112 , mpBindings(pBindings
)
114 , maA11yCheckController(FN_STAT_ACCESSIBILITY_CHECK
, *pBindings
, *this)
116 , mbAutomaticCheckEnabled(false)
118 SwDocShell
* pDocSh
= dynamic_cast<SwDocShell
*>(SfxObjectShell::Current());
122 // Automatic a11y checking must be enabled for this panel to work properly
123 mbAutomaticCheckEnabled
124 = officecfg::Office::Common::Accessibility::OnlineAccessibilityCheck::get();
125 if (!mbAutomaticCheckEnabled
)
127 std::shared_ptr
<comphelper::ConfigurationChanges
> batch(
128 comphelper::ConfigurationChanges::create());
129 officecfg::Office::Common::Accessibility::OnlineAccessibilityCheck::set(true, batch
);
131 pBindings
->Invalidate(SID_ACCESSIBILITY_CHECK_ONLINE
);
134 mpDoc
= pDocSh
->GetDoc();
139 void A11yCheckIssuesPanel::ImplDestroy()
141 // Restore state when this panel is no longer used
142 if (!mbAutomaticCheckEnabled
)
144 std::shared_ptr
<comphelper::ConfigurationChanges
> batch(
145 comphelper::ConfigurationChanges::create());
146 officecfg::Office::Common::Accessibility::OnlineAccessibilityCheck::set(false, batch
);
148 mpBindings
->Invalidate(SID_ACCESSIBILITY_CHECK_ONLINE
);
150 m_xExpanderDocument
.reset();
151 m_xExpanderStyles
.reset();
152 m_xExpanderNoAlt
.reset();
153 m_xExpanderTable
.reset();
154 m_xExpanderFormatting
.reset();
155 m_xExpanderHyperlink
.reset();
156 m_xExpanderFakes
.reset();
157 m_xExpanderNumbering
.reset();
158 m_xExpanderOther
.reset();
159 m_xBoxDocument
.reset();
160 m_xBoxStyles
.reset();
163 m_xBoxFormatting
.reset();
164 m_xBoxHyperlink
.reset();
166 m_xBoxNumbering
.reset();
170 A11yCheckIssuesPanel::~A11yCheckIssuesPanel() { suppress_fun_call_w_exception(ImplDestroy()); }
172 void A11yCheckIssuesPanel::removeOldWidgets()
174 for (auto const& xEntry
: m_aDocumentEntries
)
175 m_xBoxDocument
->move(xEntry
->get_widget(), nullptr);
176 m_xExpanderDocument
->set_visible(false);
178 for (auto const& xEntry
: m_aStylesEntries
)
179 m_xBoxStyles
->move(xEntry
->get_widget(), nullptr);
180 m_xExpanderStyles
->set_visible(false);
182 for (auto const& xEntry
: m_aNoAltEntries
)
183 m_xBoxNoAlt
->move(xEntry
->get_widget(), nullptr);
184 m_xExpanderNoAlt
->set_visible(false);
186 for (auto const& xEntry
: m_aTableEntries
)
187 m_xBoxTable
->move(xEntry
->get_widget(), nullptr);
188 m_xExpanderTable
->set_visible(false);
190 for (auto const& xEntry
: m_aFormattingEntries
)
191 m_xBoxFormatting
->move(xEntry
->get_widget(), nullptr);
192 m_xExpanderFormatting
->set_visible(false);
194 for (auto const& xEntry
: m_aHyperlinkEntries
)
195 m_xBoxHyperlink
->move(xEntry
->get_widget(), nullptr);
196 m_xExpanderHyperlink
->set_visible(false);
198 for (auto const& xEntry
: m_aFakesEntries
)
199 m_xBoxFakes
->move(xEntry
->get_widget(), nullptr);
200 m_xExpanderFakes
->set_visible(false);
202 for (auto const& xEntry
: m_aNumberingEntries
)
203 m_xBoxNumbering
->move(xEntry
->get_widget(), nullptr);
204 m_xExpanderNumbering
->set_visible(false);
206 for (auto const& xEntry
: m_aOtherEntries
)
207 m_xBoxOther
->move(xEntry
->get_widget(), nullptr);
208 m_xExpanderOther
->set_visible(false);
211 void A11yCheckIssuesPanel::populateIssues()
215 sw::AccessibilityCheck
aCheck(mpDoc
);
217 m_aIssueCollection
= aCheck
.getIssueCollection();
221 sal_Int32 iDocument
= 0;
222 sal_Int32 iStyles
= 0;
223 sal_Int32 iNoAlt
= 0;
224 sal_Int32 iTable
= 0;
225 sal_Int32 iFormatting
= 0;
226 sal_Int32 iHyperlink
= 0;
227 sal_Int32 iFakes
= 0;
228 sal_Int32 iNumbering
= 0;
229 sal_Int32 iOther
= 0;
230 for (std::shared_ptr
<sfx::AccessibilityIssue
> const& pIssue
: m_aIssueCollection
.getIssues())
232 switch (pIssue
->m_eIssueID
)
234 case sfx::AccessibilityIssueID::DOCUMENT_TITLE
:
235 case sfx::AccessibilityIssueID::DOCUMENT_LANGUAGE
:
236 case sfx::AccessibilityIssueID::DOCUMENT_BACKGROUND
:
239 = std::make_unique
<AccessibilityCheckEntry
>(m_xBoxDocument
.get(), pIssue
);
240 m_xBoxDocument
->reorder_child(xEntry
->get_widget(), iDocument
++);
241 m_xExpanderDocument
->set_visible(true);
242 m_aDocumentEntries
.push_back(std::move(xEntry
));
245 case sfx::AccessibilityIssueID::STYLE_LANGUAGE
:
247 auto xEntry
= std::make_unique
<AccessibilityCheckEntry
>(m_xBoxStyles
.get(), pIssue
);
248 m_xBoxStyles
->reorder_child(xEntry
->get_widget(), iStyles
++);
249 m_xExpanderStyles
->set_visible(true);
250 m_aStylesEntries
.push_back(std::move(xEntry
));
253 case sfx::AccessibilityIssueID::NO_ALT_OLE
:
254 case sfx::AccessibilityIssueID::NO_ALT_GRAPHIC
:
255 case sfx::AccessibilityIssueID::NO_ALT_SHAPE
:
257 auto xEntry
= std::make_unique
<AccessibilityCheckEntry
>(m_xBoxNoAlt
.get(), pIssue
);
258 m_xBoxNoAlt
->reorder_child(xEntry
->get_widget(), iNoAlt
++);
259 m_xExpanderNoAlt
->set_visible(true);
260 m_aNoAltEntries
.push_back(std::move(xEntry
));
263 case sfx::AccessibilityIssueID::TABLE_MERGE_SPLIT
:
265 auto xEntry
= std::make_unique
<AccessibilityCheckEntry
>(m_xBoxTable
.get(), pIssue
);
266 m_xBoxTable
->reorder_child(xEntry
->get_widget(), iTable
++);
267 m_xExpanderTable
->set_visible(true);
268 m_aTableEntries
.push_back(std::move(xEntry
));
271 case sfx::AccessibilityIssueID::TEXT_FORMATTING
:
272 case sfx::AccessibilityIssueID::TABLE_FORMATTING
:
275 = std::make_unique
<AccessibilityCheckEntry
>(m_xBoxFormatting
.get(), pIssue
);
276 m_xBoxFormatting
->reorder_child(xEntry
->get_widget(), iFormatting
++);
277 m_xExpanderFormatting
->set_visible(true);
278 m_aFormattingEntries
.push_back(std::move(xEntry
));
281 case sfx::AccessibilityIssueID::HYPERLINK_IS_TEXT
:
282 case sfx::AccessibilityIssueID::HYPERLINK_SHORT
:
285 = std::make_unique
<AccessibilityCheckEntry
>(m_xBoxHyperlink
.get(), pIssue
);
286 m_xBoxHyperlink
->reorder_child(xEntry
->get_widget(), iHyperlink
++);
287 m_xExpanderHyperlink
->set_visible(true);
288 m_aHyperlinkEntries
.push_back(std::move(xEntry
));
291 case sfx::AccessibilityIssueID::FAKE_FOOTNOTE
:
292 case sfx::AccessibilityIssueID::FAKE_CAPTION
:
294 auto xEntry
= std::make_unique
<AccessibilityCheckEntry
>(m_xBoxFakes
.get(), pIssue
);
295 m_xBoxFakes
->reorder_child(xEntry
->get_widget(), iFakes
++);
296 m_xExpanderFakes
->set_visible(true);
297 m_aFakesEntries
.push_back(std::move(xEntry
));
300 case sfx::AccessibilityIssueID::MANUAL_NUMBERING
:
303 = std::make_unique
<AccessibilityCheckEntry
>(m_xBoxNumbering
.get(), pIssue
);
304 m_xBoxNumbering
->reorder_child(xEntry
->get_widget(), iNumbering
++);
305 m_xExpanderNumbering
->set_visible(true);
306 m_aNumberingEntries
.push_back(std::move(xEntry
));
309 case sfx::AccessibilityIssueID::UNSPECIFIED
:
311 auto xEntry
= std::make_unique
<AccessibilityCheckEntry
>(m_xBoxOther
.get(), pIssue
);
312 m_xBoxOther
->reorder_child(xEntry
->get_widget(), iOther
++);
313 m_xExpanderOther
->set_visible(true);
314 m_aOtherEntries
.push_back(std::move(xEntry
));
319 SAL_WARN("sw.a11y", "Invalid issue ID.");
327 void A11yCheckIssuesPanel::NotifyItemUpdate(const sal_uInt16 nSid
, const SfxItemState
/* eState */,
328 const SfxPoolItem
* pState
)
330 if (!pState
) //disposed
335 case FN_STAT_ACCESSIBILITY_CHECK
:
337 sal_Int32 nIssueCount
= static_cast<const SfxInt32Item
*>(pState
)->GetValue();
338 if (nIssueCount
!= mnIssueCount
)
340 mnIssueCount
= nIssueCount
;
351 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */