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.mcnamara@collabora.com>
diff --git a/cui/source/dialogs/SpellDialog.cxx b/cui/source/dialogs/SpellDialog.cxx
index 692c8e4..1e52d4e 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 3b8d2f9..fdf5e81 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 87e538d..7177282 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">