cui/inc/strings.hrc | 35 + cui/source/options/optaccessibility.cxx | 344 +++++++++++++ cui/source/options/optaccessibility.hxx | 9 cui/uiconfig/ui/optaccessibilitypage.ui | 113 ++++ filter/source/pdf/impdialog.cxx | 8 include/sfx2/AccessibilityIssue.hxx | 21 officecfg/registry/schema/org/openoffice/Office/Common.xcs | 305 +++++++++++ sfx2/source/accessibility/AccessibilityIssue.cxx | 1 sw/source/core/access/AccessibilityCheck.cxx | 241 ++++++++- sw/source/core/inc/AccessibilityIssue.hxx | 2 sw/source/uibase/sidebar/A11yCheckIssuesPanel.cxx | 67 +- sw/source/uibase/sidebar/A11yCheckIssuesPanel.hxx | 4 sw/uiconfig/swriter/ui/a11ycheckissuespanel.ui | 64 ++ 13 files changed, 1177 insertions(+), 37 deletions(-)
New commits: commit 33ea719d6c6ad23dfca088853d95d5688782da2d Author: Balazs Varga <balazs.varga.ext...@allotropia.de> AuthorDate: Thu Jul 4 17:33:34 2024 +0200 Commit: Balazs Varga <balazs.varga.ext...@allotropia.de> CommitDate: Thu Jul 25 17:44:22 2024 +0200 tdf#157233 - A11y: Add global Accessibility check options for managing which a11y issue should be checked. In default mode all the a11y issues are checked. Change-Id: Ib01e7d76e74b0b9cc9df259295edbee135b1c8a2 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170324 Tested-by: Jenkins Reviewed-by: Balazs Varga <balazs.varga.ext...@allotropia.de> diff --git a/cui/inc/strings.hrc b/cui/inc/strings.hrc index 96f67c5fe8f3..9b10de8b4be1 100644 --- a/cui/inc/strings.hrc +++ b/cui/inc/strings.hrc @@ -401,4 +401,39 @@ // Translatable names of color schemes #define RID_COLOR_SCHEME_LIBREOFFICE_AUTOMATIC NC_("RID_COLOR_SCHEME_LIBREOFFICE_AUTOMATIC", "Automatic") +// A11Y Options +#define STR_NO_ALT_OLE NC_("STR_NO_ALT_OLE", "Check Ole Object have alternative name or discription") +#define STR_NO_ALT_GRAPHIC NC_("STR_NO_ALT_GRAPHIC", "Check Graphic Object have alternative name or discription") +#define STR_NO_ALT_SHAPE NC_("STR_NO_ALT_SHAPE", "Check Shape Object have alternative name or discription") +#define STR_LINKED_GRAPHIC NC_("STR_LINKED_GRAPHIC", "Check Graphic object referenced as “LINK”") +#define STR_TABLE_MERGE_SPLIT NC_("STR_TABLE_MERGE_SPLIT", "Check Table object contains merges or splits") +#define STR_FAKE_NUMBERING NC_("STR_FAKE_NUMBERING", "Check document contains simulated numbering") +#define STR_HYPERLINK_TEXT_IS_LINK NC_("STR_HYPERLINK_TEXT_IS_LINK", "Check hyperlink text is the same as the link address") +#define STR_HYPERLINK_TEXT_IS_SHORT NC_("STR_HYPERLINK_TEXT_IS_SHORT", "Check hyperlink text is too short") +#define STR_HYPERLINK_NO_NAME NC_("STR_HYPERLINK_NO_NAME", "Check hyperlink have alternative name set") +#define STR_TEXT_CONTRAST NC_("STR_TEXT_CONTRAST", "Check texts contrast is too low") +#define STR_TEXT_BLINKING NC_("STR_TEXT_BLINKING", "Check blinking texts") +#define STR_AVOID_FOOTNOTES NC_("STR_AVOID_FOOTNOTES", "Check document contains footnotes") +#define STR_AVOID_FAKE_FOOTNOTES NC_("STR_AVOID_FAKE_FOOTNOTES", "Check document contains simulated footnotes") +#define STR_AVOID_FAKE_CAPTIONS NC_("STR_AVOID_FAKE_CAPTIONS", "Check document contains simulated captions") +#define STR_AVOID_ENDNOTES NC_("STR_AVOID_ENDNOTES", "Check document contains endnotes") +#define STR_AVOID_BACKGROUND_IMAGES NC_("STR_AVOID_BACKGROUND_IMAGES", "Check document contains background images") +#define STR_AVOID_NEWLINES_SPACE NC_("STR_AVOID_NEWLINES_SPACE", "Check document contains newlines to create space") +#define STR_AVOID_SPACES_SPACE NC_("STR_AVOID_SPACES_SPACE", "Check document contains spaces to create space") +#define STR_AVOID_TABS_FORMATTING NC_("STR_AVOID_TABS_FORMATTING", "Check document contains tabs for formatting") +#define STR_HEADINGS_NOT_IN_ORDER NC_("STR_HEADINGS_NOT_IN_ORDER", "Check outline levels of headings not in sequential order") +#define STR_TEXT_FORMATTING_CONVEYS_MEAN NC_("STR_TEXT_FORMATTING_CONVEYS_MEANING", "Check document contains direct formattings") +#define STR_NON_INTERACTIVE_FORMS NC_("STR_NON_INTERACTIVE_FORMS", "Check document contains interactive input fields") +#define STR_FLOATING_TEXT NC_("STR_FLOATING_TEXT", "Check Frames/Text boxes anchored “As Character“") +#define STR_HEADING_IN_TABLE NC_("STR_HEADING_IN_TABLE", "Check tables contain headings") +#define STR_HEADING_ORDER NC_("STR_HEADING_ORDER", "Check heading order is correct") +#define STR_HEADING_START NC_("STR_HEADING_START", "Check heading order start with level 1") +#define STR_FONTWORKS NC_("STR_FONTWORKS", "Check document contains fontwork objects") +#define STR_TABLE_FORMATTING NC_("STR_TABLE_FORMATTING", "Check document contains empty table cells for formatting") +#define STR_CONTENT_CONTROL_IN_HEADER NC_("STR_CONTENT_CONTROL_IN_HEADER", "Check document contains content controls in header or footer") + +#define STR_DOCUMENT_DEFAULT_LANGUAGE NC_("STR_DOCUMENT_DEFAULT_LANGUAGE", "Check document default language is set") +#define STR_STYLE_NO_LANGUAGE NC_("STR_STYLE_NO_LANGUAGE", "Check styles have language set") +#define STR_DOCUMENT_TITLE NC_("STR_DOCUMENT_TITLE", "Check document title is set") + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/cui/source/options/optaccessibility.cxx b/cui/source/options/optaccessibility.cxx index dfb9d386bed8..de129b0ab2ba 100644 --- a/cui/source/options/optaccessibility.cxx +++ b/cui/source/options/optaccessibility.cxx @@ -18,9 +18,49 @@ */ #include "optaccessibility.hxx" +#include <strings.hrc> #include <vcl/settings.hxx> #include <vcl/svapp.hxx> #include <officecfg/Office/Common.hxx> +#include <unotools/resmgr.hxx> +#include <dialmgr.hxx> + +namespace +{ + // <Option ID, <AccessibilityIssueID, TranslateId>> + constexpr std::pair<OUString, std::pair<sfx::AccessibilityIssueID, TranslateId>> options_list[] { + { u"DocumentTitle"_ustr, { sfx::AccessibilityIssueID::DOCUMENT_TITLE, STR_DOCUMENT_TITLE } }, + { u"DocumentLanguage"_ustr, { sfx::AccessibilityIssueID::DOCUMENT_LANGUAGE, STR_DOCUMENT_DEFAULT_LANGUAGE } }, + { u"DocumentBackground"_ustr, { sfx::AccessibilityIssueID::DOCUMENT_LANGUAGE, STR_AVOID_BACKGROUND_IMAGES } }, + { u"DocumentStyleLanguage"_ustr, { sfx::AccessibilityIssueID::DOCUMENT_BACKGROUND, STR_STYLE_NO_LANGUAGE } }, + { u"LinkedGraphic"_ustr, { sfx::AccessibilityIssueID::LINKED_GRAPHIC, STR_LINKED_GRAPHIC } }, + { u"NoAltOleObj"_ustr, { sfx::AccessibilityIssueID::NO_ALT_OLE, STR_NO_ALT_OLE } }, + { u"NoAltGraphicObj"_ustr, { sfx::AccessibilityIssueID::NO_ALT_GRAPHIC, STR_NO_ALT_GRAPHIC } }, + { u"NoAltShapeObj"_ustr, { sfx::AccessibilityIssueID::NO_ALT_SHAPE, STR_NO_ALT_SHAPE } }, + { u"TextFormattings"_ustr, { sfx::AccessibilityIssueID::TEXT_FORMATTING, STR_AVOID_NEWLINES_SPACE } }, + { u"DirectFormattings"_ustr, { sfx::AccessibilityIssueID::DIRECT_FORMATTING, STR_TEXT_FORMATTING_CONVEYS_MEAN } }, + { u"TableFormattings"_ustr, { sfx::AccessibilityIssueID::TABLE_FORMATTING, STR_TABLE_FORMATTING } }, + { u"TableMergeSplit"_ustr, { sfx::AccessibilityIssueID::TABLE_MERGE_SPLIT, STR_TABLE_MERGE_SPLIT } }, + { u"HyperlinkText"_ustr, { sfx::AccessibilityIssueID::HYPERLINK_IS_TEXT, STR_HYPERLINK_TEXT_IS_LINK } }, + { u"HyperlinkShort"_ustr, { sfx::AccessibilityIssueID::HYPERLINK_SHORT, STR_HYPERLINK_TEXT_IS_SHORT } }, + { u"HyperlinkNoName"_ustr, { sfx::AccessibilityIssueID::HYPERLINK_NO_NAME, STR_HYPERLINK_NO_NAME } }, + { u"FakeFootnotes"_ustr, { sfx::AccessibilityIssueID::FAKE_FOOTNOTE, STR_AVOID_FAKE_FOOTNOTES } }, + { u"FakeCaptions"_ustr, { sfx::AccessibilityIssueID::FAKE_CAPTION, STR_AVOID_FAKE_CAPTIONS } }, + { u"ManualNumbering"_ustr, { sfx::AccessibilityIssueID::MANUAL_NUMBERING, STR_FAKE_NUMBERING } }, + { u"TextContrast"_ustr, { sfx::AccessibilityIssueID::TEXT_CONTRAST, STR_TEXT_CONTRAST } }, + { u"TextBlinking"_ustr, { sfx::AccessibilityIssueID::TEXT_BLINKING, STR_TEXT_BLINKING } }, + { u"HeadingNotInOrder"_ustr, { sfx::AccessibilityIssueID::HEADINGS_NOT_IN_ORDER, STR_HEADINGS_NOT_IN_ORDER } }, + { u"NonInteractiveForms"_ustr, { sfx::AccessibilityIssueID::NON_INTERACTIVE_FORMS, STR_NON_INTERACTIVE_FORMS } }, + { u"Floatingtext"_ustr, { sfx::AccessibilityIssueID::FLOATING_TEXT, STR_FLOATING_TEXT } }, + { u"HeadingTable"_ustr, { sfx::AccessibilityIssueID::HEADING_IN_TABLE, STR_HEADING_IN_TABLE } }, + { u"HeadingStart"_ustr, { sfx::AccessibilityIssueID::HEADING_START, STR_HEADING_START } }, + { u"HeadingOrder"_ustr, { sfx::AccessibilityIssueID::HEADING_ORDER, STR_HEADING_ORDER } }, + { u"ContentControl"_ustr, { sfx::AccessibilityIssueID::CONTENT_CONTROL, STR_CONTENT_CONTROL_IN_HEADER } }, + { u"AvoidFootnotes"_ustr, { sfx::AccessibilityIssueID::AVOID_FOOTNOTES, STR_AVOID_FOOTNOTES } }, + { u"AvoidEndnotes"_ustr, { sfx::AccessibilityIssueID::AVOID_ENDNOTES, STR_AVOID_ENDNOTES } }, + { u"FontWorks"_ustr, { sfx::AccessibilityIssueID::FONTWORKS, STR_FONTWORKS } }, + }; +} SvxAccessibilityOptionsTabPage::SvxAccessibilityOptionsTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet) @@ -39,11 +79,25 @@ SvxAccessibilityOptionsTabPage::SvxAccessibilityOptionsTabPage(weld::Container* , m_xAutomaticFontColorImg(m_xBuilder->weld_widget(u"lockautofontcolor"_ustr)) , m_xPagePreviews(m_xBuilder->weld_check_button(u"systempagepreviewcolor"_ustr)) , m_xPagePreviewsImg(m_xBuilder->weld_widget(u"locksystempagepreviewcolor"_ustr)) + , m_xOptionsLB(m_xBuilder->weld_tree_view(u"options"_ustr)) + , m_xDefaultPB(m_xBuilder->weld_button(u"default"_ustr)) { #ifdef UNX // UNIX: read the gconf2 setting instead to use the checkbox m_xAccessibilityTool->hide(); #endif + + m_xOptionsLB->enable_toggle_buttons(weld::ColumnToggleType::Check); + + auto pos = m_xOptionsLB->make_iterator(); + for (const auto& [compatId, a11yId] : options_list) + { + m_xOptionsLB->append(pos.get()); + m_xOptionsLB->set_id(*pos, compatId); + m_xOptionsLB->set_text(*pos, CuiResId(a11yId.second), 0); + } + + m_xDefaultPB->connect_clicked(LINK(this, SvxAccessibilityOptionsTabPage, UseAsDefaultHdl)); } SvxAccessibilityOptionsTabPage::~SvxAccessibilityOptionsTabPage() @@ -93,6 +147,146 @@ bool SvxAccessibilityOptionsTabPage::FillItemSet( SfxItemSet* ) officecfg::Office::Common::Accessibility::IsSelectionInReadonly::set(m_xTextSelectionInReadonly->get_active(), batch); if ( !officecfg::Office::Common::Accessibility::HighContrast::isReadOnly() ) officecfg::Office::Common::Accessibility::HighContrast::set(m_xHighContrast->get_active(), batch); + + const int nCount = m_xOptionsLB->n_children(); + for (int i = 0; i < nCount; ++i) + { + OUString option = m_xOptionsLB->get_id(i); + const auto& aIssues = std::find_if( + std::begin(options_list), std::end(options_list), + [option](const auto& p) { return p.first == option; })->second; + TriState const current = m_xOptionsLB->get_toggle(i); + TriState saved = m_aSavedOptions[aIssues.first]; + if (current != saved) + { + bool const bChecked(current != TRISTATE_FALSE); + switch (aIssues.first) + { + case sfx::AccessibilityIssueID::DOCUMENT_TITLE: + officecfg::Office::Common::AccessibilityIssues::DocumentTitle::set(bChecked, batch); + break; + + case sfx::AccessibilityIssueID::DOCUMENT_LANGUAGE: + officecfg::Office::Common::AccessibilityIssues::DocumentLanguage::set(bChecked, batch); + break; + + case sfx::AccessibilityIssueID::DOCUMENT_BACKGROUND: + officecfg::Office::Common::AccessibilityIssues::DocumentBackground::set(bChecked, batch); + break; + + case sfx::AccessibilityIssueID::STYLE_LANGUAGE: + officecfg::Office::Common::AccessibilityIssues::DocumentStyleLanguage::set(bChecked, batch); + break; + + case sfx::AccessibilityIssueID::LINKED_GRAPHIC: + officecfg::Office::Common::AccessibilityIssues::LinkedGraphic::set(bChecked, batch); + break; + + case sfx::AccessibilityIssueID::NO_ALT_OLE: + officecfg::Office::Common::AccessibilityIssues::NoAltOleObj::set(bChecked, batch); + break; + + case sfx::AccessibilityIssueID::NO_ALT_GRAPHIC: + officecfg::Office::Common::AccessibilityIssues::NoAltGraphicObj::set(bChecked, batch); + break; + + case sfx::AccessibilityIssueID::NO_ALT_SHAPE: + officecfg::Office::Common::AccessibilityIssues::NoAltShapeObj::set(bChecked, batch); + break; + + case sfx::AccessibilityIssueID::TEXT_FORMATTING: + officecfg::Office::Common::AccessibilityIssues::TextFormattings::set(bChecked, batch); + break; + + case sfx::AccessibilityIssueID::DIRECT_FORMATTING: + officecfg::Office::Common::AccessibilityIssues::DirectFormattings::set(bChecked, batch); + break; + + case sfx::AccessibilityIssueID::TABLE_FORMATTING: + officecfg::Office::Common::AccessibilityIssues::TableFormattings::set(bChecked, batch); + break; + + case sfx::AccessibilityIssueID::TABLE_MERGE_SPLIT: + officecfg::Office::Common::AccessibilityIssues::TableMergeSplit::set(bChecked, batch); + break; + + case sfx::AccessibilityIssueID::HYPERLINK_IS_TEXT: + officecfg::Office::Common::AccessibilityIssues::HyperlinkText::set(bChecked, batch); + break; + + case sfx::AccessibilityIssueID::HYPERLINK_SHORT: + officecfg::Office::Common::AccessibilityIssues::HyperlinkShort::set(bChecked, batch); + break; + + case sfx::AccessibilityIssueID::HYPERLINK_NO_NAME: + officecfg::Office::Common::AccessibilityIssues::HyperlinkNoName::set(bChecked, batch); + break; + + case sfx::AccessibilityIssueID::FAKE_FOOTNOTE: + officecfg::Office::Common::AccessibilityIssues::FakeFootnotes::set(bChecked, batch); + break; + + case sfx::AccessibilityIssueID::FAKE_CAPTION: + officecfg::Office::Common::AccessibilityIssues::FakeCaptions::set(bChecked, batch); + break; + + case sfx::AccessibilityIssueID::MANUAL_NUMBERING: + officecfg::Office::Common::AccessibilityIssues::ManualNumbering::set(bChecked, batch); + break; + + case sfx::AccessibilityIssueID::TEXT_CONTRAST: + officecfg::Office::Common::AccessibilityIssues::TextContrast::set(bChecked, batch); + break; + + case sfx::AccessibilityIssueID::TEXT_BLINKING: + officecfg::Office::Common::AccessibilityIssues::TextBlinking::set(bChecked, batch); + break; + + case sfx::AccessibilityIssueID::HEADINGS_NOT_IN_ORDER: + officecfg::Office::Common::AccessibilityIssues::HeadingNotInOrder::set(bChecked, batch); + break; + + case sfx::AccessibilityIssueID::NON_INTERACTIVE_FORMS: + officecfg::Office::Common::AccessibilityIssues::NonInteractiveForms::set(bChecked, batch); + break; + + case sfx::AccessibilityIssueID::FLOATING_TEXT: + officecfg::Office::Common::AccessibilityIssues::Floatingtext::set(bChecked, batch); + break; + + case sfx::AccessibilityIssueID::HEADING_IN_TABLE: + officecfg::Office::Common::AccessibilityIssues::HeadingTable::set(bChecked, batch); + break; + + case sfx::AccessibilityIssueID::HEADING_START: + officecfg::Office::Common::AccessibilityIssues::HeadingStart::set(bChecked, batch); + break; + + case sfx::AccessibilityIssueID::HEADING_ORDER: + officecfg::Office::Common::AccessibilityIssues::HeadingOrder::set(bChecked, batch); + break; + + case sfx::AccessibilityIssueID::CONTENT_CONTROL: + officecfg::Office::Common::AccessibilityIssues::ContentControl::set(bChecked, batch); + break; + + case sfx::AccessibilityIssueID::AVOID_FOOTNOTES: + officecfg::Office::Common::AccessibilityIssues::AvoidFootnotes::set(bChecked, batch); + break; + + case sfx::AccessibilityIssueID::AVOID_ENDNOTES: + officecfg::Office::Common::AccessibilityIssues::AvoidEndnotes::set(bChecked, batch); + break; + + case sfx::AccessibilityIssueID::FONTWORKS: + officecfg::Office::Common::AccessibilityIssues::FontWorks::set(bChecked, batch); + break; + + default: + break; + } + } + } batch->commit(); AllSettings aAllSettings = Application::GetSettings(); @@ -152,9 +346,159 @@ void SvxAccessibilityOptionsTabPage::Reset( const SfxItemSet* ) m_xHighContrastImg->set_visible(true); } + m_aSavedOptions.clear(); + const sal_Int32 nCount = m_xOptionsLB->n_children(); + for (sal_Int32 i = 0; i < nCount; ++i) + { + OUString option = m_xOptionsLB->get_id(i); + const auto& aIssues = std::find_if( + std::begin(options_list), std::end(options_list), + [option](const auto& p) { return p.first == option; })->second; + bool bChecked = true; + switch (aIssues.first) + { + case sfx::AccessibilityIssueID::DOCUMENT_TITLE: + bChecked = officecfg::Office::Common::AccessibilityIssues::DocumentTitle::get(); + break; + + case sfx::AccessibilityIssueID::DOCUMENT_LANGUAGE: + bChecked = officecfg::Office::Common::AccessibilityIssues::DocumentLanguage::get(); + break; + + case sfx::AccessibilityIssueID::DOCUMENT_BACKGROUND: + bChecked = officecfg::Office::Common::AccessibilityIssues::DocumentBackground::get(); + break; + + case sfx::AccessibilityIssueID::STYLE_LANGUAGE: + bChecked = officecfg::Office::Common::AccessibilityIssues::DocumentStyleLanguage::get(); + break; + + case sfx::AccessibilityIssueID::LINKED_GRAPHIC: + bChecked = officecfg::Office::Common::AccessibilityIssues::LinkedGraphic::get(); + break; + + case sfx::AccessibilityIssueID::NO_ALT_OLE: + bChecked = officecfg::Office::Common::AccessibilityIssues::NoAltOleObj::get(); + break; + + case sfx::AccessibilityIssueID::NO_ALT_GRAPHIC: + bChecked = officecfg::Office::Common::AccessibilityIssues::NoAltGraphicObj::get(); + break; + + case sfx::AccessibilityIssueID::NO_ALT_SHAPE: + bChecked = officecfg::Office::Common::AccessibilityIssues::NoAltShapeObj::get(); + break; + + case sfx::AccessibilityIssueID::TEXT_FORMATTING: + bChecked = officecfg::Office::Common::AccessibilityIssues::TextFormattings::get(); + break; + + case sfx::AccessibilityIssueID::DIRECT_FORMATTING: + bChecked = officecfg::Office::Common::AccessibilityIssues::DirectFormattings::get(); + break; + + case sfx::AccessibilityIssueID::TABLE_MERGE_SPLIT: + bChecked = officecfg::Office::Common::AccessibilityIssues::TableMergeSplit::get(); + break; + + case sfx::AccessibilityIssueID::TABLE_FORMATTING: + bChecked = officecfg::Office::Common::AccessibilityIssues::TableFormattings::get(); + break; + + case sfx::AccessibilityIssueID::HYPERLINK_IS_TEXT: + bChecked = officecfg::Office::Common::AccessibilityIssues::HyperlinkText::get(); + break; + + case sfx::AccessibilityIssueID::HYPERLINK_SHORT: + bChecked = officecfg::Office::Common::AccessibilityIssues::HyperlinkShort::get(); + break; + + case sfx::AccessibilityIssueID::HYPERLINK_NO_NAME: + bChecked = officecfg::Office::Common::AccessibilityIssues::HyperlinkNoName::get(); + break; + + case sfx::AccessibilityIssueID::FAKE_FOOTNOTE: + bChecked = officecfg::Office::Common::AccessibilityIssues::FakeFootnotes::get(); + break; + + case sfx::AccessibilityIssueID::FAKE_CAPTION: + bChecked = officecfg::Office::Common::AccessibilityIssues::FakeCaptions::get(); + break; + + case sfx::AccessibilityIssueID::MANUAL_NUMBERING: + bChecked = officecfg::Office::Common::AccessibilityIssues::ManualNumbering::get(); + break; + + case sfx::AccessibilityIssueID::TEXT_CONTRAST: + bChecked = officecfg::Office::Common::AccessibilityIssues::TextContrast::get(); + break; + + case sfx::AccessibilityIssueID::TEXT_BLINKING: + bChecked = officecfg::Office::Common::AccessibilityIssues::TextBlinking::get(); + break; + + case sfx::AccessibilityIssueID::HEADINGS_NOT_IN_ORDER: + bChecked = officecfg::Office::Common::AccessibilityIssues::HeadingNotInOrder::get(); + break; + + case sfx::AccessibilityIssueID::NON_INTERACTIVE_FORMS: + bChecked = officecfg::Office::Common::AccessibilityIssues::NonInteractiveForms::get(); + break; + + case sfx::AccessibilityIssueID::FLOATING_TEXT: + bChecked = officecfg::Office::Common::AccessibilityIssues::Floatingtext::get(); + break; + + case sfx::AccessibilityIssueID::HEADING_IN_TABLE: + bChecked = officecfg::Office::Common::AccessibilityIssues::HeadingTable::get(); + break; + + case sfx::AccessibilityIssueID::HEADING_START: + bChecked = officecfg::Office::Common::AccessibilityIssues::HeadingStart::get(); + break; + + case sfx::AccessibilityIssueID::HEADING_ORDER: + bChecked = officecfg::Office::Common::AccessibilityIssues::HeadingOrder::get(); + break; + + case sfx::AccessibilityIssueID::CONTENT_CONTROL: + bChecked = officecfg::Office::Common::AccessibilityIssues::ContentControl::get(); + break; + + case sfx::AccessibilityIssueID::AVOID_FOOTNOTES: + bChecked = officecfg::Office::Common::AccessibilityIssues::AvoidFootnotes::get(); + break; + + case sfx::AccessibilityIssueID::AVOID_ENDNOTES: + bChecked = officecfg::Office::Common::AccessibilityIssues::AvoidEndnotes::get(); + break; + + case sfx::AccessibilityIssueID::FONTWORKS: + bChecked = officecfg::Office::Common::AccessibilityIssues::FontWorks::get(); + break; + + default: + break; + } + + TriState value = bChecked ? TRISTATE_TRUE : TRISTATE_FALSE; + m_xOptionsLB->set_toggle(i, value); + m_aSavedOptions[aIssues.first] = value; + } + AllSettings aAllSettings = Application::GetSettings(); const MiscSettings& aMiscSettings = aAllSettings.GetMiscSettings(); m_xAccessibilityTool->set_active(aMiscSettings.GetEnableATToolSupport()); } +IMPL_LINK_NOARG(SvxAccessibilityOptionsTabPage, UseAsDefaultHdl, weld::Button&, void) +{ + const int nCount = m_xOptionsLB->n_children(); + for (int i = 0; i < nCount; ++i) + { + m_xOptionsLB->set_toggle(i, TRISTATE_TRUE); + } + m_aSavedOptions.clear(); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/cui/source/options/optaccessibility.hxx b/cui/source/options/optaccessibility.hxx index 73fe167c1679..7ce308155b15 100644 --- a/cui/source/options/optaccessibility.hxx +++ b/cui/source/options/optaccessibility.hxx @@ -19,6 +19,8 @@ #pragma once #include <sfx2/tabdlg.hxx> +#include <sfx2/AccessibilityIssue.hxx> +#include <map> class SvxAccessibilityOptionsTabPage : public SfxTabPage { @@ -36,6 +38,13 @@ class SvxAccessibilityOptionsTabPage : public SfxTabPage std::unique_ptr<weld::Widget> m_xAutomaticFontColorImg; std::unique_ptr<weld::CheckButton> m_xPagePreviews; std::unique_ptr<weld::Widget> m_xPagePreviewsImg; + std::unique_ptr<weld::TreeView> m_xOptionsLB; + std::unique_ptr<weld::Button> m_xDefaultPB; + + // saved options after "Reset"; used in "FillItemSet" for comparison + std::map<sfx::AccessibilityIssueID, TriState> m_aSavedOptions; + + DECL_LINK(UseAsDefaultHdl, weld::Button&, void); public: SvxAccessibilityOptionsTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet); diff --git a/cui/uiconfig/ui/optaccessibilitypage.ui b/cui/uiconfig/ui/optaccessibilitypage.ui index 2cae4b5267ea..8106611b0a43 100644 --- a/cui/uiconfig/ui/optaccessibilitypage.ui +++ b/cui/uiconfig/ui/optaccessibilitypage.ui @@ -334,6 +334,119 @@ <property name="position">1</property> </packing> </child> + <child> + <object class="GtkFrame" id="compatframe"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="hexpand">True</property> + <property name="vexpand">True</property> + <property name="label-xalign">0</property> + <property name="shadow-type">none</property> + <child> + <!-- n-columns=1 n-rows=2 --> + <object class="GtkGrid" id="grid2"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="margin-start">12</property> + <property name="margin-top">6</property> + <property name="hexpand">True</property> + <property name="vexpand">True</property> + <property name="row-spacing">5</property> + <child> + <object class="GtkScrolledWindow" id="optionsscroll"> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="hexpand">True</property> + <property name="vexpand">True</property> + <property name="shadow-type">in</property> + <child> + <object class="GtkTreeView" id="options"> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">True</property> + <property name="hexpand">True</property> + <property name="vexpand">True</property> + <property name="model">liststore1</property> + <property name="headers-visible">False</property> + <property name="search-column">0</property> + <property name="show-expanders">False</property> + <child internal-child="selection"> + <object class="GtkTreeSelection"/> + </child> + <child> + <object class="GtkTreeViewColumn" id="treeviewcolumn4"> + <property name="resizable">True</property> + <property name="spacing">6</property> + <property name="alignment">0.5</property> + <child> + <object class="GtkCellRendererToggle" id="cellrenderer5"/> + <attributes> + <attribute name="visible">3</attribute> + <attribute name="active">0</attribute> + <attribute name="inconsistent">4</attribute> + </attributes> + </child> + </object> + </child> + <child> + <object class="GtkTreeViewColumn" id="treeviewcolumn5"> + <property name="resizable">True</property> + <property name="spacing">6</property> + <child> + <object class="GtkCellRendererText" id="cellrenderer4"/> + <attributes> + <attribute name="sensitive">6</attribute> + <attribute name="text">1</attribute> + </attributes> + </child> + </object> + </child> + </object> + </child> + </object> + <packing> + <property name="left-attach">0</property> + <property name="top-attach">0</property> + </packing> + </child> + <child> + <object class="GtkButton" id="default"> + <property name="label" translatable="yes" context="optcompatpage|default">Enable _all</property> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">True</property> + <property name="halign">end</property> + <property name="use-underline">True</property> + <child internal-child="accessible"> + <object class="AtkObject" id="default-atkobject"> + <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|default">Click to enable all the Accessibility check options.</property> + </object> + </child> + </object> + <packing> + <property name="left-attach">0</property> + <property name="top-attach">1</property> + </packing> + </child> + </object> + </child> + <child type="label"> + <object class="GtkLabel" id="label11"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="label" translatable="yes" context="optaccessibilitypage|label11">Online Accessibility Check Options</property> + <attributes> + <attribute name="weight" value="bold"/> + </attributes> + </object> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">2</property> + </packing> + </child> <child internal-child="accessible"> <object class="AtkObject" id="OptAccessibilityPage-atkobject"> <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|OptAccessibilityPage">Sets options that make the office suite programs more accessible for users with reduced sight, limited dexterity or other disabilities.</property> diff --git a/filter/source/pdf/impdialog.cxx b/filter/source/pdf/impdialog.cxx index 7c12d439fedb..ae822ad7a720 100644 --- a/filter/source/pdf/impdialog.cxx +++ b/filter/source/pdf/impdialog.cxx @@ -337,7 +337,13 @@ IMPL_LINK_NOARG(ImpPDFTabDialog, OkHdl, weld::Button&, void) if (pShell) { sfx::AccessibilityIssueCollection aCollection = pShell->runAccessibilityCheck(); - const int nIssueCount(aCollection.getIssues().size()); + auto& aIssues = aCollection.getIssues(); + const int nIssueCount = std::count_if(aIssues.begin(), aIssues.end(), + [](const std::shared_ptr<sfx::AccessibilityIssue >& pIssues) + { + return !pIssues->getHidden(); + }); + if (nIssueCount) { OUString aMessage(FilterResId(STR_WARN_PDFUA_ISSUES, nIssueCount)); diff --git a/include/sfx2/AccessibilityIssue.hxx b/include/sfx2/AccessibilityIssue.hxx index 1533159c42f8..1aae578822f4 100644 --- a/include/sfx2/AccessibilityIssue.hxx +++ b/include/sfx2/AccessibilityIssue.hxx @@ -22,7 +22,6 @@ namespace sfx { enum class AccessibilityIssueID { - UNSPECIFIED, // TODO: remove - temporary DOCUMENT_TITLE, DOCUMENT_LANGUAGE, DOCUMENT_BACKGROUND, @@ -40,13 +39,25 @@ enum class AccessibilityIssueID HYPERLINK_NO_NAME, FAKE_FOOTNOTE, FAKE_CAPTION, - MANUAL_NUMBERING + MANUAL_NUMBERING, + TEXT_CONTRAST, + TEXT_BLINKING, + HEADINGS_NOT_IN_ORDER, + NON_INTERACTIVE_FORMS, + FLOATING_TEXT, + HEADING_IN_TABLE, + HEADING_START, + HEADING_ORDER, + CONTENT_CONTROL, + AVOID_FOOTNOTES, + AVOID_ENDNOTES, + FONTWORKS, }; class SFX2_DLLPUBLIC AccessibilityIssue { public: - AccessibilityIssue(AccessibilityIssueID eIssueID = AccessibilityIssueID::UNSPECIFIED); + AccessibilityIssue(AccessibilityIssueID eIssueID); AccessibilityIssue(AccessibilityIssue const&) = default; virtual ~AccessibilityIssue(); @@ -58,10 +69,14 @@ public: void setParent(weld::Window* pParent) { m_pParent = pParent; } + void setHidden(bool bHidden) { m_bHidden = bHidden; } + bool getHidden() const { return m_bHidden; } + AccessibilityIssue& operator=(const AccessibilityIssue&) = default; AccessibilityIssueID m_eIssueID; OUString m_aIssueText; + bool m_bHidden; weld::Window* m_pParent; }; diff --git a/officecfg/registry/schema/org/openoffice/Office/Common.xcs b/officecfg/registry/schema/org/openoffice/Office/Common.xcs index 01482b557274..d55a89369c25 100644 --- a/officecfg/registry/schema/org/openoffice/Office/Common.xcs +++ b/officecfg/registry/schema/org/openoffice/Office/Common.xcs @@ -6130,6 +6130,311 @@ <value>false</value> </prop> </group> + <group oor:name="AccessibilityIssues"> + <info> + <desc>Specifies settings for the accessibility options.</desc> + </info> + <prop oor:name="DocumentTitle" oor:type="xs:boolean" oor:nillable="false"> + <info> + <desc> + Enables accessibility check of Document Title, inside the document structure + while the user edits the document. + </desc> + <label>Enable/Disable Document Title accessibility check.</label> + </info> + <value>true</value> + </prop> + <prop oor:name="DocumentLanguage" oor:type="xs:boolean" oor:nillable="false"> + <info> + <desc> + Enables accessibility check of Document Language, inside the document structure + while the user edits the document. + </desc> + <label>Enable/Disable Document Language accessibility check.</label> + </info> + <value>true</value> + </prop> + <prop oor:name="DocumentBackground" oor:type="xs:boolean" oor:nillable="false"> + <info> + <desc> + Enables accessibility check of Document Background, inside the document structure + while the user edits the document. + </desc> + <label>Enable/Disable Document Background accessibility check.</label> + </info> + <value>true</value> + </prop> + <prop oor:name="DocumentStyleLanguage" oor:type="xs:boolean" oor:nillable="false"> + <info> + <desc> + Enables accessibility check of Document Style Language, inside the document structure + while the user edits the document. + </desc> + <label>Enable/Disable Document Style Language accessibility check.</label> + </info> + <value>true</value> + </prop> + <prop oor:name="LinkedGraphic" oor:type="xs:boolean" oor:nillable="false"> + <info> + <desc> + Enables accessibility check of Linked Graphic objects, inside the document structure + while the user edits the document. + </desc> + <label>Enable/Disable Linked Graphic objects accessibility check.</label> + </info> + <value>true</value> + </prop> + <prop oor:name="NoAltOleObj" oor:type="xs:boolean" oor:nillable="false"> + <info> + <desc> + Enables accessibility check of Alternative Text of OLE_Objects, inside the document structure + while the user edits the document. + </desc> + <label>Enable/Disable Alternative Text of OLE_Objects accessibility check.</label> + </info> + <value>true</value> + </prop> + <prop oor:name="NoAltGraphicObj" oor:type="xs:boolean" oor:nillable="false"> + <info> + <desc> + Enables accessibility check of Alternative Text of Graphic Objects, inside the document structure + while the user edits the document. + </desc> + <label>Enable/Disable Alternative Text of Graphic Objects accessibility check.</label> + </info> + <value>true</value> + </prop> + <prop oor:name="NoAltShapeObj" oor:type="xs:boolean" oor:nillable="false"> + <info> + <desc> + Enables accessibility check of Alternative Text of Shape Objects, inside the document structure + while the user edits the document. + </desc> + <label>Enable/Disable Alternative Text of Shape Objects accessibility check.</label> + </info> + <value>true</value> + </prop> + <prop oor:name="TableMergeSplit" oor:type="xs:boolean" oor:nillable="false"> + <info> + <desc> + Enables accessibility check of merges or splits in Tables, inside the document structure + while the user edits the document. + </desc> + <label>Enable/Disable merges or splits in Tables accessibility check.</label> + </info> + <value>true</value> + </prop> + <prop oor:name="TextFormattings" oor:type="xs:boolean" oor:nillable="false"> + <info> + <desc> + Enables accessibility check of Text formattings, inside the document structure + while the user edits the document. + </desc> + <label>Enable/Disable Text formattings accessibility check.</label> + </info> + <value>true</value> + </prop> + <prop oor:name="DirectFormattings" oor:type="xs:boolean" oor:nillable="false"> + <info> + <desc> + Enables accessibility check of Direct formattings, inside the document structure + while the user edits the document. + </desc> + <label>Enable/Disable Direct formattings accessibility check.</label> + </info> + <value>true</value> + </prop> + <prop oor:name="TableFormattings" oor:type="xs:boolean" oor:nillable="false"> + <info> + <desc> + Enables accessibility check of Table formattings, inside the document structure + while the user edits the document. + </desc> + <label>Enable/Disable Text formattings accessibility check.</label> + </info> + <value>true</value> + </prop> + <prop oor:name="HyperlinkText" oor:type="xs:boolean" oor:nillable="false"> + <info> + <desc> + Enables accessibility check of Hyperlink texts, inside the document structure + while the user edits the document. + </desc> + <label>Enable/Disable hyperlink texts accessibility check.</label> + </info> + <value>true</value> + </prop> + <prop oor:name="HyperlinkShort" oor:type="xs:boolean" oor:nillable="false"> + <info> + <desc> + Enables accessibility check of short hyperlinks, inside the document structure + while the user edits the document. + </desc> + <label>Enable/Disable short hyperlinks accessibility check.</label> + </info> + <value>true</value> + </prop> + <prop oor:name="HyperlinkNoName" oor:type="xs:boolean" oor:nillable="false"> + <info> + <desc> + Enables accessibility check of missing hyperlink name, inside the document structure + while the user edits the document. + </desc> + <label>Enable/Disable missing hyperlink name accessibility check.</label> + </info> + <value>true</value> + </prop> + <prop oor:name="FakeFootnotes" oor:type="xs:boolean" oor:nillable="false"> + <info> + <desc> + Enables accessibility check of simulated footnotes, inside the document structure + while the user edits the document. + </desc> + <label>Enable/Disable simulated footnotes accessibility check.</label> + </info> + <value>true</value> + </prop> + <prop oor:name="FakeCaptions" oor:type="xs:boolean" oor:nillable="false"> + <info> + <desc> + Enables accessibility check of simulated captions, inside the document structure + while the user edits the document. + </desc> + <label>Enable/Disable simulated captions accessibility check.</label> + </info> + <value>true</value> + </prop> + <prop oor:name="ManualNumbering" oor:type="xs:boolean" oor:nillable="false"> + <info> + <desc> + Enables accessibility check of simulated numbering, inside the document structure + while the user edits the document. + </desc> + <label>Enable/Disable simulated numbering accessibility check.</label> + </info> + <value>true</value> + </prop> + <prop oor:name="TextContrast" oor:type="xs:boolean" oor:nillable="false"> + <info> + <desc> + Enables accessibility check texts contrast is too low, inside the document structure + while the user edits the document. + </desc> + <label>Enable/Disable texts contrast is too low accessibility check.</label> + </info> + <value>true</value> + </prop> + <prop oor:name="TextBlinking" oor:type="xs:boolean" oor:nillable="false"> + <info> + <desc> + Enables accessibility check of blinking texts, inside the document structure + while the user edits the document. + </desc> + <label>Enable/Disable blinking texts accessibility issues.</label> + </info> + <value>true</value> + </prop> + <prop oor:name="HeadingNotInOrder" oor:type="xs:boolean" oor:nillable="false"> + <info> + <desc> + Enables accessibility check of outline levels of headings not in sequential order, + inside the document structure while the user edits the document. + </desc> + <label>Enable/Disable outline levels of headings not in sequential order accessibility issues.</label> + </info> + <value>true</value> + </prop> + <prop oor:name="NonInteractiveForms" oor:type="xs:boolean" oor:nillable="false"> + <info> + <desc> + Enables accessibility check of non interactive input fields, inside the document structure + while the user edits the document. + </desc> + <label>Enable/Disable accessibility check of non interactive input fields accessibility issues.</label> + </info> + <value>true</value> + </prop> + <prop oor:name="Floatingtext" oor:type="xs:boolean" oor:nillable="false"> + <info> + <desc> + Enables accessibility check of Frames/Text boxes anchored “As Character“, inside the document structure + while the user edits the document. + </desc> + <label>Enable/Disable Frames, Text boxes anchored “As Character“ accessibility issues.</label> + </info> + <value>true</value> + </prop> + <prop oor:name="HeadingTable" oor:type="xs:boolean" oor:nillable="false"> + <info> + <desc> + Enables accessibility check of tables contain headings, inside the document structure + while the user edits the document. + </desc> + <label>Enable/Disable tables contain headings accessibility issues.</label> + </info> + <value>true</value> + </prop> + <prop oor:name="HeadingStart" oor:type="xs:boolean" oor:nillable="false"> + <info> + <desc> + Enables accessibility check of heading order start with level 1, inside the document structure + while the user edits the document. + </desc> + <label>Enable/Disable heading order start with level 1 accessibility issues.</label> + </info> + <value>true</value> + </prop> + <prop oor:name="HeadingOrder" oor:type="xs:boolean" oor:nillable="false"> + <info> + <desc> + Enables accessibility check of heading order is correct, inside the document structure + while the user edits the document. + </desc> + <label>Enable/Disable heading order is correct accessibility issues.</label> + </info> + <value>true</value> + </prop> + <prop oor:name="ContentControl" oor:type="xs:boolean" oor:nillable="false"> + <info> + <desc> + Enables accessibility check of content controls in header or footer, inside the document structure + while the user edits the document. + </desc> + <label>Enable/Disable document contains content controls in header or footer accessibility issues.</label> + </info> + <value>true</value> + </prop> + <prop oor:name="AvoidFootnotes" oor:type="xs:boolean" oor:nillable="false"> + <info> + <desc> + Enables accessibility check of footnotes, inside the document structure + while the user edits the document. + </desc> + <label>Enable/Disable document contains footnotes accessibility issues.</label> + </info> + <value>true</value> + </prop> + <prop oor:name="AvoidEndnotes" oor:type="xs:boolean" oor:nillable="false"> + <info> + <desc> + Enables accessibility check of endnotes, inside the document structure + while the user edits the document. + </desc> + <label>Enable/Disable document contains endnotes accessibility issues.</label> + </info> + <value>true</value> + </prop> + <prop oor:name="FontWorks" oor:type="xs:boolean" oor:nillable="false"> + <info> + <desc> + Enables accessibility check of fontwork objects, inside the document structure + while the user edits the document. + </desc> + <label>Enable/Disable document contains fontwork objects accessibility issues.</label> + </info> + <value>true</value> + </prop> + </group> <group oor:name="ExternalMailer"> <info> <desc>Specifies an external mail application to be used for Send as diff --git a/sfx2/source/accessibility/AccessibilityIssue.cxx b/sfx2/source/accessibility/AccessibilityIssue.cxx index eba2c1931d85..44ff3adb1e8f 100644 --- a/sfx2/source/accessibility/AccessibilityIssue.cxx +++ b/sfx2/source/accessibility/AccessibilityIssue.cxx @@ -14,6 +14,7 @@ namespace sfx { AccessibilityIssue::AccessibilityIssue(AccessibilityIssueID eIssueID) : m_eIssueID(eIssueID) + , m_bHidden(false) , m_pParent(nullptr) { } diff --git a/sw/source/core/access/AccessibilityCheck.cxx b/sw/source/core/access/AccessibilityCheck.cxx index 429b94a02efb..0939c16091c6 100644 --- a/sw/source/core/access/AccessibilityCheck.cxx +++ b/sw/source/core/access/AccessibilityCheck.cxx @@ -24,6 +24,7 @@ #include <com/sun/star/text/XTextContent.hpp> #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp> #include <com/sun/star/style/XStyleFamiliesSupplier.hpp> +#include <officecfg/Office/Common.hxx> #include <unoparagraph.hxx> #include <unotools/intlwrapper.hxx> #include <tools/urlobj.hxx> @@ -73,12 +74,209 @@ SwTextNode* lclSearchNextTextNode(SwNode* pCurrent) return pTextNode; } +void lcl_SetHiddenIssues(std::shared_ptr<sw::AccessibilityIssue>& pIssue) +{ + switch (pIssue->m_eIssueID) + { + case sfx::AccessibilityIssueID::DOCUMENT_TITLE: + { + if (!officecfg::Office::Common::AccessibilityIssues::DocumentTitle::get()) + pIssue->setHidden(true); + } + break; + case sfx::AccessibilityIssueID::DOCUMENT_LANGUAGE: + { + if (!officecfg::Office::Common::AccessibilityIssues::DocumentLanguage::get()) + pIssue->setHidden(true); + } + break; + case sfx::AccessibilityIssueID::DOCUMENT_BACKGROUND: + { + if (!officecfg::Office::Common::AccessibilityIssues::DocumentBackground::get()) + pIssue->setHidden(true); + } + break; + case sfx::AccessibilityIssueID::STYLE_LANGUAGE: + { + if (!officecfg::Office::Common::AccessibilityIssues::DocumentStyleLanguage::get()) + pIssue->setHidden(true); + } + break; + case sfx::AccessibilityIssueID::LINKED_GRAPHIC: + { + if (!officecfg::Office::Common::AccessibilityIssues::LinkedGraphic::get()) + pIssue->setHidden(true); + } + break; + case sfx::AccessibilityIssueID::NO_ALT_OLE: + { + if (!officecfg::Office::Common::AccessibilityIssues::NoAltOleObj::get()) + pIssue->setHidden(true); + } + break; + case sfx::AccessibilityIssueID::NO_ALT_GRAPHIC: + { + if (!officecfg::Office::Common::AccessibilityIssues::NoAltGraphicObj::get()) + pIssue->setHidden(true); + } + break; + case sfx::AccessibilityIssueID::NO_ALT_SHAPE: + { + if (!officecfg::Office::Common::AccessibilityIssues::NoAltShapeObj::get()) + pIssue->setHidden(true); + } + break; + case sfx::AccessibilityIssueID::TABLE_MERGE_SPLIT: + { + if (!officecfg::Office::Common::AccessibilityIssues::TableMergeSplit::get()) + pIssue->setHidden(true); + } + break; + case sfx::AccessibilityIssueID::TEXT_FORMATTING: + { + if (!officecfg::Office::Common::AccessibilityIssues::TextFormattings::get()) + pIssue->setHidden(true); + } + break; + case sfx::AccessibilityIssueID::TABLE_FORMATTING: + { + if (!officecfg::Office::Common::AccessibilityIssues::TableFormattings::get()) + pIssue->setHidden(true); + } + break; + case sfx::AccessibilityIssueID::DIRECT_FORMATTING: + { + if (!officecfg::Office::Common::AccessibilityIssues::DirectFormattings::get()) + pIssue->setHidden(true); + } + break; + case sfx::AccessibilityIssueID::HYPERLINK_IS_TEXT: + { + if (!officecfg::Office::Common::AccessibilityIssues::HyperlinkText::get()) + pIssue->setHidden(true); + } + break; + case sfx::AccessibilityIssueID::HYPERLINK_SHORT: + { + if (!officecfg::Office::Common::AccessibilityIssues::HyperlinkShort::get()) + pIssue->setHidden(true); + } + break; + case sfx::AccessibilityIssueID::HYPERLINK_NO_NAME: + { + if (!officecfg::Office::Common::AccessibilityIssues::HyperlinkNoName::get()) + pIssue->setHidden(true); + } + break; + case sfx::AccessibilityIssueID::FAKE_FOOTNOTE: + { + if (!officecfg::Office::Common::AccessibilityIssues::FakeFootnotes::get()) + pIssue->setHidden(true); + } + break; + case sfx::AccessibilityIssueID::FAKE_CAPTION: + { + if (!officecfg::Office::Common::AccessibilityIssues::FakeCaptions::get()) + pIssue->setHidden(true); + } + break; + case sfx::AccessibilityIssueID::MANUAL_NUMBERING: + { + if (!officecfg::Office::Common::AccessibilityIssues::ManualNumbering::get()) + pIssue->setHidden(true); + } + break; + + case sfx::AccessibilityIssueID::TEXT_CONTRAST: + { + if (!officecfg::Office::Common::AccessibilityIssues::TextContrast::get()) + pIssue->setHidden(true); + } + break; + case sfx::AccessibilityIssueID::TEXT_BLINKING: + { + if (!officecfg::Office::Common::AccessibilityIssues::TextBlinking::get()) + pIssue->setHidden(true); + } + break; + case sfx::AccessibilityIssueID::HEADINGS_NOT_IN_ORDER: + { + if (!officecfg::Office::Common::AccessibilityIssues::HeadingNotInOrder::get()) + pIssue->setHidden(true); + } + break; + case sfx::AccessibilityIssueID::NON_INTERACTIVE_FORMS: + { + if (!officecfg::Office::Common::AccessibilityIssues::NonInteractiveForms::get()) + pIssue->setHidden(true); + } + break; + case sfx::AccessibilityIssueID::FLOATING_TEXT: + { + if (!officecfg::Office::Common::AccessibilityIssues::Floatingtext::get()) + pIssue->setHidden(true); + } + break; + case sfx::AccessibilityIssueID::HEADING_IN_TABLE: + { + if (!officecfg::Office::Common::AccessibilityIssues::HeadingTable::get()) + pIssue->setHidden(true); + } + break; + case sfx::AccessibilityIssueID::HEADING_START: + { + if (!officecfg::Office::Common::AccessibilityIssues::HeadingStart::get()) + pIssue->setHidden(true); + } + break; + case sfx::AccessibilityIssueID::HEADING_ORDER: + { + if (!officecfg::Office::Common::AccessibilityIssues::HeadingOrder::get()) + pIssue->setHidden(true); + } + break; + case sfx::AccessibilityIssueID::CONTENT_CONTROL: + { + if (!officecfg::Office::Common::AccessibilityIssues::ContentControl::get()) + pIssue->setHidden(true); + } + break; + case sfx::AccessibilityIssueID::AVOID_FOOTNOTES: + { + if (!officecfg::Office::Common::AccessibilityIssues::AvoidFootnotes::get()) + pIssue->setHidden(true); + } + break; + case sfx::AccessibilityIssueID::AVOID_ENDNOTES: + { + if (!officecfg::Office::Common::AccessibilityIssues::AvoidEndnotes::get()) + pIssue->setHidden(true); + } + break; + case sfx::AccessibilityIssueID::FONTWORKS: + { + if (!officecfg::Office::Common::AccessibilityIssues::FontWorks::get()) + pIssue->setHidden(true); + } + break; + default: + { + SAL_WARN("sw.a11y", "Invalid issue ID."); + break; + } + } +} + std::shared_ptr<sw::AccessibilityIssue> lclAddIssue(sfx::AccessibilityIssueCollection& rIssueCollection, OUString const& rText, - sfx::AccessibilityIssueID eIssue = sfx::AccessibilityIssueID::UNSPECIFIED) + sfx::AccessibilityIssueID eIssue) { auto pIssue = std::make_shared<sw::AccessibilityIssue>(eIssue); pIssue->m_aIssueText = rText; + + // check which a11y issue should be visible + lcl_SetHiddenIssues(pIssue); + rIssueCollection.getIssues().push_back(pIssue); return pIssue; } @@ -617,7 +815,8 @@ private: double fContrastRatio = calculateContrastRatio(aForegroundColor, aBackgroundColor); if (fContrastRatio < 4.5) { - auto pIssue = lclAddIssue(m_rIssueCollection, SwResId(STR_TEXT_CONTRAST)); + auto pIssue = lclAddIssue(m_rIssueCollection, SwResId(STR_TEXT_CONTRAST), + sfx::AccessibilityIssueID::TEXT_CONTRAST); pIssue->setIssueObject(IssueObject::TEXT); pIssue->setNode(pTextNode); pIssue->setDoc(pTextNode->GetDoc()); @@ -1156,7 +1355,8 @@ private: if (bBlinking) { - auto pIssue = lclAddIssue(m_rIssueCollection, SwResId(STR_TEXT_BLINKING)); + auto pIssue = lclAddIssue(m_rIssueCollection, SwResId(STR_TEXT_BLINKING), + sfx::AccessibilityIssueID::TEXT_BLINKING); pIssue->setIssueObject(IssueObject::TEXT); pIssue->setNode(pTextNode); pIssue->setDoc(pTextNode->GetDoc()); @@ -1223,7 +1423,8 @@ public: assert(nLevel >= 0); if (nLevel > m_nPreviousLevel && std::abs(nLevel - m_nPreviousLevel) > 1) { - auto pIssue = lclAddIssue(m_rIssueCollection, SwResId(STR_HEADINGS_NOT_IN_ORDER)); + auto pIssue = lclAddIssue(m_rIssueCollection, SwResId(STR_HEADINGS_NOT_IN_ORDER), + sfx::AccessibilityIssueID::HEADINGS_NOT_IN_ORDER); pIssue->setIssueObject(IssueObject::TEXT); pIssue->setDoc(pCurrent->GetDoc()); pIssue->setNode(pCurrent); @@ -1268,7 +1469,8 @@ public: if (!bCheck) { sal_Int32 nStart = 0; - auto pIssue = lclAddIssue(m_rIssueCollection, SwResId(STR_NON_INTERACTIVE_FORMS)); + auto pIssue = lclAddIssue(m_rIssueCollection, SwResId(STR_NON_INTERACTIVE_FORMS), + sfx::AccessibilityIssueID::NON_INTERACTIVE_FORMS); pIssue->setIssueObject(IssueObject::TEXT); pIssue->setNode(pTextNode); pIssue->setDoc(pTextNode->GetDoc()); @@ -1315,7 +1517,8 @@ public: { if (aIdx == aCurrentIdx) { - auto pIssue = lclAddIssue(m_rIssueCollection, SwResId(STR_FLOATING_TEXT)); + auto pIssue = lclAddIssue(m_rIssueCollection, SwResId(STR_FLOATING_TEXT), + sfx::AccessibilityIssueID::FLOATING_TEXT); pIssue->setIssueObject(IssueObject::TEXTFRAME); pIssue->setObjectID(pFormat->GetName()); pIssue->setDoc(pCurrent->GetDoc()); @@ -1358,7 +1561,8 @@ public: if (parentTable) { m_bPrevPassed = false; - auto pIssue = lclAddIssue(m_rIssueCollection, SwResId(STR_HEADING_IN_TABLE)); + auto pIssue = lclAddIssue(m_rIssueCollection, SwResId(STR_HEADING_IN_TABLE), + sfx::AccessibilityIssueID::HEADING_IN_TABLE); pIssue->setIssueObject(IssueObject::TEXT); pIssue->setDoc(pCurrent->GetDoc()); pIssue->setNode(pCurrent); @@ -1392,19 +1596,22 @@ public: { // Preparing and posting a warning. OUString resultString; + sfx::AccessibilityIssueID eIssueID; if (!m_prevLevel) { resultString = SwResId(STR_HEADING_START); + eIssueID = sfx::AccessibilityIssueID::HEADING_START; } else { resultString = SwResId(STR_HEADING_ORDER); resultString = resultString.replaceAll("%LEVEL_PREV%", OUString::number(m_prevLevel)); + eIssueID = sfx::AccessibilityIssueID::HEADING_ORDER; } resultString = resultString.replaceAll("%LEVEL_CURRENT%", OUString::number(currentLevel)); - auto pIssue = lclAddIssue(m_rIssueCollection, resultString); + auto pIssue = lclAddIssue(m_rIssueCollection, resultString, eIssueID); pIssue->setIssueObject(IssueObject::TEXT); pIssue->setDoc(pCurrent->GetDoc()); pIssue->setNode(pCurrent); @@ -1448,7 +1655,8 @@ public: { auto pIssue = lclAddIssue(m_rIssueCollection, - SwResId(STR_CONTENT_CONTROL_IN_HEADER_OR_FOOTER)); + SwResId(STR_CONTENT_CONTROL_IN_HEADER_OR_FOOTER), + sfx::AccessibilityIssueID::CONTENT_CONTROL); pIssue->setIssueObject(IssueObject::TEXT); pIssue->setDoc(pCurrent->GetDoc()); pIssue->setNode(pCurrent); @@ -1558,9 +1766,12 @@ public: for (SwTextFootnote* pTextFootnote : pDoc->GetFootnoteIdxs()) { SwFormatFootnote const& rFootnote = pTextFootnote->GetFootnote(); - auto pIssue = lclAddIssue(m_rIssueCollection, rFootnote.IsEndNote() - ? SwResId(STR_AVOID_ENDNOTES) - : SwResId(STR_AVOID_FOOTNOTES)); + OUString sError = rFootnote.IsEndNote() ? SwResId(STR_AVOID_ENDNOTES) + : SwResId(STR_AVOID_FOOTNOTES); + sfx::AccessibilityIssueID eIssueID = rFootnote.IsEndNote() + ? sfx::AccessibilityIssueID::AVOID_FOOTNOTES + : sfx::AccessibilityIssueID::AVOID_ENDNOTES; + auto pIssue = lclAddIssue(m_rIssueCollection, sError, eIssueID); pIssue->setDoc(*pDoc); pIssue->setIssueObject(IssueObject::FOOTENDNOTE); pIssue->setTextFootnote(pTextFootnote); @@ -1628,7 +1839,8 @@ void AccessibilityCheck::checkObject(SwNode* pCurrent, SdrObject* pObject) if (const uno::Any* pAny = rGeometryItem.GetPropertyValueByName(u"Type"_ustr)) if (pAny->get<OUString>().startsWith("fontwork-")) - lclAddIssue(m_aIssueCollection, SwResId(STR_FONTWORKS)); + lclAddIssue(m_aIssueCollection, SwResId(STR_FONTWORKS), + sfx::AccessibilityIssueID::FONTWORKS); } // Checking if there is floating Writer text draw object and if so, throwing a warning. @@ -1636,7 +1848,8 @@ void AccessibilityCheck::checkObject(SwNode* pCurrent, SdrObject* pObject) if (pObject->HasText() && FindFrameFormat(pObject)->GetAnchor().GetAnchorId() != RndStdIds::FLY_AS_CHAR) { - auto pIssue = lclAddIssue(m_aIssueCollection, SwResId(STR_FLOATING_TEXT)); + auto pIssue = lclAddIssue(m_aIssueCollection, SwResId(STR_FLOATING_TEXT), + sfx::AccessibilityIssueID::FLOATING_TEXT); pIssue->setIssueObject(IssueObject::TEXTFRAME); pIssue->setObjectID(pObject->GetName()); pIssue->setDoc(*m_pDoc); diff --git a/sw/source/core/inc/AccessibilityIssue.hxx b/sw/source/core/inc/AccessibilityIssue.hxx index e4c1b3206c76..eef014c5f7f3 100644 --- a/sw/source/core/inc/AccessibilityIssue.hxx +++ b/sw/source/core/inc/AccessibilityIssue.hxx @@ -49,7 +49,7 @@ private: sal_Int32 m_nEnd; public: - AccessibilityIssue(sfx::AccessibilityIssueID eIssueID = sfx::AccessibilityIssueID::UNSPECIFIED); + AccessibilityIssue(sfx::AccessibilityIssueID eIssueID); AccessibilityIssue(AccessibilityIssue const&) = default; void setIssueObject(IssueObject eIssueObject); diff --git a/sw/source/uibase/sidebar/A11yCheckIssuesPanel.cxx b/sw/source/uibase/sidebar/A11yCheckIssuesPanel.cxx index 0dded3d952b4..e71389801660 100644 --- a/sw/source/uibase/sidebar/A11yCheckIssuesPanel.cxx +++ b/sw/source/uibase/sidebar/A11yCheckIssuesPanel.cxx @@ -19,8 +19,10 @@ #include <officecfg/Office/Common.hxx> #include <sfx2/bindings.hxx> +#include <sfx2/dispatch.hxx> #include <sfx2/viewsh.hxx> #include <sfx2/AccessibilityIssue.hxx> +#include <sfx2/pageids.hxx> #include <unotools/configmgr.hxx> #include <vcl/ptrstyle.hxx> #include <vcl/svapp.hxx> @@ -107,6 +109,7 @@ std::unique_ptr<PanelLayout> A11yCheckIssuesPanel::Create(weld::Widget* pParent, A11yCheckIssuesPanel::A11yCheckIssuesPanel(weld::Widget* pParent, SfxBindings* pBindings) : PanelLayout(pParent, u"A11yCheckIssuesPanel"_ustr, u"modules/swriter/ui/a11ycheckissuespanel.ui"_ustr) + , m_xOptionsButton(m_xBuilder->weld_button(u"bOptions"_ustr)) , mxAccessibilityBox(m_xBuilder->weld_box(u"accessibilityCheckBox"_ustr)) , mxUpdateBox(m_xBuilder->weld_box(u"updateBox"_ustr)) , mxUpdateLinkButton(m_xBuilder->weld_link_button(u"updateLinkButton"_ustr)) @@ -162,6 +165,8 @@ A11yCheckIssuesPanel::A11yCheckIssuesPanel(weld::Widget* pParent, SfxBindings* p mpDoc = pDocSh->GetDoc(); + m_xOptionsButton->connect_clicked(LINK(this, A11yCheckIssuesPanel, OptionsButtonClicked)); + // If LOKit is enabled, then enable the update button and don't run the accessibility check. // In desktop don't show the update button and schedule to run the accessibility check async if (comphelper::LibreOfficeKit::isActive()) @@ -177,6 +182,13 @@ A11yCheckIssuesPanel::A11yCheckIssuesPanel(weld::Widget* pParent, SfxBindings* p } } +IMPL_LINK_NOARG(A11yCheckIssuesPanel, OptionsButtonClicked, weld::Button&, void) +{ + SfxUInt16Item aPageID(SID_OPTIONS_PAGEID, sal_uInt16(RID_SVXPAGE_ACCESSIBILITYCONFIG)); + auto pDispatcher = GetBindings()->GetDispatcher(); + pDispatcher->ExecuteList(SID_OPTIONS_TREEDIALOG, SfxCallMode::SYNCHRON, { &aPageID }); +} + IMPL_LINK_NOARG(A11yCheckIssuesPanel, UpdateLinkButtonClicked, weld::LinkButton&, bool) { mxAccessibilityBox->show(); @@ -256,73 +268,98 @@ void A11yCheckIssuesPanel::populateIssues() case sfx::AccessibilityIssueID::DOCUMENT_LANGUAGE: case sfx::AccessibilityIssueID::DOCUMENT_BACKGROUND: { - addEntryForGroup(AccessibilityCheckGroups::Document, nIndices, pIssue); + if (!pIssue->getHidden()) + addEntryForGroup(AccessibilityCheckGroups::Document, nIndices, pIssue); } break; case sfx::AccessibilityIssueID::STYLE_LANGUAGE: { - addEntryForGroup(AccessibilityCheckGroups::Styles, nIndices, pIssue); + if (!pIssue->getHidden()) + addEntryForGroup(AccessibilityCheckGroups::Styles, nIndices, pIssue); } break; case sfx::AccessibilityIssueID::LINKED_GRAPHIC: { - addEntryForGroup(AccessibilityCheckGroups::Linked, nIndices, pIssue); + if (!pIssue->getHidden()) + addEntryForGroup(AccessibilityCheckGroups::Linked, nIndices, pIssue); } break; case sfx::AccessibilityIssueID::NO_ALT_OLE: case sfx::AccessibilityIssueID::NO_ALT_GRAPHIC: case sfx::AccessibilityIssueID::NO_ALT_SHAPE: { - addEntryForGroup(AccessibilityCheckGroups::NoAlt, nIndices, pIssue); + if (!pIssue->getHidden()) + addEntryForGroup(AccessibilityCheckGroups::NoAlt, nIndices, pIssue); } break; case sfx::AccessibilityIssueID::TABLE_MERGE_SPLIT: { - addEntryForGroup(AccessibilityCheckGroups::Table, nIndices, pIssue); + if (!pIssue->getHidden()) + addEntryForGroup(AccessibilityCheckGroups::Table, nIndices, pIssue); } break; case sfx::AccessibilityIssueID::TEXT_FORMATTING: case sfx::AccessibilityIssueID::TABLE_FORMATTING: { - addEntryForGroup(AccessibilityCheckGroups::Formatting, nIndices, pIssue); + if (!pIssue->getHidden()) + addEntryForGroup(AccessibilityCheckGroups::Formatting, nIndices, pIssue); } break; case sfx::AccessibilityIssueID::DIRECT_FORMATTING: { - addEntryForGroup(AccessibilityCheckGroups::DirectFormatting, nIndices, pIssue); - nDirectFormats++; + if (!pIssue->getHidden()) + { + addEntryForGroup(AccessibilityCheckGroups::DirectFormatting, nIndices, pIssue); + nDirectFormats++; + } } break; case sfx::AccessibilityIssueID::HYPERLINK_IS_TEXT: case sfx::AccessibilityIssueID::HYPERLINK_SHORT: case sfx::AccessibilityIssueID::HYPERLINK_NO_NAME: { - addEntryForGroup(AccessibilityCheckGroups::Hyperlink, nIndices, pIssue); + if (!pIssue->getHidden()) + addEntryForGroup(AccessibilityCheckGroups::Hyperlink, nIndices, pIssue); } break; case sfx::AccessibilityIssueID::FAKE_FOOTNOTE: case sfx::AccessibilityIssueID::FAKE_CAPTION: { - addEntryForGroup(AccessibilityCheckGroups::Fakes, nIndices, pIssue); + if (!pIssue->getHidden()) + addEntryForGroup(AccessibilityCheckGroups::Fakes, nIndices, pIssue); } break; case sfx::AccessibilityIssueID::MANUAL_NUMBERING: { - addEntryForGroup(AccessibilityCheckGroups::Numbering, nIndices, pIssue); + if (!pIssue->getHidden()) + addEntryForGroup(AccessibilityCheckGroups::Numbering, nIndices, pIssue); } break; - case sfx::AccessibilityIssueID::UNSPECIFIED: + + case sfx::AccessibilityIssueID::TEXT_CONTRAST: + case sfx::AccessibilityIssueID::TEXT_BLINKING: + case sfx::AccessibilityIssueID::HEADINGS_NOT_IN_ORDER: + case sfx::AccessibilityIssueID::NON_INTERACTIVE_FORMS: + case sfx::AccessibilityIssueID::FLOATING_TEXT: + case sfx::AccessibilityIssueID::HEADING_IN_TABLE: + case sfx::AccessibilityIssueID::HEADING_START: + case sfx::AccessibilityIssueID::HEADING_ORDER: + case sfx::AccessibilityIssueID::CONTENT_CONTROL: + case sfx::AccessibilityIssueID::AVOID_FOOTNOTES: + case sfx::AccessibilityIssueID::AVOID_ENDNOTES: + case sfx::AccessibilityIssueID::FONTWORKS: { - addEntryForGroup(AccessibilityCheckGroups::Other, nIndices, pIssue); + if (!pIssue->getHidden()) + addEntryForGroup(AccessibilityCheckGroups::Other, nIndices, pIssue); } break; + default: { SAL_WARN("sw.a11y", "Invalid issue ID."); continue; } - break; - }; + } } // add DirectFormats (if have) as last element to Formatting AccessibilityCheckGroup diff --git a/sw/source/uibase/sidebar/A11yCheckIssuesPanel.hxx b/sw/source/uibase/sidebar/A11yCheckIssuesPanel.hxx index b48520ca3257..f961778c4b27 100644 --- a/sw/source/uibase/sidebar/A11yCheckIssuesPanel.hxx +++ b/sw/source/uibase/sidebar/A11yCheckIssuesPanel.hxx @@ -79,6 +79,7 @@ private: std::array<std::vector<std::unique_ptr<AccessibilityCheckEntry>>, 11> m_aEntries; std::array<std::unique_ptr<weld::Expander>, 11> m_xExpanders; std::array<std::unique_ptr<weld::Box>, 11> m_xBoxes; + std::unique_ptr<weld::Button> m_xOptionsButton; std::unique_ptr<weld::Box> mxAccessibilityBox; std::unique_ptr<weld::Box> mxUpdateBox; std::unique_ptr<weld::LinkButton> mxUpdateLinkButton; @@ -87,12 +88,15 @@ private: void removeAllEntries(); void populateIssues(); + DECL_LINK(OptionsButtonClicked, weld::Button&, void); DECL_LINK(UpdateLinkButtonClicked, weld::LinkButton&, bool); DECL_LINK(PopulateIssuesHdl, void*, void); void addEntryForGroup(AccessibilityCheckGroups eGroup, std::vector<sal_Int32>& rIndices, std::shared_ptr<sfx::AccessibilityIssue> const& pIssue); + SfxBindings* GetBindings() { return mpBindings; } + SfxBindings* mpBindings; SwDoc* mpDoc; ::sfx2::sidebar::ControllerItem maA11yCheckController; diff --git a/sw/uiconfig/swriter/ui/a11ycheckissuespanel.ui b/sw/uiconfig/swriter/ui/a11ycheckissuespanel.ui index 7bf6885fd49a..54feea39482a 100644 --- a/sw/uiconfig/swriter/ui/a11ycheckissuespanel.ui +++ b/sw/uiconfig/swriter/ui/a11ycheckissuespanel.ui @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Generated with glade 3.40.0 --> +<!-- Generated with glade 3.38.2 --> <interface domain="sw"> <requires lib="gtk+" version="3.20"/> <object class="GtkBox" id="A11yCheckIssuesPanel"> @@ -9,6 +9,64 @@ <property name="hexpand">True</property> <property name="vexpand">True</property> <property name="orientation">vertical</property> + <child> + <!-- n-columns=2 n-rows=1 --> + <object class="GtkGrid" id="gridOptions"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <child> + <object class="GtkLabel" id="lbOptions"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="hexpand">True</property> + <property name="label" translatable="yes" context="optsecuritypage|lbOptions">Adjust accessibility check options.</property> + <property name="wrap">True</property> + <property name="width-chars">56</property> + <property name="max-width-chars">56</property> + <property name="xalign">0</property> + </object> + <packing> + <property name="left-attach">0</property> + <property name="top-attach">0</property> + </packing> + </child> + <child> + <object class="GtkButton" id="bOptions"> + <property name="label" translatable="yes" context="optsecuritypage|bOptions">O_ptions...</property> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">True</property> + <property name="valign">center</property> + <property name="use-underline">True</property> + <child internal-child="accessible"> + <object class="AtkObject" id="bOptions-atkobject"> + <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|bOptions">Opens the "Accesibility options" page.</property> + </object> + </child> + </object> + <packing> + <property name="left-attach">1</property> + <property name="top-attach">0</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkSeparator" id="sep"> + <property name="visible">True</property> + <property name="can-focus">False</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> <child> <object class="GtkBox" id="accessibilityCheckBox"> <property name="visible">True</property> @@ -343,7 +401,7 @@ <packing> <property name="expand">False</property> <property name="fill">True</property> - <property name="position">0</property> + <property name="position">2</property> </packing> </child> <child> @@ -369,7 +427,7 @@ <packing> <property name="expand">False</property> <property name="fill">True</property> - <property name="position">1</property> + <property name="position">3</property> </packing> </child> </object>