base work to trigger pivot table filter popup with a callback

Change-Id: I5b85a760eb1f3f9090fbbd02f5510878ad3c51c2
Reviewed-on: https://gerrit.libreoffice.org/34007
Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
Tested-by: Tomaž Vajngerl <quikee@gmail.com>
diff --git a/sc/source/ui/inc/dbfunc.hxx b/sc/source/ui/inc/dbfunc.hxx
index ad71348..e407580 100644
--- a/sc/source/ui/inc/dbfunc.hxx
+++ b/sc/source/ui/inc/dbfunc.hxx
@@ -86,6 +86,7 @@ public:
    void DataPilotInput( const ScAddress& rPos, const OUString& rString );

    void            DataPilotSort( const ScAddress& rPos, bool bAscending, sal_uInt16* pUserListId = nullptr );
    void            DataPilotSort(ScDPObject* pDPObject, long nDimIndex, bool bAscending, sal_uInt16* pUserListId = nullptr);
    bool            DataPilotMove( const ScRange& rSource, const ScAddress& rDest );

    bool HasSelectionForDrillDown( sal_uInt16& rOrientation );
diff --git a/sc/source/ui/inc/gridwin.hxx b/sc/source/ui/inc/gridwin.hxx
index 709b388..dff2da7 100644
--- a/sc/source/ui/inc/gridwin.hxx
+++ b/sc/source/ui/inc/gridwin.hxx
@@ -213,8 +213,8 @@ class ScGridWindow : public vcl::Window, public DropTargetHelper, public DragSou
     *         mouse event handling is necessary, false otherwise.
     */
    bool DPTestFieldPopupArrow(const MouseEvent& rMEvt, const ScAddress& rPos, const ScAddress& rDimPos, ScDPObject* pDPObj);
    void            DPLaunchFieldPopupMenu(
        const Point& rScrPos, const Size& rScrSize, const ScAddress& rPos, ScDPObject* pDPObj);

    void DPLaunchFieldPopupMenu(const Point& rScrPos, const Size& rScrSize, const ScAddress& rPos, ScDPObject* pDPObj);

    void            RFMouseMove( const MouseEvent& rMEvt, bool bUp );

@@ -364,6 +364,9 @@ public:

    css::sheet::DataPilotFieldOrientation GetDPFieldOrientation( SCCOL nCol, SCROW nRow ) const;

    void DPLaunchFieldPopupMenu(const Point& rScrPos, const Size& rScrSize,
                                long nDimIndex, ScDPObject* pDPObj);

    void DrawButtons(SCCOL nX1, SCCOL nX2, const ScTableInfo& rTabInfo, OutputDevice* pContentDev);

    using Window::Draw;
diff --git a/sc/source/ui/inc/tabview.hxx b/sc/source/ui/inc/tabview.hxx
index 5afc3d3..d7c659e 100644
--- a/sc/source/ui/inc/tabview.hxx
+++ b/sc/source/ui/inc/tabview.hxx
@@ -482,6 +482,7 @@ public:
    void            ClearHighlightRanges();

    void            DoChartSelection( const css::uno::Sequence< css::chart2::data::HighlightedRange > & rHilightRanges );
    void            DoDPFieldPopup(Point aPoint, Size aSize);

    long            GetGridWidth( ScHSplitPos eWhich );
    long            GetGridHeight( ScVSplitPos eWhich );
diff --git a/sc/source/ui/view/dbfunc3.cxx b/sc/source/ui/view/dbfunc3.cxx
index 1a35636..d298d39 100644
--- a/sc/source/ui/view/dbfunc3.cxx
+++ b/sc/source/ui/view/dbfunc3.cxx
@@ -1610,10 +1610,8 @@ struct ScOUStringCollate
    }
};

void ScDBFunc::DataPilotSort( const ScAddress& rPos, bool bAscending, sal_uInt16* pUserListId )
void ScDBFunc::DataPilotSort(ScDPObject* pDPObj, long nDimIndex, bool bAscending, sal_uInt16* pUserListId)
{
    ScDocument* pDoc = GetViewData().GetDocument();
    ScDPObject* pDPObj = pDoc->GetDPAtCursor(rPos.Col(), rPos.Row(), rPos.Tab());
    if (!pDPObj)
        return;

@@ -1621,8 +1619,6 @@ void ScDBFunc::DataPilotSort( const ScAddress& rPos, bool bAscending, sal_uInt16
    if ( pUserListId )
        pDPObj->BuildAllDimensionMembers();

    sal_uInt16 nOrientation;
    long nDimIndex = pDPObj->GetHeaderDim(rPos, nOrientation);
    if (nDimIndex < 0)
        // Invalid dimension index.  Bail out.
        return;
@@ -1750,6 +1746,22 @@ void ScDBFunc::DataPilotSort( const ScAddress& rPos, bool bAscending, sal_uInt16
    aFunc.DataPilotUpdate(pDPObj, pNewObj.get(), true, false);
}

void ScDBFunc::DataPilotSort( const ScAddress& rPos, bool bAscending, sal_uInt16* pUserListId )
{
    ScDocument* pDoc = GetViewData().GetDocument();
    ScDPObject* pDPObj = pDoc->GetDPAtCursor(rPos.Col(), rPos.Row(), rPos.Tab());
    if (!pDPObj)
        return;

    sal_uInt16 nOrientation;
    long nDimIndex = pDPObj->GetHeaderDim(rPos, nOrientation);
    if (nDimIndex < 0)
        // Invalid dimension index.  Bail out.
        return;

    DataPilotSort(pDPObj, nDimIndex, bAscending, pUserListId);
}

bool ScDBFunc::DataPilotMove( const ScRange& rSource, const ScAddress& rDest )
{
    bool bRet = false;
diff --git a/sc/source/ui/view/gridwin2.cxx b/sc/source/ui/view/gridwin2.cxx
index 270a568..66e9dcf 100644
--- a/sc/source/ui/view/gridwin2.cxx
+++ b/sc/source/ui/view/gridwin2.cxx
@@ -400,21 +400,27 @@ class PopupSortAction : public ScMenuFloatingWindow::Action
public:
    enum SortType { ASCENDING, DESCENDING, CUSTOM };

    explicit PopupSortAction(const ScAddress& rPos, SortType eType, sal_uInt16 nUserListIndex, ScTabViewShell* pViewShell) :
        maPos(rPos), meType(eType), mnUserListIndex(nUserListIndex), mpViewShell(pViewShell) {}
    explicit PopupSortAction(ScDPObject* pDPObject, long nDimIndex, SortType eType,
                             sal_uInt16 nUserListIndex, ScTabViewShell* pViewShell)
        : mpDPObject(pDPObject)
        , mnDimIndex(nDimIndex)
        , meType(eType)
        , mnUserListIndex(nUserListIndex)
        , mpViewShell(pViewShell)
    {}

    virtual void execute() override
    {
        switch (meType)
        {
            case ASCENDING:
                mpViewShell->DataPilotSort(maPos, true);
                mpViewShell->DataPilotSort(mpDPObject, mnDimIndex, true);
            break;
            case DESCENDING:
                mpViewShell->DataPilotSort(maPos, false);
                mpViewShell->DataPilotSort(mpDPObject, mnDimIndex, false);
            break;
            case CUSTOM:
                mpViewShell->DataPilotSort(maPos, true, &mnUserListIndex);
                mpViewShell->DataPilotSort(mpDPObject, mnDimIndex, true, &mnUserListIndex);
            break;
            default:
                ;
@@ -422,7 +428,8 @@ public:
    }

private:
    ScAddress       maPos;
    ScDPObject*     mpDPObject;
    long            mnDimIndex;
    SortType        meType;
    sal_uInt16      mnUserListIndex;
    ScTabViewShell* mpViewShell;
@@ -430,12 +437,21 @@ private:

}

void ScGridWindow::DPLaunchFieldPopupMenu(
    const Point& rScrPos, const Size& rScrSize, const ScAddress& rPos, ScDPObject* pDPObj)
void ScGridWindow::DPLaunchFieldPopupMenu(const Point& rScreenPosition, const Size& rScreenSize,
                                          const ScAddress& rAddress, ScDPObject* pDPObject)
{
    sal_uInt16 nOrient;
    long nDimIndex = pDPObject->GetHeaderDim(rAddress, nOrient);

    DPLaunchFieldPopupMenu(rScreenPosition, rScreenSize, nDimIndex, pDPObject);
}

void ScGridWindow::DPLaunchFieldPopupMenu(const Point& rScrPos, const Size& rScrSize,
                                          long nDimIndex, ScDPObject* pDPObj)
{
    std::unique_ptr<DPFieldPopupData> pDPData(new DPFieldPopupData);
    sal_uInt16 nOrient;
    pDPData->mnDim = pDPObj->GetHeaderDim(rPos, nOrient);
    pDPData->mnDim = nDimIndex;
    pDPObj->GetSource();

    bool bIsDataLayout;
    OUString aDimName = pDPObj->GetDimName(pDPData->mnDim, bIsDataLayout);
@@ -493,10 +509,10 @@ void ScGridWindow::DPLaunchFieldPopupMenu(
        ScTabViewShell* pViewShell = pViewData->GetViewShell();
        mpDPFieldPopup->addMenuItem(
            SC_RESSTR(STR_MENU_SORT_ASC),
            new PopupSortAction(rPos, PopupSortAction::ASCENDING, 0, pViewShell));
            new PopupSortAction(pDPObj, nDimIndex, PopupSortAction::ASCENDING, 0, pViewShell));
        mpDPFieldPopup->addMenuItem(
            SC_RESSTR(STR_MENU_SORT_DESC),
            new PopupSortAction(rPos, PopupSortAction::DESCENDING, 0, pViewShell));
            new PopupSortAction(pDPObj, nDimIndex, PopupSortAction::DESCENDING, 0, pViewShell));
        ScMenuFloatingWindow* pSubMenu = mpDPFieldPopup->addSubMenuItem(
            SC_RESSTR(STR_MENU_SORT_CUSTOM), !aUserSortNames.empty());

@@ -507,7 +523,7 @@ void ScGridWindow::DPLaunchFieldPopupMenu(
            {
                pSubMenu->addMenuItem(
                    aUserSortNames[i],
                    new PopupSortAction(rPos, PopupSortAction::CUSTOM, static_cast<sal_uInt16>(i), pViewShell));
                    new PopupSortAction(pDPObj, nDimIndex, PopupSortAction::CUSTOM, sal_uInt16(i), pViewShell));
            }
        }
    }
diff --git a/sc/source/ui/view/tabview3.cxx b/sc/source/ui/view/tabview3.cxx
index 653e475..7690d4b 100644
--- a/sc/source/ui/view/tabview3.cxx
+++ b/sc/source/ui/view/tabview3.cxx
@@ -2465,6 +2465,29 @@ void ScTabView::DoChartSelection(
    }
}

void ScTabView::DoDPFieldPopup(Point aPoint, Size /*aSize*/)
{
    ScDocument& rDocument = aViewData.GetDocShell()->GetDocument();
    ScGridWindow* pWin = pGridWin[aViewData.GetActivePart()].get();
    if (!pWin)
        return;

    ScDPCollection* pDPs = rDocument.GetDPCollection();
    // TODO - DP name should be a parameter
    ScDPObject* pDPObj = pDPs->GetByName("DataPilot1");

    pDPObj->BuildAllDimensionMembers();

    //const ScDPSaveData* pSaveData = pDPObj->GetSaveData();
    //bool bIsDataLayout;
    //OUString aDimName = pDPObj->GetDimName(0, bIsDataLayout);

    Point aScreenPoint = pWin->OutputToScreenPixel(pWin->LogicToPixel(aPoint));
    //Size aScreenSize = pWin->LogicToPixel(aSize);

    pWin->DPLaunchFieldPopupMenu(aScreenPoint, Size(1, 1), 1, pDPObj);
}

//  PaintGrid - repaint data range

void ScTabView::PaintGrid()
diff --git a/sc/source/ui/view/tabvwshb.cxx b/sc/source/ui/view/tabvwshb.cxx
index 76877a8..bdf391f 100644
--- a/sc/source/ui/view/tabvwshb.cxx
+++ b/sc/source/ui/view/tabvwshb.cxx
@@ -98,6 +98,30 @@ void ScTabViewShell::ConnectObject( SdrOle2Obj* pObj )
    }
}

class PopupCallback : public cppu::WeakImplHelper<css::awt::XCallback>
{
    ScTabViewShell* m_pViewShell;
    SdrOle2Obj* m_pObject;

public:
    explicit PopupCallback(ScTabViewShell* pViewShell, SdrOle2Obj* pObject)
        : m_pViewShell(pViewShell)
        , m_pObject(pObject)
    {}

    // XCallback
    virtual void SAL_CALL notify(const css::uno::Any& /*aData*/) override
    {
        Rectangle aRect = m_pObject->GetLogicRect();
        m_pViewShell->DoDPFieldPopup(aRect.TopLeft(), aRect.GetSize());
    }

    virtual void SAL_CALL disposing()
    {
        m_pViewShell = nullptr;
    }
};

void ScTabViewShell::ActivateObject( SdrOle2Obj* pObj, long nVerb )
{
    // Do not leave the hint message box on top of the object
@@ -183,12 +207,19 @@ void ScTabViewShell::ActivateObject( SdrOle2Obj* pObj, long nVerb )
                            xSup->getComponent(), uno::UNO_QUERY_THROW );
                        uno::Reference< chart2::data::XRangeHighlighter > xRangeHightlighter(
                            xDataReceiver->getRangeHighlighter());
                        if( xRangeHightlighter.is())
                        if (xRangeHightlighter.is())
                        {
                            uno::Reference< view::XSelectionChangeListener > xListener(
                                new ScChartRangeSelectionListener( this ));
                            xRangeHightlighter->addSelectionChangeListener( xListener );
                        }
                        uno::Reference<chart2::data::XPopupRequest> xPopupRequest(xDataReceiver->getPopupRequest());
                        if (xPopupRequest.is())
                        {
                            uno::Reference<awt::XCallback> xCallback(new PopupCallback(this, pObj));
                            uno::Any aAny;
                            xPopupRequest->addCallback(xCallback, aAny);
                        }
                    }
                    catch( const uno::Exception & )
                    {