include/svl/hint.hxx                           |    3 +
 svx/source/tbxctrls/tbunosearchcontrollers.cxx |    6 ++
 sw/inc/crsrsh.hxx                              |    2 
 sw/source/core/crsr/crstrvl.cxx                |    4 -
 sw/source/uibase/inc/conttree.hxx              |    2 
 sw/source/uibase/uiview/viewsrch.cxx           |    5 +
 sw/source/uibase/utlui/content.cxx             |   68 +++++++++++++++++++++++++
 7 files changed, 87 insertions(+), 3 deletions(-)

New commits:
commit 6f7f5f280abaf4ee84472359acd4952b2eea40a4
Author:     Jim Raykowski <rayk...@gmail.com>
AuthorDate: Tue Apr 21 01:49:36 2020 -0800
Commit:     Jim Raykowski <rayk...@gmail.com>
CommitDate: Sun Sep 20 08:25:24 2020 +0200

    tdf#132366 Writer enhancement that highlights search results
    
    This enhancement selects outline headings in the Writer Navigator
    content tree according to 'Find All' search results. It does this when
    the content navigation view is set to show headings content only.
    
    Change-Id: I77dabcdd38c8877b7f8a177689da094638d5fe00
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/92886
    Tested-by: Jenkins
    Reviewed-by: Jim Raykowski <rayk...@gmail.com>

diff --git a/include/svl/hint.hxx b/include/svl/hint.hxx
index 708986e31631..77e838a5d21c 100644
--- a/include/svl/hint.hxx
+++ b/include/svl/hint.hxx
@@ -112,6 +112,7 @@ enum class SfxHintId {
     SwDrawViewsCreated,
     SwSplitNodeOperation,
     SwSectionFrameMoveAndDelete,
+    SwNavigatorSelectOutlinesWithSelections,
 
     ThisIsAnSdrHint // used to avoid dynamic_cast
 };
@@ -192,6 +193,8 @@ inline std::basic_ostream<charT, traits> & operator <<(
     case SfxHintId::SwDrawViewsCreated: return stream << "SwDrawViewsCreated";
     case SfxHintId::SwSplitNodeOperation: return stream << 
"SwSplitNodeOperation";
     case SfxHintId::SwSectionFrameMoveAndDelete: return stream << 
"SwSectionFrameMoveAndDelete";
+    case SfxHintId::SwNavigatorSelectOutlinesWithSelections:
+        return stream << "SwNavigatorSelectOutlinesWithSelections";
     case SfxHintId::ThisIsAnSdrHint: return stream << "SdrHint";
     default: return stream << "unk(" << std::to_string(int(id)) << ")";
     }
diff --git a/svx/source/tbxctrls/tbunosearchcontrollers.cxx 
b/svx/source/tbxctrls/tbunosearchcontrollers.cxx
index 8372d7876c9b..a86739988185 100644
--- a/svx/source/tbxctrls/tbunosearchcontrollers.cxx
+++ b/svx/source/tbxctrls/tbunosearchcontrollers.cxx
@@ -141,7 +141,13 @@ void impl_executeSearch( const css::uno::Reference< 
css::uno::XComponentContext
             {
                 FindTextFieldControl* pItemWin = 
static_cast<FindTextFieldControl*>(pToolBox->GetItemWindow(id));
                 if (pItemWin)
+                {
                     sFindText = pItemWin->get_active_text();
+                    if (aFindAll)
+                        pItemWin->GrabFocus();
+                    else
+                        pItemWin->GrabFocusToDocument();
+                }
             } else if ( sItemCommand == COMMAND_MATCHCASE )
             {
                 CheckButtonItemWindow* pItemWin = 
static_cast<CheckButtonItemWindow*>(pToolBox->GetItemWindow(id));
diff --git a/sw/inc/crsrsh.hxx b/sw/inc/crsrsh.hxx
index 78b32299ff31..d6888bcac2cb 100644
--- a/sw/inc/crsrsh.hxx
+++ b/sw/inc/crsrsh.hxx
@@ -610,7 +610,7 @@ public:
     // to the next/previous or the given OutlineNode
     void GotoOutline( SwOutlineNodes::size_type nIdx );
     // find the "outline position" in the nodes array of the current chapter
-    SwOutlineNodes::size_type GetOutlinePos( sal_uInt8 nLevel = UCHAR_MAX );
+    SwOutlineNodes::size_type GetOutlinePos(sal_uInt8 nLevel = UCHAR_MAX, 
SwPaM* pPaM = nullptr);
     // select the given range of OutlineNodes. Optionally including the 
children
     // the sal_uInt16s are the positions in OutlineNodes-Array (EditShell)
     bool MakeOutlineSel(SwOutlineNodes::size_type nSttPos, 
SwOutlineNodes::size_type nEndPos,
diff --git a/sw/source/core/crsr/crstrvl.cxx b/sw/source/core/crsr/crstrvl.cxx
index 11589b8e4181..38676f772659 100644
--- a/sw/source/core/crsr/crstrvl.cxx
+++ b/sw/source/core/crsr/crstrvl.cxx
@@ -1132,9 +1132,9 @@ bool SwCursorShell::GotoPrevOutline()
 }
 
 /// search "outline position" before previous outline node at given level
-SwOutlineNodes::size_type SwCursorShell::GetOutlinePos( sal_uInt8 nLevel )
+SwOutlineNodes::size_type SwCursorShell::GetOutlinePos(sal_uInt8 nLevel, 
SwPaM* pPaM)
 {
-    SwPaM* pCursor = getShellCursor( true );
+    SwPaM* pCursor = pPaM ? pPaM : getShellCursor(true);
     const SwNodes& rNds = GetDoc()->GetNodes();
 
     SwNode* pNd = &(pCursor->GetNode());
diff --git a/sw/source/uibase/inc/conttree.hxx 
b/sw/source/uibase/inc/conttree.hxx
index 282a714d5634..80b9d8d69bbe 100644
--- a/sw/source/uibase/inc/conttree.hxx
+++ b/sw/source/uibase/inc/conttree.hxx
@@ -225,6 +225,8 @@ public:
 
     void Select();
 
+    void SelectOutlinesWithSelection();
+
     // return true if it has any children
     bool RequestingChildren(const weld::TreeIter& rParent);
 
diff --git a/sw/source/uibase/uiview/viewsrch.cxx 
b/sw/source/uibase/uiview/viewsrch.cxx
index bc4ac9b353ff..de7f0be5b369 100644
--- a/sw/source/uibase/uiview/viewsrch.cxx
+++ b/sw/source/uibase/uiview/viewsrch.cxx
@@ -235,6 +235,8 @@ void SwView::ExecSearch(SfxRequest& rReq)
                         lcl_emitSearchResultCallbacks(s_pSrchItem, 
m_pWrtShell.get(), /* bHighlightAll = */ false);
                 }
                 rReq.SetReturnValue(SfxBoolItem(nSlot, bRet));
+
+                m_pEditWin->GrabFocus();
             }
             break;
             case SvxSearchCmd::FIND_ALL:
@@ -244,6 +246,9 @@ void SwView::ExecSearch(SfxRequest& rReq)
                 bool bRet = SearchAll();
                 m_pWrtShell->GetSfxViewShell()->setTiledSearching(false);
 
+                GetDocShell()->Broadcast(
+                            
SfxHint(SfxHintId::SwNavigatorSelectOutlinesWithSelections));
+
                 if( !bRet )
                 {
 #if HAVE_FEATURE_DESKTOP
diff --git a/sw/source/uibase/utlui/content.cxx 
b/sw/source/uibase/utlui/content.cxx
index 36cf1449881c..97dc04351d26 100644
--- a/sw/source/uibase/utlui/content.cxx
+++ b/sw/source/uibase/utlui/content.cxx
@@ -2700,6 +2700,20 @@ void SwContentTree::Notify(SfxBroadcaster & rBC, SfxHint 
const& rHint)
     }
     switch (rHint.GetId())
     {
+        case SfxHintId::SwNavigatorSelectOutlinesWithSelections:
+        {
+            if (m_nRootType == ContentTypeId::OUTLINE)
+            {
+                SelectOutlinesWithSelection();
+                // make first selected entry visible
+                std::unique_ptr<weld::TreeIter> 
xEntry(m_xTreeView->make_iterator());
+                if (xEntry && m_xTreeView->get_selected(xEntry.get()))
+                    m_xTreeView->scroll_to_row(*xEntry);
+            }
+            else if (m_nRootType == ContentTypeId::UNKNOWN)
+                m_xTreeView->unselect_all();
+            break;
+        }
         case SfxHintId::DocChanged:
             if (!m_bIgnoreViewChange)
             {
@@ -3160,6 +3174,60 @@ IMPL_LINK_NOARG(SwContentTree, TimerUpdate, Timer *, 
void)
     }
 }
 
+void SwContentTree::SelectOutlinesWithSelection()
+{
+    SwCursor* pFirstCursor = m_pActiveShell->GetSwCursor();
+    SwCursor* pCursor = pFirstCursor;
+    std::vector<SwOutlineNodes::size_type> aOutlinePositions;
+    do
+    {
+        if (pCursor)
+        {
+            if (pCursor->HasMark())
+            {
+                
aOutlinePositions.push_back(m_pActiveShell->GetOutlinePos(UCHAR_MAX, pCursor));
+            }
+            pCursor = pCursor->GetNext();
+        }
+    } while (pCursor && pCursor != pFirstCursor);
+
+    if (!aOutlinePositions.empty())
+    {
+        // remove duplicates before selecting
+        aOutlinePositions.erase(std::unique(aOutlinePositions.begin(), 
aOutlinePositions.end()),
+                                aOutlinePositions.end());
+
+        m_xTreeView->unselect_all();
+
+        for (auto nOutlinePosition : aOutlinePositions)
+        {
+            m_xTreeView->all_foreach([this, nOutlinePosition](const 
weld::TreeIter& rEntry){
+                if (lcl_IsContent(rEntry, *m_xTreeView) &&
+                        reinterpret_cast<SwContent*>(
+                        
m_xTreeView->get_id(rEntry).toInt64())->GetParent()->GetType() ==
+                        ContentTypeId::OUTLINE)
+                {
+                    if (reinterpret_cast<SwOutlineContent*>(
+                            
m_xTreeView->get_id(rEntry).toInt64())->GetOutlinePos() ==
+                            nOutlinePosition)
+                    {
+                        std::unique_ptr<weld::TreeIter> xParent =
+                                m_xTreeView->make_iterator(&rEntry);
+                        if (m_xTreeView->iter_parent(*xParent) &&
+                                !m_xTreeView->get_row_expanded(*xParent))
+                            m_xTreeView->expand_row(*xParent);
+                        m_xTreeView->select(rEntry);
+                        return true;
+                    }
+                }
+                return false;
+            });
+        }
+
+        Select();
+    }
+}
+
 void SwContentTree::MoveOutline(SwOutlineNodes::size_type nTargetPos)
 {
     SwWrtShell *const pShell = GetWrtShell();
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to