LibreOffice Module sw (master) 1
A11yCheckIssuesPanel.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 */
9
10#include <sal/config.h>
11
12#include <AccessibilityCheck.hxx>
13#include <cmdid.h>
14#include <doc.hxx>
15#include <docsh.hxx>
16#include <ndtxt.hxx>
17#include <wrtsh.hxx>
18
19#include <officecfg/Office/Common.hxx>
20#include <sfx2/bindings.hxx>
23#include <vcl/svapp.hxx>
24
26
27#include <com/sun/star/lang/IllegalArgumentException.hpp>
28
29namespace sw::sidebar
30{
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)
39{
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());
42
43 if (m_pAccessibilityIssue->canGotoIssue())
44 {
45 m_xGotoButton->set_label(m_pAccessibilityIssue->m_aIssueText);
46
47 // int nPrefWidth(m_xGotoButton->get_preferred_size().Width());
48 int nMaxWidth = m_xGotoButton->get_approximate_digit_width() * 10;
49 // if (nPrefWidth > nMaxWidth)
50 {
51 // tdf#156137 allow LinkButton label to wrap
52 m_xGotoButton->set_label_wrap(true);
53 m_xGotoButton->set_size_request(nMaxWidth, -1);
54 }
55
56 m_xGotoButton->connect_activate_link(
57 LINK(this, AccessibilityCheckEntry, GotoButtonClicked));
58 m_xLabel->set_visible(false);
59 }
60 else
61 {
62 m_xLabel->set_label(m_pAccessibilityIssue->m_aIssueText);
63 m_xGotoButton->set_visible(false);
64 }
65
66 m_xFixButton->set_visible(m_pAccessibilityIssue->canQuickFixIssue());
67 m_xFixButton->connect_clicked(LINK(this, AccessibilityCheckEntry, FixButtonClicked));
68
69 m_pAccessibilityIssue->setParent(dynamic_cast<weld::Window*>(get_widget()));
70}
71
73{
74 m_pAccessibilityIssue->gotoIssue();
75 return true;
76}
77
79{
80 m_pAccessibilityIssue->quickFixIssue();
81}
82
83std::unique_ptr<PanelLayout> A11yCheckIssuesPanel::Create(weld::Widget* pParent,
84 SfxBindings* pBindings)
85{
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);
90}
91
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)
113 , mpDoc(nullptr)
114 , maA11yCheckController(FN_STAT_ACCESSIBILITY_CHECK, *pBindings, *this)
115 , mnIssueCount(0)
116 , mbAutomaticCheckEnabled(false)
117{
118 SwDocShell* pDocSh = dynamic_cast<SwDocShell*>(SfxObjectShell::Current());
119 if (!pDocSh)
120 return;
121
122 // Automatic a11y checking must be enabled for this panel to work properly
126 {
127 std::shared_ptr<comphelper::ConfigurationChanges> batch(
129 officecfg::Office::Common::Accessibility::OnlineAccessibilityCheck::set(true, batch);
130 batch->commit();
131 pBindings->Invalidate(SID_ACCESSIBILITY_CHECK_ONLINE);
132 }
133
134 mpDoc = pDocSh->GetDoc();
135
137}
138
140{
141 // Restore state when this panel is no longer used
143 {
144 std::shared_ptr<comphelper::ConfigurationChanges> batch(
146 officecfg::Office::Common::Accessibility::OnlineAccessibilityCheck::set(false, batch);
147 batch->commit();
148 mpBindings->Invalidate(SID_ACCESSIBILITY_CHECK_ONLINE);
149 }
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();
161 m_xBoxNoAlt.reset();
162 m_xBoxTable.reset();
163 m_xBoxFormatting.reset();
164 m_xBoxHyperlink.reset();
165 m_xBoxFakes.reset();
166 m_xBoxNumbering.reset();
167 m_xBoxOther.reset();
168}
169
171
173{
174 for (auto const& xEntry : m_aDocumentEntries)
175 m_xBoxDocument->move(xEntry->get_widget(), nullptr);
176 m_xExpanderDocument->set_visible(false);
177
178 for (auto const& xEntry : m_aStylesEntries)
179 m_xBoxStyles->move(xEntry->get_widget(), nullptr);
180 m_xExpanderStyles->set_visible(false);
181
182 for (auto const& xEntry : m_aNoAltEntries)
183 m_xBoxNoAlt->move(xEntry->get_widget(), nullptr);
184 m_xExpanderNoAlt->set_visible(false);
185
186 for (auto const& xEntry : m_aTableEntries)
187 m_xBoxTable->move(xEntry->get_widget(), nullptr);
188 m_xExpanderTable->set_visible(false);
189
190 for (auto const& xEntry : m_aFormattingEntries)
191 m_xBoxFormatting->move(xEntry->get_widget(), nullptr);
192 m_xExpanderFormatting->set_visible(false);
193
194 for (auto const& xEntry : m_aHyperlinkEntries)
195 m_xBoxHyperlink->move(xEntry->get_widget(), nullptr);
196 m_xExpanderHyperlink->set_visible(false);
197
198 for (auto const& xEntry : m_aFakesEntries)
199 m_xBoxFakes->move(xEntry->get_widget(), nullptr);
200 m_xExpanderFakes->set_visible(false);
201
202 for (auto const& xEntry : m_aNumberingEntries)
203 m_xBoxNumbering->move(xEntry->get_widget(), nullptr);
204 m_xExpanderNumbering->set_visible(false);
205
206 for (auto const& xEntry : m_aOtherEntries)
207 m_xBoxOther->move(xEntry->get_widget(), nullptr);
208 m_xExpanderOther->set_visible(false);
209}
210
212{
213 if (!mpDoc)
214 return;
216 aCheck.check();
218
220
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())
231 {
232 switch (pIssue->m_eIssueID)
233 {
237 {
238 auto xEntry
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));
243 }
244 break;
246 {
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));
251 }
252 break;
256 {
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));
261 }
262 break;
264 {
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));
269 }
270 break;
273 {
274 auto xEntry
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));
279 }
280 break;
283 {
284 auto xEntry
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));
289 }
290 break;
293 {
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));
298 }
299 break;
301 {
302 auto xEntry
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));
307 }
308 break;
310 {
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));
315 }
316 break;
317 default:
318 {
319 SAL_WARN("sw.a11y", "Invalid issue ID.");
320 continue;
321 }
322 break;
323 };
324 }
325}
326
327void A11yCheckIssuesPanel::NotifyItemUpdate(const sal_uInt16 nSid, const SfxItemState /* eState */,
328 const SfxPoolItem* pState)
329{
330 if (!pState) //disposed
331 return;
332
333 switch (nSid)
334 {
336 {
337 sal_Int32 nIssueCount = static_cast<const SfxInt32Item*>(pState)->GetValue();
338 if (nIssueCount != mnIssueCount)
339 {
340 mnIssueCount = nIssueCount;
342 }
343 }
344 break;
345 default:
346 break;
347 }
348}
349}
350
351/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
void Invalidate(sal_uInt16 nId)
static SAL_WARN_UNUSED_RESULT SfxObjectShell * Current()
SwDoc * GetDoc()
returns Doc. But be careful!
Definition: docsh.hxx:204
static std::shared_ptr< ConfigurationChanges > create()
std::unique_ptr< weld::Label > m_xLabel
AccessibilityIssueCollection & getIssueCollection()
std::vector< std::shared_ptr< AccessibilityIssue > > & getIssues()
std::vector< std::unique_ptr< AccessibilityCheckEntry > > m_aHyperlinkEntries
std::unique_ptr< weld::Expander > m_xExpanderDocument
std::unique_ptr< weld::Expander > m_xExpanderNoAlt
std::vector< std::unique_ptr< AccessibilityCheckEntry > > m_aNoAltEntries
std::vector< std::unique_ptr< AccessibilityCheckEntry > > m_aDocumentEntries
std::vector< std::unique_ptr< AccessibilityCheckEntry > > m_aFormattingEntries
std::unique_ptr< weld::Box > m_xBoxHyperlink
std::unique_ptr< weld::Expander > m_xExpanderFakes
std::unique_ptr< weld::Box > m_xBoxNoAlt
std::vector< std::unique_ptr< AccessibilityCheckEntry > > m_aTableEntries
std::unique_ptr< weld::Box > m_xBoxTable
std::unique_ptr< weld::Expander > m_xExpanderNumbering
std::vector< std::unique_ptr< AccessibilityCheckEntry > > m_aFakesEntries
sfx::AccessibilityIssueCollection m_aIssueCollection
static std::unique_ptr< PanelLayout > Create(weld::Widget *pParent, SfxBindings *pBindings)
A11yCheckIssuesPanel(weld::Widget *pParent, SfxBindings *pBindings)
std::unique_ptr< weld::Box > m_xBoxDocument
std::unique_ptr< weld::Box > m_xBoxFakes
std::unique_ptr< weld::Expander > m_xExpanderFormatting
std::unique_ptr< weld::Box > m_xBoxOther
std::unique_ptr< weld::Box > m_xBoxNumbering
std::vector< std::unique_ptr< AccessibilityCheckEntry > > m_aOtherEntries
std::unique_ptr< weld::Box > m_xBoxFormatting
std::unique_ptr< weld::Expander > m_xExpanderTable
std::vector< std::unique_ptr< AccessibilityCheckEntry > > m_aNumberingEntries
std::unique_ptr< weld::Expander > m_xExpanderStyles
std::unique_ptr< weld::Expander > m_xExpanderOther
std::unique_ptr< weld::Box > m_xBoxStyles
virtual void NotifyItemUpdate(const sal_uInt16 nSId, const SfxItemState eState, const SfxPoolItem *pState) override
std::vector< std::unique_ptr< AccessibilityCheckEntry > > m_aStylesEntries
std::unique_ptr< weld::Expander > m_xExpanderHyperlink
std::shared_ptr< sfx::AccessibilityIssue > const & m_pAccessibilityIssue
AccessibilityCheckEntry(weld::Container *pParent, std::shared_ptr< sfx::AccessibilityIssue > const &pAccessibilityIssue)
std::unique_ptr< weld::Container > m_xContainer
std::unique_ptr< weld::Button > m_xFixButton
std::unique_ptr< weld::Label > m_xLabel
std::unique_ptr< weld::LinkButton > m_xGotoButton
#define FN_STAT_ACCESSIBILITY_CHECK
Definition: cmdid.h:870
#define suppress_fun_call_w_exception(expr)
#define SAL_WARN(area, stream)
css::uno::Reference< css::linguistic2::XProofreadingIterator > get(css::uno::Reference< css::uno::XComponentContext > const &context)
IMPL_LINK_NOARG(AccessibilityCheckEntry, GotoButtonClicked, weld::LinkButton &, bool)
Reference< XNameAccess > m_xContainer
const char GetValue[]
SfxItemState