cui/source/dialogs/SpellDialog.cxx |   72 +++++++++++++++++++++++++++++++++++--
 cui/source/inc/SpellDialog.hxx     |    9 ++++
 cui/uiconfig/ui/spellingdialog.ui  |    3 +
 3 files changed, 79 insertions(+), 5 deletions(-)

New commits:
commit 43677cb0d95de06bea0f08e87ccfa3230dc8bd6b
Author:     Caolán McNamara <caolan.mcnam...@collabora.com>
AuthorDate: Tue Sep 12 13:22:04 2023 +0100
Commit:     Caolán McNamara <caolan.mcnam...@collabora.com>
CommitDate: Tue Sep 12 15:23:36 2023 +0200

    Resolves: tdf#157148 spelling dialog sentence box has no scrollbars
    
    Change-Id: Ia1a7c2d73b0a5406ce3b08c4729e85ad724b44ae
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/156843
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com>

diff --git a/cui/source/dialogs/SpellDialog.cxx 
b/cui/source/dialogs/SpellDialog.cxx
index 692c8e4512d1..1e52d4e2aed3 100644
--- a/cui/source/dialogs/SpellDialog.cxx
+++ b/cui/source/dialogs/SpellDialog.cxx
@@ -173,7 +173,7 @@ SpellDialog::SpellDialog(SpellDialogChildWindow* 
pChildWindow,
     , m_xExplainFT(m_xBuilder->weld_label("explain"))
     , m_xExplainLink(m_xBuilder->weld_link_button("explainlink"))
     , m_xNotInDictFT(m_xBuilder->weld_label("notindictft"))
-    , m_xSentenceED(new SentenceEditWindow_Impl)
+    , m_xSentenceED(new 
SentenceEditWindow_Impl(m_xBuilder->weld_scrolled_window("scrolledwindow", 
true)))
     , m_xSuggestionFT(m_xBuilder->weld_label("suggestionsft"))
     , m_xSuggestionLB(m_xBuilder->weld_tree_view("suggestionslb"))
     , m_xIgnorePB(m_xBuilder->weld_button("ignore"))
@@ -1129,13 +1129,15 @@ bool 
SpellDialog::ApplyChangeAllList_Impl(SpellPortions& rSentence, bool &bHasRe
     return bRet;
 }
 
-SentenceEditWindow_Impl::SentenceEditWindow_Impl()
-    : m_pSpellDialog(nullptr)
+SentenceEditWindow_Impl::SentenceEditWindow_Impl(std::unique_ptr<weld::ScrolledWindow>
 xScrolledWindow)
+    : m_xScrolledWindow(std::move(xScrolledWindow))
+    , m_pSpellDialog(nullptr)
     , m_pToolbar(nullptr)
     , m_nErrorStart(0)
     , m_nErrorEnd(0)
     , m_bIsUndoEditMode(false)
 {
+    m_xScrolledWindow->connect_vadjustment_changed(LINK(this, 
SentenceEditWindow_Impl, ScrollHdl));
 }
 
 void SentenceEditWindow_Impl::SetDrawingArea(weld::DrawingArea* pDrawingArea)
@@ -1147,6 +1149,8 @@ void 
SentenceEditWindow_Impl::SetDrawingArea(weld::DrawingArea* pDrawingArea)
     // tdf#132288 don't merge equal adjacent attributes
     m_xEditEngine->DisableAttributeExpanding();
 
+    m_xEditEngine->SetStatusEventHdl(LINK(this, SentenceEditWindow_Impl, 
EditStatusHdl));
+
     // tdf#142631 use document background color in this widget
     Color aBgColor = 
svtools::ColorConfig().GetColorValue(svtools::DOCCOLOR).nColor;
     OutputDevice& rDevice = pDrawingArea->get_ref_device();
@@ -1155,6 +1159,68 @@ void 
SentenceEditWindow_Impl::SetDrawingArea(weld::DrawingArea* pDrawingArea)
     m_xEditEngine->SetBackgroundColor(aBgColor);
 }
 
+IMPL_LINK_NOARG(SentenceEditWindow_Impl, EditStatusHdl, EditStatus&, void)
+{
+    SetScrollBarRange();
+    DoScroll();
+}
+
+IMPL_LINK_NOARG(SentenceEditWindow_Impl, ScrollHdl, weld::ScrolledWindow&, 
void)
+{
+    DoScroll();
+}
+
+void SentenceEditWindow_Impl::DoScroll()
+{
+    if (m_xEditView)
+    {
+        auto currentDocPos = m_xEditView->GetVisArea().Top();
+        auto nDiff = currentDocPos - 
m_xScrolledWindow->vadjustment_get_value();
+        // we expect SetScrollBarRange callback to be triggered by Scroll
+        // to set where we ended up
+        m_xEditView->Scroll(0, nDiff);
+    }
+}
+
+void SentenceEditWindow_Impl::EditViewScrollStateChange()
+{
+    // editengine height has changed or editview scroll pos has changed
+    SetScrollBarRange();
+}
+
+void SentenceEditWindow_Impl::SetScrollBarRange()
+{
+    EditEngine *pEditEngine = GetEditEngine();
+    if (!pEditEngine)
+        return;
+    if (!m_xScrolledWindow)
+        return;
+    EditView* pEditView = GetEditView();
+    if (!pEditView)
+        return;
+
+    int nVUpper = pEditEngine->GetTextHeight();
+    int nVCurrentDocPos = pEditView->GetVisArea().Top();
+    const Size aOut(pEditView->GetOutputArea().GetSize());
+    int nVStepIncrement = aOut.Height() * 2 / 10;
+    int nVPageIncrement = aOut.Height() * 8 / 10;
+    int nVPageSize = aOut.Height();
+
+    /* limit the page size to below nUpper because gtk's 
gtk_scrolled_window_start_deceleration has
+       effectively...
+
+       lower = gtk_adjustment_get_lower
+       upper = gtk_adjustment_get_upper - gtk_adjustment_get_page_size
+
+       and requires that upper > lower or the deceleration animation never ends
+    */
+    nVPageSize = std::min(nVPageSize, nVUpper);
+
+    m_xScrolledWindow->vadjustment_configure(nVCurrentDocPos, 0, nVUpper,
+                                             nVStepIncrement, nVPageIncrement, 
nVPageSize);
+    m_xScrolledWindow->set_vpolicy(nVUpper > nVPageSize ? 
VclPolicyType::ALWAYS : VclPolicyType::NEVER);
+}
+
 SentenceEditWindow_Impl::~SentenceEditWindow_Impl()
 {
 }
diff --git a/cui/source/inc/SpellDialog.hxx b/cui/source/inc/SpellDialog.hxx
index 3b8d2f9fa02f..fdf5e81bcdf3 100644
--- a/cui/source/inc/SpellDialog.hxx
+++ b/cui/source/inc/SpellDialog.hxx
@@ -46,6 +46,7 @@ struct SpellErrorDescription;
 class SentenceEditWindow_Impl : public WeldEditView
 {
 private:
+    std::unique_ptr<weld::ScrolledWindow> m_xScrolledWindow;
     std::set<sal_Int32> m_aIgnoreErrorsAt;
     SpellDialog*        m_pSpellDialog;
     weld::Toolbar*      m_pToolbar;
@@ -61,14 +62,20 @@ private:
 
     bool GetErrorDescription(SpellErrorDescription& rSpellErrorDescription, 
sal_Int32 nPosition);
 
+    DECL_LINK(ScrollHdl, weld::ScrolledWindow&, void);
+    DECL_LINK(EditStatusHdl, EditStatus&, void);
     DECL_LINK(ToolbarHdl, const OUString&, void);
 
+    void DoScroll();
+    void SetScrollBarRange();
+
 protected:
     virtual bool    KeyInput( const KeyEvent& rKEvt ) override;
 
 public:
-    SentenceEditWindow_Impl();
+    SentenceEditWindow_Impl(std::unique_ptr<weld::ScrolledWindow> 
xScrolledWindow);
     virtual void SetDrawingArea(weld::DrawingArea* pDrawingArea) override;
+    virtual void EditViewScrollStateChange() override;
     void SetSpellDialog(SpellDialog* pDialog) { m_pSpellDialog = pDialog; }
     virtual ~SentenceEditWindow_Impl() override;
 
diff --git a/cui/uiconfig/ui/spellingdialog.ui 
b/cui/uiconfig/ui/spellingdialog.ui
index 87e538d68146..71772829f104 100644
--- a/cui/uiconfig/ui/spellingdialog.ui
+++ b/cui/uiconfig/ui/spellingdialog.ui
@@ -154,10 +154,11 @@
               </packing>
             </child>
             <child>
-              <object class="GtkScrolledWindow">
+              <object class="GtkScrolledWindow" id="scrolledwindow">
                 <property name="visible">True</property>
                 <property name="can-focus">True</property>
                 <property name="border-width">0</property>
+                <property name="hscrollbar-policy">never</property>
                 <property name="shadow-type">in</property>
                 <child>
                   <object class="GtkViewport">

Reply via email to