Resolves: tdf#154535 create the OXFormsDescriptor on-demand

so we don't cause an unwanted Binding to be created unless we are forced
to.

Change-Id: Id78cbbb72ebd4e78b82a1ba614bbcb6488d04ce4
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/150774
Tested-by: Jenkins
Reviewed-by: Michael Stahl <michael.stahl@allotropia.de>
diff --git a/include/svx/xmlexchg.hxx b/include/svx/xmlexchg.hxx
index e03bdb4..73137c9 100644
--- a/include/svx/xmlexchg.hxx
+++ b/include/svx/xmlexchg.hxx
@@ -23,6 +23,7 @@
#include <rtl/ustring.hxx>
#include <vcl/transfer.hxx>
#include <svx/svxdllapi.h>
#include <functional>

namespace com::sun::star::beans {
    class SAL_NO_VTABLE XPropertySet;
@@ -61,17 +62,17 @@ namespace svx
            virtual void        AddSupportedFormats() override;
            virtual bool GetData( const css::datatransfer::DataFlavor& rFlavor, const OUString& rDestDoc ) override;

            OXFormsDescriptor m_aDescriptor;
            std::function<OXFormsDescriptor()> m_getDescriptorFunc;

        public:

            /** construct the transferable
            */
            OXFormsTransferable( const OXFormsDescriptor &rhs );
            OXFormsTransferable(const std::function<OXFormsDescriptor()>& getDescriptorFunc);

            /** extracts an xform descriptor from the transferable given
            */
            static const OXFormsDescriptor &extractDescriptor( const TransferableDataHelper& _rData );
            static OXFormsDescriptor extractDescriptor( const TransferableDataHelper& _rData );
    };


diff --git a/svx/source/fmcomp/xmlexchg.cxx b/svx/source/fmcomp/xmlexchg.cxx
index 1f8d44e..86bc1bb 100644
--- a/svx/source/fmcomp/xmlexchg.cxx
+++ b/svx/source/fmcomp/xmlexchg.cxx
@@ -27,8 +27,8 @@ namespace svx

    using namespace ::com::sun::star::datatransfer;

    OXFormsTransferable::OXFormsTransferable( const OXFormsDescriptor &rhs ) :
        m_aDescriptor(rhs)
    OXFormsTransferable::OXFormsTransferable(const std::function<OXFormsDescriptor()>& getDescriptorFunc) :
        m_getDescriptorFunc(getDescriptorFunc)
    {
    }

@@ -47,13 +47,13 @@ namespace svx
        return false;
    }

    const OXFormsDescriptor &OXFormsTransferable::extractDescriptor( const TransferableDataHelper &_rData ) {

    OXFormsDescriptor OXFormsTransferable::extractDescriptor( const TransferableDataHelper &_rData )
    {
        using namespace ::com::sun::star::uno;
        Reference<XTransferable> &transfer = const_cast<Reference<XTransferable> &>(_rData.GetTransferable());
        XTransferable *pInterface = transfer.get();
        OXFormsTransferable& rThis = dynamic_cast<OXFormsTransferable&>(*pInterface);
        return rThis.m_aDescriptor;
        return rThis.m_getDescriptorFunc();
    }

}
diff --git a/svx/source/form/datanavi.cxx b/svx/source/form/datanavi.cxx
index 635e55c..ee4a12f 100644
--- a/svx/source/form/datanavi.cxx
+++ b/svx/source/form/datanavi.cxx
@@ -300,19 +300,29 @@ namespace svxform
                return;
        }

        OXFormsDescriptor desc;
        desc.szName = m_xItemList->get_text(*m_xScratchIter);
        if(pItemNode->m_xNode.is()) {
            // a valid node interface tells us that we need to create a control from a binding
            desc.szServiceName = GetServiceNameForNode(pItemNode->m_xNode);
            desc.xPropSet = GetBindingForNode(pItemNode->m_xNode);
            DBG_ASSERT( desc.xPropSet.is(), "DataTreeListBox::StartDrag(): invalid node binding" );
        }
        else {
            desc.szServiceName = FM_COMPONENT_COMMANDBUTTON;
            desc.xPropSet = pItemNode->m_xPropSet;
        }
        xTransferable = rtl::Reference<TransferDataContainer>(new OXFormsTransferable(desc));
        OUString szName = m_xItemList->get_text(*m_xScratchIter);
        Reference<css::xml::dom::XNode> xNode(pItemNode->m_xNode);
        Reference<XPropertySet> xPropSet(pItemNode->m_xPropSet);

        // tdf#154535 create the OXFormsDescriptor on-demand so we don't cause an unwanted
        // Binding to be created unless we are forced to.
        auto fnCreateFormsDescriptor = [this, szName, xNode, xPropSet](){
            OXFormsDescriptor desc;
            desc.szName = szName;
            if (xNode) {
                // a valid node interface tells us that we need to create a control from a binding
                desc.szServiceName = GetServiceNameForNode(xNode);
                desc.xPropSet = GetBindingForNode(xNode);
                DBG_ASSERT( desc.xPropSet.is(), "DataTreeListBox::StartDrag(): invalid node binding" );
            }
            else {
                desc.szServiceName = FM_COMPONENT_COMMANDBUTTON;
                desc.xPropSet = xPropSet;
            }
            return desc;
        };

        xTransferable = rtl::Reference<TransferDataContainer>(new OXFormsTransferable(fnCreateFormsDescriptor));
        m_xItemList->enable_drag_source(xTransferable, DND_ACTION_COPY);
    }

diff --git a/sw/source/uibase/dochdl/swdtflvr.cxx b/sw/source/uibase/dochdl/swdtflvr.cxx
index ee8bec1..3d8fe6b 100644
--- a/sw/source/uibase/dochdl/swdtflvr.cxx
+++ b/sw/source/uibase/dochdl/swdtflvr.cxx
@@ -3236,8 +3236,8 @@ bool SwTransferable::PasteDBData( const TransferableDataHelper& rData,
            FmFormView* pFmView = dynamic_cast<FmFormView*>( rSh.GetDrawView()  );
            if (pFmView && pDragPt)
            {
                const OXFormsDescriptor &rDesc = OXFormsTransferable::extractDescriptor(rData);
                rtl::Reference<SdrObject> pObj = pFmView->CreateXFormsControl(rDesc);
                OXFormsDescriptor aDesc = OXFormsTransferable::extractDescriptor(rData);
                rtl::Reference<SdrObject> pObj = pFmView->CreateXFormsControl(aDesc);
                if(pObj)
                {
                    rSh.SwFEShell::InsertDrawObj( *pObj, *pDragPt );