officecfg/registry/data/org/openoffice/Office/UI/Sidebar.xcu |   52 +++
 sw/Library_sw.mk                                             |    1 
 sw/UIConfig_swriter.mk                                       |    1 
 sw/source/uibase/sidebar/QuickFindPanel.cxx                  |  190 +++++++++++
 sw/source/uibase/sidebar/QuickFindPanel.hxx                  |   42 ++
 sw/source/uibase/sidebar/SwPanelFactory.cxx                  |    7 
 sw/uiconfig/swriter/ui/sidebarquickfind.ui                   |   97 +++++
 7 files changed, 390 insertions(+)

New commits:
commit 9338f87a6644e9b2309c3a009af096e38fbb107e
Author:     khushishikhu <dpskhu13...@gmail.com>
AuthorDate: Thu Dec 7 14:48:10 2023 +0530
Commit:     Jim Raykowski <rayk...@gmail.com>
CommitDate: Thu Apr 4 20:46:29 2024 +0200

    tdf#95405 Sidebar: Quick Find for writer
    
    Implemented the quick find deck on the sidebar of Writer with a 
corresponding panel in it.
    
    Change-Id: Ic4ce6823e11b27b3386e820a657bc5d973e47007
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/160500
    Tested-by: Jenkins
    Reviewed-by: Jim Raykowski <rayk...@gmail.com>

diff --git a/officecfg/registry/data/org/openoffice/Office/UI/Sidebar.xcu 
b/officecfg/registry/data/org/openoffice/Office/UI/Sidebar.xcu
index e038472d704e..291f4dd84153 100644
--- a/officecfg/registry/data/org/openoffice/Office/UI/Sidebar.xcu
+++ b/officecfg/registry/data/org/openoffice/Office/UI/Sidebar.xcu
@@ -335,7 +335,28 @@
         </prop>
       </node>
 
+      <node oor:name="FindDeck" oor:op="replace">
+        <prop oor:name="Title" oor:type="xs:string">
+          <value xml:lang="en-US">Find</value>
+        </prop>
+        <prop oor:name="Id" oor:type="xs:string">
+          <value>FindDeck</value>
+        </prop>
+        <prop oor:name="IconURL" oor:type="xs:string">
+          <value>private:graphicrepository/cmd/lc_recsearch.png</value>
+        </prop>
+        <prop oor:name="ContextList">
+          <value oor:separator=";">
+             WriterVariants, any, visible ;
+          </value>
+        </prop>
+        <prop oor:name="OrderIndex" oor:type="xs:int">
+          <value>1000</value>
+        </prop>
+      </node>
+
     </node>
+
     <node oor:name="PanelList">
 
       <node oor:name="StylesPropertyPanel" oor:op="replace">
@@ -2020,6 +2041,37 @@
         </prop>
       </node>
 
+      <node oor:name="QuickFindPanel" oor:op="replace">
+        <prop oor:name="Title" oor:type="xs:string">
+          <value xml:lang="en-US">QuickFind</value>
+        </prop>
+        <prop oor:name="TitleBarIsOptional" oor:type="xs:boolean">
+          <value>true</value>
+        </prop>
+        <prop oor:name="Id" oor:type="xs:string">
+          <value>QuickFindPanel</value>
+        </prop>
+        <prop oor:name="DeckId" oor:type="xs:string">
+          <value>FindDeck</value>
+        </prop>
+        <prop oor:name="ContextList">
+          <value oor:separator=";">
+            Writer, any, visible;
+          </value>
+        </prop>
+        <prop oor:name="ImplementationURL" oor:type="xs:string">
+          
<value>private:resource/toolpanel/SwPanelFactory/QuickFindPanel</value>
+        </prop>
+        <prop oor:name="OrderIndex" oor:type="xs:int">
+          <value>300</value>
+        </prop>
+        <prop oor:name="WantsAWT" oor:type="xs:boolean">
+          <value>false</value>
+        </prop>
+      </node>
+
+
+
     </node>
   </node>
 </oor:component-data>
diff --git a/sw/Library_sw.mk b/sw/Library_sw.mk
index c8cc2e96814a..872ae8812286 100644
--- a/sw/Library_sw.mk
+++ b/sw/Library_sw.mk
@@ -736,6 +736,7 @@ $(eval $(call gb_Library_add_exception_objects,sw,\
     sw/source/uibase/sidebar/SwPanelFactory \
     sw/source/uibase/sidebar/WriterInspectorTextPanel \
     sw/source/uibase/sidebar/A11yCheckIssuesPanel \
+    sw/source/uibase/sidebar/QuickFindPanel \
     sw/source/uibase/table/chartins \
     sw/source/uibase/table/swtablerep \
     sw/source/uibase/table/tablemgr \
diff --git a/sw/UIConfig_swriter.mk b/sw/UIConfig_swriter.mk
index 309eb8666293..27b7248d74e5 100644
--- a/sw/UIConfig_swriter.mk
+++ b/sw/UIConfig_swriter.mk
@@ -291,6 +291,7 @@ $(eval $(call gb_UIConfig_add_uifiles,modules/swriter,\
        sw/uiconfig/swriter/ui/sidebarstylepresets \
        sw/uiconfig/swriter/ui/sidebartableedit \
        sw/uiconfig/swriter/ui/sidebartheme \
+       sw/uiconfig/swriter/ui/sidebarquickfind \
        sw/uiconfig/swriter/ui/sortdialog \
        sw/uiconfig/swriter/ui/spellmenu \
        sw/uiconfig/swriter/ui/splittable \
diff --git a/sw/source/uibase/sidebar/QuickFindPanel.cxx 
b/sw/source/uibase/sidebar/QuickFindPanel.cxx
new file mode 100644
index 000000000000..90f428b1ed0c
--- /dev/null
+++ b/sw/source/uibase/sidebar/QuickFindPanel.cxx
@@ -0,0 +1,190 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ */
+
+#include "QuickFindPanel.hxx"
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include <svl/srchitem.hxx>
+#include <view.hxx>
+#include <comphelper/dispatchcommand.hxx>
+#include <comphelper/propertysequence.hxx>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <swmodule.hxx>
+#include <pam.hxx>
+#include <contentindex.hxx>
+#include <node.hxx>
+#include <ndtxt.hxx>
+#include <edtwin.hxx>
+#include <com/sun/star/uno/Any.h>
+using namespace css;
+using namespace std;
+
+const int MinimumPanelWidth = 250;
+
+namespace sw::sidebar
+{
+std::unique_ptr<PanelLayout> QuickFindPanel::Create(weld::Widget* pParent)
+{
+    if (pParent == nullptr)
+        throw css::lang::IllegalArgumentException(
+            "no parent Window given to QuickFindPanel::Create", nullptr, 0);
+    return std::make_unique<QuickFindPanel>(pParent);
+}
+
+QuickFindPanel::QuickFindPanel(weld::Widget* pParent)
+    : PanelLayout(pParent, "QuickFindPanel", 
"modules/swriter/ui/sidebarquickfind.ui")
+    , m_xSearchFindEntry(m_xBuilder->weld_entry("Find"))
+    , m_xSearchFindsList(m_xBuilder->weld_tree_view("searchfinds"))
+    , m_nRowHeight(m_xSearchFindsList->get_height_rows(4))
+    , m_pWrtShell(::GetActiveWrtShell())
+
+{
+    m_xContainer->set_size_request(MinimumPanelWidth, -1);
+    m_xSearchFindsList->set_size_request(1, m_nRowHeight);
+    m_xSearchFindEntry->connect_activate(
+        LINK(this, QuickFindPanel, SearchFindEntryActivateHandler));
+    m_xSearchFindEntry->connect_changed(LINK(this, QuickFindPanel, 
SearchFindEntryChangedHandler));
+    m_xSearchFindsList->connect_custom_get_size(
+        LINK(this, QuickFindPanel, SearchFindsListCustomGetSizeHandler));
+    m_xSearchFindsList->connect_custom_render(LINK(this, QuickFindPanel, 
SearchFindsListRender));
+    m_xSearchFindsList->set_column_custom_renderer(1, true);
+    m_xSearchFindsList->connect_changed(
+        LINK(this, QuickFindPanel, SearchFindsListSelectionChangedHandler));
+    m_xSearchFindsList->connect_row_activated(
+        LINK(this, QuickFindPanel, SearchFindsListRowActivatedHandler));
+}
+
+QuickFindPanel::~QuickFindPanel()
+{
+    m_xSearchFindEntry.reset();
+    m_xSearchFindsList.reset();
+}
+
+IMPL_LINK_NOARG(QuickFindPanel, SearchFindEntryActivateHandler, weld::Entry&, 
bool)
+{
+    FillSearchFindsList();
+    return true;
+}
+
+IMPL_LINK_NOARG(QuickFindPanel, SearchFindsListCustomGetSizeHandler, 
weld::TreeView::get_size_args,
+                Size)
+{
+    return Size(1, m_nRowHeight);
+}
+
+IMPL_LINK(QuickFindPanel, SearchFindsListRender, weld::TreeView::render_args, 
aPayload, void)
+{
+    vcl::RenderContext& rRenderContext = std::get<0>(aPayload);
+    const ::tools::Rectangle& rRect = std::get<1>(aPayload);
+    const OUString& rId = std::get<3>(aPayload);
+    int nIndex = m_xSearchFindsList->find_id(rId);
+    OUString aEntry(m_xSearchFindsList->get_text(nIndex));
+    DrawTextFlags const nTextStyle = DrawTextFlags::Left | 
DrawTextFlags::VCenter
+                                     | DrawTextFlags::MultiLine | 
DrawTextFlags::WordBreak;
+    tools::Rectangle aRect(
+        rRect.TopLeft(),
+        Size(rRenderContext.GetOutputSize().Width() - rRect.Left(), 
rRect.GetHeight()));
+    rRenderContext.DrawText(aRect, aEntry, nTextStyle);
+}
+
+IMPL_LINK_NOARG(QuickFindPanel, SearchFindsListSelectionChangedHandler, 
weld::TreeView&, void)
+{
+    std::unique_ptr<SwPaM>& rxPaM = 
m_vPaMs[m_xSearchFindsList->get_cursor_index()];
+
+    m_pWrtShell->StartAction();
+    bool bFound = false;
+    for (SwPaM& rPaM : m_pWrtShell->GetCursor()->GetRingContainer())
+    {
+        if (*rxPaM->GetPoint() == *rPaM.GetPoint() && *rxPaM->GetMark() == 
*rPaM.GetMark())
+        {
+            bFound = true;
+            break;
+        }
+        m_pWrtShell->GoNextCursor();
+    }
+    if (!bFound)
+    {
+        m_pWrtShell->AssureStdMode();
+        m_pWrtShell->SetSelection(*rxPaM);
+    }
+    m_pWrtShell->EndAction();
+
+    SwShellCursor* pShellCursor = m_pWrtShell->GetCursor_();
+    std::vector<basegfx::B2DRange> vRanges;
+    for (const SwRect& rRect : *pShellCursor)
+    {
+        tools::Rectangle aRect = rRect.SVRect();
+        vRanges.emplace_back(aRect.Left(), aRect.Top(), aRect.Right(), 
aRect.Bottom());
+    }
+    m_pWrtShell->GetView().BringToAttention(std::move(vRanges));
+}
+
+IMPL_LINK_NOARG(QuickFindPanel, SearchFindsListRowActivatedHandler, 
weld::TreeView&, bool)
+{
+    m_pWrtShell->GetView().GetEditWin().GrabFocus();
+    return true;
+}
+
+IMPL_LINK_NOARG(QuickFindPanel, SearchFindEntryChangedHandler, weld::Entry&, 
void)
+{
+    m_xSearchFindsList->clear();
+}
+
+void QuickFindPanel::FillSearchFindsList()
+{
+    m_vPaMs.clear();
+    m_xSearchFindsList->clear();
+    const OUString& sText = m_xSearchFindEntry->get_text();
+    css::uno::Sequence<css::beans::PropertyValue> 
aPropertyValues(comphelper::InitPropertySequence({
+        { "SearchItem.SearchString", css::uno::Any(sText) },
+        { "SearchItem.Backward", css::uno::Any(false) },
+        { "SearchItem.Command", 
css::uno::Any(sal_uInt16(SvxSearchCmd::FIND_ALL)) },
+    }));
+
+    comphelper::dispatchCommand(".uno:ExecuteSearch", aPropertyValues);
+
+    if (m_pWrtShell->HasMark())
+    {
+        for (SwPaM& rPaM : m_pWrtShell->GetCursor()->GetRingContainer())
+        {
+            SwPosition* pMarkPosition = rPaM.GetMark();
+            const SwContentIndex aContentIndex = pMarkPosition->nContent;
+            const SwContentNode* pContentNode = aContentIndex.GetContentNode();
+            const SwTextNode* pTextNode = pContentNode->GetTextNode();
+            const OUString& sNodeText = pTextNode->GetText();
+            auto nMarkIndex = rPaM.GetMark()->nContent.GetIndex();
+            auto nPointIndex = rPaM.GetPoint()->nContent.GetIndex();
+
+            auto nStartIndex = nMarkIndex - 50;
+            if (nStartIndex < 0)
+                nStartIndex = 0;
+            auto nEndIndex = nPointIndex + 50;
+            if (nEndIndex > sNodeText.getLength())
+            {
+                nEndIndex = sNodeText.getLength();
+            }
+            auto nCount = nMarkIndex - nStartIndex;
+            OUString sTextBeforeFind = 
OUString::Concat(sNodeText.subView(nStartIndex, nCount));
+            auto nCount1 = nPointIndex - nMarkIndex;
+            OUString sFind = OUString::Concat(sNodeText.subView(nMarkIndex, 
nCount1));
+            auto nCount2 = nEndIndex - nPointIndex;
+            OUString sTextAfterFind = 
OUString::Concat(sNodeText.subView(nPointIndex, nCount2));
+            OUString sStr = sTextBeforeFind + "[" + sFind + "]" + 
sTextAfterFind;
+
+            std::unique_ptr<SwPaM> 
xPaM(std::make_unique<SwPaM>(*rPaM.GetMark(), *rPaM.GetPoint()));
+            m_vPaMs.push_back(std::move(xPaM));
+            OUString sId = OUString::number(m_xSearchFindsList->n_children());
+            m_xSearchFindsList->append(sId, sStr);
+        }
+    }
+}
+}
+
+// end of namespace ::sw::sidebar
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/sidebar/QuickFindPanel.hxx 
b/sw/source/uibase/sidebar/QuickFindPanel.hxx
new file mode 100644
index 000000000000..af95bd18fb44
--- /dev/null
+++ b/sw/source/uibase/sidebar/QuickFindPanel.hxx
@@ -0,0 +1,42 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ */
+
+#pragma once
+#include <sfx2/sidebar/PanelLayout.hxx>
+#include <wrtsh.hxx>
+
+namespace sw::sidebar
+{
+class QuickFindPanel : public PanelLayout
+{
+public:
+    static std::unique_ptr<PanelLayout> Create(weld::Widget* pParent);
+
+    QuickFindPanel(weld::Widget* pParent);
+    virtual ~QuickFindPanel() override;
+
+private:
+    std::unique_ptr<weld::Entry> m_xSearchFindEntry;
+    std::unique_ptr<weld::TreeView> m_xSearchFindsList;
+    std::vector<std::unique_ptr<SwPaM>> m_vPaMs;
+    int m_nRowHeight;
+
+    SwWrtShell* m_pWrtShell;
+
+    DECL_LINK(SearchFindEntryActivateHandler, weld::Entry&, bool);
+    DECL_LINK(SearchFindsListCustomGetSizeHandler, 
weld::TreeView::get_size_args, Size);
+    DECL_LINK(SearchFindsListRender, weld::TreeView::render_args, void);
+    DECL_LINK(SearchFindsListSelectionChangedHandler, weld::TreeView&, void);
+    DECL_LINK(SearchFindEntryChangedHandler, weld::Entry&, void);
+    DECL_LINK(SearchFindsListRowActivatedHandler, weld::TreeView&, bool);
+    void FillSearchFindsList();
+};
+}
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/sidebar/SwPanelFactory.cxx 
b/sw/source/uibase/sidebar/SwPanelFactory.cxx
index 5ae3a781bc2d..75b7e2f17257 100644
--- a/sw/source/uibase/sidebar/SwPanelFactory.cxx
+++ b/sw/source/uibase/sidebar/SwPanelFactory.cxx
@@ -26,6 +26,7 @@
 #include "PageFormatPanel.hxx"
 #include "PageHeaderPanel.hxx"
 #include "PageFooterPanel.hxx"
+#include "QuickFindPanel.hxx"
 #include "WrapPropertyPanel.hxx"
 #include "WriterInspectorTextPanel.hxx"
 #include "TableEditPanel.hxx"
@@ -203,6 +204,12 @@ Reference<ui::XUIElement> SAL_CALL 
SwPanelFactory::createUIElement (
         xElement = sfx2::sidebar::SidebarPanelBase::Create(
                         rsResourceURL, xFrame, std::move(xPanel), 
ui::LayoutSize(-1,-1,-1));
     }
+    else if (rsResourceURL.endsWith("/QuickFindPanel"))
+    {
+        std::unique_ptr<PanelLayout> xPanel = 
sw::sidebar::QuickFindPanel::Create(pParent);
+        xElement = sfx2::sidebar::SidebarPanelBase::Create(rsResourceURL, 
xFrame, std::move(xPanel),
+                                                           ui::LayoutSize(-1, 
-1, -1));
+    }
 
     return xElement;
 }
diff --git a/sw/uiconfig/swriter/ui/sidebarquickfind.ui 
b/sw/uiconfig/swriter/ui/sidebarquickfind.ui
new file mode 100644
index 000000000000..92e3e5bdc4fc
--- /dev/null
+++ b/sw/uiconfig/swriter/ui/sidebarquickfind.ui
@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.40.0 -->
+<interface domain="sw">
+  <requires lib="gtk+" version="3.20"/>
+  <object class="GtkTreeStore" id="liststore1">
+    <columns>
+      <!-- column-name text1 -->
+      <column type="gchararray"/>
+      <!-- column-name text2 -->
+      <column type="gchararray"/>
+      <!-- column-name id -->
+      <column type="gchararray"/>
+    </columns>
+  </object>
+  <!-- n-columns=1 n-rows=1 -->
+  <object class="GtkGrid" id="QuickFindPanel">
+    <property name="visible">True</property>
+    <property name="can-focus">False</property>
+    <property name="hexpand">True</property>
+    <property name="vexpand">True</property>
+    <property name="row-spacing">6</property>
+    <property name="column-spacing">6</property>
+    <property name="row-homogeneous">True</property>
+    <property name="column-homogeneous">True</property>
+    <child>
+      <object class="GtkBox">
+        <property name="visible">True</property>
+        <property name="can-focus">False</property>
+        <property name="border-width">6</property>
+        <property name="orientation">vertical</property>
+        <property name="spacing">2</property>
+        <child>
+          <object class="GtkEntry" id="Find">
+            <property name="visible">True</property>
+            <property name="can-focus">True</property>
+            <property name="placeholder-text">Find</property>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkScrolledWindow">
+            <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="searchfinds">
+                <property name="width-request">-1</property>
+                <property name="visible">True</property>
+                <property name="can-focus">True</property>
+                <property name="hexpand">True</property>
+                <property name="vexpand">True</property>
+                <property name="border-width">0</property>
+                <property name="model">liststore1</property>
+                <property name="headers-visible">False</property>
+                <property name="enable-search">False</property>
+                <property name="search-column">1</property>
+                <property name="show-expanders">False</property>
+                <property name="activate-on-single-click">False</property>
+                <child internal-child="selection">
+                  <object class="GtkTreeSelection"/>
+                </child>
+                <child>
+                  <object class="GtkTreeViewColumn" id="treeviewcolumn0"/>
+                </child>
+                <child>
+                  <object class="GtkTreeViewColumn" id="treeviewcolumn1">
+                    <child>
+                      <object class="GtkCellRendererText" 
id="cellrenderertext"/>
+                      <attributes>
+                        <attribute name="text">0</attribute>
+                      </attributes>
+                    </child>
+                  </object>
+                </child>
+              </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">0</property>
+        <property name="top-attach">0</property>
+      </packing>
+    </child>
+  </object>
+</interface>

Reply via email to