tdf#86568 Move the scrollbar to the EditWindow in Basic IDE

Currently, the Basic IDE has a shared horizontal scrollbar used both for the code editor window and the dialog editor window.

However, the problem is that this causes the horizontal scrollbar to be placed at an unintuitive place when the code editor is being used. To avoid this problem the code editor already has its own vertical scrollbar.

This patch creates a separate horizontal scrollbar for the code editor window and places it underneath the editor window to make it clearer what this scrollbar is meant to scroll.

Change-Id: Ib873c004db902f0f729fd512c51effd8f5e38a9d
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/143580
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
diff --git a/basctl/source/basicide/baside2.cxx b/basctl/source/basicide/baside2.cxx
index 1eb4b90..9452ef2 100644
--- a/basctl/source/basicide/baside2.cxx
+++ b/basctl/source/basicide/baside2.cxx
@@ -255,9 +255,6 @@ void ModulWindow::GetFocus()

void ModulWindow::DoInit()
{
    if (GetVScrollBar())
        GetVScrollBar()->Hide();
    GetHScrollBar()->Show();
    GetEditorWindow().InitScrollBars();
}

diff --git a/basctl/source/basicide/baside2.hxx b/basctl/source/basicide/baside2.hxx
index 969f823..9a8700a 100644
--- a/basctl/source/basicide/baside2.hxx
+++ b/basctl/source/basicide/baside2.hxx
@@ -259,6 +259,7 @@ private:
    VclPtr<LineNumberWindow> aLineNumberWindow;
    VclPtr<EditorWindow>     aEdtWindow;
    VclPtr<ScrollAdaptor>    aEWVScrollBar;
    VclPtr<ScrollAdaptor>    aEWHScrollBar;

    virtual void DataChanged(DataChangedEvent const & rDCEvt) override;

@@ -273,6 +274,7 @@ public:
    LineNumberWindow&   GetLineNumberWindow() { return *aLineNumberWindow; }
    EditorWindow&       GetEdtWindow()      { return *aEdtWindow; }
    ScrollAdaptor&      GetEWVScrollBar()   { return *aEWVScrollBar; }
    ScrollAdaptor&      GetEWHScrollBar()   { return *aEWHScrollBar; }

    void SetLineNumberDisplay(bool b);
};
@@ -366,6 +368,7 @@ public:
    BreakPointWindow&   GetBreakPointWindow()   { return m_aXEditorWindow->GetBrkWindow(); }
    LineNumberWindow&   GetLineNumberWindow()   { return m_aXEditorWindow->GetLineNumberWindow(); }
    ScrollAdaptor&      GetEditVScrollBar()     { return m_aXEditorWindow->GetEWVScrollBar(); }
    ScrollAdaptor&      GetEditHScrollBar()     { return m_aXEditorWindow->GetEWHScrollBar(); }
    ExtTextEngine*      GetEditEngine()         { return GetEditorWindow().GetEditEngine(); }
    TextView*           GetEditView()           { return GetEditorWindow().GetEditView(); }
    BreakPointList&     GetBreakPoints()        { return GetBreakPointWindow().GetBreakPoints(); }
diff --git a/basctl/source/basicide/baside2b.cxx b/basctl/source/basicide/baside2b.cxx
index 89edcec..e0dfe9f 100644
--- a/basctl/source/basicide/baside2b.cxx
+++ b/basctl/source/basicide/baside2b.cxx
@@ -499,7 +499,7 @@ void EditorWindow::Command( const CommandEvent& rCEvt )
         ( rCEvt.GetCommand() == CommandEventId::StartAutoScroll ) ||
         ( rCEvt.GetCommand() == CommandEventId::AutoScroll ) )
    {
        HandleScrollCommand( rCEvt, rModulWindow.GetHScrollBar(), &rModulWindow.GetEditVScrollBar() );
        HandleScrollCommand( rCEvt, &rModulWindow.GetEditHScrollBar(), &rModulWindow.GetEditVScrollBar() );
    } else if ( rCEvt.GetCommand() == CommandEventId::ContextMenu ) {
        SfxDispatcher* pDispatcher = GetDispatcher();
        if ( pDispatcher )
@@ -1082,9 +1082,8 @@ void EditorWindow::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint )
    TextHint const& rTextHint = *pTextHint;
    if( rTextHint.GetId() == SfxHintId::TextViewScrolled )
    {
        if ( rModulWindow.GetHScrollBar() )
            rModulWindow.GetHScrollBar()->SetThumbPos( pEditView->GetStartDocPos().X() );
        rModulWindow.GetEditVScrollBar().SetThumbPos( pEditView->GetStartDocPos().Y() );
        rModulWindow.GetEditHScrollBar().SetThumbPos( pEditView->GetStartDocPos().X() );
        rModulWindow.GetBreakPointWindow().DoScroll
            ( rModulWindow.GetBreakPointWindow().GetCurYOffset() - pEditView->GetStartDocPos().Y() );
        rModulWindow.GetLineNumberWindow().DoScroll
@@ -1106,15 +1105,13 @@ void EditorWindow::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint )
    }
    else if( rTextHint.GetId() == SfxHintId::TextFormatted )
    {
        if ( rModulWindow.GetHScrollBar() )

        const tools::Long nWidth = pEditEngine->CalcTextWidth();
        if ( nWidth != nCurTextWidth )
        {
            const tools::Long nWidth = pEditEngine->CalcTextWidth();
            if ( nWidth != nCurTextWidth )
            {
                nCurTextWidth = nWidth;
                rModulWindow.GetHScrollBar()->SetRange( Range( 0, nCurTextWidth-1) );
                rModulWindow.GetHScrollBar()->SetThumbPos( pEditView->GetStartDocPos().X() );
            }
            nCurTextWidth = nWidth;
            rModulWindow.GetEditHScrollBar().SetRange( Range( 0, nCurTextWidth-1) );
            rModulWindow.GetEditHScrollBar().SetThumbPos( pEditView->GetStartDocPos().X() );
        }
        tools::Long nPrevTextWidth = nCurTextWidth;
        nCurTextWidth = pEditEngine->CalcTextWidth();
@@ -1169,10 +1166,8 @@ void EditorWindow::SetScrollBarRanges()
    if ( !pEditEngine )
        return;

    if ( rModulWindow.GetHScrollBar() )
        rModulWindow.GetHScrollBar()->SetRange( Range( 0, nCurTextWidth-1 ) );

    rModulWindow.GetEditVScrollBar().SetRange( Range( 0, pEditEngine->GetTextHeight()-1 ) );
    rModulWindow.GetEditHScrollBar().SetRange( Range( 0, nCurTextWidth-1 ) );
}

void EditorWindow::InitScrollBars()
@@ -1188,14 +1183,11 @@ void EditorWindow::InitScrollBars()
    rModulWindow.GetEditVScrollBar().SetThumbPos(pEditView->GetStartDocPos().Y());
    rModulWindow.GetEditVScrollBar().Show();

    if (rModulWindow.GetHScrollBar())
    {
        rModulWindow.GetHScrollBar()->SetVisibleSize(aOutSz.Width());
        rModulWindow.GetHScrollBar()->SetPageSize(aOutSz.Width() * 8 / 10);
        rModulWindow.GetHScrollBar()->SetLineSize(GetTextWidth( "x" ) );
        rModulWindow.GetHScrollBar()->SetThumbPos(pEditView->GetStartDocPos().X());
        rModulWindow.GetHScrollBar()->Show();
    }
    rModulWindow.GetEditHScrollBar().SetVisibleSize(aOutSz.Width());
    rModulWindow.GetEditHScrollBar().SetPageSize(aOutSz.Width() * 8 / 10);
    rModulWindow.GetEditHScrollBar().SetLineSize(GetTextWidth( "x" ));
    rModulWindow.GetEditHScrollBar().SetThumbPos(pEditView->GetStartDocPos().X());
    rModulWindow.GetEditHScrollBar().Show();
}

void EditorWindow::ImpDoHighlight( sal_uInt32 nLine )
@@ -1971,7 +1963,8 @@ ComplexEditorWindow::ComplexEditorWindow( ModulWindow* pParent ) :
    aBrkWindow(VclPtr<BreakPointWindow>::Create(this, pParent)),
    aLineNumberWindow(VclPtr<LineNumberWindow>::Create(this, pParent)),
    aEdtWindow(VclPtr<EditorWindow>::Create(this, pParent)),
    aEWVScrollBar( VclPtr<ScrollAdaptor>::Create(this, false) )
    aEWVScrollBar(VclPtr<ScrollAdaptor>::Create(this, false)),
    aEWHScrollBar(VclPtr<ScrollAdaptor>::Create(this, true))
{
    aEdtWindow->Show();
    aBrkWindow->Show();
@@ -1980,6 +1973,11 @@ ComplexEditorWindow::ComplexEditorWindow( ModulWindow* pParent ) :
    aEWVScrollBar->SetPageSize(nScrollPage);
    aEWVScrollBar->SetScrollHdl( LINK( this, ComplexEditorWindow, ScrollHdl ) );
    aEWVScrollBar->Show();

    aEWHScrollBar->SetLineSize(nScrollLine);
    aEWHScrollBar->SetPageSize(nScrollPage);
    aEWHScrollBar->SetScrollHdl( LINK( this, ComplexEditorWindow, ScrollHdl ) );
    aEWHScrollBar->Show();
}

ComplexEditorWindow::~ComplexEditorWindow()
@@ -1993,6 +1991,7 @@ void ComplexEditorWindow::dispose()
    aLineNumberWindow.disposeAndClear();
    aEdtWindow.disposeAndClear();
    aEWVScrollBar.disposeAndClear();
    aEWHScrollBar.disposeAndClear();
    vcl::Window::dispose();
}

@@ -2004,35 +2003,40 @@ void ComplexEditorWindow::Resize()
    aSz.AdjustHeight( -(2*DWBORDER) );
    tools::Long nBrkWidth = 20;
    tools::Long nSBWidth = aEWVScrollBar->GetSizePixel().Width();
    tools::Long nSBHeight = aEWHScrollBar->GetSizePixel().Height();

    Size aBrkSz(nBrkWidth, aSz.Height());
    Size aBrkSz(nBrkWidth, aSz.Height() - nSBHeight);

    if (aLineNumberWindow->IsVisible())
    {
        Size aLnSz(aLineNumberWindow->GetWidth(), aSz.Height());
        aBrkWindow->SetPosSizePixel( Point( DWBORDER, DWBORDER ), aBrkSz );
        aLineNumberWindow->SetPosSizePixel(Point(DWBORDER + aBrkSz.Width() - 1, DWBORDER), aLnSz);
        Size aEWSz(aSz.Width() - nBrkWidth - aLineNumberWindow->GetWidth() - nSBWidth + 2, aSz.Height());
        aEdtWindow->SetPosSizePixel( Point( DWBORDER + aBrkSz.Width() + aLnSz.Width() - 1, DWBORDER ), aEWSz );
        Size aLnSz(aLineNumberWindow->GetWidth(), aSz.Height() - nSBHeight);
        Size aEWSz(aSz.Width() - nBrkWidth - aLineNumberWindow->GetWidth() - nSBWidth, aSz.Height() - nSBHeight);
        aBrkWindow->SetPosSizePixel(Point(DWBORDER, DWBORDER), aBrkSz);
        aLineNumberWindow->SetPosSizePixel(Point(DWBORDER + nBrkWidth, DWBORDER), aLnSz);
        aEdtWindow->SetPosSizePixel(Point(DWBORDER + nBrkWidth + aLnSz.Width(), DWBORDER), aEWSz);
    }
    else
    {
        Size aEWSz(aSz.Width() - nBrkWidth - nSBWidth, aSz.Height() - nSBHeight);
        aBrkWindow->SetPosSizePixel( Point( DWBORDER, DWBORDER ), aBrkSz );
        Size aEWSz(aSz.Width() - nBrkWidth - nSBWidth + 2, aSz.Height());
        aEdtWindow->SetPosSizePixel(Point(DWBORDER + aBrkSz.Width() - 1, DWBORDER), aEWSz);
        aEdtWindow->SetPosSizePixel(Point(DWBORDER + nBrkWidth, DWBORDER), aEWSz);
    }

    aEWVScrollBar->SetPosSizePixel( Point( aOutSz.Width() - DWBORDER - nSBWidth, DWBORDER ), Size( nSBWidth, aSz.Height() ) );
    aEWVScrollBar->SetPosSizePixel(Point(aOutSz.Width() - DWBORDER - nSBWidth, DWBORDER),
                                   Size(nSBWidth, aSz.Height() - nSBHeight));
    aEWHScrollBar->SetPosSizePixel(Point(DWBORDER, aOutSz.Height() - DWBORDER - nSBHeight),
                                   Size(aSz.Width() - nSBWidth, nSBHeight));
}

IMPL_LINK_NOARG(ComplexEditorWindow, ScrollHdl, weld::Scrollbar&, void)
{
    if (aEdtWindow->GetEditView())
    {
        tools::Long nDiff = aEdtWindow->GetEditView()->GetStartDocPos().Y() - aEWVScrollBar->GetThumbPos();
        aEdtWindow->GetEditView()->Scroll( 0, nDiff );
        aBrkWindow->DoScroll( nDiff );
        aLineNumberWindow->DoScroll( nDiff );
        tools::Long nXDiff = aEdtWindow->GetEditView()->GetStartDocPos().X() - aEWHScrollBar->GetThumbPos();
        tools::Long nYDiff = aEdtWindow->GetEditView()->GetStartDocPos().Y() - aEWVScrollBar->GetThumbPos();
        aEdtWindow->GetEditView()->Scroll(nXDiff, nYDiff);
        aBrkWindow->DoScroll( nYDiff );
        aLineNumberWindow->DoScroll( nYDiff );
        aEdtWindow->GetEditView()->ShowCursor(false);
        aEWVScrollBar->SetThumbPos( aEdtWindow->GetEditView()->GetStartDocPos().Y() );
    }
diff --git a/basctl/source/basicide/baside3.cxx b/basctl/source/basicide/baside3.cxx
index c7cb87c..2b3bbe3 100644
--- a/basctl/source/basicide/baside3.cxx
+++ b/basctl/source/basicide/baside3.cxx
@@ -232,8 +232,6 @@ void DialogWindow::NotifyUndoActionHdl( std::unique_ptr<SdrUndoAction> )

void DialogWindow::DoInit()
{
    GetHScrollBar()->Show();
    GetVScrollBar()->Show();
    m_pEditor->SetScrollBars( GetHScrollBar(), GetVScrollBar() );
}

diff --git a/basctl/source/basicide/basides1.cxx b/basctl/source/basicide/basides1.cxx
index 3f4e9f7..490a4dc 100644
--- a/basctl/source/basicide/basides1.cxx
+++ b/basctl/source/basicide/basides1.cxx
@@ -1250,7 +1250,6 @@ void Shell::SetCurWindow( BaseWindow* pNewWin, bool bUpdateTabBar, bool bRemembe
    SetUndoManager( pCurWin ? pCurWin->GetUndoManager() : nullptr );
    InvalidateBasicIDESlots();
    InvalidateControlSlots();
    EnableScrollbars(pCurWin != nullptr);

    if ( m_pCurLocalizationMgr )
        m_pCurLocalizationMgr->handleTranslationbar();
@@ -1408,17 +1407,29 @@ void Shell::AdjustPosSizePixel( const Point &rPos, const Size &rSize )

    Size aSz( rSize );
    auto nScrollBarSz(Application::GetSettings().GetStyleSettings().GetScrollBarSize());
    aSz.AdjustHeight(-nScrollBarSz);
    aSz.AdjustHeight(-aTabBarSize.Height());

    Size aOutSz( aSz );
    aSz.AdjustWidth(-nScrollBarSz);
    aSz.AdjustHeight(-nScrollBarSz);
    aVScrollBar->SetPosSizePixel( Point( rPos.X()+aSz.Width(), rPos.Y() ), Size( nScrollBarSz, aSz.Height() ) );
    aHScrollBar->SetPosSizePixel( Point( rPos.X(), rPos.Y()+aSz.Height() ), Size( aOutSz.Width(), nScrollBarSz ) );
    pTabBar->SetPosSizePixel( Point( rPos.X(), rPos.Y() + nScrollBarSz + aSz.Height()), aTabBarSize );

    // The size to be applied depends on whether it is a DialogWindow or a ModulWindow
    if (pLayout)
        pLayout->SetPosSizePixel(rPos, dynamic_cast<DialogWindow*>(pCurWin.get()) ? aSz : aOutSz);
    {
        if (dynamic_cast<DialogWindow*>(pCurWin.get()))
        {
            pCurWin->ShowShellScrollBars();
            pLayout->SetPosSizePixel(rPos, aSz);
        }
        else
        {
            pCurWin->ShowShellScrollBars(false);
            pLayout->SetPosSizePixel(rPos, aOutSz);
        }
    }
}

Reference< XModel > Shell::GetCurrentDocument() const
diff --git a/basctl/source/basicide/basidesh.cxx b/basctl/source/basicide/basidesh.cxx
index bc1204c..a08a675 100644
--- a/basctl/source/basicide/basidesh.cxx
+++ b/basctl/source/basicide/basidesh.cxx
@@ -434,10 +434,6 @@ void Shell::InitScrollBars()
    aVScrollBar->SetPageSize( 2000 );
    aHScrollBar->SetLineSize( 300 );
    aHScrollBar->SetPageSize( 2000 );
    aHScrollBar->Enable();
    aVScrollBar->Enable();
    aVScrollBar->Show();
    aHScrollBar->Show();
}

void Shell::InitTabBar()
@@ -911,12 +907,6 @@ void Shell::InvalidateControlSlots()
    pBindings->Invalidate( SID_CHOOSE_CONTROLS );
}

void Shell::EnableScrollbars( bool bEnable )
{
    aHScrollBar->Enable(bEnable);
    aVScrollBar->Enable(bEnable);
}

void Shell::SetCurLib( const ScriptDocument& rDocument, const OUString& aLibName, bool bUpdateWindows, bool bCheck )
{
    if ( bCheck && rDocument == m_aCurDocument && aLibName == m_aCurLibName )
diff --git a/basctl/source/basicide/bastypes.cxx b/basctl/source/basicide/bastypes.cxx
index 1f41ea7..c682094 100644
--- a/basctl/source/basicide/bastypes.cxx
+++ b/basctl/source/basicide/bastypes.cxx
@@ -147,6 +147,36 @@ bool BaseWindow::EventNotify( NotifyEvent& rNEvt )
    return bDone || Window::EventNotify( rNEvt );
}

void BaseWindow::ShowShellScrollBars(bool bVisible)
{
    if (bVisible)
    {
        if (pShellHScrollBar)
        {
            pShellHScrollBar->Enable();
            pShellHScrollBar->Show();
        }
        if (pShellVScrollBar)
        {
            pShellVScrollBar->Enable();
            pShellVScrollBar->Show();
        }
    }
    else
    {
        if (pShellHScrollBar)
        {
            pShellHScrollBar->Disable();
            pShellHScrollBar->Hide();
        }
        if (pShellVScrollBar)
        {
            pShellVScrollBar->Disable();
            pShellVScrollBar->Hide();
        }
    }
}

void BaseWindow::DoScroll( Scrollable* )
{
}
diff --git a/basctl/source/inc/basidesh.hxx b/basctl/source/inc/basidesh.hxx
index 89e22c1..c8c634d 100644
--- a/basctl/source/inc/basidesh.hxx
+++ b/basctl/source/inc/basidesh.hxx
@@ -107,7 +107,6 @@ private:
    static void         InvalidateBasicIDESlots();
    void                StoreAllWindowData( bool bPersistent = true );
    void                SetMDITitle();
    void                EnableScrollbars( bool bEnable );
    void                SetCurLib( const ScriptDocument& rDocument, const OUString& aLibName, bool bUpdateWindows = true , bool bCheck = true );
    void                SetCurLibForLocalization( const ScriptDocument& rDocument, const OUString& aLibName );

diff --git a/basctl/source/inc/bastypes.hxx b/basctl/source/inc/bastypes.hxx
index a0809d90..79229f9 100644
--- a/basctl/source/inc/bastypes.hxx
+++ b/basctl/source/inc/bastypes.hxx
@@ -184,8 +184,9 @@ public:
    virtual void    Deactivating () = 0;
    void            GrabScrollBars(ScrollAdaptor* pHScroll, ScrollAdaptor* pVScroll);

    ScrollAdaptor*  GetHScrollBar() const { return pShellHScrollBar; }
    ScrollAdaptor*  GetVScrollBar() const { return pShellVScrollBar; }
    ScrollAdaptor*  GetHScrollBar() const { return pShellHScrollBar.get(); }
    ScrollAdaptor*  GetVScrollBar() const { return pShellVScrollBar.get(); }
    void            ShowShellScrollBars(bool bVisible = true);

    virtual void    ExecuteCommand (SfxRequest&);
    virtual void    ExecuteGlobal (SfxRequest&);