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>

Reply via email to