include/svx/srchdlg.hxx              |    4 +++
 svx/source/dialog/srchdlg.cxx        |   20 +++++++++++++++++
 svx/uiconfig/ui/findreplacedialog.ui |   39 +++++++++++++++++++++++++++++++++++
 3 files changed, 63 insertions(+)

New commits:
commit a0a7aa586989bc0829425b1b608d342690524808
Author:     Sahil Gautam <sahil.gau...@collabora.com>
AuthorDate: Thu Jul 31 12:08:09 2025 +0530
Commit:     Szymon Kłos <szymon.k...@collabora.com>
CommitDate: Thu Jul 31 12:31:39 2025 +0200

    tdf#167647 add tabs to find and replace dialog
    
    add two toggle buttons on top of the "find replace dialog" and make
    them behave as tabs i.e. when replace is clicked, show the replace
    controls.
    
    when the dialog first shows up, we hide the replace controls and when
    the user switches to replace tab, we show the replace controls, find
    controls are always visible.
    
    i thought through various other ways it could have been done (most of
    them being more complicated than the current solution).
    
    1. "could we create one tab and just return a shared pointer to it
    for different tabs so that they share the page". this requires us to
    return a shared pointer from TabPageClass::Create which is passed in
    the AddTabPage function. i thought "could we internally store a raw
    pointer and then in the Create function of the tab page, we return
    the unique_ptr to it." this doesn't seem like a good idea as when the
    first tab page is destructed, the raw pointer in the Create function
    and the unique pointers in other tab pages will become invalid leading
    to double free.
    
    2. "what if i add the frame only to the first tab and in the code
    set it as a child of the second tab as well, using something like
    set_child" -> weld doesn't have any such function as far as i could
    search.
    
    3. convert the current find-replace dialog into a tab page and add two
    different instances of it to the dialog. then transfer the data to
    the other tab on tab switch. this would require addition of a lot of
    getters and setters and might introduce bugs.
    
    Change-Id: I49c5640f39262578e31caee839c2059bb86610a6
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/188644
    Reviewed-by: Szymon Kłos <szymon.k...@collabora.com>
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>

diff --git a/include/svx/srchdlg.hxx b/include/svx/srchdlg.hxx
index a5ee0f8d8cf1..f403f033283e 100644
--- a/include/svx/srchdlg.hxx
+++ b/include/svx/srchdlg.hxx
@@ -188,6 +188,8 @@ private:
     std::unique_ptr<weld::Label> m_xSearchLabel;
     std::unique_ptr<weld::Image> m_xSearchIcon;
     std::unique_ptr<weld::Container> m_xSearchBox;
+    std::unique_ptr<weld::ToggleButton> m_xFindTabBtn;
+    std::unique_ptr<weld::ToggleButton> m_xReplaceTabBtn;
 
     std::unique_ptr<weld::Frame> m_xReplaceFrame;
     std::unique_ptr<weld::ComboBox> m_xReplaceLB;
@@ -249,8 +251,10 @@ private:
     DECL_DLLPRIVATE_LINK(NoFormatHdl_Impl, weld::Button&, void);
     DECL_DLLPRIVATE_LINK(AttributeHdl_Impl, weld::Button&, void);
     DECL_DLLPRIVATE_LINK( TimeoutHdl_Impl, Timer*, void );
+    DECL_DLLPRIVATE_LINK(OnTabBtnClick, weld::Toggleable&, void);
     SVX_DLLPRIVATE void ClickHdl_Impl(const weld::Widget* pCtrl);
 
+    SVX_DLLPRIVATE void SetReplaceCtrlsVisible(bool bVisible);
     SVX_DLLPRIVATE void Construct_Impl();
     SVX_DLLPRIVATE void InitControls_Impl();
     SVX_DLLPRIVATE void ShowOptionalControls_Impl();
diff --git a/svx/source/dialog/srchdlg.cxx b/svx/source/dialog/srchdlg.cxx
index 07a02d60f300..9b2eff684252 100644
--- a/svx/source/dialog/srchdlg.cxx
+++ b/svx/source/dialog/srchdlg.cxx
@@ -262,6 +262,8 @@ SvxSearchDialog::SvxSearchDialog(weld::Window* pParent, 
SfxChildWindow* pChildWi
     , m_xSearchLabel(m_xBuilder->weld_label(u"searchlabel"_ustr))
     , m_xSearchIcon(m_xBuilder->weld_image(u"searchicon"_ustr))
     , m_xSearchBox(m_xBuilder->weld_container(u"searchbox"_ustr))
+    , m_xFindTabBtn(m_xBuilder->weld_toggle_button(u"find_tab_btn"_ustr))
+    , m_xReplaceTabBtn(m_xBuilder->weld_toggle_button(u"replace_tab_btn"_ustr))
     , m_xReplaceFrame(m_xBuilder->weld_frame(u"replaceframe"_ustr))
     , m_xReplaceLB(m_xBuilder->weld_combo_box(u"replaceterm"_ustr))
     , m_xReplaceTmplLB(m_xBuilder->weld_combo_box(u"replacelist"_ustr))
@@ -343,6 +345,7 @@ SvxSearchDialog::SvxSearchDialog(weld::Window* pParent, 
SfxChildWindow* pChildWi
     m_xReplaceTmplLB->set_size_request(nTermWidth, -1);
 
     Construct_Impl();
+    SetReplaceCtrlsVisible(false);
 }
 
 IMPL_LINK_NOARG(SvxSearchDialog, PresentTimeoutHdl_Impl, Timer*, void)
@@ -374,6 +377,16 @@ SvxSearchDialog::~SvxSearchDialog()
     pImpl.reset();
 }
 
+void SvxSearchDialog::SetReplaceCtrlsVisible(bool bVisible)
+{
+    m_xFindTabBtn->set_active(!bVisible);
+    m_xReplaceTabBtn->set_active(bVisible);
+
+    m_xReplaceFrame->set_visible(bVisible);
+    m_xReplaceBtn->set_visible(bVisible);
+    m_xReplaceAllBtn->set_visible(bVisible);
+}
+
 void SvxSearchDialog::Construct_Impl()
 {
     pImpl.reset( new SearchDlg_Impl() );
@@ -641,6 +654,8 @@ void SvxSearchDialog::InitControls_Impl()
 
     m_xSearchLB->connect_changed( LINK( this, SvxSearchDialog, ModifyHdl_Impl 
) );
     m_xReplaceLB->connect_changed( LINK( this, SvxSearchDialog, ModifyHdl_Impl 
) );
+    m_xFindTabBtn->connect_toggled(LINK(this, SvxSearchDialog, OnTabBtnClick));
+    m_xReplaceTabBtn->connect_toggled(LINK(this, SvxSearchDialog, 
OnTabBtnClick));
 
     Link<weld::Widget&,void> aLink = LINK( this, SvxSearchDialog, 
FocusHdl_Impl );
     m_xSearchLB->connect_focus_in( aLink );
@@ -1270,6 +1285,11 @@ void SvxSearchDialog::ClickHdl_Impl(const weld::Widget* 
pCtrl)
         SaveToModule_Impl();
 }
 
+IMPL_LINK(SvxSearchDialog, OnTabBtnClick, weld::Toggleable&, rBtn, void)
+{
+    SetReplaceCtrlsVisible(&rBtn == m_xReplaceTabBtn.get());
+}
+
 IMPL_LINK(SvxSearchDialog, CommandHdl_Impl, weld::Button&, rBtn, void)
 {
     bool bInclusive = ( m_xLayoutBtn->get_label() == aLayoutStr );
diff --git a/svx/uiconfig/ui/findreplacedialog.ui 
b/svx/uiconfig/ui/findreplacedialog.ui
index e915a647f710..7a81b437beca 100644
--- a/svx/uiconfig/ui/findreplacedialog.ui
+++ b/svx/uiconfig/ui/findreplacedialog.ui
@@ -56,6 +56,45 @@
             <property name="position">0</property>
           </packing>
         </child>
+        <child>
+          <object class="GtkBox" id="findreplacetabbox">
+            <property name="visible">True</property>
+            <property name="can-focus">False</property>
+            <property name="halign">start</property>
+            <property name="spacing">6</property>
+            <child>
+              <object class="GtkToggleButton" id="find_tab_btn">
+                <property name="label" translatable="yes" 
context="findreplacedialog|find_tab_btn">Find</property>
+                <property name="visible">True</property>
+                <property name="can-focus">True</property>
+                <property name="receives-default">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkToggleButton" id="replace_tab_btn">
+                <property name="label" translatable="yes" 
context="findreplacedialog|replace_tab_btn">Replace</property>
+                <property name="visible">True</property>
+                <property name="can-focus">True</property>
+                <property name="receives-default">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
         <child>
           <object class="GtkBox" id="parent _container_box">
             <property name="visible">True</property>

Reply via email to