lokdialog: do not lock events when opened ScFilter Dialog

When exists 2 or more views and one of the views open the ScFilter dialog,
the other views are locked and no event process.

In tiled rendering case, collaborative editing is not functional with 2 or
more views are locked, so the patch prevents locking the other views

Change-Id: I0133d38ac5ecef4d3ebc22f3e922602704dcd0b3
Reviewed-on: https://gerrit.libreoffice.org/51370
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Henry Castro <hcastro@collabora.com>
diff --git a/sc/qa/unit/tiledrendering/tiledrendering.cxx b/sc/qa/unit/tiledrendering/tiledrendering.cxx
index 2eba199..cdd9af6 100644
--- a/sc/qa/unit/tiledrendering/tiledrendering.cxx
+++ b/sc/qa/unit/tiledrendering/tiledrendering.cxx
@@ -30,10 +30,12 @@

#include <comphelper/lok.hxx>
#include <comphelper/propertyvalue.hxx>
#include <sfx2/childwin.hxx>
#include <sfx2/lokhelper.hxx>
#include <svx/svdpage.hxx>
#include <vcl/scheduler.hxx>
#include <vcl/vclevent.hxx>
#include <sc.hrc>

#include <chrono>
#include <cstddef>
@@ -91,6 +93,7 @@ public:
    void testLanguageStatus();
    void testMultiViewCopyPaste();
    void testIMESupport();
    void testFilterDlg();

    CPPUNIT_TEST_SUITE(ScTiledRenderingTest);
    CPPUNIT_TEST(testRowColumnSelections);
@@ -122,6 +125,7 @@ public:
    CPPUNIT_TEST(testLanguageStatus);
    CPPUNIT_TEST(testMultiViewCopyPaste);
    CPPUNIT_TEST(testIMESupport);
    CPPUNIT_TEST(testFilterDlg);
    CPPUNIT_TEST_SUITE_END();

private:
@@ -1608,6 +1612,45 @@ void ScTiledRenderingTest::testIMESupport()
    comphelper::LibreOfficeKit::setActive(false);
}

void ScTiledRenderingTest::testFilterDlg()
{
    comphelper::LibreOfficeKit::setActive();

    createDoc("empty.ods");

    // view #1
    SfxViewShell* pView1 = SfxViewShell::Current();
    int nView1 = SfxLokHelper::getView();

    // view #2
    SfxLokHelper::createView();
    SfxViewShell* pView2 = SfxViewShell::Current();
    CPPUNIT_ASSERT(pView1 != pView2);
    {
        pView2->GetViewFrame()->GetDispatcher()->Execute(SID_FILTER,
            SfxCallMode::SLOT|SfxCallMode::RECORD);
    }

    Scheduler::ProcessEventsToIdle();
    SfxChildWindow* pRefWindow = pView2->GetViewFrame()->GetChildWindow(SID_FILTER);
    CPPUNIT_ASSERT(pRefWindow);

    // switch to view 1
    SfxLokHelper::setView(nView1);
    CPPUNIT_ASSERT_EQUAL(true, pView2->GetViewFrame()->GetDispatcher()->IsLocked());
    CPPUNIT_ASSERT_EQUAL(false, pView1->GetViewFrame()->GetDispatcher()->IsLocked());

    KeyEvent aEvent(27, KEY_ESCAPE, 0);
    Application::PostKeyEvent(VclEventId::WindowKeyInput, pRefWindow->GetWindow(), &aEvent);
    Application::PostKeyEvent(VclEventId::WindowKeyUp, pRefWindow->GetWindow(), &aEvent);

    Scheduler::ProcessEventsToIdle();
    CPPUNIT_ASSERT_EQUAL(false, pView2->GetViewFrame()->GetDispatcher()->IsLocked());
    CPPUNIT_ASSERT_EQUAL(false, pView1->GetViewFrame()->GetDispatcher()->IsLocked());

    comphelper::LibreOfficeKit::setActive(false);
}

}

CPPUNIT_TEST_SUITE_REGISTRATION(ScTiledRenderingTest);
diff --git a/sc/source/ui/app/scmod.cxx b/sc/source/ui/app/scmod.cxx
index 8cd2725..29c2c33 100644
--- a/sc/source/ui/app/scmod.cxx
+++ b/sc/source/ui/app/scmod.cxx
@@ -1554,20 +1554,25 @@ void ScModule::SetRefDialog( sal_uInt16 nId, bool bVis, SfxViewFrame* pViewFrm )
    }
}

static SfxChildWindow* lcl_GetChildWinFromAnyView( sal_uInt16 nId )
static inline SfxChildWindow* lcl_GetChildWinFromCurrentView( sal_uInt16 nId )
{
    // First, try the current view
    SfxViewFrame* pViewFrm = SfxViewFrame::Current();

    // #i46999# current view frame can be null (for example, when closing help)
    SfxChildWindow* pChildWnd = pViewFrm ? pViewFrm->GetChildWindow( nId ) : nullptr;
    return pViewFrm ? pViewFrm->GetChildWindow( nId ) : nullptr;
}

static SfxChildWindow* lcl_GetChildWinFromAnyView( sal_uInt16 nId )
{
    // First, try the current view
    SfxChildWindow* pChildWnd = lcl_GetChildWinFromCurrentView( nId );
    if ( pChildWnd )
        return pChildWnd;           // found in the current view

    //  if not found there, get the child window from any open view
    //  it can be open only in one view because nCurRefDlgId is global

    pViewFrm = SfxViewFrame::GetFirst();
    SfxViewFrame* pViewFrm = SfxViewFrame::GetFirst();
    while ( pViewFrm )
    {
        pChildWnd = pViewFrm->GetChildWindow( nId );
@@ -1588,7 +1593,7 @@ bool ScModule::IsModalMode(SfxObjectShell* pDocSh)

    if ( nCurRefDlgId )
    {
        SfxChildWindow* pChildWnd = lcl_GetChildWinFromAnyView( nCurRefDlgId );
        SfxChildWindow* pChildWnd = lcl_GetChildWinFromCurrentView( nCurRefDlgId );
        if ( pChildWnd )
        {
            IAnyRefDialog* pRefDlg = dynamic_cast<IAnyRefDialog*>(pChildWnd->GetWindow());
@@ -1596,15 +1601,6 @@ bool ScModule::IsModalMode(SfxObjectShell* pDocSh)
            bIsModal = pChildWnd->IsVisible() && pRefDlg &&
                !( pRefDlg->IsRefInputMode() && pRefDlg->IsDocAllowed(pDocSh) );
        }
        else
        {
            // in 592 and above, the dialog isn't visible in other views
            //  if the dialog is open but can't be accessed, disable input
            bIsModal = true;
        }

        //  pChildWnd can be 0 if the dialog has not been created by another Shell yet after
        //  switching over(e.g. in GetFocus())
    }
    else if (pDocSh)
    {
@@ -1650,11 +1646,9 @@ bool ScModule::IsRefDialogOpen()

    if ( nCurRefDlgId )
    {
        SfxChildWindow* pChildWnd = lcl_GetChildWinFromAnyView( nCurRefDlgId );
        SfxChildWindow* pChildWnd = lcl_GetChildWinFromCurrentView( nCurRefDlgId );
        if ( pChildWnd )
            bIsOpen = pChildWnd->IsVisible();
        else
            bIsOpen = true;     // for other views, see IsModalMode
    }

    return bIsOpen;
@@ -1674,15 +1668,13 @@ bool ScModule::IsFormulaMode()

    if ( nCurRefDlgId )
    {
        SfxChildWindow* pChildWnd = lcl_GetChildWinFromAnyView( nCurRefDlgId );
        SfxChildWindow* pChildWnd = lcl_GetChildWinFromCurrentView( nCurRefDlgId );
        if ( pChildWnd )
        {
            IAnyRefDialog* pRefDlg = dynamic_cast<IAnyRefDialog*>(pChildWnd->GetWindow());
            assert(pRefDlg);
            bIsFormula = pChildWnd->IsVisible() && pRefDlg && pRefDlg->IsRefInputMode();
        }
        else
            bIsFormula = true;
    }
    else
    {
diff --git a/sc/source/ui/formdlg/formula.cxx b/sc/source/ui/formdlg/formula.cxx
index 7c4590f..4832a16 100644
--- a/sc/source/ui/formdlg/formula.cxx
+++ b/sc/source/ui/formdlg/formula.cxx
@@ -109,7 +109,7 @@ ScFormulaDlg::ScFormulaDlg( SfxBindings* pB, SfxChildWindow* pCW,
    ScFormulaReferenceHelper::enableInput( true );
    ScFormulaReferenceHelper::EnableSpreadsheets();
    m_aHelper.Init();
    ScFormulaReferenceHelper::SetDispatcherLock( true );
    m_aHelper.SetDispatcherLock( true );

    notifyChange();
    fill();
@@ -552,7 +552,7 @@ void ScFormulaDlg::dispatch(bool _bOK, bool _bMatrixChecked)
    if ( aStrItem.GetValue().isEmpty() )
        aRetItem.SetValue( false );     // sal_False = Cancel

    ScFormulaReferenceHelper::SetDispatcherLock( false ); // turn off modal-mode
    m_aHelper.SetDispatcherLock( false ); // turn off modal-mode

    clear();

@@ -562,7 +562,7 @@ void ScFormulaDlg::dispatch(bool _bOK, bool _bMatrixChecked)
}
void ScFormulaDlg::setDispatcherLock( bool bLock )
{
    ScFormulaReferenceHelper::SetDispatcherLock( bLock );
    m_aHelper.SetDispatcherLock( bLock );
}
void ScFormulaDlg::deleteFormData()
{
diff --git a/sc/source/ui/inc/anyrefdg.hxx b/sc/source/ui/inc/anyrefdg.hxx
index d9bf5d8..1abdb8b 100644
--- a/sc/source/ui/inc/anyrefdg.hxx
+++ b/sc/source/ui/inc/anyrefdg.hxx
@@ -90,7 +90,7 @@ public:

    void         SetWindow(vcl::Window* _pWindow) { m_pWindow = _pWindow; }
    void                DoClose( sal_uInt16 nId );
    static void         SetDispatcherLock( bool bLock );
    void                SetDispatcherLock( bool bLock );
    static void         EnableSpreadsheets( bool bFlag = true );
    static void         ViewShellChanged();

@@ -126,7 +126,7 @@ protected:
    void                disposeRefHandler();
    bool                DoClose( sal_uInt16 nId );

    static void         SetDispatcherLock( bool bLock );
    void                SetDispatcherLock( bool bLock );

    virtual void        RefInputStart( formula::RefEdit* pEdit, formula::RefButton* pButton = nullptr ) override;
    virtual void        RefInputDone( bool bForced = false ) override;
diff --git a/sc/source/ui/miscdlgs/anyrefdg.cxx b/sc/source/ui/miscdlgs/anyrefdg.cxx
index e4e51f9..196d097 100644
--- a/sc/source/ui/miscdlgs/anyrefdg.cxx
+++ b/sc/source/ui/miscdlgs/anyrefdg.cxx
@@ -648,26 +648,20 @@ void ScFormulaReferenceHelper::DoClose( sal_uInt16 nId )

void ScFormulaReferenceHelper::SetDispatcherLock( bool bLock )
{
    //  lock / unlock only the dispatchers of Calc documents

    ScDocShell* pDocShell = static_cast<ScDocShell*>(SfxObjectShell::GetFirst(checkSfxObjectShell<ScDocShell>));
    while( pDocShell )
    //  lock / unlock only the dispatcher of Calc document
    SfxDispatcher* pDisp = nullptr;
    if ( m_pBindings )
    {
        SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pDocShell );
        while( pFrame )
        {
            SfxDispatcher* pDisp = pFrame->GetDispatcher();
            if (pDisp)
                pDisp->Lock( bLock );

            pFrame = SfxViewFrame::GetNext( *pFrame, pDocShell );
        }
        pDocShell = static_cast<ScDocShell*>(SfxObjectShell::GetNext(*pDocShell, checkSfxObjectShell<ScDocShell>));
        pDisp = m_pBindings->GetDispatcher();
    }
    else if(SfxViewFrame* pViewFrame = SfxViewFrame::Current())
    {
        if (dynamic_cast< ScTabViewShell* >(pViewFrame->GetViewShell()))
            pDisp = pViewFrame->GetDispatcher();
    }

    //  if a new view is created while the dialog is open,
    //  that view's dispatcher is locked when trying to create the dialog
    //  for that view (ScTabViewShell::CreateRefDialog)
    if (pDisp)
        pDisp->Lock(bLock);
}

void ScFormulaReferenceHelper::ViewShellChanged()
@@ -812,7 +806,7 @@ bool ScRefHandler::EnterRefMode()

    m_aHelper.Init();

    ScFormulaReferenceHelper::SetDispatcherLock( true );
    m_aHelper.SetDispatcherLock( true );

    return m_bInRefMode = true;
}
@@ -901,7 +895,7 @@ bool ScRefHandler::DoClose( sal_uInt16 nId )

void ScRefHandler::SetDispatcherLock( bool bLock )
{
    ScFormulaReferenceHelper::SetDispatcherLock( bLock );
    m_aHelper.SetDispatcherLock( bLock );
}

void ScRefHandler::ViewShellChanged()