include/svx/labelitemwindow.hxx | 11 ++++ include/svx/srchdlg.hxx | 2 svx/source/dialog/srchdlg.cxx | 40 +++++++---------- svx/source/form/labelitemwindow.cxx | 24 +++++++++- svx/uiconfig/ui/findreplacedialog.ui | 80 +++++++++++++++++++++++++---------- svx/uiconfig/ui/labelbox.ui | 29 ++++++++++-- 6 files changed, 135 insertions(+), 51 deletions(-)
New commits: commit 97d3d4f371f82704dba907975e6cfdaac456fe4d Author: Heiko Tietze <tietze.he...@gmail.com> AuthorDate: Fri Sep 15 14:23:50 2023 +0200 Commit: Heiko Tietze <heiko.tie...@documentfoundation.org> CommitDate: Sat Oct 28 11:23:12 2023 +0200 Resolves tdf#156227 - More appealing feedback for find/quickfind ErrorMessageType removed in favor of an infobar-like label Accessibility notification added for the quickfind bar Change-Id: Iec2498d04152392b3e181146005bdb0c9db8ec50 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/156943 Reviewed-by: Michael Weghorn <m.wegh...@posteo.de> Tested-by: Jenkins Reviewed-by: Heiko Tietze <heiko.tie...@documentfoundation.org> diff --git a/include/svx/labelitemwindow.hxx b/include/svx/labelitemwindow.hxx index 5271482b11ad..d9aeccbb7bfd 100644 --- a/include/svx/labelitemwindow.hxx +++ b/include/svx/labelitemwindow.hxx @@ -12,14 +12,23 @@ #include <vcl/InterimItemWindow.hxx> #include <svx/svxdllapi.h> +enum class LabelItemWindowType +{ + Text, + Info, +}; + class SVXCORE_DLLPUBLIC LabelItemWindow final : public InterimItemWindow { private: + std::unique_ptr<weld::Box> m_xBox; std::unique_ptr<weld::Label> m_xLabel; + std::unique_ptr<weld::Image> m_xImage; public: LabelItemWindow(vcl::Window* pParent, const OUString& rLabel); - void set_label(const OUString& rLabel); + void set_label(const OUString& rLabel, + const LabelItemWindowType eType = LabelItemWindowType::Text); OUString get_label() const; void SetOptimalSize(); diff --git a/include/svx/srchdlg.hxx b/include/svx/srchdlg.hxx index f069af48c539..7223a51cd324 100644 --- a/include/svx/srchdlg.hxx +++ b/include/svx/srchdlg.hxx @@ -177,6 +177,8 @@ private: std::unique_ptr<weld::ComboBox> m_xSearchTmplLB; std::unique_ptr<weld::Label> m_xSearchAttrText; std::unique_ptr<weld::Label> m_xSearchLabel; + std::unique_ptr<weld::Image> m_xSearchIcon; + std::unique_ptr<weld::Box> m_xSearchBox; std::unique_ptr<weld::Frame> m_xReplaceFrame; std::unique_ptr<weld::ComboBox> m_xReplaceLB; diff --git a/svx/source/dialog/srchdlg.cxx b/svx/source/dialog/srchdlg.cxx index a17711bc46fb..b5cf7bcf34fd 100644 --- a/svx/source/dialog/srchdlg.cxx +++ b/svx/source/dialog/srchdlg.cxx @@ -285,6 +285,8 @@ SvxSearchDialog::SvxSearchDialog(weld::Window* pParent, SfxChildWindow* pChildWi , m_xSearchTmplLB(m_xBuilder->weld_combo_box("searchlist")) , m_xSearchAttrText(m_xBuilder->weld_label("searchdesc")) , m_xSearchLabel(m_xBuilder->weld_label("searchlabel")) + , m_xSearchIcon(m_xBuilder->weld_image("searchicon")) + , m_xSearchBox(m_xBuilder->weld_box("searchbox")) , m_xReplaceFrame(m_xBuilder->weld_frame("replaceframe")) , m_xReplaceLB(m_xBuilder->weld_combo_box("replaceterm")) , m_xReplaceTmplLB(m_xBuilder->weld_combo_box("replacelist")) @@ -340,6 +342,9 @@ SvxSearchDialog::SvxSearchDialog(weld::Window* pParent, SfxChildWindow* pChildWi m_xSearchTmplLB->make_sorted(); m_xSearchAttrText->hide(); + m_xSearchLabel->set_font_color(Color(0x00, 0x47, 0x85)); + this->SetSearchLabel(""); // hide the message but keep the box height + m_xReplaceTmplLB->make_sorted(); m_xReplaceAttrText->hide(); @@ -581,14 +586,18 @@ void SvxSearchDialog::SetSearchLabel(const OUString& rStr) m_xSearchLabel->set_label(rStr); if (!rStr.isEmpty()) { - // hide/show to fire SHOWING state change event so search label text - // is announced by screen reader - m_xSearchLabel->hide(); m_xSearchLabel->show(); + m_xSearchIcon->show(); + m_xSearchBox->set_background(Color(0xBD, 0xE5, 0xF8)); // same as InfobarType::INFO + } + else + { + const Size aSize = m_xSearchBox->get_preferred_size(); + m_xSearchLabel->hide(); + m_xSearchIcon->hide(); + m_xSearchBox->set_size_request(-1, aSize.Height()); + m_xSearchBox->set_background(COL_TRANSPARENT); } - - if (rStr == SvxResId(RID_SVXSTR_SEARCH_NOT_FOUND)) - m_xSearchLB->set_entry_message_type(weld::EntryMessageType::Error); } void SvxSearchDialog::ApplyTransliterationFlags_Impl( TransliterationFlags nSettings ) @@ -2360,8 +2369,6 @@ SfxChildWinInfo SvxSearchDialogWrapper::GetInfo() const static void lcl_SetSearchLabelWindow(const OUString& rStr, SfxViewFrame& rViewFrame) { - bool bNotFound = rStr == SvxResId(RID_SVXSTR_SEARCH_NOT_FOUND); - css::uno::Reference< css::beans::XPropertySet > xPropSet( rViewFrame.GetFrame().GetFrameInterface(), css::uno::UNO_QUERY_THROW); css::uno::Reference< css::frame::XLayoutManager > xLayoutManager; @@ -2380,21 +2387,8 @@ static void lcl_SetSearchLabelWindow(const OUString& rStr, SfxViewFrame& rViewFr { LabelItemWindow* pSearchLabel = dynamic_cast<LabelItemWindow*>(pToolBox->GetItemWindow(id)); assert(pSearchLabel); - pSearchLabel->set_label(rStr); - if (rStr.isEmpty()) - pSearchLabel->SetSizePixel(Size(16, pSearchLabel->GetSizePixel().Height())); - else - pSearchLabel->SetOptimalSize(); - } - - if (pToolBox->GetItemCommand(id) == ".uno:FindText") - { - FindTextFieldControl* pFindText = dynamic_cast<FindTextFieldControl*>(pToolBox->GetItemWindow(id)); - assert(pFindText); - if (bNotFound) - pFindText->set_entry_message_type(weld::EntryMessageType::Error); - else - pFindText->set_entry_message_type(weld::EntryMessageType::Normal); + pSearchLabel->set_label(rStr, LabelItemWindowType::Info); + pSearchLabel->SetOptimalSize(); } } xLayoutManager->doLayout(); diff --git a/svx/source/form/labelitemwindow.cxx b/svx/source/form/labelitemwindow.cxx index 77965cbd4a4e..bdff03e060f2 100644 --- a/svx/source/form/labelitemwindow.cxx +++ b/svx/source/form/labelitemwindow.cxx @@ -11,11 +11,14 @@ LabelItemWindow::LabelItemWindow(vcl::Window* pParent, const OUString& rLabel) : InterimItemWindow(pParent, "svx/ui/labelbox.ui", "LabelBox") + , m_xBox(m_xBuilder->weld_box("LabelBox")) , m_xLabel(m_xBuilder->weld_label("label")) + , m_xImage(m_xBuilder->weld_image("image")) { InitControlBase(m_xLabel.get()); m_xLabel->set_label(rLabel); + m_xImage->hide(); SetOptimalSize(); @@ -24,13 +27,30 @@ LabelItemWindow::LabelItemWindow(vcl::Window* pParent, const OUString& rLabel) void LabelItemWindow::SetOptimalSize() { - Size aSize(m_xLabel->get_preferred_size()); + Size aSize(m_xBox->get_preferred_size()); aSize.AdjustWidth(12); SetSizePixel(aSize); } -void LabelItemWindow::set_label(const OUString& rLabel) { m_xLabel->set_label(rLabel); } +void LabelItemWindow::set_label(const OUString& rLabel, const LabelItemWindowType eType) +{ + m_xLabel->set_visible(false); // a11y announcement + m_xLabel->set_label(rLabel); + if ((eType == LabelItemWindowType::Text) || rLabel.isEmpty()) + { + m_xImage->hide(); + m_xLabel->set_font_color(COL_AUTO); + m_xBox->set_background(COL_AUTO); + } + else if (eType == LabelItemWindowType::Info) + { + m_xImage->show(); + m_xLabel->set_font_color(Color(0x00, 0x47, 0x85)); + m_xBox->set_background(Color(0xBD, 0xE5, 0xF8)); // same as InfobarType::INFO + } + m_xLabel->set_visible(!rLabel.isEmpty()); +} OUString LabelItemWindow::get_label() const { return m_xLabel->get_label(); } diff --git a/svx/uiconfig/ui/findreplacedialog.ui b/svx/uiconfig/ui/findreplacedialog.ui index fbb033504a94..57a16e666a2f 100644 --- a/svx/uiconfig/ui/findreplacedialog.ui +++ b/svx/uiconfig/ui/findreplacedialog.ui @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Generated with glade 3.38.2 --> +<!-- Generated with glade 3.40.0 --> <interface domain="svx"> <requires lib="gtk+" version="3.20"/> <object class="GtkDialog" id="FindReplaceDialog"> @@ -171,26 +171,6 @@ <property name="top-attach">2</property> </packing> </child> - <child> - <object class="GtkLabel" id="searchlabel"> - <property name="visible">True</property> - <property name="can-focus">False</property> - <property name="no-show-all">True</property> - <property name="hexpand">True</property> - <property name="wrap">True</property> - <property name="ellipsize">end</property> - <property name="xalign">0</property> - <child internal-child="accessible"> - <object class="AtkObject" id="searchlabel-atkobject"> - <property name="AtkObject::accessible-role" translatable="no">notification</property> - </object> - </child> - </object> - <packing> - <property name="left-attach">1</property> - <property name="top-attach">4</property> - </packing> - </child> <child> <object class="GtkBox" id="checkboxrow"> <property name="visible">True</property> @@ -301,6 +281,64 @@ <property name="top-attach">3</property> </packing> </child> + <child> + <object class="GtkBox" id="searchbox"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="halign">start</property> + <child> + <object class="GtkImage" id="searchicon"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="margin-start">6</property> + <property name="margin-end">3</property> + <property name="margin-top">3</property> + <property name="margin-bottom">3</property> + <property name="icon-name">res/info.png</property> + <child internal-child="accessible"> + <object class="AtkObject" id="searchicon-atkobject"> + <property name="AtkObject::accessible-name" translatable="yes" context="findreplacedialog|searchicon">Search icon</property> + </object> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="searchlabel"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="no-show-all">True</property> + <property name="halign">start</property> + <property name="margin-start">3</property> + <property name="margin-end">6</property> + <property name="margin-top">3</property> + <property name="margin-bottom">3</property> + <property name="hexpand">True</property> + <property name="wrap">True</property> + <property name="ellipsize">end</property> + <property name="xalign">0</property> + <child internal-child="accessible"> + <object class="AtkObject" id="searchlabel-atkobject"> + <property name="AtkObject::accessible-role">notification</property> + </object> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="left-attach">1</property> + <property name="top-attach">4</property> + </packing> + </child> <child> <placeholder/> </child> diff --git a/svx/uiconfig/ui/labelbox.ui b/svx/uiconfig/ui/labelbox.ui index eca99a463c9e..f77cd5da7f4e 100644 --- a/svx/uiconfig/ui/labelbox.ui +++ b/svx/uiconfig/ui/labelbox.ui @@ -1,25 +1,46 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Generated with glade 3.36.0 --> +<!-- Generated with glade 3.40.0 --> <interface domain="svx"> <requires lib="gtk+" version="3.20"/> <object class="GtkBox" id="LabelBox"> <property name="visible">True</property> - <property name="can_focus">False</property> + <property name="can-focus">False</property> <property name="hexpand">True</property> <property name="vexpand">True</property> <property name="spacing">4</property> + <child> + <object class="GtkImage" id="image"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="margin-start">6</property> + <property name="margin-top">3</property> + <property name="margin-bottom">3</property> + <property name="icon-name">res/info.png</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> <child> <object class="GtkLabel" id="label"> <property name="visible">True</property> - <property name="can_focus">False</property> + <property name="can-focus">False</property> + <property name="margin-end">6</property> <property name="hexpand">True</property> <property name="vexpand">True</property> <property name="xalign">0</property> + <child internal-child="accessible"> + <object class="AtkObject" id="label-atkobject"> + <property name="AtkObject::accessible-role">notification</property> + </object> + </child> </object> <packing> <property name="expand">False</property> <property name="fill">True</property> - <property name="position">0</property> + <property name="position">1</property> </packing> </child> </object>