tdf#114567 tdf#138934 Hyperlink-Target in Doc Headings expand/collapse

Provides parent child expand/collapse for Headings in the Hyperlink-
Target in Document dialog target treeview

Change-Id: I8cc57b4cbf3830cec76d64a0ef587e199c39e360
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/109930
Tested-by: Jenkins
Reviewed-by: Jim Raykowski <raykowj@gmail.com>
diff --git a/cui/source/dialogs/hlmarkwn.cxx b/cui/source/dialogs/hlmarkwn.cxx
index 8996c0e..cdc1039 100644
--- a/cui/source/dialogs/hlmarkwn.cxx
+++ b/cui/source/dialogs/hlmarkwn.cxx
@@ -283,6 +283,9 @@
// Fill Tree-Control
int SvxHlinkDlgMarkWnd::FillTree( const uno::Reference< container::XNameAccess >& xLinks, const weld::TreeIter* pParentEntry )
{
    // used to create the Headings outline parent children tree view relation
    std::stack<std::pair<std::unique_ptr<weld::TreeIter>, const sal_Int32>> aHeadingsParentEntryStack;

    int nEntries=0;
    const uno::Sequence< OUString > aNames( xLinks->getElementNames() );
    const sal_Int32 nLinks = aNames.getLength();
@@ -331,7 +334,50 @@
                OUString sId(OUString::number(reinterpret_cast<sal_Int64>(pData)));

                std::unique_ptr<weld::TreeIter> xEntry(mxLbTree->make_iterator());
                mxLbTree->insert(pParentEntry, -1, &aStrDisplayname, &sId, nullptr, nullptr, false, xEntry.get());
                if (pParentEntry)
                {
                    OUString sContentType = mxLbTree->get_text(*pParentEntry);
                    if (sContentType == "Headings")
                    {
                        if (aHeadingsParentEntryStack.empty())
                            aHeadingsParentEntryStack.push(
                                        std::pair(mxLbTree->make_iterator(pParentEntry), -1));

                        // get the headings name to display
                        aAny = xTarget->getPropertyValue("ActualOutlineName");
                        OUString sActualOutlineName;
                        aAny >>= sActualOutlineName;

                        // get the headings outline level
                        aAny = xTarget->getPropertyValue("OutlineLevel");
                        sal_Int32 nOutlineLevel;
                        aAny >>= nOutlineLevel;

                        // pop until the top of stack entry has an outline level less than
                        // the to be inserted heading outline level
                        while (nOutlineLevel <= aHeadingsParentEntryStack.top().second)
                            aHeadingsParentEntryStack.pop();

                        mxLbTree->insert(aHeadingsParentEntryStack.top().first.get(), -1,
                                         &sActualOutlineName, &sId, nullptr, nullptr, false,
                                         xEntry.get());

                        // push if the inserted entry is a child
                        if (nOutlineLevel > aHeadingsParentEntryStack.top().second)
                            aHeadingsParentEntryStack.push(
                                        std::pair(std::move(xEntry), nOutlineLevel));
                    }
                    else
                    {
                        mxLbTree->insert(pParentEntry, -1, &aStrDisplayname, &sId, nullptr,
                                         nullptr, false, xEntry.get());
                    }
                }
                else
                {
                    mxLbTree->insert(pParentEntry, -1, &aStrDisplayname, &sId, nullptr, nullptr,
                                     false, xEntry.get());
                }

                try
                {
diff --git a/cui/source/inc/hlmarkwn.hxx b/cui/source/inc/hlmarkwn.hxx
index 9552bc1..d88ddda 100644
--- a/cui/source/inc/hlmarkwn.hxx
+++ b/cui/source/inc/hlmarkwn.hxx
@@ -30,8 +30,6 @@
class SvxHlinkDlgMarkWnd : public weld::GenericDialogController
{
private:
    friend class SvxHlmarkTreeLBox;

    SvxHyperlinkTabPageBase* mpParent;

    sal_uInt16          mnError;
diff --git a/sw/inc/unotxdoc.hxx b/sw/inc/unotxdoc.hxx
index df6309d7..4dbb35b 100644
--- a/sw/inc/unotxdoc.hxx
+++ b/sw/inc/unotxdoc.hxx
@@ -558,9 +558,12 @@
{
    const SfxItemPropertySet*   m_pPropSet;
    OUString                    m_sOutlineText;
    OUString                    m_sActualText;
    const sal_Int32             m_nOutlineLevel;

public:
    SwXOutlineTarget(const OUString& rOutlineText);
    SwXOutlineTarget(const OUString& rOutlineText, const rtl::OUString &rActualText,
                     const sal_Int32 nOutlineLevel);
    virtual ~SwXOutlineTarget() override;

    //XPropertySet
diff --git a/sw/source/uibase/uno/unotxdoc.cxx b/sw/source/uibase/uno/unotxdoc.cxx
index ec2b23a..ea00f9a 100644
--- a/sw/source/uibase/uno/unotxdoc.cxx
+++ b/sw/source/uibase/uno/unotxdoc.cxx
@@ -162,6 +162,8 @@

#include <svx/svdpage.hxx>

#include <IDocumentOutlineNodes.hxx>

#define TWIPS_PER_PIXEL 15

using namespace ::com::sun::star;
@@ -1022,10 +1024,11 @@
    return nRet;
}

static OUString lcl_CreateOutlineString( size_t nIndex,
            const SwOutlineNodes& rOutlineNodes, const SwNumRule* pOutlRule)
static OUString lcl_CreateOutlineString(const size_t nIndex, const SwDoc* pDoc)
{
    OUStringBuffer sEntry;
    const SwOutlineNodes& rOutlineNodes = pDoc->GetNodes().GetOutLineNds();
    const SwNumRule* pOutlRule = pDoc->GetOutlineNumRule();
    const SwTextNode * pTextNd = rOutlineNodes[ nIndex ]->GetTextNode();
    SwNumberTree::tNumberVector aNumVector = pTextNd->GetNumberVector();
    if( pOutlRule && pTextNd->GetNumRule())
@@ -1039,8 +1042,9 @@
            sEntry.append(OUString::number( nVal ));
            sEntry.append(".");
        }
    sEntry.append( rOutlineNodes[ nIndex ]->
                    GetTextNode()->GetExpandText(nullptr) );
    OUString sOutlineText = pDoc->getIDocumentOutlineNodes().getOutlineText(
                nIndex, pDoc->GetDocShell()->GetWrtShell()->GetLayout(), false);
    sEntry.append(sOutlineText);
    return sEntry.makeStringAndClear();
}

@@ -4047,11 +4051,14 @@

                    for (size_t i = 0; i < nOutlineCount && !bFound; ++i)
                    {
                        const SwOutlineNodes& rOutlineNodes = pDoc->GetNodes().GetOutLineNds();
                        const SwNumRule* pOutlRule = pDoc->GetOutlineNumRule();
                        if(sParam == lcl_CreateOutlineString(i, rOutlineNodes, pOutlRule))
                        if(sParam == lcl_CreateOutlineString(i, pDoc))
                        {
                            Reference< XPropertySet >  xOutline = new SwXOutlineTarget(sParam);
                            OUString sOutlineText =
                                    pDoc->getIDocumentOutlineNodes().getOutlineText(
                                        i, pDoc->GetDocShell()->GetWrtShell()->GetLayout());
                            sal_Int32 nOutlineLevel = pDoc->getIDocumentOutlineNodes().getOutlineLevel(i);
                            Reference<XPropertySet> xOutline =
                                    new SwXOutlineTarget(sParam, sOutlineText, nOutlineLevel);
                            aRet <<= xOutline;
                            bFound = true;
                        }
@@ -4107,10 +4114,9 @@
            const size_t nOutlineCount = rOutlineNodes.size();
            aRet.realloc(nOutlineCount);
            OUString* pResArr = aRet.getArray();
            const SwNumRule* pOutlRule = pDoc->GetOutlineNumRule();
            for (size_t i = 0; i < nOutlineCount; ++i)
            {
                OUString sEntry = lcl_CreateOutlineString(i, rOutlineNodes, pOutlRule) + "|outline";
                OUString sEntry = lcl_CreateOutlineString(i, pDoc) + "|outline";
                pResArr[i] = sEntry;
            }
        }
@@ -4165,10 +4171,7 @@

                    for (size_t i = 0; i < nOutlineCount && !bRet; ++i)
                    {
                        const SwOutlineNodes& rOutlineNodes = pDoc->GetNodes().GetOutLineNds();
                        const SwNumRule* pOutlRule = pDoc->GetOutlineNumRule();
                        if(sParam ==
                            lcl_CreateOutlineString(i, rOutlineNodes, pOutlRule))
                        if(sParam == lcl_CreateOutlineString(i, pDoc))
                        {
                            bRet = true;
                        }
@@ -4314,9 +4317,12 @@
    return aRet;
}

SwXOutlineTarget::SwXOutlineTarget(const OUString& rOutlineText) :
SwXOutlineTarget::SwXOutlineTarget(const OUString& rOutlineText, const OUString& rActualText,
                                   const sal_Int32 nOutlineLevel) :
    m_pPropSet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_LINK_TARGET)),
    m_sOutlineText(rOutlineText)
    m_sOutlineText(rOutlineText),
    m_sActualText(rActualText),
    m_nOutlineLevel(nOutlineLevel)
{
}

@@ -4338,9 +4344,16 @@

Any SwXOutlineTarget::getPropertyValue(const OUString& rPropertyName)
{
    if(rPropertyName != UNO_LINK_DISPLAY_NAME)
    if (rPropertyName != UNO_LINK_DISPLAY_NAME && rPropertyName != "ActualOutlineName" &&
            rPropertyName != "OutlineLevel")
        throw UnknownPropertyException(rPropertyName);

    if (rPropertyName == "ActualOutlineName")
        return Any(m_sActualText);

    if (rPropertyName == "OutlineLevel")
        return Any(m_nOutlineLevel);

    return Any(m_sOutlineText);
}