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">