tdf#142447 related: SwNavigator: Copy outlines

Change-Id: Ibfc173ab6db3d9cbb1e8c59b515c40f1846f1e42
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/129542
Tested-by: Jenkins
Reviewed-by: Jim Raykowski <raykowj@gmail.com>
diff --git a/sw/source/uibase/inc/conttree.hxx b/sw/source/uibase/inc/conttree.hxx
index 2de7dc5..9f595de 100644
--- a/sw/source/uibase/inc/conttree.hxx
+++ b/sw/source/uibase/inc/conttree.hxx
@@ -158,6 +158,7 @@ class SwContentTree final : public SfxListener
    void            ExecuteContextMenuAction(const OString& rSelectedPopupEntry);

    void DeleteOutlineSelections();
    void CopyOutlineSelections();

    size_t GetEntryCount() const;

diff --git a/sw/source/uibase/utlui/content.cxx b/sw/source/uibase/utlui/content.cxx
index c793f63..6194247 100644
--- a/sw/source/uibase/utlui/content.cxx
+++ b/sw/source/uibase/utlui/content.cxx
@@ -1426,6 +1426,7 @@ IMPL_LINK(SwContentTree, CommandHdl, const CommandEvent&, rCEvt, bool)

    bool bRemovePostItEntries = true;
    bool bRemoveIndexEntries = true;
    bool bRemoveCopyEntry = true;
    bool bRemoveEditEntry = true;
    bool bRemoveUnprotectEntry = true;
    bool bRemoveDeleteEntry = true;
@@ -1569,6 +1570,7 @@ IMPL_LINK(SwContentTree, CommandHdl, const CommandEvent&, rCEvt, bool)
                    bRemoveSelectEntry = false;
                    bRemoveChapterEntries = false;
                }
                bRemoveCopyEntry = false;
            }
            else if (!bReadonly && (bEditable || bDeletable))
            {
@@ -1704,7 +1706,11 @@ IMPL_LINK(SwContentTree, CommandHdl, const CommandEvent&, rCEvt, bool)
            bRemoveSendOutlineEntry)
        xPop->remove("separator1");

    if (bRemoveCopyEntry)
        xPop->remove("copy");

    if (bRemoveGotoEntry &&
            bRemoveCopyEntry &&
            bRemoveSelectEntry &&
            bRemoveDeleteEntry &&
            bRemoveChapterEntries &&
@@ -4053,6 +4059,8 @@ IMPL_LINK(SwContentTree, KeyInputHdl, const KeyEvent&, rEvent, bool)
                        ExecCommand("chapterup", !aCode.IsShift());
                    else if (aCode.GetCode() == KEY_DOWN)
                        ExecCommand("chapterdown", !aCode.IsShift());
                    else if (aCode.GetCode() == KEY_C)
                        CopyOutlineSelections();
                    else
                        bConsumed = false;
                }
@@ -4168,6 +4176,11 @@ IMPL_LINK(SwContentTree, QueryTooltipHdl, const weld::TreeIter&, rEntry, OUStrin

void SwContentTree::ExecuteContextMenuAction(const OString& rSelectedPopupEntry)
{
    if (rSelectedPopupEntry == "copy")
    {
        CopyOutlineSelections();
        return;
    }
    if (rSelectedPopupEntry == "collapseallcategories")
    {
        std::unique_ptr<weld::TreeIter> xEntry = m_xTreeView->make_iterator();
@@ -4870,6 +4883,32 @@ static void lcl_AssureStdModeAtShell(SwWrtShell* pWrtShell)
        pWrtShell->EnterStdMode();
}

void SwContentTree::CopyOutlineSelections()
{
    m_pActiveShell->LockView(true);
    {
        MakeAllOutlineContentTemporarilyVisible a(m_pActiveShell->GetDoc());
        lcl_AssureStdModeAtShell(m_pActiveShell);
        m_pActiveShell->EnterAddMode();
        size_t nCount = m_xTreeView->get_selected_rows().size();
        m_xTreeView->selected_foreach([this, &nCount](weld::TreeIter& rEntry){
            SwOutlineNodes::size_type nOutlinePos = reinterpret_cast<SwOutlineContent*>(
                        m_xTreeView->get_id(rEntry).toInt64())->GetOutlinePos();
            m_pActiveShell->SttSelect();
            m_pActiveShell->MakeOutlineSel(nOutlinePos, nOutlinePos,
                                           !m_xTreeView->get_row_expanded(rEntry), false);
            // don't move if this is the last selected outline or the cursor is at start of para
            if (--nCount && !m_pActiveShell->IsSttPara())
                m_pActiveShell->Right(CRSR_SKIP_CHARS, true, 1, false);
            m_pActiveShell->EndSelect();
            return false;
        });
        m_pActiveShell->LeaveAddMode();
        m_pActiveShell->GetView().GetViewFrame()->GetBindings().Execute(SID_COPY);
    }
    m_pActiveShell->LockView(false);
}

void SwContentTree::GotoContent(const SwContent* pCnt)
{
    m_nLastGotoContentWasOutlinePos = SwOutlineNodes::npos;
diff --git a/sw/uiconfig/swriter/ui/navigatorcontextmenu.ui b/sw/uiconfig/swriter/ui/navigatorcontextmenu.ui
index e393685..d7619e6 100644
--- a/sw/uiconfig/swriter/ui/navigatorcontextmenu.ui
+++ b/sw/uiconfig/swriter/ui/navigatorcontextmenu.ui
@@ -45,6 +45,15 @@
      </object>
    </child>
    <child>
      <object class="GtkMenuItem" id="copy">
        <property name="visible">True</property>
        <property name="can-focus">False</property>
        <property name="label" translatable="yes" context="navigatorcontextmenu|STR_COPY_ENTRY">_Copy</property>
        <property name="use-underline">True</property>
        <accelerator key="C" signal="activate" modifiers="GDK_CONTROL_MASK"/>
      </object>
    </child>
    <child>
      <object class="GtkMenuItem" id="806">
        <property name="visible">True</property>
        <property name="can-focus">False</property>