diff options
Diffstat (limited to 'cui/source/dialogs/SpellDialog.cxx')
-rw-r--r-- | cui/source/dialogs/SpellDialog.cxx | 201 |
1 files changed, 145 insertions, 56 deletions
diff --git a/cui/source/dialogs/SpellDialog.cxx b/cui/source/dialogs/SpellDialog.cxx index dae7b92c9155..dfdad984ec41 100644 --- a/cui/source/dialogs/SpellDialog.cxx +++ b/cui/source/dialogs/SpellDialog.cxx @@ -26,6 +26,7 @@ #include <svl/undo.hxx> #include <tools/debug.hxx> #include <unotools/lingucfg.hxx> +#include <editeng/editund2.hxx> #include <editeng/colritem.hxx> #include <editeng/eeitem.hxx> #include <editeng/langitem.hxx> @@ -50,6 +51,7 @@ #include <SpellDialog.hxx> #include <optlingu.hxx> #include <treeopt.hxx> +#include <svtools/colorcfg.hxx> #include <svtools/langtab.hxx> #include <sal/log.hxx> #include <i18nlangtag/languagetag.hxx> @@ -160,6 +162,7 @@ SpellDialog::SpellDialog(SpellDialogChildWindow* pChildWindow, : SfxModelessDialogController (_pBindings, pChildWindow, pParent, "cui/ui/spellingdialog.ui", "SpellingDialog") , aDialogUndoLink(LINK (this, SpellDialog, DialogUndoHdl)) + , m_pInitHdlEvent(nullptr) , bFocusLocked(true) , rParent(*pChildWindow) , pImpl( new SpellDialog_Impl ) @@ -171,7 +174,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")) @@ -218,11 +221,19 @@ SpellDialog::SpellDialog(SpellDialogChildWindow* pChildWindow, //InitHdl wants to use virtual methods, so it //can't be called during the ctor, so init //it on next event cycle post-ctor - Application::PostUserEvent(LINK(this, SpellDialog, InitHdl)); + m_pInitHdlEvent = Application::PostUserEvent(LINK(this, SpellDialog, InitHdl)); } SpellDialog::~SpellDialog() { + if (m_xOptionsDlg) + { + m_xOptionsDlg->response(RET_CANCEL); + m_xOptionsDlg.reset(); + } + + if (m_pInitHdlEvent) + Application::RemoveUserEvent(m_pInitHdlEvent); if (pImpl) { // save possibly modified user-dictionaries @@ -351,6 +362,11 @@ void SpellDialog::SpellContinue_Impl(std::unique_ptr<UndoChangeGroupGuard>* pGua //then GetNextSentence() has to be called followed again by MarkNextError() //MarkNextError is not initially called if the UndoEdit mode is active bool bNextSentence = false; + if (!m_xSentenceED) + { + return; + } + if(!((!m_xSentenceED->IsUndoEditMode() && m_xSentenceED->MarkNextError( bIgnoreCurrentError, xSpell )) || ( bNextSentence = GetNextSentence_Impl(pGuard, bUseSavedSentence, m_xSentenceED->IsUndoEditMode()) && m_xSentenceED->MarkNextError( false, xSpell )))) return; @@ -364,16 +380,10 @@ void SpellDialog::SpellContinue_Impl(std::unique_ptr<UndoChangeGroupGuard>* pGua { m_xNotInDictFT.get(), m_xSentenceED->GetDrawingArea(), - m_xLanguageFT.get(), - nullptr + m_xLanguageFT.get() }; - sal_Int32 nIdx = 0; - do - { - aControls[nIdx]->set_sensitive(true); - } - while(aControls[++nIdx]); - + for (weld::Widget* pWidget : aControls) + pWidget->set_sensitive(true); } if( bNextSentence ) { @@ -387,6 +397,7 @@ void SpellDialog::SpellContinue_Impl(std::unique_ptr<UndoChangeGroupGuard>* pGua */ IMPL_LINK_NOARG( SpellDialog, InitHdl, void*, void) { + m_pInitHdlEvent = nullptr; m_xDialog->freeze(); //show or hide AutoCorrect depending on the modules abilities m_xAutoCorrPB->set_visible(rParent.HasAutoCorrection()); @@ -401,7 +412,9 @@ IMPL_LINK_NOARG( SpellDialog, InitHdl, void*, void) InitUserDicts(); LockFocusChanges(true); - if( m_xChangePB->get_sensitive() ) + if(m_xSentenceED->IsEnabled()) + m_xSentenceED->GrabFocus(); + else if( m_xChangePB->get_sensitive() ) m_xChangePB->grab_focus(); else if( m_xIgnorePB->get_sensitive() ) m_xIgnorePB->grab_focus(); @@ -456,19 +469,22 @@ IMPL_LINK_NOARG(SpellDialog, CheckGrammarHdl, weld::Toggleable&, void) void SpellDialog::StartSpellOptDlg_Impl() { - SfxItemSetFixed<SID_AUTOSPELL_CHECK,SID_AUTOSPELL_CHECK> aSet( SfxGetpApp()->GetPool() ); - SfxSingleTabDialogController aDlg(m_xDialog.get(), &aSet, "cui/ui/spelloptionsdialog.ui", "SpellOptionsDialog"); + auto xSet = std::make_shared<SfxItemSetFixed<SID_AUTOSPELL_CHECK,SID_AUTOSPELL_CHECK>>( SfxGetpApp()->GetPool() ); + m_xOptionsDlg = std::make_shared<SfxSingleTabDialogController>( + m_xDialog.get(), xSet.get(), "content", "cui/ui/spelloptionsdialog.ui", "SpellOptionsDialog"); - std::unique_ptr<SfxTabPage> xPage = SvxLinguTabPage::Create(aDlg.get_content_area(), &aDlg, &aSet); + std::unique_ptr<SfxTabPage> xPage = SvxLinguTabPage::Create(m_xOptionsDlg->get_content_area(), m_xOptionsDlg.get(), xSet.get()); static_cast<SvxLinguTabPage*>(xPage.get())->HideGroups( GROUP_MODULES ); - aDlg.SetTabPage(std::move(xPage)); - if (RET_OK == aDlg.run()) - { - InitUserDicts(); - const SfxItemSet* pOutSet = aDlg.GetOutputItemSet(); - if(pOutSet) - OfaTreeOptionsDialog::ApplyLanguageOptions(*pOutSet); - } + m_xOptionsDlg->SetTabPage(std::move(xPage)); + weld::GenericDialogController::runAsync(m_xOptionsDlg, [this, xSet] (sal_uInt32 nResult) { + if (RET_OK == nResult) + { + InitUserDicts(); + const SfxItemSet* pOutSet = m_xOptionsDlg->GetOutputItemSet(); + if(pOutSet) + OfaTreeOptionsDialog::ApplyLanguageOptions(*pOutSet); + } + }); } namespace @@ -713,8 +729,7 @@ void SpellDialog::Close() // section - in that case, the cursor can move from the editable field to // the protected area, and the slots get disabled because of // SfxDisableFlags::SwOnProtectedCursor (see FN_SPELL_GRAMMAR_DIALOG in .sdi). - SfxViewFrame* pViewFrame = SfxViewFrame::Current(); - if (pViewFrame) + if (SfxViewFrame* pViewFrame = SfxViewFrame::Current()) pViewFrame->ToggleChildWindow(rParent.GetType()); } @@ -828,15 +843,15 @@ int SpellDialog::InitUserDicts() IMPL_LINK_NOARG(SpellDialog, AddToDictClickHdl, weld::Button&, void) { - AddToDictionaryExecute(OString::number(1)); + AddToDictionaryExecute(OUString::number(1)); } -IMPL_LINK(SpellDialog, AddToDictSelectHdl, const OString&, rIdent, void) +IMPL_LINK(SpellDialog, AddToDictSelectHdl, const OUString&, rIdent, void) { AddToDictionaryExecute(rIdent); } -void SpellDialog::AddToDictionaryExecute(const OString& rItemId) +void SpellDialog::AddToDictionaryExecute(const OUString& rItemId) { auto xGuard(std::make_unique<UndoChangeGroupGuard>(*m_xSentenceED)); @@ -945,7 +960,7 @@ void SpellDialog::Activate() void SpellDialog::Deactivate() { - SfxModelessDialogController::Activate(); + SfxModelessDialogController::Deactivate(); ToplevelFocusChanged(); } @@ -969,15 +984,11 @@ void SpellDialog::InvalidateDialog() m_xChangePB.get(), m_xChangeAllPB.get(), m_xAutoCorrPB.get(), - m_xUndoPB.get(), - nullptr + m_xUndoPB.get() }; - sal_Int16 i = 0; - while(aDisableArr[i]) - { - aDisableArr[i]->set_sensitive(false); - i++; - } + for (weld::Widget* pWidget : aDisableArr) + pWidget->set_sensitive(false); + SfxModelessDialogController::Deactivate(); } @@ -1119,13 +1130,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) @@ -1136,6 +1149,77 @@ void SentenceEditWindow_Impl::SetDrawingArea(weld::DrawingArea* pDrawingArea) WeldEditView::SetDrawingArea(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(); + rDevice.SetBackground(aBgColor); + m_xEditView->SetBackgroundColor(aBgColor); + 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() @@ -1163,7 +1247,10 @@ namespace void ExtractErrorDescription(const EECharAttrib& rEECharAttrib, SpellErrorDescription& rSpellErrorDescription) { css::uno::Sequence<css::uno::Any> aSequence; - static_cast<const SfxGrabBagItem*>(rEECharAttrib.pAttr)->GetGrabBag().find("SpellErrorDescription")->second >>= aSequence; + const auto pGrabBag = static_cast<const SfxGrabBagItem*>(rEECharAttrib.pAttr)->GetGrabBag(); + const auto iter = pGrabBag.find("SpellErrorDescription"); + assert(iter != pGrabBag.end()); + iter->second >>= aSequence; rSpellErrorDescription.fromSequence(aSequence); } } @@ -1487,6 +1574,8 @@ bool SentenceEditWindow_Impl::KeyInput(const KeyEvent& rKeyEvt) //start position if (!IsUndoEditMode() && bIsErrorActive) { + aAttribList.clear(); + m_xEditEngine->GetCharAttribs(0, aAttribList); const EECharAttrib* pFontColor = FindCharAttrib(nCursor, EE_CHAR_COLOR, aAttribList); const EECharAttrib* pErrorAttrib = FindCharAttrib(m_nErrorStart, EE_CHAR_GRABBAG, aAttribList); if (pFontColor && pErrorAttrib) @@ -1518,7 +1607,7 @@ void SentenceEditWindow_Impl::Init(weld::Toolbar* pToolbar) m_pToolbar->connect_clicked(LINK(this,SentenceEditWindow_Impl,ToolbarHdl)); } -IMPL_LINK(SentenceEditWindow_Impl, ToolbarHdl, const OString&, rCurItemId, void) +IMPL_LINK(SentenceEditWindow_Impl, ToolbarHdl, const OUString&, rCurItemId, void) { if (rCurItemId == "paste") { @@ -1667,8 +1756,12 @@ void SentenceEditWindow_Impl::MoveErrorMarkTo(sal_Int32 nStart, sal_Int32 nEnd, m_xEditEngine->RemoveAttribs(aAll, false, EE_CHAR_WEIGHT_CJK); m_xEditEngine->RemoveAttribs(aAll, false, EE_CHAR_WEIGHT_CTL); + // tdf#116566 Use color defined in the current Color Scheme + Color aSpellErrorCollor = svtools::ColorConfig().GetColorValue(svtools::SPELL).nColor; + Color aGrammarErrorCollor = svtools::ColorConfig().GetColorValue(svtools::GRAMMAR).nColor; + SfxItemSet aSet(m_xEditEngine->GetEmptyItemSet()); - aSet.Put(SvxColorItem(bGrammarError ? COL_LIGHTBLUE : COL_LIGHTRED, EE_CHAR_COLOR)); + aSet.Put(SvxColorItem(bGrammarError ? aGrammarErrorCollor : aSpellErrorCollor, EE_CHAR_COLOR)); aSet.Put(SvxWeightItem(WEIGHT_BOLD, EE_CHAR_WEIGHT)); aSet.Put(SvxWeightItem(WEIGHT_BOLD, EE_CHAR_WEIGHT_CJK)); aSet.Put(SvxWeightItem(WEIGHT_BOLD, EE_CHAR_WEIGHT_CTL)); @@ -1683,6 +1776,8 @@ void SentenceEditWindow_Impl::MoveErrorMarkTo(sal_Int32 nStart, sal_Int32 nEnd, if (!bCurrentSelectionInRange) { m_xEditView->SetSelection(ESelection(0, nStart)); + // tdf#157148 ensure current location is auto-scrolled to be visible + m_xEditView->ShowCursor(); } Invalidate(); @@ -1816,7 +1911,7 @@ void SentenceEditWindow_Impl::SetAlternatives( const Reference< XSpellAlternativ aLocale = xAlt->getLocale(); aAlts = xAlt->getAlternatives(); } - SpellErrorDescription aDesc( false, aWord, aLocale, aAlts, nullptr); + SpellErrorDescription aDesc( false, aWord, std::move(aLocale), aAlts, nullptr); SfxGrabBagItem aSpellErrorDescription(EE_CHAR_GRABBAG); aSpellErrorDescription.GetGrabBag()["SpellErrorDescription"] <<= aDesc.toSequence(); SetAttrib(aSpellErrorDescription, m_nErrorStart, m_nErrorEnd); @@ -1945,7 +2040,6 @@ svx::SpellPortions SentenceEditWindow_Impl::CreateSpellPortions() const aPortion1.eLanguage = eLang; aPortion1.sText = m_xEditEngine->GetText(ESelection(0, nStart, 0, aStart->nPosition)); - bool bIsIgnoreError = m_aIgnoreErrorsAt.find( nStart ) != m_aIgnoreErrorsAt.end(); if( bIsIgnoreError ) { @@ -1977,7 +2071,7 @@ svx::SpellPortions SentenceEditWindow_Impl::CreateSpellPortions() const aPortion2.sText = aLeftOverText.makeStringAndClear(); aRet.push_back( aPortion2 ); } - else + else if (!aLeftOverText.isEmpty() && !aRet.empty()) { // we just need to append the left-over text to the last portion (which had no errors) aRet[ aRet.size() - 1 ].sText += aLeftOverText; } @@ -1989,7 +2083,7 @@ svx::SpellPortions SentenceEditWindow_Impl::CreateSpellPortions() const void SentenceEditWindow_Impl::Undo() { - SfxUndoManager& rUndoMgr = m_xEditEngine->GetUndoManager(); + EditUndoManager& rUndoMgr = m_xEditEngine->GetUndoManager(); DBG_ASSERT(GetUndoActionCount(), "no undo actions available" ); if(!GetUndoActionCount()) return; @@ -2008,13 +2102,13 @@ void SentenceEditWindow_Impl::Undo() void SentenceEditWindow_Impl::ResetUndo() { - SfxUndoManager& rUndo = m_xEditEngine->GetUndoManager(); + EditUndoManager& rUndo = m_xEditEngine->GetUndoManager(); rUndo.Clear(); } void SentenceEditWindow_Impl::AddUndoAction( std::unique_ptr<SfxUndoAction> pAction ) { - SfxUndoManager& rUndoMgr = m_xEditEngine->GetUndoManager(); + EditUndoManager& rUndoMgr = m_xEditEngine->GetUndoManager(); rUndoMgr.AddUndoAction(std::move(pAction)); GetSpellDialog()->m_xUndoPB->set_sensitive(true); } @@ -2063,15 +2157,10 @@ void SentenceEditWindow_Impl::SetUndoEditMode(bool bSet) pSpellDialog->m_xLanguageLB->get_widget(), pSpellDialog->m_xAddToDictMB.get(), pSpellDialog->m_xAddToDictPB.get(), - pSpellDialog->m_xAutoCorrPB.get(), - nullptr + pSpellDialog->m_xAutoCorrPB.get() }; - sal_Int32 nIdx = 0; - do - { - aControls[nIdx]->set_sensitive(false); - } - while(aControls[++nIdx]); + for (weld::Widget* pWidget : aControls) + pWidget->set_sensitive(false); //remove error marks ESelection aAll(0, 0, 0, EE_TEXTPOS_ALL); |