weld SpellDialog
a) use EditEngine instead of TextEngine as the former can be hosted in a
foreign widget
b) use a SfxGrabBagItem to hold the custom spellchecking info inside the
EditEngine
c) in longer paragraphs the current word is now auto-scrolled into view
d) rename Invalidate to InvalidateDialog
Change-Id: Ic6db019c32cdfd5f354c58ee7394fdaa040b86e1
Reviewed-on: https://gerrit.libreoffice.org/74119
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
diff --git a/cui/Library_cui.mk b/cui/Library_cui.mk
index b025205..e3cd0c3 100644
--- a/cui/Library_cui.mk
+++ b/cui/Library_cui.mk
@@ -135,7 +135,6 @@ $(eval $(call gb_Library_add_exception_objects,cui,\
cui/source/dialogs/SignSignatureLineDialog \
cui/source/dialogs/sdrcelldlg \
cui/source/dialogs/showcols \
cui/source/dialogs/SpellAttrib \
cui/source/dialogs/SpellDialog \
cui/source/dialogs/splitcelldlg \
cui/source/dialogs/srchxtra \
diff --git a/cui/source/dialogs/SpellAttrib.cxx b/cui/source/dialogs/SpellAttrib.cxx
deleted file mode 100644
index 9d761a5..0000000
--- a/cui/source/dialogs/SpellAttrib.cxx
+++ /dev/null
@@ -1,105 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#include "SpellAttrib.hxx"
#include <vcl/font.hxx>
using namespace svx;
using namespace com::sun::star::linguistic2;
using namespace com::sun::star::uno;
SpellErrorAttrib::SpellErrorAttrib( const SpellErrorDescription& rDesc ) :
TextAttrib(TEXTATTR_SPELL_ERROR),
m_aSpellErrorDescription( rDesc )
{
}
void SpellErrorAttrib::SetFont( vcl::Font& ) const
{
//this attribute doesn't have a visual effect
}
std::unique_ptr<TextAttrib> SpellErrorAttrib::Clone() const
{
return std::unique_ptr<TextAttrib>(new SpellErrorAttrib(*this));
}
bool SpellErrorAttrib::operator==( const TextAttrib& rAttr ) const
{
return Which() == rAttr.Which() &&
m_aSpellErrorDescription == static_cast<const SpellErrorAttrib&>(rAttr).m_aSpellErrorDescription;
}
SpellLanguageAttrib::SpellLanguageAttrib(LanguageType eLang) :
TextAttrib(TEXTATTR_SPELL_LANGUAGE),
m_eLanguage(eLang)
{
}
void SpellLanguageAttrib::SetFont( vcl::Font& ) const
{
//no visual effect
}
std::unique_ptr<TextAttrib> SpellLanguageAttrib::Clone() const
{
return std::unique_ptr<TextAttrib>(new SpellLanguageAttrib(*this));
}
bool SpellLanguageAttrib::operator==( const TextAttrib& rAttr ) const
{
return Which() == rAttr.Which() &&
m_eLanguage == static_cast<const SpellLanguageAttrib&>(rAttr).m_eLanguage;
}
SpellBackgroundAttrib::SpellBackgroundAttrib(const Color& rCol) :
TextAttrib(TEXTATTR_SPELL_BACKGROUND),
m_aBackgroundColor(rCol)
{
}
void SpellBackgroundAttrib::SetFont( vcl::Font& rFont ) const
{
rFont.SetFillColor(m_aBackgroundColor);
}
std::unique_ptr<TextAttrib> SpellBackgroundAttrib::Clone() const
{
return std::unique_ptr<TextAttrib>(new SpellBackgroundAttrib(*this));
}
bool SpellBackgroundAttrib::operator==( const TextAttrib& rAttr ) const
{
return Which() == rAttr.Which() &&
m_aBackgroundColor == static_cast<const SpellBackgroundAttrib&>(rAttr).m_aBackgroundColor;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/SpellAttrib.hxx b/cui/source/dialogs/SpellAttrib.hxx
index 2a45816..a106bce 100644
--- a/cui/source/dialogs/SpellAttrib.hxx
+++ b/cui/source/dialogs/SpellAttrib.hxx
@@ -19,7 +19,6 @@
#ifndef INCLUDED_CUI_SOURCE_DIALOGS_SPELLATTRIB_HXX
#define INCLUDED_CUI_SOURCE_DIALOGS_SPELLATTRIB_HXX
#include <vcl/txtattr.hxx>
#include <i18nlangtag/lang.h>
#include <com/sun/star/uno/Reference.h>
#include <com/sun/star/uno/Sequence.h>
@@ -27,10 +26,6 @@
#include <com/sun/star/linguistic2/XProofreader.hpp>
#include <tools/color.hxx>
#define TEXTATTR_SPELL_ERROR (TEXTATTR_USER_START + 1)
#define TEXTATTR_SPELL_LANGUAGE (TEXTATTR_USER_START + 2)
#define TEXTATTR_SPELL_BACKGROUND (TEXTATTR_USER_START + 3)
namespace svx{
struct SpellErrorDescription
{
@@ -61,16 +56,21 @@ struct SpellErrorDescription
aLocale( rLocale ),
xGrammarChecker( rxGrammarChecker ),
aSuggestions( rSuggestions )
{
if( pDialogTitle )
sDialogTitle = *pDialogTitle;
if( pExplanation )
sExplanation = *pExplanation;
if( pExplanationURL )
sExplanationURL = *pExplanationURL;
if( pRuleId )
sRuleId = *pRuleId;
};
{
if( pDialogTitle )
sDialogTitle = *pDialogTitle;
if( pExplanation )
sExplanation = *pExplanation;
if( pExplanationURL )
sExplanationURL = *pExplanationURL;
if( pRuleId )
sRuleId = *pRuleId;
};
SpellErrorDescription()
: bIsGrammarError(false)
{
}
bool operator==( const SpellErrorDescription& rDesc ) const
{
@@ -86,54 +86,36 @@ struct SpellErrorDescription
sExplanationURL == rDesc.sExplanationURL &&
sRuleId == rDesc.sRuleId;
}
css::uno::Sequence<css::uno::Any> toSequence() const
{
css::uno::Sequence<css::uno::Any> aEntries(9);
aEntries[0] <<= bIsGrammarError;
aEntries[1] <<= sErrorText;
aEntries[2] <<= sDialogTitle;
aEntries[3] <<= sExplanation;
aEntries[4] <<= sExplanationURL;
aEntries[5] <<= aLocale;
aEntries[6] <<= xGrammarChecker;
aEntries[7] <<= aSuggestions;
aEntries[8] <<= sRuleId;
return aEntries;
}
void fromSequence(const css::uno::Sequence<css::uno::Any>& rEntries)
{
rEntries[0] >>= bIsGrammarError;
rEntries[1] >>= sErrorText;
rEntries[2] >>= sDialogTitle;
rEntries[3] >>= sExplanation;
rEntries[4] >>= sExplanationURL;
rEntries[5] >>= aLocale;
rEntries[6] >>= xGrammarChecker;
rEntries[7] >>= aSuggestions;
rEntries[8] >>= sRuleId;
}
};
class SpellErrorAttrib : public TextAttrib
{
public:
private:
SpellErrorDescription m_aSpellErrorDescription;
public:
SpellErrorAttrib( const SpellErrorDescription& );
const SpellErrorDescription& GetErrorDescription() const { return m_aSpellErrorDescription; }
virtual void SetFont( vcl::Font& rFont ) const override;
virtual std::unique_ptr<TextAttrib> Clone() const override;
virtual bool operator==( const TextAttrib& rAttr ) const override;
};
class SpellLanguageAttrib : public TextAttrib
{
LanguageType m_eLanguage;
public:
SpellLanguageAttrib(LanguageType eLanguage);
LanguageType GetLanguage() const {return m_eLanguage;}
virtual void SetFont( vcl::Font& rFont ) const override;
virtual std::unique_ptr<TextAttrib> Clone() const override;
virtual bool operator==( const TextAttrib& rAttr ) const override;
};
class SpellBackgroundAttrib : public TextAttrib
{
Color m_aBackgroundColor;
public:
SpellBackgroundAttrib(const Color& rCol);
virtual void SetFont( vcl::Font& rFont ) const override;
virtual std::unique_ptr<TextAttrib> Clone() const override;
virtual bool operator==( const TextAttrib& rAttr ) const override;
};
}//namespace svx
#endif
diff --git a/cui/source/dialogs/SpellDialog.cxx b/cui/source/dialogs/SpellDialog.cxx
index 0757d01..6d77aeb 100644
--- a/cui/source/dialogs/SpellDialog.cxx
+++ b/cui/source/dialogs/SpellDialog.cxx
@@ -18,25 +18,20 @@
*/
#include <memory>
#include <vcl/event.hxx>
#include <vcl/weld.hxx>
#include <vcl/wrkwin.hxx>
#include <vcl/menu.hxx>
#include <vcl/scrbar.hxx>
#include <vcl/settings.hxx>
#include <vcl/svapp.hxx>
#include "SpellAttrib.hxx"
#include <sfx2/dispatch.hxx>
#include <sfx2/bindings.hxx>
#include <sfx2/sfxsids.hrc>
#include <sfx2/viewfrm.hxx>
#include <svl/grabbagitem.hxx>
#include <svl/undo.hxx>
#include <unotools/lingucfg.hxx>
#include <vcl/textdata.hxx>
#include <vcl/textview.hxx>
#include <vcl/graphicfilter.hxx>
#include <editeng/unolingu.hxx>
#include <editeng/colritem.hxx>
#include <editeng/eeitem.hxx>
#include <editeng/langitem.hxx>
#include <editeng/splwrap.hxx>
#include <editeng/unolingu.hxx>
#include <editeng/wghtitem.hxx>
#include <linguistic/lngprops.hxx>
#include <linguistic/misc.hxx>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
@@ -48,8 +43,15 @@
#include <com/sun/star/linguistic2/XSearchableDictionaryList.hpp>
#include <com/sun/star/linguistic2/XSpellChecker1.hpp>
#include <sfx2/app.hxx>
#include <vcl/help.hxx>
#include <vcl/cursor.hxx>
#include <vcl/event.hxx>
#include <vcl/graph.hxx>
#include <vcl/help.hxx>
#include <vcl/graphicfilter.hxx>
#include <vcl/ptrstyle.hxx>
#include <vcl/settings.hxx>
#include <vcl/svapp.hxx>
#include <vcl/weld.hxx>
#include <osl/file.hxx>
#include <editeng/optitems.hxx>
#include <editeng/svxenum.hxx>
@@ -165,81 +167,73 @@ sal_uInt16 SpellUndoAction_Impl::GetId()const
// class SvxSpellCheckDialog ---------------------------------------------
SpellDialog::SpellDialog(SpellDialogChildWindow* pChildWindow,
vcl::Window * pParent, SfxBindings* _pBindings)
: SfxModelessDialog (_pBindings, pChildWindow,
pParent, "SpellingDialog", "cui/ui/spellingdialog.ui")
weld::Window * pParent, SfxBindings* _pBindings)
: SfxModelessDialogController (_pBindings, pChildWindow,
pParent, "cui/ui/spellingdialog.ui", "SpellingDialog")
, aDialogUndoLink(LINK (this, SpellDialog, DialogUndoHdl))
, bFocusLocked(true)
, rParent(*pChildWindow)
, pImpl( new SpellDialog_Impl )
, m_xAltTitle(m_xBuilder->weld_label("alttitleft"))
, m_xResumeFT(m_xBuilder->weld_label("resumeft"))
, m_xNoSuggestionsFT(m_xBuilder->weld_label("nosuggestionsft"))
, m_xLanguageFT(m_xBuilder->weld_label("languageft"))
, m_xLanguageLB(new LanguageBox(m_xBuilder->weld_combo_box("languagelb")))
, 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_xSuggestionFT(m_xBuilder->weld_label("suggestionsft"))
, m_xSuggestionLB(m_xBuilder->weld_tree_view("suggestionslb"))
, m_xIgnorePB(m_xBuilder->weld_button("ignore"))
, m_xIgnoreAllPB(m_xBuilder->weld_button("ignoreall"))
, m_xIgnoreRulePB(m_xBuilder->weld_button("ignorerule"))
, m_xAddToDictPB(m_xBuilder->weld_button("add"))
, m_xAddToDictMB(m_xBuilder->weld_menu_button("addmb"))
, m_xChangePB(m_xBuilder->weld_button("change"))
, m_xChangeAllPB(m_xBuilder->weld_button("changeall"))
, m_xAutoCorrPB(m_xBuilder->weld_button("autocorrect"))
, m_xCheckGrammarCB(m_xBuilder->weld_check_button("checkgrammar"))
, m_xOptionsPB(m_xBuilder->weld_button("options"))
, m_xUndoPB(m_xBuilder->weld_button("undo"))
, m_xClosePB(m_xBuilder->weld_button("close"))
, m_xToolbar(m_xBuilder->weld_toolbar("toolbar"))
, m_xSentenceEDWeld(new weld::CustomWeld(*m_xBuilder, "sentence", *m_xSentenceED))
{
m_sTitleSpellingGrammar = GetText();
m_sTitleSpelling = get<FixedText>("alttitleft")->GetText();
m_xSentenceED->SetSpellDialog(this);
m_xSentenceED->Init(m_xToolbar.get());
m_sTitleSpellingGrammar = m_xDialog->get_title();
m_sTitleSpelling = m_xAltTitle->get_label();
// fdo#68794 set initial title for cases where no text has been processed
// yet to show its language attributes
OUString sTitle = rParent.HasGrammarChecking() ? m_sTitleSpellingGrammar : m_sTitleSpelling;
SetText(sTitle.replaceFirst("$LANGUAGE ($LOCATION)", ""));
m_xDialog->set_title(m_xDialog->strip_mnemonic(sTitle.replaceFirst("$LANGUAGE ($LOCATION)", "")));
m_sResumeST = get<FixedText>("resumeft")->GetText();
m_sNoSuggestionsST = get<FixedText>("nosuggestionsft")->GetText();
m_sResumeST = m_xResumeFT->get_label();
m_sNoSuggestionsST = m_xNoSuggestionsFT->strip_mnemonic(m_xNoSuggestionsFT->get_label());
get(m_pLanguageFT, "languageft");
get(m_pLanguageLB, "languagelb");
get(m_pExplainFT, "explain");
get(m_pExplainLink, "explainlink");
get(m_pNotInDictFT, "notindictft");
get(m_pSentenceED, "sentence");
Size aEdSize(LogicToPixel(Size(197, 48), MapMode(MapUnit::MapAppFont)));
m_pSentenceED->set_width_request(aEdSize.Width());
m_pSentenceED->set_height_request(aEdSize.Height());
get(m_pSuggestionFT, "suggestionsft");
get(m_pSuggestionLB, "suggestionslb");
m_pSuggestionLB->SetDropDownLineCount(5);
m_pSuggestionLB->set_width_request(aEdSize.Width());
get(m_pIgnorePB, "ignore");
m_sIgnoreOnceST = m_pIgnorePB->GetText();
get(m_pIgnoreAllPB, "ignoreall");
get(m_pIgnoreRulePB, "ignorerule");
get(m_pAddToDictPB, "add");
get(m_pAddToDictMB, "addmb");
m_pAddToDictMB->SetHelpId(m_pAddToDictPB->GetHelpId());
get(m_pChangePB, "change");
get(m_pChangeAllPB, "changeall");
get(m_pAutoCorrPB, "autocorrect");
get(m_pCheckGrammarCB, "checkgrammar");
get(m_pOptionsPB, "options");
get(m_pUndoPB, "undo");
get(m_pClosePB, "close");
get(m_pToolbar, "toolbar");
m_pSentenceED->Init(m_pToolbar);
Size aEdSize(m_xSuggestionLB->get_approximate_digit_width() * 60,
m_xSuggestionLB->get_height_rows(6));
m_xSuggestionLB->set_size_request(aEdSize.Width(), -1);
m_sIgnoreOnceST = m_xIgnorePB->get_label();
m_xAddToDictMB->set_help_id(m_xAddToDictPB->get_help_id());
xSpell = LinguMgr::GetSpellChecker();
const StyleSettings& rSettings = GetSettings().GetStyleSettings();
Color aCol = rSettings.GetHelpColor();
Wallpaper aWall( aCol );
m_pExplainLink->SetBackground( aWall );
m_pExplainFT->SetBackground( aWall );
Init_Impl();
// disable controls if service is missing
Enable(xSpell.is());
m_xDialog->set_sensitive(xSpell.is());
//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 ), nullptr, true );
Application::PostUserEvent(LINK(this, SpellDialog, InitHdl));
}
SpellDialog::~SpellDialog()
{
disposeOnce();
}
void SpellDialog::dispose()
{
if (pImpl)
{
// save possibly modified user-dictionaries
@@ -249,90 +243,69 @@ void SpellDialog::dispose()
pImpl.reset();
}
m_pLanguageFT.clear();
m_pLanguageLB.clear();
m_pExplainFT.clear();
m_pExplainLink.clear();
m_pNotInDictFT.clear();
m_pSentenceED.clear();
m_pSuggestionFT.clear();
m_pSuggestionLB.clear();
m_pIgnorePB.clear();
m_pIgnoreAllPB.clear();
m_pIgnoreRulePB.clear();
m_pAddToDictPB.clear();
m_pAddToDictMB.clear();
m_pChangePB.clear();
m_pChangeAllPB.clear();
m_pAutoCorrPB.clear();
m_pCheckGrammarCB.clear();
m_pOptionsPB.clear();
m_pUndoPB.clear();
m_pClosePB.clear();
m_pToolbar.clear();
SfxModelessDialog::dispose();
}
void SpellDialog::Init_Impl()
{
// initialize handler
m_pClosePB->SetClickHdl(LINK( this, SpellDialog, CancelHdl ) );
m_pChangePB->SetClickHdl(LINK( this, SpellDialog, ChangeHdl ) );
m_pChangeAllPB->SetClickHdl(LINK( this, SpellDialog, ChangeAllHdl ) );
m_pIgnorePB->SetClickHdl(LINK( this, SpellDialog, IgnoreHdl ) );
m_pIgnoreAllPB->SetClickHdl(LINK( this, SpellDialog, IgnoreAllHdl ) );
m_pIgnoreRulePB->SetClickHdl(LINK( this, SpellDialog, IgnoreAllHdl ) );
m_pUndoPB->SetClickHdl(LINK( this, SpellDialog, UndoHdl ) );
m_xClosePB->connect_clicked(LINK( this, SpellDialog, CancelHdl ) );
m_xChangePB->connect_clicked(LINK( this, SpellDialog, ChangeHdl ) );
m_xChangeAllPB->connect_clicked(LINK( this, SpellDialog, ChangeAllHdl ) );
m_xIgnorePB->connect_clicked(LINK( this, SpellDialog, IgnoreHdl ) );
m_xIgnoreAllPB->connect_clicked(LINK( this, SpellDialog, IgnoreAllHdl ) );
m_xIgnoreRulePB->connect_clicked(LINK( this, SpellDialog, IgnoreAllHdl ) );
m_xUndoPB->connect_clicked(LINK( this, SpellDialog, UndoHdl ) );
m_pAutoCorrPB->SetClickHdl( LINK( this, SpellDialog, ExtClickHdl ) );
m_pCheckGrammarCB->SetClickHdl( LINK( this, SpellDialog, CheckGrammarHdl ));
m_pOptionsPB->SetClickHdl( LINK( this, SpellDialog, ExtClickHdl ) );
m_xAutoCorrPB->connect_clicked( LINK( this, SpellDialog, ExtClickHdl ) );
m_xCheckGrammarCB->connect_clicked( LINK( this, SpellDialog, CheckGrammarHdl ));
m_xOptionsPB->connect_clicked( LINK( this, SpellDialog, ExtClickHdl ) );
m_pSuggestionLB->SetDoubleClickHdl( LINK( this, SpellDialog, DoubleClickChangeHdl ) );
m_xSuggestionLB->connect_row_activated( LINK( this, SpellDialog, DoubleClickChangeHdl ) );
m_pSentenceED->SetModifyHdl(LINK ( this, SpellDialog, ModifyHdl) );
m_xSentenceED->SetModifyHdl(LINK ( this, SpellDialog, ModifyHdl) );
m_pAddToDictMB->SetSelectHdl(LINK ( this, SpellDialog, AddToDictSelectHdl ) );
m_pAddToDictPB->SetClickHdl(LINK ( this, SpellDialog, AddToDictClickHdl ) );
m_xAddToDictMB->connect_selected(LINK ( this, SpellDialog, AddToDictSelectHdl ) );
m_xAddToDictPB->connect_clicked(LINK ( this, SpellDialog, AddToDictClickHdl ) );
m_pLanguageLB->SetSelectHdl(LINK( this, SpellDialog, LanguageSelectHdl ) );
m_xLanguageLB->connect_changed(LINK( this, SpellDialog, LanguageSelectHdl ) );
// initialize language ListBox
m_pLanguageLB->SetLanguageList( SvxLanguageListFlags::SPELL_USED, false, true );
m_xLanguageLB->SetLanguageList(SvxLanguageListFlags::SPELL_USED, false, false, true);
m_pSentenceED->ClearModifyFlag();
m_xSentenceED->ClearModifyFlag();
LinguMgr::GetChangeAllList()->clear();
}
void SpellDialog::UpdateBoxes_Impl(bool bCallFromSelectHdl)
{
sal_Int32 i;
m_pSuggestionLB->Clear();
m_xSuggestionLB->clear();
const SpellErrorDescription* pSpellErrorDescription = m_pSentenceED->GetAlternatives();
SpellErrorDescription aSpellErrorDescription;
bool bSpellErrorDescription = m_xSentenceED->GetAlternatives(aSpellErrorDescription);
LanguageType nAltLanguage = LANGUAGE_NONE;
Sequence< OUString > aNewWords;
bool bIsGrammarError = false;
if( pSpellErrorDescription )
if( bSpellErrorDescription )
{
nAltLanguage = LanguageTag::convertToLanguageType( pSpellErrorDescription->aLocale );
aNewWords = pSpellErrorDescription->aSuggestions;
bIsGrammarError = pSpellErrorDescription->bIsGrammarError;
m_pExplainLink->SetURL( pSpellErrorDescription->sExplanationURL );
m_pExplainFT->SetText( pSpellErrorDescription->sExplanation );
nAltLanguage = LanguageTag::convertToLanguageType( aSpellErrorDescription.aLocale );
aNewWords = aSpellErrorDescription.aSuggestions;
bIsGrammarError = aSpellErrorDescription.bIsGrammarError;
m_xExplainLink->set_uri( aSpellErrorDescription.sExplanationURL );
m_xExplainFT->set_label( aSpellErrorDescription.sExplanation );
}
if( pSpellErrorDescription && !pSpellErrorDescription->sDialogTitle.isEmpty() )
if( bSpellErrorDescription && !aSpellErrorDescription.sDialogTitle.isEmpty() )
{
// use this function to apply the correct image to be used...
SetTitle_Impl( nAltLanguage );
// then change the title to the one to be actually used
SetText( pSpellErrorDescription->sDialogTitle );
m_xDialog->set_title(m_xDialog->strip_mnemonic(aSpellErrorDescription.sDialogTitle));
}
else
SetTitle_Impl( nAltLanguage );
if( !bCallFromSelectHdl )
m_pLanguageLB->SelectLanguage( nAltLanguage );
m_xLanguageLB->set_active_id( nAltLanguage );
int nDicts = InitUserDicts();
// enter alternatives
@@ -341,76 +314,73 @@ void SpellDialog::UpdateBoxes_Impl(bool bCallFromSelectHdl)
for ( i = 0; i < nSize; ++i )
{
OUString aTmp( pNewWords[i] );
if ( LISTBOX_ENTRY_NOTFOUND == m_pSuggestionLB->GetEntryPos( aTmp ) )
{
m_pSuggestionLB->InsertEntry( aTmp );
m_pSuggestionLB->SetEntryFlags(m_pSuggestionLB->GetEntryCount() - 1, ListBoxEntryFlags::MultiLine);
}
if (m_xSuggestionLB->find_text(aTmp) == -1)
m_xSuggestionLB->append_text(aTmp);
}
if(!nSize)
m_pSuggestionLB->InsertEntry(m_sNoSuggestionsST);
m_pAutoCorrPB->Enable( nSize > 0 );
m_xSuggestionLB->append_text(m_sNoSuggestionsST);
m_xAutoCorrPB->set_sensitive( nSize > 0 );
m_pSuggestionFT->Enable(nSize > 0);
m_pSuggestionLB->Enable(nSize > 0);
m_xSuggestionFT->set_sensitive(nSize > 0);
m_xSuggestionLB->set_sensitive(nSize > 0);
if( nSize )
{
m_pSuggestionLB->SelectEntryPos(0);
m_xSuggestionLB->select(0);
}
m_pChangePB->Enable( nSize > 0);
m_pChangeAllPB->Enable(nSize > 0);
m_xChangePB->set_sensitive( nSize > 0);
m_xChangeAllPB->set_sensitive(nSize > 0);
bool bShowChangeAll = !bIsGrammarError;
m_pChangeAllPB->Show( bShowChangeAll );
m_pExplainFT->Show( !bShowChangeAll );
m_pLanguageLB->Enable( bShowChangeAll );
m_pIgnoreAllPB->Show( bShowChangeAll );
m_xChangeAllPB->set_visible( bShowChangeAll );
m_xExplainFT->set_visible( !bShowChangeAll );
m_xLanguageLB->set_sensitive( bShowChangeAll );
m_xIgnoreAllPB->set_visible( bShowChangeAll );
m_pAddToDictMB->Show( bShowChangeAll && nDicts > 1);
m_pAddToDictPB->Show( bShowChangeAll && nDicts <= 1);
m_pIgnoreRulePB->Show( !bShowChangeAll );
m_pIgnoreRulePB->Enable(pSpellErrorDescription && !pSpellErrorDescription->sRuleId.isEmpty());
m_pAutoCorrPB->Show( bShowChangeAll && rParent.HasAutoCorrection() );
m_xAddToDictMB->set_visible( bShowChangeAll && nDicts > 1);
m_xAddToDictPB->set_visible( bShowChangeAll && nDicts <= 1);
m_xIgnoreRulePB->set_visible( !bShowChangeAll );
m_xIgnoreRulePB->set_sensitive(bSpellErrorDescription && !aSpellErrorDescription.sRuleId.isEmpty());
m_xAutoCorrPB->set_visible( bShowChangeAll && rParent.HasAutoCorrection() );
bool bOldShowGrammar = m_pCheckGrammarCB->IsVisible();
bool bOldShowExplain = m_pExplainLink->IsVisible();
bool bOldShowGrammar = m_xCheckGrammarCB->get_visible();
bool bOldShowExplain = m_xExplainLink->get_visible();
m_pCheckGrammarCB->Show(rParent.HasGrammarChecking());
m_pExplainLink->Show(!m_pExplainLink->GetURL().isEmpty());
if (m_pExplainFT->GetText().isEmpty())
m_xCheckGrammarCB->set_visible(rParent.HasGrammarChecking());
m_xExplainLink->set_visible(!m_xExplainLink->get_uri().isEmpty());
if (m_xExplainFT->get_label().isEmpty())
{
m_pExplainFT->Hide();
m_pExplainLink->Hide();
m_xExplainFT->hide();
m_xExplainLink->hide();
}
if (bOldShowExplain != m_pExplainLink->IsVisible() || bOldShowGrammar != m_pCheckGrammarCB->IsVisible())
setOptimalLayoutSize();
if (bOldShowExplain != m_xExplainLink->get_visible() || bOldShowGrammar != m_xCheckGrammarCB->get_visible())
m_xDialog->resize_to_request();
}
void SpellDialog::SpellContinue_Impl(bool bUseSavedSentence, bool bIgnoreCurrentError )
{
//initially or after the last error of a sentence MarkNextError will fail
//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_pSentenceED->IsUndoEditMode() && m_pSentenceED->MarkNextError( bIgnoreCurrentError, xSpell )) ||
( bNextSentence = GetNextSentence_Impl(bUseSavedSentence, m_pSentenceED->IsUndoEditMode()) && m_pSentenceED->MarkNextError( false, xSpell )))
if((!m_xSentenceED->IsUndoEditMode() && m_xSentenceED->MarkNextError( bIgnoreCurrentError, xSpell )) ||
( bNextSentence = GetNextSentence_Impl(bUseSavedSentence, m_xSentenceED->IsUndoEditMode()) && m_xSentenceED->MarkNextError( false, xSpell )))
{
const SpellErrorDescription* pSpellErrorDescription = m_pSentenceED->GetAlternatives();
if( pSpellErrorDescription )
SpellErrorDescription aSpellErrorDescription;
bool bSpellErrorDescription = m_xSentenceED->GetAlternatives(aSpellErrorDescription);
if (bSpellErrorDescription)
{
UpdateBoxes_Impl();
Control* aControls[] =
weld::Widget* aControls[] =
{
m_pNotInDictFT,
m_pSentenceED,
m_pLanguageFT,
m_xNotInDictFT.get(),
m_xSentenceED->GetDrawingArea(),
m_xLanguageFT.get(),
nullptr
};
sal_Int32 nIdx = 0;
do
{
aControls[nIdx]->Enable();
aControls[nIdx]->set_sensitive(true);
}
while(aControls[++nIdx]);
@@ -418,8 +388,8 @@ void SpellDialog::SpellContinue_Impl(bool bUseSavedSentence, bool bIgnoreCurrent
if( bNextSentence )
{
//remove undo if a new sentence is active
m_pSentenceED->ResetUndo();
m_pUndoPB->Enable(false);
m_xSentenceED->ResetUndo();
m_xUndoPB->set_sensitive(false);
}
}
}
@@ -428,12 +398,12 @@ void SpellDialog::SpellContinue_Impl(bool bUseSavedSentence, bool bIgnoreCurrent
*/
IMPL_LINK_NOARG( SpellDialog, InitHdl, void*, void)
{
SetUpdateMode( false );
m_xDialog->freeze();
//show or hide AutoCorrect depending on the modules abilities
m_pAutoCorrPB->Show(rParent.HasAutoCorrection());
m_xAutoCorrPB->set_visible(rParent.HasAutoCorrection());
SpellContinue_Impl();
m_pSentenceED->ResetUndo();
m_pUndoPB->Enable(false);
m_xSentenceED->ResetUndo();
m_xUndoPB->set_sensitive(false);
// get current language
UpdateBoxes_Impl();
@@ -442,41 +412,40 @@ IMPL_LINK_NOARG( SpellDialog, InitHdl, void*, void)
InitUserDicts();
LockFocusChanges(true);
if( m_pChangePB->IsEnabled() )
m_pChangePB->GrabFocus();
else if( m_pIgnorePB->IsEnabled() )
m_pIgnorePB->GrabFocus();
else if( m_pClosePB->IsEnabled() )
m_pClosePB->GrabFocus();
if( m_xChangePB->get_sensitive() )
m_xChangePB->grab_focus();
else if( m_xIgnorePB->get_sensitive() )
m_xIgnorePB->grab_focus();
else if( m_xClosePB->get_sensitive() )
m_xClosePB->grab_focus();
LockFocusChanges(false);
//show grammar CheckBox depending on the modules abilities
m_pCheckGrammarCB->Check( rParent.IsGrammarChecking() );
SetUpdateMode( true );
Show();
m_xCheckGrammarCB->set_active(rParent.IsGrammarChecking());
m_xDialog->thaw();
};
IMPL_LINK( SpellDialog, ExtClickHdl, Button *, pBtn, void )
IMPL_LINK( SpellDialog, ExtClickHdl, weld::Button&, rBtn, void )
{
if (m_pOptionsPB == pBtn)
if (m_xOptionsPB.get() == &rBtn)
StartSpellOptDlg_Impl();
else if (m_pAutoCorrPB == pBtn)
else if (m_xAutoCorrPB.get() == &rBtn)
{
//get the currently selected wrong word
OUString sCurrentErrorText = m_pSentenceED->GetErrorText();
OUString sCurrentErrorText = m_xSentenceED->GetErrorText();
//get the wrong word from the XSpellAlternative
const SpellErrorDescription* pSpellErrorDescription = m_pSentenceED->GetAlternatives();
if( pSpellErrorDescription )
SpellErrorDescription aSpellErrorDescription;
bool bSpellErrorDescription = m_xSentenceED->GetAlternatives(aSpellErrorDescription);
if (bSpellErrorDescription)
{
OUString sWrong(pSpellErrorDescription->sErrorText);
OUString sWrong(aSpellErrorDescription.sErrorText);
//if the word has not been edited in the MultiLineEdit then
//the current suggestion should be used
//if it's not the 'no suggestions' entry
if(sWrong == sCurrentErrorText &&
m_pSuggestionLB->IsEnabled() && m_pSuggestionLB->GetSelectedEntryCount() > 0 &&
m_sNoSuggestionsST != m_pSuggestionLB->GetSelectedEntry())
m_xSuggestionLB->get_sensitive() && m_xSuggestionLB->get_selected_index() != -1 &&
m_sNoSuggestionsST != m_xSuggestionLB->get_selected_text())
{
sCurrentErrorText = m_pSuggestionLB->GetSelectedEntry();
sCurrentErrorText = m_xSuggestionLB->get_selected_text();
}
if(sWrong != sCurrentErrorText)
{
@@ -488,16 +457,16 @@ IMPL_LINK( SpellDialog, ExtClickHdl, Button *, pBtn, void )
}
}
IMPL_LINK( SpellDialog, CheckGrammarHdl, Button*, pBox, void )
IMPL_LINK_NOARG(SpellDialog, CheckGrammarHdl, weld::Button&, void)
{
rParent.SetGrammarChecking( static_cast<CheckBox*>(pBox)->IsChecked() );
rParent.SetGrammarChecking(m_xCheckGrammarCB->get_active());
Impl_Restore(true);
}
void SpellDialog::StartSpellOptDlg_Impl()
{
SfxItemSet aSet( SfxGetpApp()->GetPool(), svl::Items<SID_AUTOSPELL_CHECK,SID_AUTOSPELL_CHECK>{});
SfxSingleTabDialogController aDlg(GetFrameWeld(), &aSet, "cui/ui/spelloptionsdialog.ui", "SpellOptionsDialog");
SfxSingleTabDialogController aDlg(m_xDialog.get(), &aSet, "cui/ui/spelloptionsdialog.ui", "SpellOptionsDialog");
TabPageParent aParent(aDlg.get_content_area(), &aDlg);
VclPtr<SfxTabPage> xPage = SvxLinguTabPage::Create(aParent, &aSet);
@@ -530,54 +499,51 @@ namespace
}
}
OUString SpellDialog::getReplacementString() const
{
OUString sOrigString = m_pSentenceED->GetErrorText();
OUString sOrigString = m_xSentenceED->GetErrorText();
OUString sReplacement(sOrigString);
if(m_pSuggestionLB->IsEnabled() &&
m_pSuggestionLB->GetSelectedEntryCount()>0 &&
m_sNoSuggestionsST != m_pSuggestionLB->GetSelectedEntry())
sReplacement = m_pSuggestionLB->GetSelectedEntry();
if(m_xSuggestionLB->get_sensitive() &&
m_xSuggestionLB->get_selected_index() != -1 &&
m_sNoSuggestionsST != m_xSuggestionLB->get_selected_text())
sReplacement = m_xSuggestionLB->get_selected_text();
return getDotReplacementString(sOrigString, sReplacement);
}
IMPL_LINK_NOARG(SpellDialog, DoubleClickChangeHdl, ListBox&, void)
IMPL_LINK_NOARG(SpellDialog, DoubleClickChangeHdl, weld::TreeView&, void)
{
ChangeHdl(nullptr);
ChangeHdl(*m_xChangePB);
}
IMPL_LINK_NOARG(SpellDialog, ChangeHdl, Button*, void)
IMPL_LINK_NOARG(SpellDialog, ChangeHdl, weld::Button&, void)
{
if(m_pSentenceED->IsUndoEditMode())
if (m_xSentenceED->IsUndoEditMode())
{
SpellContinue_Impl();
}
else
{
m_pSentenceED->UndoActionStart( SPELLUNDO_CHANGE_GROUP );
m_xSentenceED->UndoActionStart( SPELLUNDO_CHANGE_GROUP );
OUString aString = getReplacementString();
m_pSentenceED->ChangeMarkedWord(aString, GetSelectedLang_Impl());
m_xSentenceED->ChangeMarkedWord(aString, GetSelectedLang_Impl());
SpellContinue_Impl();
m_pSentenceED->UndoActionEnd();
m_xSentenceED->UndoActionEnd();
}
if(!m_pChangePB->IsEnabled())
m_pIgnorePB->GrabFocus();
if(!m_xChangePB->get_sensitive())
m_xIgnorePB->grab_focus();
}
IMPL_LINK_NOARG(SpellDialog, ChangeAllHdl, Button*, void)
IMPL_LINK_NOARG(SpellDialog, ChangeAllHdl, weld::Button&, void)
{
m_pSentenceED->UndoActionStart( SPELLUNDO_CHANGE_GROUP );
m_xSentenceED->UndoActionStart( SPELLUNDO_CHANGE_GROUP );
OUString aString = getReplacementString();
LanguageType eLang = GetSelectedLang_Impl();
// add new word to ChangeAll list
OUString aOldWord( m_pSentenceED->GetErrorText() );
OUString aOldWord( m_xSentenceED->GetErrorText() );
SvxPrepareAutoCorrect( aOldWord, aString );
Reference<XDictionary> aXDictionary( LinguMgr::GetChangeAllList(), UNO_QUERY );
DictionaryError nAdded = AddEntryToDic( aXDictionary,
@@ -590,31 +556,31 @@ IMPL_LINK_NOARG(SpellDialog, ChangeAllHdl, Button*, void)
SPELLUNDO_CHANGE_ADD_TO_DICTIONARY, aDialogUndoLink));
pAction->SetDictionary(aXDictionary);
pAction->SetAddedWord(aOldWord);
m_pSentenceED->AddUndoAction(std::move(pAction));
m_xSentenceED->AddUndoAction(std::move(pAction));
}
m_pSentenceED->ChangeMarkedWord(aString, eLang);
m_xSentenceED->ChangeMarkedWord(aString, eLang);
SpellContinue_Impl();
m_pSentenceED->UndoActionEnd();
m_xSentenceED->UndoActionEnd();
}
IMPL_LINK( SpellDialog, IgnoreAllHdl, Button *, pButton, void )
IMPL_LINK( SpellDialog, IgnoreAllHdl, weld::Button&, rButton, void )
{
m_pSentenceED->UndoActionStart( SPELLUNDO_CHANGE_GROUP );
m_xSentenceED->UndoActionStart( SPELLUNDO_CHANGE_GROUP );
// add word to IgnoreAll list
Reference< XDictionary > aXDictionary( LinguMgr::GetIgnoreAllList(), UNO_QUERY );
//in case the error has been changed manually it has to be restored
m_pSentenceED->RestoreCurrentError();
if (pButton == m_pIgnoreRulePB)
m_xSentenceED->RestoreCurrentError();
if (&rButton == m_xIgnoreRulePB.get())
{
const SpellErrorDescription* pSpellErrorDescription = m_pSentenceED->GetAlternatives();
SpellErrorDescription aSpellErrorDescription;
bool bSpellErrorDescription = m_xSentenceED->GetAlternatives(aSpellErrorDescription);
try
{
if( pSpellErrorDescription && pSpellErrorDescription->xGrammarChecker.is() )
if( bSpellErrorDescription && aSpellErrorDescription.xGrammarChecker.is() )
{
pSpellErrorDescription->xGrammarChecker->ignoreRule( pSpellErrorDescription->sRuleId,
pSpellErrorDescription->aLocale );
aSpellErrorDescription.xGrammarChecker->ignoreRule(aSpellErrorDescription.sRuleId,
aSpellErrorDescription.aLocale);
// refresh the layout (workaround to launch a dictionary event)
aXDictionary->setActive(false);
aXDictionary->setActive(true);
@@ -626,30 +592,29 @@ IMPL_LINK( SpellDialog, IgnoreAllHdl, Button *, pButton, void )
}
else
{
OUString sErrorText(m_pSentenceED->GetErrorText());
OUString sErrorText(m_xSentenceED->GetErrorText());
DictionaryError nAdded = AddEntryToDic( aXDictionary,
sErrorText, false,
OUString() );
if(nAdded == DictionaryError::NONE)
if (nAdded == DictionaryError::NONE)
{
std::unique_ptr<SpellUndoAction_Impl> pAction(new SpellUndoAction_Impl(
SPELLUNDO_CHANGE_ADD_TO_DICTIONARY, aDialogUndoLink));
pAction->SetDictionary(aXDictionary);
pAction->SetAddedWord(sErrorText);
m_pSentenceED->AddUndoAction(std::move(pAction));
m_xSentenceED->AddUndoAction(std::move(pAction));
}
}
SpellContinue_Impl();
m_pSentenceED->UndoActionEnd();
m_xSentenceED->UndoActionEnd();
}
IMPL_LINK_NOARG(SpellDialog, UndoHdl, Button*, void)
IMPL_LINK_NOARG(SpellDialog, UndoHdl, weld::Button&, void)
{
m_pSentenceED->Undo();
if(!m_pSentenceED->GetUndoActionCount())
m_pUndoPB->Enable(false);
m_xSentenceED->Undo();
if(!m_xSentenceED->GetUndoActionCount())
m_xUndoPB->set_sensitive(false);
}
@@ -660,14 +625,14 @@ IMPL_LINK( SpellDialog, DialogUndoHdl, SpellUndoAction_Impl&, rAction, void )
case SPELLUNDO_CHANGE_TEXTENGINE:
{
if(rAction.IsEnableChangePB())
m_pChangePB->Enable(false);
m_xChangePB->set_sensitive(false);
if(rAction.IsEnableChangeAllPB())
m_pChangeAllPB->Enable(false);
m_xChangeAllPB->set_sensitive(false);
}
break;
case SPELLUNDO_CHANGE_NEXTERROR:
{
m_pSentenceED->MoveErrorMarkTo(static_cast<sal_Int32>(rAction.GetOldErrorStart()),
m_xSentenceED->MoveErrorMarkTo(static_cast<sal_Int32>(rAction.GetOldErrorStart()),
static_cast<sal_Int32>(rAction.GetOldErrorEnd()),
false);
if(rAction.IsErrorLanguageSelected())
@@ -685,7 +650,7 @@ IMPL_LINK( SpellDialog, DialogUndoHdl, SpellUndoAction_Impl&, rAction, void )
case SPELLUNDO_MOVE_ERROREND :
{
if(rAction.GetOffset() != 0)
m_pSentenceED->MoveErrorEnd(rAction.GetOffset());
m_xSentenceED->MoveErrorEnd(rAction.GetOffset());
}
break;
case SPELLUNDO_UNDO_EDIT_MODE :
@@ -705,16 +670,16 @@ void SpellDialog::Impl_Restore(bool bUseSavedSentence)
//clear the "ChangeAllList"
LinguMgr::GetChangeAllList()->clear();
//get a new sentence
m_pSentenceED->SetText(OUString());
m_pSentenceED->ResetModified();
m_xSentenceED->SetText(OUString());
m_xSentenceED->ResetModified();
//Resolves: fdo#39348 refill the dialog with the currently spelled sentence
SpellContinue_Impl(bUseSavedSentence);
m_pIgnorePB->SetText(m_sIgnoreOnceST);
m_xIgnorePB->set_label(m_sIgnoreOnceST);
}
IMPL_LINK_NOARG(SpellDialog, IgnoreHdl, Button*, void)
IMPL_LINK_NOARG(SpellDialog, IgnoreHdl, weld::Button&, void)
{
if (m_sResumeST == m_pIgnorePB->GetText())
if (m_sResumeST == m_xIgnorePB->get_label())
{
Impl_Restore(false);
}
@@ -722,35 +687,35 @@ IMPL_LINK_NOARG(SpellDialog, IgnoreHdl, Button*, void)
{
//in case the error has been changed manually it has to be restored,
// since the users choice now was to ignore the error
m_pSentenceED->RestoreCurrentError();
m_xSentenceED->RestoreCurrentError();
// the word is being ignored
SpellContinue_Impl( false, true );
}
}
bool SpellDialog::Close()
void SpellDialog::Close()
{
if (IsClosing())
return;
// We have to call ToggleChildWindow directly; calling SfxDispatcher's
// Execute() does not work here when we are in a document with protected
// 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::Current()->ToggleChildWindow(rParent.GetType());
return true;
SfxViewFrame* pViewFrame = SfxViewFrame::Current();
if (pViewFrame)
pViewFrame->ToggleChildWindow(rParent.GetType());
}
LanguageType SpellDialog::GetSelectedLang_Impl() const
{
LanguageType nLang = m_pLanguageLB->GetSelectedLanguage();
LanguageType nLang = m_xLanguageLB->get_active_id();
return nLang;
}
IMPL_LINK(SpellDialog, LanguageSelectHdl, ListBox&, rBox, void)
IMPL_LINK_NOARG(SpellDialog, LanguageSelectHdl, weld::ComboBox&, void)
{
//If selected language changes, then add->list should be regenerated to
//match
@@ -758,37 +723,36 @@ IMPL_LINK(SpellDialog, LanguageSelectHdl, ListBox&, rBox, void)
//if currently an error is selected then search for alternatives for
//this word and fill the alternatives ListBox accordingly
OUString sError = m_pSentenceED->GetErrorText();
m_pSuggestionLB->Clear();
if(!sError.isEmpty())
OUString sError = m_xSentenceED->GetErrorText();
m_xSuggestionLB->clear();
if (!sError.isEmpty())
{
LanguageType eLanguage = static_cast<SvxLanguageBox*>(&rBox)->GetSelectedLanguage();
LanguageType eLanguage = m_xLanguageLB->get_active_id();
Reference <XSpellAlternatives> xAlt = xSpell->spell( sError, static_cast<sal_uInt16>(eLanguage),
Sequence< PropertyValue >() );
if( xAlt.is() )
m_pSentenceED->SetAlternatives( xAlt );
m_xSentenceED->SetAlternatives( xAlt );
else
{
m_pSentenceED->ChangeMarkedWord( sError, eLanguage );
m_xSentenceED->ChangeMarkedWord( sError, eLanguage );
SpellContinue_Impl();
}
m_pSentenceED->AddUndoAction(std::make_unique<SpellUndoAction_Impl>(SPELLUNDO_CHANGE_LANGUAGE, aDialogUndoLink));
m_xSentenceED->AddUndoAction(std::make_unique<SpellUndoAction_Impl>(SPELLUNDO_CHANGE_LANGUAGE, aDialogUndoLink));
}
SpellDialog::UpdateBoxes_Impl(true);
}
void SpellDialog::SetTitle_Impl(LanguageType nLang)
{
OUString sTitle = rParent.HasGrammarChecking() ? m_sTitleSpellingGrammar : m_sTitleSpelling;
sTitle = sTitle.replaceFirst( "$LANGUAGE ($LOCATION)", SvtLanguageTable::GetLanguageString(nLang) );
SetText( sTitle );
m_xDialog->set_title(m_xDialog->strip_mnemonic(sTitle));
}
int SpellDialog::InitUserDicts()
{
const LanguageType nLang = m_pLanguageLB->GetSelectedLanguage();
const LanguageType nLang = m_xLanguageLB->get_active_id();
const Reference< XDictionary > *pDic = nullptr;
@@ -812,10 +776,7 @@ int SpellDialog::InitUserDicts()
bool bEnable = false;
const sal_Int32 nSize = pImpl->aDics.getLength();
pDic = pImpl->aDics.getConstArray();
PopupMenu* pMenu = m_pAddToDictMB->GetPopupMenu();
assert(pMenu);
pMenu->Clear();
pMenu->SetMenuFlags(MenuFlags::NoAutoMnemonics);
m_xAddToDictMB->clear();
sal_uInt16 nItemId = 1; // menu items should be enumerated from 1 and not 0
for (sal_Int32 i = 0; i < nSize; ++i)
{
@@ -830,57 +791,51 @@ int SpellDialog::InitUserDicts()
&& (nLang == nActLanguage || LANGUAGE_NONE == nActLanguage )
&& (!xStor.is() || !xStor->isReadonly()) )
{
pMenu->InsertItem( nItemId, xDicTmp->getName() );
bEnable = true;
OUString aDictionaryImageUrl;
uno::Reference< lang::XServiceInfo > xSvcInfo( xDicTmp, uno::UNO_QUERY );
if (xSvcInfo.is())
{
OUString aDictionaryImageUrl( aCfg.GetSpellAndGrammarContextDictionaryImage(
xSvcInfo->getImplementationName()) );
if (!aDictionaryImageUrl.isEmpty())
{
Image aImage( aDictionaryImageUrl );
pMenu->SetItemImage( nItemId, aImage );
}
aDictionaryImageUrl = aCfg.GetSpellAndGrammarContextDictionaryImage(
xSvcInfo->getImplementationName());
}
m_xAddToDictMB->append_item(OUString::number(nItemId), xDicTmp->getName(), aDictionaryImageUrl);
++nItemId;
}
}
m_pAddToDictMB->Enable( bEnable );
m_pAddToDictPB->Enable( bEnable );
m_xAddToDictMB->set_sensitive( bEnable );
m_xAddToDictPB->set_sensitive( bEnable );
int nDicts = nItemId-1;
m_pAddToDictMB->Show( nDicts > 1 );
m_pAddToDictPB->Show( nDicts <= 1 );
m_xAddToDictMB->set_visible( nDicts > 1 );
m_xAddToDictPB->set_visible( nDicts <= 1 );
return nDicts;
}
IMPL_LINK_NOARG(SpellDialog, AddToDictClickHdl, Button*, void)
IMPL_LINK_NOARG(SpellDialog, AddToDictClickHdl, weld::Button&, void)
{
AddToDictionaryExecute(1, m_pAddToDictMB->GetPopupMenu());
AddToDictionaryExecute(OString::number(1));
}
IMPL_LINK(SpellDialog, AddToDictSelectHdl, MenuButton*, pButton, void )
IMPL_LINK(SpellDialog, AddToDictSelectHdl, const OString&, rIdent, void)
{
AddToDictionaryExecute(pButton->GetCurItemId(), pButton->GetPopupMenu());
AddToDictionaryExecute(rIdent);
}
void SpellDialog::AddToDictionaryExecute( sal_uInt16 nItemId, PopupMenu const *pMenu )
void SpellDialog::AddToDictionaryExecute(const OString& rItemId)
{
m_pSentenceED->UndoActionStart( SPELLUNDO_CHANGE_GROUP );
m_xSentenceED->UndoActionStart( SPELLUNDO_CHANGE_GROUP );
//GetErrorText() returns the current error even if the text is already
//manually changed
const OUString aNewWord = m_pSentenceED->GetErrorText();
const OUString aNewWord = m_xSentenceED->GetErrorText();
OUString aDicName ( pMenu->GetItemText( nItemId ) );
OUString aDicName(m_xAddToDictMB->get_item_label(rItemId));
uno::Reference< linguistic2::XDictionary > xDic;
uno::Reference< linguistic2::XSearchableDictionaryList > xDicList( LinguMgr::GetDictionaryList() );
@@ -902,7 +857,7 @@ void SpellDialog::AddToDictionaryExecute( sal_uInt16 nItemId, PopupMenu const *p
SPELLUNDO_CHANGE_ADD_TO_DICTIONARY, aDialogUndoLink));
pAction->SetDictionary( xDic );
pAction->SetAddedWord( aNewWord );
m_pSentenceED->AddUndoAction( std::move(pAction) );
m_xSentenceED->AddUndoAction( std::move(pAction) );
}
// failed because there is already an entry?
if (DictionaryError::NONE != nAddRes && xDic->getEntry( aNewWord ).is())
@@ -910,48 +865,42 @@ void SpellDialog::AddToDictionaryExecute( sal_uInt16 nItemId, PopupMenu const *p
}
if (DictionaryError::NONE != nAddRes)
{
SvxDicError(GetFrameWeld(), nAddRes);
SvxDicError(m_xDialog.get(), nAddRes);
return; // don't continue
}
// go on
SpellContinue_Impl();
m_pSentenceED->UndoActionEnd();
m_xSentenceED->UndoActionEnd();
}
IMPL_LINK(SpellDialog, ModifyHdl, Edit&, rEd, void)
IMPL_LINK_NOARG(SpellDialog, ModifyHdl, LinkParamNone*, void)
{
if (m_pSentenceED == &rEd)
m_xSuggestionLB->unselect_all();
m_xSuggestionLB->set_sensitive(false);
m_xAutoCorrPB->set_sensitive(false);
std::unique_ptr<SpellUndoAction_Impl> pSpellAction(new SpellUndoAction_Impl(SPELLUNDO_CHANGE_TEXTENGINE, aDialogUndoLink));
if(!m_xChangeAllPB->get_sensitive())
{
m_pSuggestionLB->SetNoSelection();
m_pSuggestionLB->Disable();
m_pAutoCorrPB->Disable();
std::unique_ptr<SpellUndoAction_Impl> pSpellAction(new SpellUndoAction_Impl(SPELLUNDO_CHANGE_TEXTENGINE, aDialogUndoLink));
if(!m_pChangeAllPB->IsEnabled())
{
m_pChangeAllPB->Enable();
pSpellAction->SetEnableChangeAllPB();
}
if(!m_pChangePB->IsEnabled())
{
m_pChangePB->Enable();
pSpellAction->SetEnableChangePB();
}
m_pSentenceED->AddUndoAction(std::move(pSpellAction));
m_xChangeAllPB->set_sensitive(true);
pSpellAction->SetEnableChangeAllPB();
}
};
if(!m_xChangePB->get_sensitive())
{
m_xChangePB->set_sensitive(true);
pSpellAction->SetEnableChangePB();
}
m_xSentenceED->AddUndoAction(std::move(pSpellAction));
}
IMPL_LINK_NOARG(SpellDialog, CancelHdl, Button*, void)
IMPL_LINK_NOARG(SpellDialog, CancelHdl, weld::Button&, void)
{
//apply changes and ignored text parts first - if there are any
rParent.ApplyChangedSentence(m_pSentenceED->CreateSpellPortions(), false);
rParent.ApplyChangedSentence(m_xSentenceED->CreateSpellPortions(), false);
Close();
}
bool SpellDialog::EventNotify( NotifyEvent& rNEvt )
void SpellDialog::ToplevelFocusChanged()
{
/* #i38338#
* FIXME: LoseFocus and GetFocus are signals from vcl that
@@ -962,66 +911,75 @@ bool SpellDialog::EventNotify( NotifyEvent& rNEvt )
* The only sensible thing would be to call the new Method differently,
* e.g. DialogGot/LostFocus or so.
*/
if( IsVisible() && !bFocusLocked )
if (m_xDialog->get_visible() && !bFocusLocked)
{
if( rNEvt.GetType() == MouseNotifyEvent::GETFOCUS )
if (m_xDialog->has_toplevel_focus())
{
//notify the child window of the focus change
rParent.GetFocus();
}
else if( rNEvt.GetType() == MouseNotifyEvent::LOSEFOCUS )
else
{
//notify the child window of the focus change
rParent.LoseFocus();
}
}
return SfxModelessDialog::EventNotify(rNEvt);
}
void SpellDialog::Activate()
{
SfxModelessDialogController::Activate();
ToplevelFocusChanged();
}
void SpellDialog::Deactivate()
{
SfxModelessDialogController::Activate();
ToplevelFocusChanged();
}
void SpellDialog::InvalidateDialog()
{
if( bFocusLocked )
return;
m_pIgnorePB->SetText(m_sResumeST);
vcl::Window* aDisableArr[] =
m_xIgnorePB->set_label(m_sResumeST);
weld::Widget* aDisableArr[] =
{
m_pNotInDictFT,
m_pSentenceED,
m_pSuggestionFT,
m_pSuggestionLB,
m_pLanguageFT,
m_pLanguageLB,
m_pIgnoreAllPB,
m_pIgnoreRulePB,
m_pAddToDictMB,
m_pAddToDictPB,
m_pChangePB,
m_pChangeAllPB,
m_pAutoCorrPB,
m_pUndoPB,
m_xNotInDictFT.get(),
m_xSentenceED->GetDrawingArea(),
m_xSuggestionFT.get(),
m_xSuggestionLB.get(),
m_xLanguageFT.get(),
m_xLanguageLB->get_widget(),
m_xIgnoreAllPB.get(),
m_xIgnoreRulePB.get(),
m_xAddToDictMB.get(),
m_xAddToDictPB.get(),
m_xChangePB.get(),
m_xChangeAllPB.get(),
m_xAutoCorrPB.get(),
m_xUndoPB.get(),
nullptr
};
sal_Int16 i = 0;
while(aDisableArr[i])
{
aDisableArr[i]->Enable(false);
aDisableArr[i]->set_sensitive(false);
i++;
}
SfxModelessDialog::Deactivate();
SfxModelessDialogController::Deactivate();
}
bool SpellDialog::GetNextSentence_Impl(bool bUseSavedSentence, bool bRecheck)
{
bool bRet = false;
if(!bUseSavedSentence)
{
//apply changes and ignored text parts
rParent.ApplyChangedSentence(m_pSentenceED->CreateSpellPortions(), bRecheck);
rParent.ApplyChangedSentence(m_xSentenceED->CreateSpellPortions(), bRecheck);
}
m_pSentenceED->ResetIgnoreErrorsAt();
m_pSentenceED->ResetModified();
m_xSentenceED->ResetIgnoreErrorsAt();
m_xSentenceED->ResetModified();
SpellPortions aSentence = bUseSavedSentence ? m_aSavedSentence : rParent.GetNextWrongSentence( bRecheck );
if(!bUseSavedSentence)
m_aSavedSentence = aSentence;
@@ -1049,7 +1007,7 @@ bool SpellDialog::GetNextSentence_Impl(bool bUseSavedSentence, bool bRecheck)
if(!elem.bIsHidden)
sText.append(elem.sText);
}
m_pSentenceED->SetText(sText.makeStringAndClear());
m_xSentenceED->SetText(sText.makeStringAndClear());
sal_Int32 nStartPosition = 0;
sal_Int32 nEndPosition = 0;
@@ -1067,7 +1025,9 @@ bool SpellDialog::GetNextSentence_Impl(bool bUseSavedSentence, bool bRecheck)
sServiceName = xNamed->getName();
SpellErrorDescription aDesc( false, elem.xAlternatives->getWord(),
elem.xAlternatives->getLocale(), elem.xAlternatives->getAlternatives(), nullptr);
m_pSentenceED->SetAttrib( SpellErrorAttrib(aDesc), 0, nStartPosition, nEndPosition );
SfxGrabBagItem aSpellErrorDescription(EE_CHAR_GRABBAG);
aSpellErrorDescription.GetGrabBag()["SpellErrorDescription"] <<= aDesc.toSequence();
m_xSentenceED->SetAttrib(aSpellErrorDescription, nStartPosition, nEndPosition);
}
else if(elem.bIsGrammarError )
{
@@ -1093,19 +1053,23 @@ bool SpellDialog::GetNextSentence_Impl(bool bUseSavedSentence, bool bRecheck)
&elem.aGrammarError.aFullComment,
&elem.aGrammarError.aRuleIdentifier,
&sFullCommentURL );
m_pSentenceED->SetAttrib( SpellErrorAttrib(aDesc), 0, nStartPosition, nEndPosition );
SfxGrabBagItem aSpellErrorDescriptionItem(EE_CHAR_GRABBAG);
aSpellErrorDescriptionItem.GetGrabBag()["SpellErrorDescription"] <<= aDesc.toSequence();
m_xSentenceED->SetAttrib(aSpellErrorDescriptionItem, nStartPosition, nEndPosition);
}
if(elem.bIsField)
m_pSentenceED->SetAttrib( SpellBackgroundAttrib(COL_LIGHTGRAY), 0, nStartPosition, nEndPosition );
m_pSentenceED->SetAttrib( SpellLanguageAttrib(elem.eLanguage), 0, nStartPosition, nEndPosition );
if (elem.bIsField)
m_xSentenceED->SetAttrib(SvxBackgroundColorItem(COL_LIGHTGRAY, EE_CHAR_BKGCOLOR), nStartPosition, nEndPosition);
m_xSentenceED->SetAttrib(SvxLanguageItem(elem.eLanguage, EE_CHAR_LANGUAGE), nStartPosition, nEndPosition);
nStartPosition = nEndPosition;
}
}
//the edit field needs to be modified to apply the change from the ApplyChangeAllList
if(!bHasReplaced)
m_pSentenceED->ClearModifyFlag();
m_pSentenceED->ResetUndo();
m_pUndoPB->Enable(false);
m_xSentenceED->ClearModifyFlag();
m_xSentenceED->ResetUndo();
m_xUndoPB->set_sensitive(false);
bRet = nStartPosition > 0;
}
return bRet;
@@ -1145,26 +1109,149 @@ bool SpellDialog::ApplyChangeAllList_Impl(SpellPortions& rSentence, bool &bHasRe
return bRet;
}
SentenceEditWindow_Impl::SentenceEditWindow_Impl(vcl::Window * pParent, WinBits nBits)
: VclMultiLineEdit(pParent, nBits)
, m_nErrorStart(0)
SentenceEditWindow_Impl::SentenceEditWindow_Impl()
: m_nErrorStart(0)
, m_nErrorEnd(0)
, m_bIsUndoEditMode(false)
{
DisableSelectionOnFocus();
}
void SentenceEditWindow_Impl::SetDrawingArea(weld::DrawingArea* pDrawingArea)
{
Size aSize(pDrawingArea->get_approximate_digit_width() * 60,
pDrawingArea->get_text_height() * 6);
pDrawingArea->set_size_request(aSize.Width(), aSize.Height());
SetOutputSizePixel(aSize);
weld::CustomWidgetController::SetDrawingArea(pDrawingArea);
EnableRTL(false);
const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
Color aBgColor = rStyleSettings.GetWindowColor();
OutputDevice& rDevice = pDrawingArea->get_ref_device();
rDevice.SetMapMode(MapMode(MapUnit::MapTwip));
rDevice.SetBackground(aBgColor);
Size aOutputSize(rDevice.PixelToLogic(aSize));
aSize = aOutputSize;
aSize.setHeight( aSize.Height() * 4 );
m_xEditEngine.reset(new EditEngine(EditEngine::CreatePool()));
m_xEditEngine->SetPaperSize( aSize );
m_xEditEngine->SetRefDevice( &rDevice );
m_xEditEngine->SetControlWord(m_xEditEngine->GetControlWord() | EEControlBits::MARKFIELDS);
m_xEdView.reset(new EditView(m_xEditEngine.get(), nullptr));
m_xEdView->setEditViewCallbacks(this);
m_xEdView->SetOutputArea(tools::Rectangle(Point(0,0), aOutputSize));
m_xEdView->SetBackgroundColor(aBgColor);
m_xEditEngine->InsertView(m_xEdView.get());
pDrawingArea->set_cursor(PointerStyle::Text);
}
void SentenceEditWindow_Impl::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect)
{
//note: ClassificationEditView::Paint is similar
rRenderContext.Push(PushFlags::ALL);
rRenderContext.SetClipRegion();
const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
Color aBgColor = rStyleSettings.GetWindowColor();
m_xEdView->SetBackgroundColor(aBgColor);
rRenderContext.SetBackground(aBgColor);
tools::Rectangle aLogicRect(rRenderContext.PixelToLogic(rRect));
m_xEdView->Paint(aLogicRect, &rRenderContext);
if (HasFocus())
{
m_xEdView->ShowCursor();
vcl::Cursor* pCursor = m_xEdView->GetCursor();
pCursor->DrawToDevice(rRenderContext);
}
std::vector<tools::Rectangle> aLogicRects;
// get logic selection
m_xEdView->GetSelectionRectangles(aLogicRects);
rRenderContext.SetLineColor();
rRenderContext.SetFillColor(COL_BLACK);
rRenderContext.SetRasterOp(RasterOp::Invert);
for (const auto &rSelectionRect : aLogicRects)
rRenderContext.DrawRect(rSelectionRect);
rRenderContext.Pop();
}
bool SentenceEditWindow_Impl::MouseMove(const MouseEvent& rMEvt)
{
return m_xEdView->MouseMove(rMEvt);
}
bool SentenceEditWindow_Impl::MouseButtonDown(const MouseEvent& rMEvt)
{
if (!HasFocus())
GrabFocus();
return m_xEdView->MouseButtonDown(rMEvt);
}
bool SentenceEditWindow_Impl::MouseButtonUp(const MouseEvent& rMEvt)
{
return m_xEdView->MouseButtonUp(rMEvt);
}
void SentenceEditWindow_Impl::Resize()
{
OutputDevice& rDevice = GetDrawingArea()->get_ref_device();
Size aOutputSize(rDevice.PixelToLogic(GetOutputSizePixel()));
Size aSize(aOutputSize);
aSize.setHeight( aSize.Height() * 4 );
m_xEditEngine->SetPaperSize(aSize);
m_xEdView->SetOutputArea(tools::Rectangle(Point(0,0), aOutputSize));
weld::CustomWidgetController::Resize();
}
SentenceEditWindow_Impl::~SentenceEditWindow_Impl()
{
disposeOnce();
}
extern "C" SAL_DLLPUBLIC_EXPORT void makeSentenceEditWindow(VclPtr<vcl::Window> & rRet, VclPtr<vcl::Window> & pParent, VclBuilder::stringmap &)
namespace
{
rRet = VclPtr<SentenceEditWindow_Impl>::Create(pParent, WB_BORDER|WB_VSCROLL|WB_IGNORETAB);
}
const EECharAttrib* FindCharAttrib(int nStartPosition, int nEndPosition, sal_uInt16 nWhich, std::vector<EECharAttrib>& rAttribList)
{
for (const auto& rTextAtr : rAttribList)
{
if (rTextAtr.pAttr->Which() != nWhich)
continue;
if (rTextAtr.nStart <= nStartPosition && rTextAtr.nEnd >= nEndPosition)
{
return &rTextAtr;
}
}
return nullptr;
}
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;
rSpellErrorDescription.fromSequence(aSequence);
}
}
/*-------------------------------------------------------------------------
The selection before inputting a key may have a range or not
@@ -1239,309 +1326,312 @@ extern "C" SAL_DLLPUBLIC_EXPORT void makeSentenceEditWindow(VclPtr<vcl::Window>
#define ACTION_SELECTFIELD 2
#define ACTION_EXPAND 3
bool SentenceEditWindow_Impl::PreNotify( NotifyEvent& rNEvt )
bool SentenceEditWindow_Impl::KeyInput(const KeyEvent& rKeyEvt)
{
bool bChange = false;
if(rNEvt.GetType() == MouseNotifyEvent::KEYINPUT)
if (rKeyEvt.GetKeyCode().GetCode() == KEY_TAB)
return false;
bool bConsumed = false;
bool bChange = TextEngine::DoesKeyChangeText( rKeyEvt );
if (bChange && !IsUndoEditMode())
{
const KeyEvent& rKeyEvt = *rNEvt.GetKeyEvent();
bChange = TextEngine::DoesKeyChangeText( rKeyEvt );
if(bChange && !IsUndoEditMode() &&
rKeyEvt.GetKeyCode().GetCode() != KEY_TAB)
bConsumed = true;
ESelection aCurrentSelection(m_xEdView->GetSelection());
aCurrentSelection.Adjust();
//determine if the selection contains a field
bool bHasFieldLeft = false;
bool bHasErrorLeft = false;
bool bHasRange = aCurrentSelection.HasRange();
sal_uInt8 nSelectionType = 0; // invalid type!
std::vector<EECharAttrib> aAttribList;
m_xEditEngine->GetCharAttribs(0, aAttribList);
auto nCursor = aCurrentSelection.nStartPos;
const EECharAttrib* pBackAttr = FindCharAttrib(nCursor, nCursor, EE_CHAR_BKGCOLOR, aAttribList);
const EECharAttrib* pErrorAttr = FindCharAttrib(nCursor, nCursor, EE_CHAR_GRABBAG, aAttribList);
const EECharAttrib* pBackAttrLeft = nullptr;
const EECharAttrib* pErrorAttrLeft = nullptr;
bool bHasField = pBackAttr != nullptr && (bHasRange || pBackAttr->nEnd > nCursor);
bool bHasError = pErrorAttr != nullptr && (bHasRange || pErrorAttr->nEnd > nCursor);
if (bHasRange)
{
TextEngine* pTextEngine = GetTextEngine();
TextView* pTextView = pTextEngine->GetActiveView();
TextSelection aCurrentSelection = pTextView->GetSelection();
aCurrentSelection.Justify();
//determine if the selection contains a field
bool bHasFieldLeft = false;
bool bHasErrorLeft = false;
bool bHasRange = aCurrentSelection.HasRange();
sal_uInt8 nSelectionType = 0; // invalid type!
TextPaM aCursor(aCurrentSelection.GetStart());
const TextCharAttrib* pBackAttr = pTextEngine->FindCharAttrib( aCursor, TEXTATTR_SPELL_BACKGROUND );
const TextCharAttrib* pErrorAttr = pTextEngine->FindCharAttrib( aCursor, TEXTATTR_SPELL_ERROR );
const TextCharAttrib* pBackAttrLeft = nullptr;
const TextCharAttrib* pErrorAttrLeft = nullptr;
bool bHasField = pBackAttr != nullptr && (bHasRange || pBackAttr->GetEnd() > aCursor.GetIndex());
bool bHasError = pErrorAttr != nullptr && (bHasRange || pErrorAttr->GetEnd() > aCursor.GetIndex());
if(bHasRange)
if (pBackAttr &&
pBackAttr->nStart == aCurrentSelection.nStartPos &&
pBackAttr->nEnd == aCurrentSelection.nEndPos)
{
if(pBackAttr &&
pBackAttr->GetStart() == aCurrentSelection.GetStart().GetIndex() &&
pBackAttr->GetEnd() == aCurrentSelection.GetEnd().GetIndex())
{
nSelectionType = FULL;
}
else if(pErrorAttr &&
pErrorAttr->GetStart() <= aCurrentSelection.GetStart().GetIndex() &&
pErrorAttr->GetEnd() >= aCurrentSelection.GetEnd().GetIndex())
{
nSelectionType = INSIDE_YES;
}
else
{
nSelectionType = bHasField||bHasError ? BRACE : OUTSIDE_NO;
while(aCursor.GetIndex() < aCurrentSelection.GetEnd().GetIndex())
{
++aCursor.GetIndex();
const TextCharAttrib* pIntBackAttr = pTextEngine->FindCharAttrib( aCursor, TEXTATTR_SPELL_BACKGROUND );
const TextCharAttrib* pIntErrorAttr = pTextEngine->FindCharAttrib( aCursor, TEXTATTR_SPELL_ERROR );
//if any attr has been found then BRACE
if(pIntBackAttr || pIntErrorAttr)
nSelectionType = BRACE;
//the field has to be selected
if(pIntBackAttr && !pBackAttr)
pBackAttr = pIntBackAttr;
bHasField |= pIntBackAttr != nullptr;
}
}
nSelectionType = FULL;
}
else if (pErrorAttr &&
pErrorAttr->nStart <= aCurrentSelection.nStartPos &&
pErrorAttr->nEnd >= aCurrentSelection.nEndPos)
{
nSelectionType = INSIDE_YES;
}
else
{
//no range selection: then 1 2 3 and 8 are possible
const TextCharAttrib* pCurAttr = pBackAttr ? pBackAttr : pErrorAttr;
if(pCurAttr)
nSelectionType = bHasField||bHasError ? BRACE : OUTSIDE_NO;
while (nCursor < aCurrentSelection.nEndPos)
{
nSelectionType = pCurAttr->GetStart() == aCurrentSelection.GetStart().GetIndex() ?
LEFT_NO : pCurAttr->GetEnd() == aCurrentSelection.GetEnd().GetIndex() ? RIGHT_NO : INSIDE_NO;
}
else
nSelectionType = OUTSIDE_NO;
bHasFieldLeft = pBackAttr && pBackAttr->GetEnd() == aCursor.GetIndex();
if(bHasFieldLeft)
{
pBackAttrLeft = pBackAttr;
pBackAttr = nullptr;
}
bHasErrorLeft = pErrorAttr && pErrorAttr->GetEnd() == aCursor.GetIndex();
if(bHasErrorLeft)
{
pErrorAttrLeft = pErrorAttr;
pErrorAttr = nullptr;
}
//check previous position if this exists
//that is a redundant in the case the attribute found above already is on the left cursor side
//but it's o.k. for two errors/fields side by side
if(aCursor.GetIndex())
{
--aCursor.GetIndex();
pBackAttrLeft = pTextEngine->FindCharAttrib( aCursor, TEXTATTR_SPELL_BACKGROUND );
pErrorAttrLeft = pTextEngine->FindCharAttrib( aCursor, TEXTATTR_SPELL_ERROR );
bHasFieldLeft = pBackAttrLeft !=nullptr;
bHasErrorLeft = pErrorAttrLeft != nullptr;
++aCursor.GetIndex();
++nCursor;
const EECharAttrib* pIntBackAttr = FindCharAttrib(nCursor, nCursor, EE_CHAR_BKGCOLOR, aAttribList);
const EECharAttrib* pIntErrorAttr = FindCharAttrib(nCursor, nCursor, EE_CHAR_GRABBAG, aAttribList);
//if any attr has been found then BRACE
if (pIntBackAttr || pIntErrorAttr)
nSelectionType = BRACE;
//the field has to be selected
if (pIntBackAttr && !pBackAttr)
pBackAttr = pIntBackAttr;
bHasField |= pIntBackAttr != nullptr;
}
}
//Here we have to determine if the error found is the one currently active
bool bIsErrorActive = (pErrorAttr && pErrorAttr->GetStart() == m_nErrorStart) ||
(pErrorAttrLeft && pErrorAttrLeft->GetStart() == m_nErrorStart);
SAL_WARN_IF(
nSelectionType == INVALID, "cui.dialogs",
"selection type not set");
const vcl::KeyCode& rKeyCode = rKeyEvt.GetKeyCode();
bool bDelete = rKeyCode.GetCode() == KEY_DELETE;
bool bBackspace = rKeyCode.GetCode() == KEY_BACKSPACE;
sal_Int8 nAction = ACTION_CONTINUE;
switch(nSelectionType)
{
// 1 - backspace delete any other
// UE on field FS on error CO on field FS on error CO
case LEFT_NO :
if(bBackspace)
{
nAction = bHasFieldLeft ? ACTION_SELECTFIELD : ACTION_UNDOEDIT;
//to force the use of pBackAttrLeft
pBackAttr = nullptr;
}
else if(bDelete)
nAction = bHasField ? ACTION_SELECTFIELD : ACTION_CONTINUE;
else
nAction = bHasError && !aCursor.GetIndex() ? ACTION_CONTINUE :
bHasError ? ACTION_EXPAND : bHasErrorLeft ? ACTION_CONTINUE : ACTION_UNDOEDIT;
break;
// 2 - on field FS on error C
case INSIDE_NO :
nAction = bHasField ? ACTION_SELECTFIELD :
bIsErrorActive ? ACTION_CONTINUE : ACTION_UNDOEDIT;
break;
// 3 - backspace delete any other
// on field FS on error CO UE on field UE on error EX
case RIGHT_NO :
if(bBackspace)
nAction = bHasFieldLeft ? ACTION_SELECTFIELD : ACTION_CONTINUE;
else if(bDelete)
nAction = bHasFieldLeft && bHasError ? ACTION_CONTINUE : ACTION_UNDOEDIT;
else
nAction = bHasFieldLeft && bHasError ? ACTION_EXPAND :
bHasError ? ACTION_CONTINUE : bHasErrorLeft ? ACTION_EXPAND :ACTION_UNDOEDIT;
break;
// 4 - on field UE and on error CO
case FULL :
nAction = ACTION_UNDOEDIT;
break;
// 5 - on field FS and on error CO
case INSIDE_YES :
nAction = bHasField ? ACTION_SELECTFIELD : ACTION_CONTINUE;
break;
// 6 - on field FS and on error UE
case BRACE :
nAction = bHasField ? ACTION_SELECTFIELD : ACTION_UNDOEDIT;
break;
// 7 - UE
// 8 - UE
case OUTSIDE_NO :
case OUTSIDE_YES:
nAction = ACTION_UNDOEDIT;
break;
}
//save the current paragraph
sal_Int32 nCurrentLen = GetText().getLength();
if(nAction != ACTION_SELECTFIELD)
pTextView->GetWindow()->KeyInput(rKeyEvt);
else
{
const TextCharAttrib* pCharAttr = pBackAttr ? pBackAttr : pBackAttrLeft;
if(pCharAttr)
{
TextPaM aStart(0, pCharAttr->GetStart());
TextPaM aEnd(0, pCharAttr->GetEnd());
TextSelection aNewSel(aStart, aEnd);
pTextView->SetSelection( aNewSel);
}
}
if(nAction == ACTION_EXPAND)
{
DBG_ASSERT(pErrorAttrLeft || pErrorAttr, "where is the error");
//text has been added on the right and only the 'error attribute has to be corrected
if(pErrorAttrLeft)
{
std::unique_ptr<TextAttrib> pNewError(pErrorAttrLeft->GetAttr().Clone());
const sal_Int32 nStart = pErrorAttrLeft->GetStart();
sal_Int32 nEnd = pErrorAttrLeft->GetEnd();
pTextEngine->RemoveAttrib( 0, *pErrorAttrLeft );
SetAttrib( *pNewError, 0, nStart, ++nEnd );
//only active errors move the mark
if(bIsErrorActive)
{
bool bGrammar = static_cast<const SpellErrorAttrib&>(*pNewError).GetErrorDescription().bIsGrammarError;
MoveErrorMarkTo(nStart, nEnd, bGrammar);
}
}
//text has been added on the left then the error attribute has to be expanded and the
//field attribute on the right - if any - has to be contracted
else if(pErrorAttr)
{
//determine the change
sal_Int32 nAddedChars = GetText().getLength() - nCurrentLen;
std::unique_ptr<TextAttrib> pNewError(pErrorAttr->GetAttr().Clone());
sal_Int32 nStart = pErrorAttr->GetStart();
sal_Int32 nEnd = pErrorAttr->GetEnd();
pTextEngine->RemoveAttrib( 0, *pErrorAttr );
nStart = nStart - nAddedChars;
SetAttrib( *pNewError, 0, nStart - nAddedChars, nEnd );
//only if the error is active the mark is moved here
if(bIsErrorActive)
{
bool bGrammar = static_cast<const SpellErrorAttrib&>(*pNewError).GetErrorDescription().bIsGrammarError;
MoveErrorMarkTo(nStart, nEnd, bGrammar);
}
pNewError.reset();
if(pBackAttrLeft)
{
std::unique_ptr<TextAttrib> pNewBack(pBackAttrLeft->GetAttr().Clone());
const sal_Int32 _nStart = pBackAttrLeft->GetStart();
const sal_Int32 _nEnd = pBackAttrLeft->GetEnd();
pTextEngine->RemoveAttrib( 0, *pBackAttrLeft );
SetAttrib( *pNewBack, 0, _nStart, _nEnd - nAddedChars);
}
}
}
else if(nAction == ACTION_UNDOEDIT)
{
SetUndoEditMode(true);
}
//make sure the error positions are correct after text changes
//the old attribute may have been deleted
//all changes inside of the current error leave the error attribute at the current
//start position
if(!IsUndoEditMode() && bIsErrorActive)
{
const TextCharAttrib* pFontColor = pTextEngine->FindCharAttrib( aCursor, TEXTATTR_FONTCOLOR );
const TextCharAttrib* pErrorAttrib = pTextEngine->FindCharAttrib( TextPaM(0, m_nErrorStart), TEXTATTR_SPELL_ERROR );
if(pFontColor && pErrorAttrib )
{
m_nErrorStart = pFontColor->GetStart();
m_nErrorEnd = pFontColor->GetEnd();
if(pErrorAttrib->GetStart() != m_nErrorStart || pErrorAttrib->GetEnd() != m_nErrorEnd)
{
std::unique_ptr<TextAttrib> pNewError(pErrorAttrib->GetAttr().Clone());
pTextEngine->RemoveAttrib( 0, *pErrorAttr );
SetAttrib( *pNewError, 0, m_nErrorStart, m_nErrorEnd );
}
}
}
//this is not a modification anymore
if(nAction != ACTION_SELECTFIELD && !m_bIsUndoEditMode)
CallModifyLink();
}
else
bChange = false;
{
//no range selection: then 1 2 3 and 8 are possible
const EECharAttrib* pCurAttr = pBackAttr ? pBackAttr : pErrorAttr;
if (pCurAttr)
{
nSelectionType = pCurAttr->nStart == aCurrentSelection.nStartPos ?
LEFT_NO : pCurAttr->nEnd == aCurrentSelection.nEndPos ? RIGHT_NO : INSIDE_NO;
}
else
nSelectionType = OUTSIDE_NO;
bHasFieldLeft = pBackAttr && pBackAttr->nEnd == nCursor;
if(bHasFieldLeft)
{
pBackAttrLeft = pBackAttr;
pBackAttr = nullptr;
}
bHasErrorLeft = pErrorAttr && pErrorAttr->nEnd == nCursor;
if(bHasErrorLeft)
{
pErrorAttrLeft = pErrorAttr;
pErrorAttr = nullptr;
}
//check previous position if this exists
//that is a redundant in the case the attribute found above already is on the left cursor side
//but it's o.k. for two errors/fields side by side
if (nCursor)
{
--nCursor;
pBackAttrLeft = FindCharAttrib(nCursor, nCursor, EE_CHAR_BKGCOLOR, aAttribList);
pErrorAttrLeft = FindCharAttrib(nCursor, nCursor, EE_CHAR_GRABBAG, aAttribList);
bHasFieldLeft = pBackAttrLeft !=nullptr;
bHasErrorLeft = pErrorAttrLeft != nullptr;
++nCursor;
}
}
//Here we have to determine if the error found is the one currently active
bool bIsErrorActive = (pErrorAttr && pErrorAttr->nStart == m_nErrorStart) ||
(pErrorAttrLeft && pErrorAttrLeft->nStart == m_nErrorStart);
SAL_WARN_IF(
nSelectionType == INVALID, "cui.dialogs",
"selection type not set");
const vcl::KeyCode& rKeyCode = rKeyEvt.GetKeyCode();
bool bDelete = rKeyCode.GetCode() == KEY_DELETE;
bool bBackspace = rKeyCode.GetCode() == KEY_BACKSPACE;
sal_Int8 nAction = ACTION_CONTINUE;
switch(nSelectionType)
{
// 1 - backspace delete any other
// UE on field FS on error CO on field FS on error CO
case LEFT_NO :
if(bBackspace)
{
nAction = bHasFieldLeft ? ACTION_SELECTFIELD : ACTION_UNDOEDIT;
//to force the use of pBackAttrLeft
pBackAttr = nullptr;
}
else if(bDelete)
nAction = bHasField ? ACTION_SELECTFIELD : ACTION_CONTINUE;
else
nAction = bHasError && !nCursor ? ACTION_CONTINUE :
bHasError ? ACTION_EXPAND : bHasErrorLeft ? ACTION_CONTINUE : ACTION_UNDOEDIT;
break;
// 2 - on field FS on error C
case INSIDE_NO :
nAction = bHasField ? ACTION_SELECTFIELD :
bIsErrorActive ? ACTION_CONTINUE : ACTION_UNDOEDIT;
break;
// 3 - backspace delete any other
// on field FS on error CO UE on field UE on error EX
case RIGHT_NO :
if(bBackspace)
nAction = bHasFieldLeft ? ACTION_SELECTFIELD : ACTION_CONTINUE;
else if(bDelete)
nAction = bHasFieldLeft && bHasError ? ACTION_CONTINUE : ACTION_UNDOEDIT;
else
nAction = bHasFieldLeft && bHasError ? ACTION_EXPAND :
bHasError ? ACTION_CONTINUE : bHasErrorLeft ? ACTION_EXPAND :ACTION_UNDOEDIT;
break;
// 4 - on field UE and on error CO
case FULL :
nAction = ACTION_UNDOEDIT;
break;
// 5 - on field FS and on error CO
case INSIDE_YES :
nAction = bHasField ? ACTION_SELECTFIELD : ACTION_CONTINUE;
break;
// 6 - on field FS and on error UE
case BRACE :
nAction = bHasField ? ACTION_SELECTFIELD : ACTION_UNDOEDIT;
break;
// 7 - UE
// 8 - UE
case OUTSIDE_NO :
case OUTSIDE_YES:
nAction = ACTION_UNDOEDIT;
break;
}
//save the current paragraph
sal_Int32 nCurrentLen = m_xEditEngine->GetText().getLength();
if (nAction != ACTION_SELECTFIELD)
{
m_xEdView->PostKeyEvent(rKeyEvt);
}
else
{
const EECharAttrib* pCharAttr = pBackAttr ? pBackAttr : pBackAttrLeft;
if (pCharAttr)
m_xEdView->SetSelection(ESelection(0, pCharAttr->nStart, 0, pCharAttr->nEnd));
}
if(nAction == ACTION_EXPAND)
{
DBG_ASSERT(pErrorAttrLeft || pErrorAttr, "where is the error");
//text has been added on the right and only the 'error attribute has to be corrected
if (pErrorAttrLeft)
{
SpellErrorDescription aSpellErrorDescription;
ExtractErrorDescription(*pErrorAttrLeft, aSpellErrorDescription);
std::unique_ptr<SfxPoolItem> xNewError(pErrorAttrLeft->pAttr->Clone());
sal_Int32 nStart = pErrorAttrLeft->nStart;
sal_Int32 nEnd = pErrorAttrLeft->nEnd + 1;
m_xEditEngine->RemoveAttribs(ESelection(0, nStart, 0, nEnd), false, EE_CHAR_GRABBAG);
SetAttrib(*xNewError, nStart, nEnd);
//only active errors move the mark
if (bIsErrorActive)
{
bool bGrammar = aSpellErrorDescription.bIsGrammarError;
MoveErrorMarkTo(nStart, nEnd, bGrammar);
}
}
//text has been added on the left then the error attribute has to be expanded and the
//field attribute on the right - if any - has to be contracted
else if (pErrorAttr)
{
SpellErrorDescription aSpellErrorDescription;
ExtractErrorDescription(*pErrorAttr, aSpellErrorDescription);
//determine the change
sal_Int32 nAddedChars = m_xEditEngine->GetText().getLength() - nCurrentLen;
std::unique_ptr<SfxPoolItem> xNewError(pErrorAttr->pAttr->Clone());
sal_Int32 nStart = pErrorAttr->nStart + nAddedChars;
sal_Int32 nEnd = pErrorAttr->nEnd + nAddedChars;
m_xEditEngine->RemoveAttribs(ESelection(0, nStart, 0, nEnd), false, EE_CHAR_GRABBAG);
nStart = pErrorAttr->nStart;
SetAttrib(*xNewError, nStart, nEnd);
//only if the error is active the mark is moved here
if (bIsErrorActive)
{
bool bGrammar = aSpellErrorDescription.bIsGrammarError;
MoveErrorMarkTo(nStart, nEnd, bGrammar);
}
xNewError.reset();
if (pBackAttrLeft)
{
std::unique_ptr<SfxPoolItem> xNewBack(pBackAttrLeft->pAttr->Clone());
sal_Int32 _nStart = pBackAttrLeft->nStart + nAddedChars;
sal_Int32 _nEnd = pBackAttrLeft->nEnd + nAddedChars;
m_xEditEngine->RemoveAttribs(ESelection(0, _nStart, 0, _nEnd), false, EE_CHAR_BKGCOLOR);
_nStart = pBackAttrLeft->nStart;
SetAttrib(*xNewBack, _nStart, _nEnd);
}
}
}
else if(nAction == ACTION_UNDOEDIT)
{
SetUndoEditMode(true);
}
//make sure the error positions are correct after text changes
//the old attribute may have been deleted
//all changes inside of the current error leave the error attribute at the current
//start position
if (!IsUndoEditMode() && bIsErrorActive)
{
const EECharAttrib* pFontColor = FindCharAttrib(nCursor, nCursor, EE_CHAR_COLOR, aAttribList);
const EECharAttrib* pErrorAttrib = FindCharAttrib(m_nErrorStart, m_nErrorStart, EE_CHAR_GRABBAG, aAttribList);
if (pFontColor && pErrorAttrib)
{
m_nErrorStart = pFontColor->nStart;
m_nErrorEnd = pFontColor->nEnd;
if (pErrorAttrib->nStart != m_nErrorStart || pErrorAttrib->nEnd != m_nErrorEnd)
{
std::unique_ptr<SfxPoolItem> xNewError(pErrorAttrib->pAttr->Clone());
m_xEditEngine->RemoveAttribs(ESelection(0, pErrorAttr->nStart, 0, pErrorAttr->nEnd), false, EE_CHAR_GRABBAG);
SetAttrib(*xNewError, m_nErrorStart, m_nErrorEnd);
}
}
}
//this is not a modification anymore
if(nAction != ACTION_SELECTFIELD && !m_bIsUndoEditMode)
CallModifyLink();
}
return bChange || VclMultiLineEdit::PreNotify(rNEvt);
else
bConsumed = m_xEdView->PostKeyEvent(rKeyEvt);
return bConsumed;
}
void SentenceEditWindow_Impl::Init(VclPtr<ToolBox> const &rToolbar)
void SentenceEditWindow_Impl::Init(weld::Toolbar* pToolbar)
{
m_xToolbar = rToolbar;
m_xToolbar->SetSelectHdl(LINK(this,SentenceEditWindow_Impl,ToolbarHdl));
m_pToolbar = pToolbar;
m_pToolbar->connect_clicked(LINK(this,SentenceEditWindow_Impl,ToolbarHdl));
}
IMPL_LINK_NOARG(SentenceEditWindow_Impl, ToolbarHdl, ToolBox *, void)
IMPL_LINK(SentenceEditWindow_Impl, ToolbarHdl, const OString&, rCurItemId, void)
{
const sal_uInt16 nCurItemId = m_xToolbar->GetCurItemId();
if (nCurItemId == m_xToolbar->GetItemId("paste"))
if (rCurItemId == "paste")
{
Paste();
m_xEdView->Paste();
CallModifyLink();
}
else if (nCurItemId == m_xToolbar->GetItemId("insert"))
else if (rCurItemId == "insert")
{
if (Edit::GetGetSpecialCharsFunction())
{
OUString aChars = Edit::GetGetSpecialCharsFunction()( this, GetFont() );
OUString aChars = Edit::GetGetSpecialCharsFunction()(GetDrawingArea(), m_xEditEngine->GetStandardFont(0));
if (!aChars.isEmpty())
{
ReplaceSelected(aChars);
ESelection aCurrentSelection(m_xEdView->GetSelection());
m_xEditEngine->QuickInsertText(aChars, aCurrentSelection);
CallModifyLink();
}
}
}
}
void SentenceEditWindow_Impl::dispose()
{
m_xToolbar.clear();
VclMultiLineEdit::dispose();
}
bool SentenceEditWindow_Impl::MarkNextError( bool bIgnoreCurrentError, const css::uno::Reference<css::linguistic2::XSpellChecker1>& xSpell )
{
if (bIgnoreCurrentError)
m_aIgnoreErrorsAt.insert( m_nErrorStart );
ExtTextEngine* pTextEngine = GetTextEngine();
const sal_Int32 nTextLen = pTextEngine->GetTextLen(0);
if(m_nErrorEnd >= nTextLen - 1)
const sal_Int32 nTextLen = m_xEditEngine->GetTextLen(0);
if (m_nErrorEnd >= nTextLen - 1)
return false;
//if it's not already modified the modified flag has to be reset at the end of the marking
bool bModified = IsModified();
@@ -1551,42 +1641,62 @@ bool SentenceEditWindow_Impl::MarkNextError( bool bIgnoreCurrentError, const css
//create a cursor behind the end of the last error
//- or at 0 at the start of the sentence
TextPaM aCursor(0, m_nErrorEnd ? m_nErrorEnd + 1 : 0);
//search for SpellErrorAttrib
int nCursor(m_nErrorEnd ? m_nErrorEnd + 1 : 0);
const TextCharAttrib* pNextError = nullptr;
//search for SpellErrorDescription
SpellErrorDescription aSpellErrorDescription;
std::vector<EECharAttrib> aAttribList;
m_xEditEngine->GetCharAttribs(0, aAttribList);
//iterate over the text and search for the next error that maybe has
//to be replace by a ChangeAllList replacement
bool bGrammarError = false;
while(aCursor.GetIndex() < nTextLen)
while (nCursor < nTextLen)
{
while(aCursor.GetIndex() < nTextLen &&
nullptr == (pNextError = pTextEngine->FindCharAttrib( aCursor, TEXTATTR_SPELL_ERROR)))
{
++aCursor.GetIndex();
}
// maybe the error found here is already in the ChangeAllList and has to be replaced
const SpellErrorDescription* pSpellErrorDescription = nullptr;
const EECharAttrib* pEECharAttrib = nullptr;
sal_Int32 nMinPos = nTextLen + 1;
for (const auto& rTextAtr : aAttribList)
{
if (rTextAtr.pAttr->Which() != EE_CHAR_GRABBAG)
continue;
if (rTextAtr.nEnd > nCursor && rTextAtr.nStart < nMinPos)
{
nMinPos = rTextAtr.nStart;
pEECharAttrib = &rTextAtr;
}
}
if (pEECharAttrib)
{
ExtractErrorDescription(*pEECharAttrib, aSpellErrorDescription);
bGrammarError = aSpellErrorDescription.bIsGrammarError;
m_nErrorStart = pEECharAttrib->nStart;
m_nErrorEnd = pEECharAttrib->nEnd;
pSpellErrorDescription = &aSpellErrorDescription;
}
nCursor = nMinPos;
// maybe the error found here is already in the ChangeAllList and has to be replaced
Reference<XDictionary> xChangeAll( LinguMgr::GetChangeAllList(), UNO_QUERY );
Reference<XDictionaryEntry> xEntry;
const SpellErrorDescription* pSpellErrorDescription = nullptr;
if(pNextError)
{
pSpellErrorDescription = &static_cast<const SpellErrorAttrib&>(pNextError->GetAttr()).GetErrorDescription();
bGrammarError = pSpellErrorDescription->bIsGrammarError;
m_nErrorStart = pNextError->GetStart();
m_nErrorEnd = pNextError->GetEnd();
}
if(xChangeAll->getCount() && pSpellErrorDescription &&
if (xChangeAll->getCount() && pSpellErrorDescription &&
(xEntry = xChangeAll->getEntry( pSpellErrorDescription->sErrorText )).is())
{
OUString sReplacement(getDotReplacementString(GetErrorText(), xEntry->getReplacementText()));
ChangeMarkedWord(sReplacement, LanguageTag::convertToLanguageType( pSpellErrorDescription->aLocale ));
int nLenChange = ChangeMarkedWord(sReplacement, LanguageTag::convertToLanguageType(pSpellErrorDescription->aLocale));
aCursor.GetIndex() += sReplacement.getLength();
nCursor += sReplacement.getLength();
if (nLenChange)
m_xEditEngine->GetCharAttribs(0, aAttribList);
// maybe the error found here is already added to the dictionary and has to be ignored
}
else if(pSpellErrorDescription && !bGrammarError &&
@@ -1594,26 +1704,30 @@ bool SentenceEditWindow_Impl::MarkNextError( bool bIgnoreCurrentError, const css
static_cast<sal_uInt16>(LanguageTag::convertToLanguageType( pSpellErrorDescription->aLocale )),
Sequence< PropertyValue >() ))
{
++aCursor.GetIndex();
++nCursor;
}
else
break;
}
//if an attrib has been found search for the end of the error string
if(aCursor.GetIndex() < nTextLen)
if (nCursor < nTextLen)
{
MoveErrorMarkTo(aCursor.GetIndex(), pNextError->GetEnd(), bGrammarError);
MoveErrorMarkTo(nCursor, m_nErrorEnd, bGrammarError);
bRet = true;
//add an undo action
std::unique_ptr<SpellUndoAction_Impl> pAction(new SpellUndoAction_Impl(
SPELLUNDO_CHANGE_NEXTERROR, GetSpellDialog()->aDialogUndoLink));
pAction->SetErrorMove(nOldErrorStart, nOldErrorEnd);
const SpellErrorAttrib* pOldAttrib = static_cast<const SpellErrorAttrib*>(
pTextEngine->FindAttrib( TextPaM(0, nOldErrorStart), TEXTATTR_SPELL_ERROR ));
pAction->SetErrorLanguageSelected(pOldAttrib && pOldAttrib->GetErrorDescription().aSuggestions.hasElements() &&
LanguageTag( pOldAttrib->GetErrorDescription().aLocale).getLanguageType() ==
GetSpellDialog()->m_pLanguageLB->GetSelectedLanguage());
if (GetErrorDescription(aSpellErrorDescription, nOldErrorStart))
{
pAction->SetErrorLanguageSelected(aSpellErrorDescription.aSuggestions.hasElements() &&
LanguageTag(aSpellErrorDescription.aLocale).getLanguageType() == GetSpellDialog()->m_xLanguageLB->get_active_id());
}
else
pAction->SetErrorLanguageSelected(false);
AddUndoAction(std::move(pAction));
}
else
@@ -1621,75 +1735,93 @@ bool SentenceEditWindow_Impl::MarkNextError( bool bIgnoreCurrentError, const css
if( !bModified )
ClearModifyFlag();
SpellDialog* pSpellDialog = GetSpellDialog();
pSpellDialog->m_pIgnorePB->Enable(bRet);
pSpellDialog->m_pIgnoreAllPB->Enable(bRet);
pSpellDialog->m_pAutoCorrPB->Enable(bRet);
pSpellDialog->m_pAddToDictMB->Enable(bRet);
pSpellDialog->m_pAddToDictPB->Enable(bRet);
pSpellDialog->m_xIgnorePB->set_sensitive(bRet);
pSpellDialog->m_xIgnoreAllPB->set_sensitive(bRet);
pSpellDialog->m_xAutoCorrPB->set_sensitive(bRet);
pSpellDialog->m_xAddToDictMB->set_sensitive(bRet);
pSpellDialog->m_xAddToDictPB->set_sensitive(bRet);
return bRet;
}
void SentenceEditWindow_Impl::MoveErrorMarkTo(sal_Int32 nStart, sal_Int32 nEnd, bool bGrammarError)
{
TextEngine* pTextEngine = GetTextEngine();
pTextEngine->RemoveAttribs( 0, sal_uInt16(TEXTATTR_FONTCOLOR) );
pTextEngine->RemoveAttribs( 0, sal_uInt16(TEXTATTR_FONTWEIGHT) );
pTextEngine->SetAttrib( TextAttribFontWeight(WEIGHT_BOLD), 0, nStart, nEnd );
pTextEngine->SetAttrib( TextAttribFontColor(bGrammarError ? COL_LIGHTBLUE : COL_LIGHTRED), 0, nStart, nEnd );
ESelection aAll(0, 0, 0, EE_TEXTPOS_ALL);
m_xEditEngine->RemoveAttribs(aAll, false, EE_CHAR_COLOR);
m_xEditEngine->RemoveAttribs(aAll, false, EE_CHAR_WEIGHT);
m_xEditEngine->RemoveAttribs(aAll, false, EE_CHAR_WEIGHT_CJK);
m_xEditEngine->RemoveAttribs(aAll, false, EE_CHAR_WEIGHT_CTL);
SfxItemSet aSet(m_xEditEngine->GetEmptyItemSet());
aSet.Put(SvxColorItem(bGrammarError ? COL_LIGHTBLUE : COL_LIGHTRED, 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));
m_xEditEngine->QuickSetAttribs(aSet, ESelection(0, nStart, 0, nEnd));
// so the editview will autoscroll to make this visible
m_xEdView->SetSelection(ESelection(0, nStart));
Invalidate();
m_nErrorStart = nStart;
m_nErrorEnd = nEnd;
}
void SentenceEditWindow_Impl::ChangeMarkedWord(const OUString& rNewWord, LanguageType eLanguage)
int SentenceEditWindow_Impl::ChangeMarkedWord(const OUString& rNewWord, LanguageType eLanguage)
{
//calculate length changes
long nDiffLen = rNewWord.getLength() - m_nErrorEnd + m_nErrorStart;
TextSelection aSel(TextPaM(0, m_nErrorStart), TextPaM(0, m_nErrorEnd));
//Remove spell error attribute
ExtTextEngine* pTextEngine = GetTextEngine();
pTextEngine->UndoActionStart();
const TextCharAttrib* pErrorAttrib = pTextEngine->FindCharAttrib( TextPaM(0, m_nErrorStart), TEXTATTR_SPELL_ERROR );
std::unique_ptr<TextCharAttrib> pReleasedErrorAttrib;
std::unique_ptr<TextCharAttrib> pReleasedLangAttrib;
std::unique_ptr<TextCharAttrib> pReleasedBackAttrib;
DBG_ASSERT(pErrorAttrib, "no error attribute found");
const SpellErrorDescription* pSpellErrorDescription = nullptr;
if(pErrorAttrib)
{
pReleasedErrorAttrib = pTextEngine->RemoveAttrib(0, *pErrorAttrib);
pSpellErrorDescription = &static_cast<const SpellErrorAttrib&>(pErrorAttrib->GetAttr()).GetErrorDescription();
}
const TextCharAttrib* pBackAttrib = pTextEngine->FindCharAttrib( TextPaM(0, m_nErrorStart), TEXTATTR_SPELL_BACKGROUND );
pTextEngine->ReplaceText( aSel, rNewWord );
std::vector<EECharAttrib> aAttribList;
m_xEditEngine->GetCharAttribs(0, aAttribList);
if(!m_nErrorStart)
//calculate length changes
auto nDiffLen = rNewWord.getLength() - m_nErrorEnd + m_nErrorStart;
//Remove spell error attribute
m_xEditEngine->UndoActionStart(SPELLUNDO_MOVE_ERROREND);
const EECharAttrib* pErrorAttrib = FindCharAttrib(m_nErrorStart, m_nErrorStart, EE_CHAR_GRABBAG, aAttribList);
DBG_ASSERT(pErrorAttrib, "no error attribute found");
bool bSpellErrorDescription = false;
SpellErrorDescription aSpellErrorDescription;
if (pErrorAttrib)
{
ExtractErrorDescription(*pErrorAttrib, aSpellErrorDescription);
m_xEditEngine->RemoveAttribs(ESelection(0, pErrorAttrib->nStart, 0, pErrorAttrib->nEnd), false, EE_CHAR_GRABBAG);
bSpellErrorDescription = true;
}
const EECharAttrib* pBackAttrib = FindCharAttrib(m_nErrorStart, m_nErrorStart, EE_CHAR_BKGCOLOR, aAttribList);
ESelection aSel(0, m_nErrorStart, 0, m_nErrorEnd);
m_xEditEngine->QuickInsertText(rNewWord, aSel);
const sal_Int32 nTextLen = m_xEditEngine->GetTextLen(0);
if (nDiffLen)
m_xEditEngine->GetCharAttribs(0, aAttribList);
if (!m_nErrorStart)
{
//attributes following an error at the start of the text are not moved but expanded from the
//text engine - this is done to keep full-paragraph-attributes
//in the current case that handling is not desired
const TextCharAttrib* pLangAttrib =
pTextEngine->FindCharAttrib(
TextPaM(0, m_nErrorEnd), TEXTATTR_SPELL_LANGUAGE );
const sal_Int32 nTextLen = pTextEngine->GetTextLen( 0 );
if(pLangAttrib && !pLangAttrib->GetStart() && pLangAttrib->GetEnd() ==
nTextLen)
const EECharAttrib* pLangAttrib = FindCharAttrib(m_nErrorEnd, m_nErrorEnd, EE_CHAR_LANGUAGE, aAttribList);
if (pLangAttrib && !pLangAttrib->nStart && pLangAttrib->nEnd == nTextLen)
{
SpellLanguageAttrib aNewLangAttrib( static_cast<const SpellLanguageAttrib&>(pLangAttrib->GetAttr()).GetLanguage());
pReleasedLangAttrib = pTextEngine->RemoveAttrib(0, *pLangAttrib);
pTextEngine->SetAttrib( aNewLangAttrib, 0, m_nErrorEnd + nDiffLen, nTextLen );
LanguageType eNewLanguage = static_cast<const SvxLanguageItem*>(pLangAttrib->pAttr)->GetLanguage();
m_xEditEngine->RemoveAttribs(ESelection(0, pLangAttrib->nStart, 0, pLangAttrib->nEnd), false, EE_CHAR_LANGUAGE);
SetAttrib(SvxLanguageItem(eNewLanguage, EE_CHAR_LANGUAGE), m_nErrorEnd + nDiffLen, nTextLen);
}
}
// undo expanded attributes!
if( pBackAttrib && pBackAttrib->GetStart() < m_nErrorStart && pBackAttrib->GetEnd() == m_nErrorEnd + nDiffLen)
if (pBackAttrib && pBackAttrib->nStart < m_nErrorStart && pBackAttrib->nEnd == m_nErrorEnd + nDiffLen)
{
std::unique_ptr<TextAttrib> pNewBackground(pBackAttrib->GetAttr().Clone());
const sal_Int32 nStart = pBackAttrib->GetStart();
pReleasedBackAttrib = pTextEngine->RemoveAttrib(0, *pBackAttrib);
pTextEngine->SetAttrib(*pNewBackground, 0, nStart, m_nErrorStart);
std::unique_ptr<SfxPoolItem> xNewBackground(pBackAttrib->pAttr->Clone());
const sal_Int32 nStart = pBackAttrib->nStart;
m_xEditEngine->RemoveAttribs(ESelection(0, pBackAttrib->nStart, 0, pBackAttrib->nEnd), false, EE_CHAR_BKGCOLOR);
SetAttrib(*xNewBackground, nStart, m_nErrorStart);
}
pTextEngine->SetModified(true);
m_xEditEngine->SetModified();
//adjust end position
long nEndTemp = m_nErrorEnd;
@@ -1700,48 +1832,56 @@ void SentenceEditWindow_Impl::ChangeMarkedWord(const OUString& rNewWord, Languag
SPELLUNDO_MOVE_ERROREND, GetSpellDialog()->aDialogUndoLink));
pAction->SetOffset(nDiffLen);
AddUndoAction(std::move(pAction));
if(pSpellErrorDescription)
SetAttrib( SpellErrorAttrib(*pSpellErrorDescription), 0, m_nErrorStart, m_nErrorEnd );
SetAttrib( SpellLanguageAttrib(eLanguage), 0, m_nErrorStart, m_nErrorEnd );
pTextEngine->UndoActionEnd();
}
if (bSpellErrorDescription)
{
SfxGrabBagItem aSpellErrorDescriptionItem(EE_CHAR_GRABBAG);
aSpellErrorDescriptionItem.GetGrabBag()["SpellErrorDescription"] <<= aSpellErrorDescription.toSequence();
SetAttrib(aSpellErrorDescriptionItem, m_nErrorStart, m_nErrorEnd);
}
SetAttrib(SvxLanguageItem(eLanguage, EE_CHAR_LANGUAGE), m_nErrorStart, m_nErrorEnd);
m_xEditEngine->UndoActionEnd();
Invalidate();
return nDiffLen;
}
OUString SentenceEditWindow_Impl::GetErrorText() const
{
return GetTextEngine()->GetText(TextSelection(TextPaM(0, m_nErrorStart), TextPaM(0, m_nErrorEnd) ));
return m_xEditEngine->GetText(ESelection(0, m_nErrorStart, 0, m_nErrorEnd));
}
const SpellErrorDescription* SentenceEditWindow_Impl::GetAlternatives()
bool SentenceEditWindow_Impl::GetErrorDescription(SpellErrorDescription& rSpellErrorDescription, sal_Int32 nPosition)
{
TextPaM aCursor(0, m_nErrorStart);
const SpellErrorAttrib* pAttrib = static_cast<const SpellErrorAttrib*>(
GetTextEngine()->FindAttrib( aCursor, TEXTATTR_SPELL_ERROR));
return pAttrib ? &pAttrib->GetErrorDescription() : nullptr;
std::vector<EECharAttrib> aAttribList;
m_xEditEngine->GetCharAttribs(0, aAttribList);
if (const EECharAttrib* pEECharAttrib = FindCharAttrib(nPosition, nPosition, EE_CHAR_GRABBAG, aAttribList))
{
ExtractErrorDescription(*pEECharAttrib, rSpellErrorDescription);
return true;
}
return false;
}
bool SentenceEditWindow_Impl::GetAlternatives(SpellErrorDescription& rSpellErrorDescription)
{
return GetErrorDescription(rSpellErrorDescription, m_nErrorStart);
}
void SentenceEditWindow_Impl::RestoreCurrentError()
{
TextPaM aCursor(0, m_nErrorStart);
const SpellErrorAttrib* pAttrib = static_cast<const SpellErrorAttrib*>(
GetTextEngine()->FindAttrib( aCursor, TEXTATTR_SPELL_ERROR));
if( pAttrib )
SpellErrorDescription aSpellErrorDescription;
if (GetErrorDescription(aSpellErrorDescription, m_nErrorStart))
{
const SpellErrorDescription& rDesc = pAttrib->GetErrorDescription();
if( rDesc.sErrorText != GetErrorText() )
ChangeMarkedWord(rDesc.sErrorText, LanguageTag::convertToLanguageType( rDesc.aLocale ));
if (aSpellErrorDescription.sErrorText != GetErrorText() )
ChangeMarkedWord(aSpellErrorDescription.sErrorText, LanguageTag::convertToLanguageType(aSpellErrorDescription.aLocale));
}
}
void SentenceEditWindow_Impl::SetAlternatives( const Reference< XSpellAlternatives>& xAlt )
{
TextPaM aCursor(0, m_nErrorStart);
DBG_ASSERT(static_cast<const SpellErrorAttrib*>(
GetTextEngine()->FindAttrib( aCursor, TEXTATTR_SPELL_ERROR)), "no error set?");
OUString aWord;
lang::Locale aLocale;
uno::Sequence< OUString > aAlts;
@@ -1756,22 +1896,25 @@ void SentenceEditWindow_Impl::SetAlternatives( const Reference< XSpellAlternativ
sServiceName = xNamed->getName();
}
SpellErrorDescription aDesc( false, aWord, aLocale, aAlts, nullptr);
GetTextEngine()->SetAttrib( SpellErrorAttrib(aDesc), 0, m_nErrorStart, m_nErrorEnd );
SfxGrabBagItem aSpellErrorDescription(EE_CHAR_GRABBAG);
aSpellErrorDescription.GetGrabBag()["SpellErrorDescription"] <<= aDesc.toSequence();
SetAttrib(aSpellErrorDescription, m_nErrorStart, m_nErrorEnd);
}
void SentenceEditWindow_Impl::SetAttrib( const TextAttrib& rAttr, sal_uInt32 nPara, sal_Int32 nStart, sal_Int32 nEnd )
void SentenceEditWindow_Impl::SetAttrib(const SfxPoolItem& rItem, sal_Int32 nStart, sal_Int32 nEnd)
{
GetTextEngine()->SetAttrib(rAttr, nPara, nStart, nEnd);
SfxItemSet aSet(m_xEditEngine->GetEmptyItemSet());
aSet.Put(rItem);
m_xEditEngine->QuickSetAttribs(aSet, ESelection(0, nStart, 0, nEnd));
Invalidate();
}
void SentenceEditWindow_Impl::SetText( const OUString& rStr )
{
m_nErrorStart = m_nErrorEnd = 0;
GetTextEngine()->SetText(rStr);
m_xEditEngine->SetText(rStr);
}
struct LanguagePosition_Impl
{
sal_Int32 nPosition;
@@ -1808,6 +1951,7 @@ static void lcl_InsertBreakPosition_Impl(
}
rBreakPositions.emplace_back(nInsert, eLanguage);
}
/*-------------------------------------------------------------------------
Returns the text in spell portions. Each portion contains text with an
equal language and attribute. The spell alternatives are empty.
@@ -1815,35 +1959,39 @@ static void lcl_InsertBreakPosition_Impl(
svx::SpellPortions SentenceEditWindow_Impl::CreateSpellPortions() const
{
svx::SpellPortions aRet;
ExtTextEngine* pTextEngine = GetTextEngine();
const sal_Int32 nTextLen = pTextEngine->GetTextLen(0);
if(nTextLen)
const sal_Int32 nTextLen = m_xEditEngine->GetTextLen(0);
std::vector<EECharAttrib> aAttribList;
m_xEditEngine->GetCharAttribs(0, aAttribList);
if (nTextLen)
{
TextPaM aCursor(0, 0);
int nCursor(0);
LanguagePositions_Impl aBreakPositions;
const TextCharAttrib* pLastLang = nullptr;
const TextCharAttrib* pLastError = nullptr;
const EECharAttrib* pLastLang = nullptr;
const EECharAttrib* pLastError = nullptr;
LanguageType eLang = LANGUAGE_DONTKNOW;
const TextCharAttrib* pError = nullptr;
while(aCursor.GetIndex() < nTextLen)
const EECharAttrib* pError = nullptr;
while (nCursor < nTextLen)
{
const TextCharAttrib* pLang = pTextEngine->FindCharAttrib( aCursor, TEXTATTR_SPELL_LANGUAGE);
const EECharAttrib* pLang = FindCharAttrib(nCursor, nCursor, EE_CHAR_LANGUAGE, aAttribList);
if(pLang && pLang != pLastLang)
{
eLang = static_cast<const SpellLanguageAttrib&>(pLang->GetAttr()).GetLanguage();
lcl_InsertBreakPosition_Impl(aBreakPositions, pLang->GetStart(), eLang);
lcl_InsertBreakPosition_Impl(aBreakPositions, pLang->GetEnd(), eLang);
eLang = static_cast<const SvxLanguageItem*>(pLang->pAttr)->GetLanguage();
lcl_InsertBreakPosition_Impl(aBreakPositions, pLang->nStart, eLang);
lcl_InsertBreakPosition_Impl(aBreakPositions, pLang->nEnd, eLang);
pLastLang = pLang;
}
pError = pTextEngine->FindCharAttrib( aCursor, TEXTATTR_SPELL_ERROR);
if(pError && pLastError != pError)
pError = FindCharAttrib(nCursor, nCursor, EE_CHAR_GRABBAG, aAttribList);
if (pError && pLastError != pError)
{
lcl_InsertBreakPosition_Impl(aBreakPositions, pError->GetStart(), eLang);
lcl_InsertBreakPosition_Impl(aBreakPositions, pError->GetEnd(), eLang);
lcl_InsertBreakPosition_Impl(aBreakPositions, pError->nStart, eLang);
lcl_InsertBreakPosition_Impl(aBreakPositions, pError->nEnd, eLang);
pLastError = pError;
}
++aCursor.GetIndex();
++nCursor;
}
if (aBreakPositions.empty())
@@ -1851,11 +1999,10 @@ svx::SpellPortions SentenceEditWindow_Impl::CreateSpellPortions() const
//if all content has been overwritten the attributes may have been removed, too
svx::SpellPortion aPortion1;
aPortion1.eLanguage = GetSpellDialog()->GetSelectedLang_Impl();
aPortion1.sText = pTextEngine->GetText(
TextSelection(TextPaM(0, 0), TextPaM(0, nTextLen)));
aPortion1.sText = m_xEditEngine->GetText(ESelection(0, 0, 0, nTextLen));
aRet.push_back(aPortion1);
}
else
{
@@ -1870,8 +2017,9 @@ svx::SpellPortions SentenceEditWindow_Impl::CreateSpellPortions() const
{
svx::SpellPortion aPortion1;
aPortion1.eLanguage = eLang;
aPortion1.sText = pTextEngine->GetText(
TextSelection(TextPaM(0, nStart), TextPaM(0, aStart->nPosition)));
aPortion1.sText = m_xEditEngine->GetText(ESelection(0, nStart, 0, aStart->nPosition));
bool bIsIgnoreError = m_aIgnoreErrorsAt.find( nStart ) != m_aIgnoreErrorsAt.end();
if( bIsIgnoreError )
{
@@ -1884,17 +2032,17 @@ svx::SpellPortions SentenceEditWindow_Impl::CreateSpellPortions() const
}
}
// quick partly fix of #i71318. Correct fix needs to patch the TextEngine itself...
// quick partly fix of #i71318. Correct fix needs to patch the EditEngine itself...
// this one will only prevent text from disappearing. It may to not have the
// correct language and will probably not spell checked...
const sal_uInt32 nPara = pTextEngine->GetParagraphCount();
const sal_uInt32 nPara = m_xEditEngine->GetParagraphCount();
if (nPara > 1)
{
OUStringBuffer aLeftOverText;
for (sal_uInt32 i = 1; i < nPara; ++i)
{
aLeftOverText.append("\x0a"); // the manual line break...
aLeftOverText.append(pTextEngine->GetText(i));
aLeftOverText.append(m_xEditEngine->GetText(i));
}
if (pError)
{ // we need to add a new portion containing the left-over text
@@ -1908,14 +2056,14 @@ svx::SpellPortions SentenceEditWindow_Impl::CreateSpellPortions() const
aRet[ aRet.size() - 1 ].sText += aLeftOverText;
}
}
}
}
return aRet;
}
void SentenceEditWindow_Impl::Undo()
{
SfxUndoManager& rUndoMgr = GetTextEngine()->GetUndoManager();
SfxUndoManager& rUndoMgr = m_xEditEngine->GetUndoManager();
DBG_ASSERT(GetUndoActionCount(), "no undo actions available" );
if(!GetUndoActionCount())
return;
@@ -1932,39 +2080,34 @@ void SentenceEditWindow_Impl::Undo()
GetSpellDialog()->UpdateBoxes_Impl();
}
void SentenceEditWindow_Impl::ResetUndo()
{
GetTextEngine()->ResetUndo();
SfxUndoManager& rUndo = m_xEditEngine->GetUndoManager();
rUndo.Clear();
}
void SentenceEditWindow_Impl::AddUndoAction( std::unique_ptr<SfxUndoAction> pAction )
{
SfxUndoManager& rUndoMgr = GetTextEngine()->GetUndoManager();
SfxUndoManager& rUndoMgr = m_xEditEngine->GetUndoManager();
rUndoMgr.AddUndoAction(std::move(pAction));
GetSpellDialog()->m_pUndoPB->Enable();
GetSpellDialog()->m_xUndoPB->set_sensitive(true);
}
size_t SentenceEditWindow_Impl::GetUndoActionCount()
{
return GetTextEngine()->GetUndoManager().GetUndoActionCount();
return m_xEditEngine->GetUndoManager().GetUndoActionCount();
}
void SentenceEditWindow_Impl::UndoActionStart( sal_uInt16 nId )
{
GetTextEngine()->UndoActionStart(nId);
m_xEditEngine->UndoActionStart(nId);
}
void SentenceEditWindow_Impl::UndoActionEnd()
{
GetTextEngine()->UndoActionEnd();
m_xEditEngine->UndoActionEnd();
}
void SentenceEditWindow_Impl::MoveErrorEnd(long nOffset)
{
// Shouldn't we always add the real signed value instead???
@@ -1975,44 +2118,47 @@ void SentenceEditWindow_Impl::MoveErrorEnd(long nOffset)
}
void SentenceEditWindow_Impl::SetUndoEditMode(bool bSet)
void SentenceEditWindow_Impl::SetUndoEditMode(bool bSet)
{
DBG_ASSERT(!bSet || m_bIsUndoEditMode != bSet, "SetUndoEditMode with equal values?");
m_bIsUndoEditMode = bSet;
//disable all buttons except the Change
SpellDialog* pSpellDialog = GetSpellDialog();
Control* aControls[] =
weld::Widget* aControls[] =
{
pSpellDialog->m_pChangeAllPB,
pSpellDialog->m_pExplainFT,
pSpellDialog->m_pIgnoreAllPB,
pSpellDialog->m_pIgnoreRulePB,
pSpellDialog->m_pIgnorePB,
pSpellDialog->m_pSuggestionLB,
pSpellDialog->m_pSuggestionFT,
pSpellDialog->m_pLanguageFT,
pSpellDialog->m_pLanguageLB,
pSpellDialog->m_pAddToDictMB,
pSpellDialog->m_pAddToDictPB,
pSpellDialog->m_pAutoCorrPB,
pSpellDialog->m_xChangeAllPB.get(),
pSpellDialog->m_xExplainFT.get(),
pSpellDialog->m_xIgnoreAllPB.get(),
pSpellDialog->m_xIgnoreRulePB.get(),
pSpellDialog->m_xIgnorePB.get(),
pSpellDialog->m_xSuggestionLB.get(),
pSpellDialog->m_xSuggestionFT.get(),
pSpellDialog->m_xLanguageFT.get(),
pSpellDialog->m_xLanguageLB->get_widget(),
pSpellDialog->m_xAddToDictMB.get(),
pSpellDialog->m_xAddToDictPB.get(),
pSpellDialog->m_xAutoCorrPB.get(),
nullptr
};
sal_Int32 nIdx = 0;
do
{
aControls[nIdx]->Enable(false);
aControls[nIdx]->set_sensitive(false);
}
while(aControls[++nIdx]);
//remove error marks
TextEngine* pTextEngine = GetTextEngine();
pTextEngine->RemoveAttribs( 0, sal_uInt16(TEXTATTR_FONTCOLOR) );
pTextEngine->RemoveAttribs( 0, sal_uInt16(TEXTATTR_FONTWEIGHT) );
ESelection aAll(0, 0, 0, EE_TEXTPOS_ALL);
m_xEditEngine->RemoveAttribs(aAll, false, EE_CHAR_COLOR);
m_xEditEngine->RemoveAttribs(aAll, false, EE_CHAR_WEIGHT);
m_xEditEngine->RemoveAttribs(aAll, false, EE_CHAR_WEIGHT_CJK);
m_xEditEngine->RemoveAttribs(aAll, false, EE_CHAR_WEIGHT_CTL);
Invalidate();
//put the appropriate action on the Undo-stack
AddUndoAction( std::make_unique<SpellUndoAction_Impl>(
SPELLUNDO_UNDO_EDIT_MODE, GetSpellDialog()->aDialogUndoLink) );
pSpellDialog->m_pChangePB->Enable();
pSpellDialog->m_xChangePB->set_sensitive(true);
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/cuicharmap.cxx b/cui/source/dialogs/cuicharmap.cxx
index 61899ea..f8c38f5 100644
--- a/cui/source/dialogs/cuicharmap.cxx
+++ b/cui/source/dialogs/cuicharmap.cxx
@@ -51,7 +51,7 @@
using namespace css;
SvxCharacterMap::SvxCharacterMap(weld::Window* pParent, const SfxItemSet* pSet,
SvxCharacterMap::SvxCharacterMap(weld::Widget* pParent, const SfxItemSet* pSet,
const css::uno::Reference<css::frame::XFrame>& rFrame)
: SfxDialogController(pParent, "cui/ui/specialcharacters.ui", "SpecialCharactersDialog")
, m_xVirDev(VclPtr<VirtualDevice>::Create())
diff --git a/cui/source/factory/dlgfact.cxx b/cui/source/factory/dlgfact.cxx
index af99be3..4ad9e490 100644
--- a/cui/source/factory/dlgfact.cxx
+++ b/cui/source/factory/dlgfact.cxx
@@ -271,7 +271,15 @@ short AbstractLinksDialog_Impl::Execute()
return m_xDlg->run();
}
IMPL_ABSTDLG_BASE(AbstractSpellDialog_Impl);
short AbstractSpellDialog_Impl::Execute()
{
return m_xDlg->run();
}
bool AbstractSpellDialog_Impl::StartExecuteAsync(AsyncContext &rCtx)
{
return SfxDialogController::runAsync(m_xDlg, rCtx.maEndDialogFn);
}
short AbstractSvxPostItDialog_Impl::Execute()
{
@@ -524,19 +532,19 @@ const SfxItemSet* AbstractSvxZoomDialog_Impl::GetOutputItemSet() const
return m_xDlg->GetOutputItemSet();
}
void AbstractSpellDialog_Impl::Invalidate()
void AbstractSpellDialog_Impl::InvalidateDialog()
{
pDlg->InvalidateDialog();
m_xDlg->InvalidateDialog();
}
vcl::Window* AbstractSpellDialog_Impl::GetWindow()
std::shared_ptr<SfxDialogController> AbstractSpellDialog_Impl::GetController()
{
return pDlg;
return m_xDlg;
}
SfxBindings& AbstractSpellDialog_Impl::GetBindings()
{
return pDlg->GetBindings();
return m_xDlg->GetBindings();
}
OUString AbstractTitleDialog_Impl::GetTitle() const
@@ -1050,12 +1058,11 @@ VclPtr<AbstractSvxZoomDialog> AbstractDialogFactory_Impl::CreateSvxZoomDialog(we
}
VclPtr<AbstractSpellDialog> AbstractDialogFactory_Impl::CreateSvxSpellDialog(
vcl::Window* pParent,
weld::Window* pParent,
SfxBindings* pBindings,
svx::SpellDialogChildWindow* pSpellChildWindow )
svx::SpellDialogChildWindow* pSpellChildWindow)
{
VclPtrInstance<svx::SpellDialog> pDlg(pSpellChildWindow, pParent, pBindings);
return VclPtr<AbstractSpellDialog_Impl>::Create(pDlg);
return VclPtr<AbstractSpellDialog_Impl>::Create(std::make_unique<svx::SpellDialog>(pSpellChildWindow, pParent, pBindings));
}
VclPtr<VclAbstractDialog> AbstractDialogFactory_Impl::CreateActualizeProgressDialog(weld::Window* pParent,
diff --git a/cui/source/factory/dlgfact.hxx b/cui/source/factory/dlgfact.hxx
index ca07530a..2f83409 100644
--- a/cui/source/factory/dlgfact.hxx
+++ b/cui/source/factory/dlgfact.hxx
@@ -236,10 +236,16 @@ public:
namespace svx{ class SpellDialog;}
class AbstractSpellDialog_Impl : public AbstractSpellDialog
{
public:
DECL_ABSTDLG_BASE(AbstractSpellDialog_Impl, svx::SpellDialog)
virtual void Invalidate() override;
virtual vcl::Window* GetWindow() override;
std::shared_ptr<svx::SpellDialog> m_xDlg;
public:
explicit AbstractSpellDialog_Impl(std::unique_ptr<svx::SpellDialog> p)
: m_xDlg(std::move(p))
{
}
virtual short Execute() override;
virtual bool StartExecuteAsync(AsyncContext &rCtx) override;
virtual void InvalidateDialog() override;
virtual std::shared_ptr<SfxDialogController> GetController() override;
virtual SfxBindings& GetBindings() override;
};
@@ -750,7 +756,7 @@ public:
const SdrView* pSdrView,
bool bSizeTabPage) override;
virtual VclPtr<AbstractSpellDialog> CreateSvxSpellDialog(
vcl::Window* pParent,
weld::Window* pParent,
SfxBindings* pBindings,
svx::SpellDialogChildWindow* pSpellChildWindow ) override;
diff --git a/cui/source/factory/init.cxx b/cui/source/factory/init.cxx
index eb3a99d..87f3105 100644
--- a/cui/source/factory/init.cxx
+++ b/cui/source/factory/init.cxx
@@ -23,10 +23,10 @@
// caution: needs C-Linkage since dynamically loaded via symbol name
extern "C"
{
SAL_DLLPUBLIC_EXPORT bool GetSpecialCharsForEdit(vcl::Window const * i_pParent, const vcl::Font& i_rFont, OUString& o_rResult)
SAL_DLLPUBLIC_EXPORT bool GetSpecialCharsForEdit(weld::Widget* i_pParent, const vcl::Font& i_rFont, OUString& o_rResult)
{
bool bRet = false;
SvxCharacterMap aDlg(i_pParent ? i_pParent->GetFrameWeld() : nullptr, nullptr, nullptr);
SvxCharacterMap aDlg(i_pParent, nullptr, nullptr);
aDlg.DisableFontSelection();
aDlg.SetCharFont(i_rFont);
if (aDlg.run() == RET_OK)
diff --git a/cui/source/inc/SpellDialog.hxx b/cui/source/inc/SpellDialog.hxx
index 83ea575..ee6d477 100644
--- a/cui/source/inc/SpellDialog.hxx
+++ b/cui/source/inc/SpellDialog.hxx
@@ -37,6 +37,10 @@
#include <svl/lstner.hxx>
#include <vcl/fixedhyper.hxx>
#include <vcl/xtextedt.hxx>
#include <vcl/txtattr.hxx>
#include <vcl/customweld.hxx>
#include <editeng/editeng.hxx>
#include <editeng/editview.hxx>
#include <editeng/SpellPortions.hxx>
#include <set>
@@ -55,39 +59,74 @@ namespace svx{
class SpellDialog;
struct SpellErrorDescription;
class SentenceEditWindow_Impl : public VclMultiLineEdit
class SentenceEditWindow_Impl : public weld::CustomWidgetController
, public EditViewCallbacks
{
using VclMultiLineEdit::SetText;
private:
std::set< sal_Int32 > m_aIgnoreErrorsAt;
VclPtr<ToolBox> m_xToolbar;
std::unique_ptr<EditEngine> m_xEditEngine;
std::unique_ptr<EditView> m_xEdView;
std::set<sal_Int32> m_aIgnoreErrorsAt;
SpellDialog* m_pSpellDialog;
weld::Toolbar* m_pToolbar;
sal_Int32 m_nErrorStart;
sal_Int32 m_nErrorEnd;
bool m_bIsUndoEditMode;
Link<Edit&,void> m_aModifyLink;
Link<LinkParamNone*,void> m_aModifyLink;
void CallModifyLink() {m_aModifyLink.Call(*this);}
void CallModifyLink() {m_aModifyLink.Call(nullptr); }
inline SpellDialog* GetSpellDialog() const;
SpellDialog* GetSpellDialog() const { return m_pSpellDialog; }
DECL_LINK(ToolbarHdl, ToolBox*, void);
bool GetErrorDescription(SpellErrorDescription& rSpellErrorDescription, sal_Int32 nPosition);
DECL_LINK(ToolbarHdl, const OString&, void);
protected:
virtual bool PreNotify( NotifyEvent& rNEvt ) override;
virtual void Paint( vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect ) override;
virtual bool MouseMove( const MouseEvent& rMEvt ) override;
virtual bool MouseButtonDown( const MouseEvent& rMEvt ) override;
virtual bool MouseButtonUp( const MouseEvent& rMEvt ) override;
virtual bool KeyInput( const KeyEvent& rKEvt ) override;
virtual void Resize() override;
virtual void EditViewInvalidate(const tools::Rectangle& rRect) const override
{
weld::DrawingArea* pDrawingArea = GetDrawingArea();
pDrawingArea->queue_draw_area(rRect.Left(), rRect.Top(), rRect.GetWidth(), rRect.GetHeight());
}
virtual void EditViewSelectionChange() const override
{
weld::DrawingArea* pDrawingArea = GetDrawingArea();
pDrawingArea->queue_draw();
}
virtual OutputDevice& EditViewOutputDevice() const override
{
return GetDrawingArea()->get_ref_device();
}
public:
SentenceEditWindow_Impl(vcl::Window* pParent, WinBits nBits);
SentenceEditWindow_Impl();
virtual void SetDrawingArea(weld::DrawingArea* pDrawingArea) override;
void SetSpellDialog(SpellDialog* pDialog) { m_pSpellDialog = pDialog; }
virtual ~SentenceEditWindow_Impl() override;
void Init(VclPtr<ToolBox> const &rToolbar);
void SetModifyHdl(const Link<Edit&,void>& rLink) override { m_aModifyLink = rLink;}
void Init(weld::Toolbar* pToolbar);
void SetModifyHdl(const Link<LinkParamNone*,void>& rLink)
{
m_aModifyLink = rLink;
m_xEditEngine->SetModifyHdl(m_aModifyLink);
}
void SetAttrib( const TextAttrib& rAttr, sal_uInt32 nPara, sal_Int32 nStart, sal_Int32 nEnd );
void SetText( const OUString& rStr ) override;
void SetAttrib(const SfxPoolItem& rItem, sal_Int32 nStart, sal_Int32 nEnd);
void SetText(const OUString& rStr);
bool MarkNextError( bool bIgnoreCurrentError, const css::uno::Reference<css::linguistic2::XSpellChecker1>& );
void ChangeMarkedWord(const OUString& rNewWord, LanguageType eLanguage);
int ChangeMarkedWord(const OUString& rNewWord, LanguageType eLanguage);
void MoveErrorMarkTo(sal_Int32 nErrorStart, sal_Int32 nErrorEnd, bool bGrammar);
OUString GetErrorText() const;
void RestoreCurrentError();
@@ -95,12 +134,11 @@ public:
void SetAlternatives(
const css::uno::Reference<css::linguistic2::XSpellAlternatives>& );
const SpellErrorDescription* GetAlternatives();
bool GetAlternatives(SpellErrorDescription& rDesc);
void ResetModified() { GetTextEngine()->SetModified(false); m_bIsUndoEditMode = false;}
virtual bool IsModified() const override { return GetTextEngine()->IsModified(); }
virtual void dispose() override;
void ClearModifyFlag() { m_xEditEngine->ClearModifyFlag(); }
void ResetModified() { ClearModifyFlag(); m_bIsUndoEditMode = false;}
bool IsModified() const { return m_xEditEngine->IsModified(); }
bool IsUndoEditMode() const { return m_bIsUndoEditMode;}
void SetUndoEditMode(bool bSet);
@@ -122,42 +160,10 @@ public:
// class SvxSpellDialog ---------------------------------------------
class SpellDialogChildWindow;
class SpellDialog : public SfxModelessDialog
class SpellDialog : public SfxModelessDialogController
{
using Window::Invalidate;
friend class SentenceEditWindow_Impl;
private:
VclPtr<FixedText> m_pLanguageFT;
VclPtr<SvxLanguageBox> m_pLanguageLB;
VclPtr<FixedText> m_pExplainFT;
VclPtr<FixedHyperlink> m_pExplainLink;
VclPtr<FixedText> m_pNotInDictFT;
VclPtr<SentenceEditWindow_Impl> m_pSentenceED;
VclPtr<FixedText> m_pSuggestionFT;
VclPtr<ListBox> m_pSuggestionLB;
VclPtr<PushButton> m_pIgnorePB;
VclPtr<PushButton> m_pIgnoreAllPB;
VclPtr<PushButton> m_pIgnoreRulePB;
VclPtr<PushButton> m_pAddToDictPB;
VclPtr<MenuButton> m_pAddToDictMB;
VclPtr<PushButton> m_pChangePB;
VclPtr<PushButton> m_pChangeAllPB;
VclPtr<PushButton> m_pAutoCorrPB;
VclPtr<CheckBox> m_pCheckGrammarCB;
VclPtr<PushButton> m_pOptionsPB;
VclPtr<PushButton> m_pUndoPB;
VclPtr<CloseButton> m_pClosePB;
VclPtr<ToolBox> m_pToolbar;
OUString m_sResumeST;
OUString m_sIgnoreOnceST;
OUString m_sNoSuggestionsST;
@@ -176,30 +182,58 @@ private:
css::uno::Reference<
css::linguistic2::XSpellChecker1 > xSpell;
DECL_LINK(ChangeHdl, Button*, void);
DECL_LINK(DoubleClickChangeHdl, ListBox&, void);
DECL_LINK(ChangeAllHdl, Button*, void);
DECL_LINK( IgnoreAllHdl, Button*, void );
DECL_LINK(IgnoreHdl, Button*, void);
DECL_LINK( CheckGrammarHdl, Button*, void );
DECL_LINK( ExtClickHdl, Button*, void );
DECL_LINK(CancelHdl, Button*, void);
DECL_LINK( ModifyHdl, Edit&, void);
DECL_LINK(UndoHdl, Button*, void);
DECL_LINK( AddToDictSelectHdl, MenuButton*, void );
DECL_LINK( AddToDictClickHdl, Button*, void );
DECL_LINK( LanguageSelectHdl, ListBox&, void );
DECL_LINK( DialogUndoHdl, SpellUndoAction_Impl&, void );
std::unique_ptr<weld::Label> m_xAltTitle;
std::unique_ptr<weld::Label> m_xResumeFT;
std::unique_ptr<weld::Label> m_xNoSuggestionsFT;
std::unique_ptr<weld::Label> m_xIgnoreOnceFT;
std::unique_ptr<weld::Label> m_xLanguageFT;
std::unique_ptr<LanguageBox> m_xLanguageLB;
std::unique_ptr<weld::Label> m_xExplainFT;
std::unique_ptr<weld::LinkButton> m_xExplainLink;
std::unique_ptr<weld::Label> m_xNotInDictFT;
std::unique_ptr<SentenceEditWindow_Impl> m_xSentenceED;
std::unique_ptr<weld::Label> m_xSuggestionFT;
std::unique_ptr<weld::TreeView> m_xSuggestionLB;
std::unique_ptr<weld::Button> m_xIgnorePB;
std::unique_ptr<weld::Button> m_xIgnoreAllPB;
std::unique_ptr<weld::Button> m_xIgnoreRulePB;
std::unique_ptr<weld::Button> m_xAddToDictPB;
std::unique_ptr<weld::MenuButton> m_xAddToDictMB;
std::unique_ptr<weld::Button> m_xChangePB;
std::unique_ptr<weld::Button> m_xChangeAllPB;
std::unique_ptr<weld::Button> m_xAutoCorrPB;
std::unique_ptr<weld::CheckButton> m_xCheckGrammarCB;
std::unique_ptr<weld::Button> m_xOptionsPB;
std::unique_ptr<weld::Button> m_xUndoPB;
std::unique_ptr<weld::Button> m_xClosePB;
std::unique_ptr<weld::Toolbar> m_xToolbar;
std::unique_ptr<weld::CustomWeld> m_xSentenceEDWeld;
DECL_LINK( InitHdl, void*, void );
DECL_LINK(ChangeHdl, weld::Button&, void);
DECL_LINK(DoubleClickChangeHdl, weld::TreeView&, void);
DECL_LINK(ChangeAllHdl, weld::Button&, void);
DECL_LINK(IgnoreAllHdl, weld::Button&, void);
DECL_LINK(IgnoreHdl, weld::Button&, void);
DECL_LINK(CheckGrammarHdl, weld::Button&, void);
DECL_LINK(ExtClickHdl, weld::Button&, void);
DECL_LINK(CancelHdl, weld::Button&, void);
DECL_LINK(ModifyHdl, LinkParamNone*, void);
DECL_LINK(UndoHdl, weld::Button&, void);
DECL_LINK(AddToDictSelectHdl, const OString&, void);
DECL_LINK(AddToDictClickHdl, weld::Button&, void);
DECL_LINK(LanguageSelectHdl, weld::ComboBox&, void);
DECL_LINK(DialogUndoHdl, SpellUndoAction_Impl&, void);
void AddToDictionaryExecute( sal_uInt16 ItemId, PopupMenu const *pMenu );
DECL_LINK(InitHdl, void*, void);
void AddToDictionaryExecute(const OString& rItemId);
void StartSpellOptDlg_Impl();
int InitUserDicts();
void UpdateBoxes_Impl(bool bCallFromSelectHdl = false);
void Init_Impl();
void SpellContinue_Impl(bool UseSavedSentence = false, bool bIgnoreCurrentError = false );
void LockFocusChanges( bool bLock ) {bFocusLocked = bLock;}
void ToplevelFocusChanged();
void Impl_Restore(bool bUseSavedSentence);
LanguageType GetSelectedLang_Impl() const;
@@ -213,25 +247,24 @@ private:
void SetTitle_Impl(LanguageType nLang);
protected:
virtual bool EventNotify( NotifyEvent& rNEvt ) override;
OUString getReplacementString() const;
public:
SpellDialog(
svx::SpellDialogChildWindow* pChildWindow,
vcl::Window * pParent,
weld::Window * pParent,
SfxBindings* pBindings);
virtual ~SpellDialog() override;
virtual void dispose() override;
virtual bool Close() override;
virtual void Activate() override;
virtual void Deactivate() override;
virtual void Close() override;
void InvalidateDialog();
};
SpellDialog* SentenceEditWindow_Impl::GetSpellDialog() const {return static_cast<SpellDialog*>(GetParentDialog());}
} //namespace svx
#endif
diff --git a/cui/uiconfig/ui/spellingdialog.ui b/cui/uiconfig/ui/spellingdialog.ui
index a1046a7..2019f32 100644
--- a/cui/uiconfig/ui/spellingdialog.ui
+++ b/cui/uiconfig/ui/spellingdialog.ui
@@ -1,14 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.19.0 -->
<!-- Generated with glade 3.22.1 -->
<interface domain="cui">
<requires lib="gtk+" version="3.18"/>
<requires lib="LibreOffice" version="1.0"/>
<object class="GtkMenu" id="addmenu">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<object class="GtkTreeStore" id="liststore1">
<columns>
<!-- column-name text -->
<column type="gchararray"/>
<!-- column-name id -->
<column type="gchararray"/>
</columns>
</object>
<object class="GtkListStore" id="liststore6">
<columns>
<!-- column-name text -->
<column type="gchararray"/>
<!-- column-name id -->
<column type="gchararray"/>
<!-- column-name image -->
<column type="GdkPixbuf"/>
</columns>
</object>
<object class="GtkDialog" id="SpellingDialog">
<property name="can_focus">False</property>
<property name="border_width">6</property>
<property name="title" translatable="yes" context="spellingdialog|SpellingDialog">Spelling: $LANGUAGE ($LOCATION)</property>
<property name="resizable">False</property>
<property name="default_width">0</property>
<property name="default_height">0</property>
<property name="type_hint">dialog</property>
<child>
<placeholder/>
</child>
<child internal-child="vbox">
<object class="GtkBox" id="dialog-vbox1">
<property name="can_focus">False</property>
@@ -95,10 +121,25 @@
<property name="row_spacing">6</property>
<property name="column_spacing">12</property>
<child>
<object class="svxcorelo-SvxLanguageBox" id="languagelb">
<object class="GtkComboBox" id="languagelb">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">end</property>
<property name="model">liststore6</property>
<property name="entry_text_column">0</property>
<property name="id_column">1</property>
<child>
<object class="GtkCellRendererText" id="cellrenderertext9"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
<child>
<object class="GtkCellRendererPixbuf" id="cellrenderertext6"/>
<attributes>
<attribute name="pixbuf">2</attribute>
</attributes>
</child>
</object>
<packing>
<property name="left_attach">1</property>
@@ -120,20 +161,6 @@
</packing>
</child>
<child>
<object class="cuilo-SentenceEditWindow" id="sentence">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">3</property>
<property name="width">2</property>
<property name="height">5</property>
</packing>
</child>
<child>
<object class="GtkButton" id="change">
<property name="label" translatable="yes" context="spellingdialog|change">Co_rrect</property>
<property name="visible">True</property>
@@ -298,24 +325,6 @@
</packing>
</child>
<child>
<object class="GtkTreeView" id="suggestionslb">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="show_expanders">False</property>
<child internal-child="selection">
<object class="GtkTreeSelection" id="treeview-selection1"/>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">9</property>
<property name="width">2</property>
<property name="height">3</property>
</packing>
</child>
<child>
<object class="GtkButton" id="add">
<property name="label" translatable="yes" context="spellingdialog|add">_Add to Dictionary</property>
<property name="visible">True</property>
@@ -330,13 +339,18 @@
</packing>
</child>
<child>
<object class="GtkButton" id="addmb:addmenu">
<object class="GtkMenuButton" id="addmb">
<property name="label" translatable="yes" context="spellingdialog|addmb">_Add to Dictionary</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="no_show_all">True</property>
<property name="valign">center</property>
<property name="use_underline">True</property>
<property name="popup">addmenu</property>
<property name="use_popover">False</property>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="left_attach">2</property>
@@ -383,7 +397,6 @@
<object class="GtkToolButton" id="paste">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="action_name">paste</property>
<property name="label" translatable="yes" context="spellingdialog|paste">Paste</property>
<property name="use_underline">True</property>
<property name="icon_name">cmd/sc_paste.png</property>
@@ -397,7 +410,6 @@
<object class="GtkToolButton" id="insert">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="action_name">insert</property>
<property name="label" translatable="yes" context="spellingdialog|insert">Special Character</property>
<property name="use_underline">True</property>
<property name="icon_name">cmd/sc_insertsymbol.png</property>
@@ -414,6 +426,73 @@
</packing>
</child>
<child>
<object class="GtkScrolledWindow">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="border_width">0</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkViewport">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkDrawingArea" id="sentence">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="events">GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_FOCUS_CHANGE_MASK | GDK_STRUCTURE_MASK</property>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">3</property>
<property name="width">2</property>
<property name="height">5</property>
</packing>
</child>
<child>
<object class="GtkScrolledWindow">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkTreeView" id="suggestionslb">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="model">liststore1</property>
<property name="headers_visible">False</property>
<property name="show_expanders">False</property>
<child internal-child="selection">
<object class="GtkTreeSelection" id="treeview-selection1"/>
</child>
<child>
<object class="GtkTreeViewColumn" id="treeviewcolumn2">
<property name="spacing">6</property>
<child>
<object class="GtkCellRendererText" id="cellrenderertext2"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">9</property>
<property name="width">2</property>
<property name="height">3</property>
</packing>
</child>
<child>
<placeholder/>
</child>
<child>
@@ -435,8 +514,4 @@
<action-widget response="-7">close</action-widget>
</action-widgets>
</object>
<object class="GtkMenu" id="addmenu">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
</interface>
diff --git a/extras/source/glade/libreoffice-catalog.xml.in b/extras/source/glade/libreoffice-catalog.xml.in
index bdfd89c..ed9f543 100644
--- a/extras/source/glade/libreoffice-catalog.xml.in
+++ b/extras/source/glade/libreoffice-catalog.xml.in
@@ -27,9 +27,6 @@
<glade-widget-class title="Search Results Box" name="sfxlo-SearchResultsBox"
generic-name="SearchResultsBox" parent="GtkComboBoxText"
icon-name="widget-gtk-comboboxtext"/>
<glade-widget-class title="Spelling View" name="cuilo-SentenceEditWindow"
generic-name="SentenceEditWindow" parent="GtkTextView"
icon-name="widget-gtk-textview"/>
<glade-widget-class title="Condition Edit" name="rptuilo-ConditionField"
generic-name="ConditionEdit" parent="GtkEntry"
icon-name="widget-gtk-comboboxtext"/>
diff --git a/include/cui/cuicharmap.hxx b/include/cui/cuicharmap.hxx
index c69107b..fbe9b11 100644
--- a/include/cui/cuicharmap.hxx
+++ b/include/cui/cuicharmap.hxx
@@ -143,7 +143,7 @@ private:
void selectCharByCode(Radix radix);
public:
SvxCharacterMap(weld::Window* pParent, const SfxItemSet* pSet,
SvxCharacterMap(weld::Widget* pParent, const SfxItemSet* pSet,
const css::uno::Reference<css::frame::XFrame>& rFrame);
virtual short run() override;
diff --git a/include/sfx2/basedlgs.hxx b/include/sfx2/basedlgs.hxx
index 4edf52e..bbcaef1 100644
--- a/include/sfx2/basedlgs.hxx
+++ b/include/sfx2/basedlgs.hxx
@@ -96,8 +96,7 @@ class SFX2_DLLPUBLIC SfxDialogController : public weld::GenericDialogController
private:
DECL_DLLPRIVATE_STATIC_LINK(SfxDialogController, InstallLOKNotifierHdl, void*, vcl::ILibreOfficeKitNotifier*);
DECL_DLLPRIVATE_LINK(FocusInHdl, weld::Widget&, void);
DECL_DLLPRIVATE_LINK(FocusOutHdl, weld::Widget&, void);
DECL_DLLPRIVATE_LINK(FocusChangeHdl, weld::Widget&, void);
public:
SfxDialogController(weld::Widget* pParent, const OUString& rUIFile, const OString& rDialogId);
diff --git a/include/svx/ClassificationEditView.hxx b/include/svx/ClassificationEditView.hxx
index 7c7070e..f3ce3b9 100644
--- a/include/svx/ClassificationEditView.hxx
+++ b/include/svx/ClassificationEditView.hxx
@@ -28,8 +28,8 @@ public:
virtual OUString CalcFieldValue(const SvxFieldItem& rField, sal_Int32 nPara, sal_Int32 nPos, boost::optional<Color>& rTxtColor, boost::optional<Color>& rFldColor) override;
};
class SVX_DLLPUBLIC ClassificationEditView : public weld::CustomWidgetController,
public EditViewCallbacks
class SVX_DLLPUBLIC ClassificationEditView : public weld::CustomWidgetController
, public EditViewCallbacks
{
public:
ClassificationEditView();
diff --git a/include/svx/langbox.hxx b/include/svx/langbox.hxx
index 9232ce8..1ba876c 100644
--- a/include/svx/langbox.hxx
+++ b/include/svx/langbox.hxx
@@ -170,7 +170,7 @@ public:
int find_text(const OUString& rStr) const { return m_xControl->find_text(rStr); }
OUString get_text(int nPos) const { return m_xControl->get_text(nPos); }
int get_count() const { return m_xControl->get_count(); }
const weld::ComboBox* get_widget() const { return m_xControl.get(); }
weld::ComboBox* get_widget() { return m_xControl.get(); }
};
class SVX_DLLPUBLIC SvxLanguageComboBox : public ComboBox, public SvxLanguageBoxBase
diff --git a/include/svx/svxdlg.hxx b/include/svx/svxdlg.hxx
index e530719..781eafd 100644
--- a/include/svx/svxdlg.hxx
+++ b/include/svx/svxdlg.hxx
@@ -99,8 +99,8 @@ class AbstractSpellDialog : public VclAbstractDialog
protected:
virtual ~AbstractSpellDialog() override = default;
public:
virtual void Invalidate() = 0;
virtual vcl::Window* GetWindow() = 0;
virtual void InvalidateDialog() = 0;
virtual std::shared_ptr<SfxDialogController> GetController() = 0;
virtual SfxBindings& GetBindings() = 0;
};
@@ -352,7 +352,7 @@ public:
virtual VclPtr<AbstractSvxZoomDialog> CreateSvxZoomDialog(weld::Window* pParent, const SfxItemSet& rCoreSet) = 0;
virtual VclPtr<AbstractSpellDialog> CreateSvxSpellDialog(vcl::Window* pParent,
virtual VclPtr<AbstractSpellDialog> CreateSvxSpellDialog(weld::Window* pParent,
SfxBindings* pBindings,
svx::SpellDialogChildWindow* pSpellChildWindow )=0;
diff --git a/include/vcl/edit.hxx b/include/vcl/edit.hxx
index caf7597..bc18f3a 100644
--- a/include/vcl/edit.hxx
+++ b/include/vcl/edit.hxx
@@ -50,7 +50,7 @@ struct Impl_IMEInfos;
#define EDIT_NOLIMIT SAL_MAX_INT32
#define EDIT_UPDATEDATA_TIMEOUT 350
typedef OUString (*FncGetSpecialChars)( vcl::Window* pWin, const vcl::Font& rFont );
typedef OUString (*FncGetSpecialChars)( weld::Widget* pWin, const vcl::Font& rFont );
class VCL_DLLPUBLIC TextFilter
{
diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx
index 7393131..35e645a 100644
--- a/include/vcl/weld.hxx
+++ b/include/vcl/weld.hxx
@@ -337,6 +337,9 @@ class VCL_DLLPUBLIC Window : virtual public Container
{
protected:
Link<Widget&, bool> m_aHelpRequestHdl;
Link<Widget&, void> m_aTopLevelFocusChangedHdl;
void signal_toplevel_focus_changed() { m_aTopLevelFocusChangedHdl.Call(*this); }
public:
virtual void set_title(const OUString& rTitle) = 0;
@@ -367,6 +370,10 @@ public:
virtual css::uno::Reference<css::awt::XWindow> GetXWindow() = 0;
void connect_help(const Link<Widget&, bool>& rLink) { m_aHelpRequestHdl = rLink; }
virtual void connect_toplevel_focus_changed(const Link<Widget&, void>& rLink)
{
m_aTopLevelFocusChangedHdl = rLink;
}
virtual SystemEnvData get_system_data() const = 0;
@@ -1007,9 +1014,11 @@ public:
virtual void insert_separator(int pos, const OUString& rId) = 0;
void append_separator(const OUString& rId) { insert_separator(-1, rId); }
virtual void remove_item(const OString& rId) = 0;
virtual void clear() = 0;
virtual void set_item_sensitive(const OString& rIdent, bool bSensitive) = 0;
virtual void set_item_active(const OString& rIdent, bool bActive) = 0;
virtual void set_item_label(const OString& rIdent, const OUString& rLabel) = 0;
virtual OUString get_item_label(const OString& rIdent) const = 0;
virtual void set_item_help_id(const OString& rIdent, const OString& rHelpId) = 0;
virtual void set_item_visible(const OString& rIdent, bool bVisible) = 0;
virtual OString get_item_help_id(const OString& rIdent) const = 0;
@@ -1096,6 +1105,7 @@ public:
virtual void set_max_length(int nChars) = 0;
// nEndPos can be -1 in order to select all text
virtual void select_region(int nStartPos, int nEndPos) = 0;
// returns true if the selection has nonzero length
virtual bool get_selection_bounds(int& rStartPos, int& rEndPos) = 0;
virtual void replace_selection(const OUString& rText) = 0;
// nCursorPos can be -1 to set to the end
diff --git a/sc/source/ui/inc/spelleng.hxx b/sc/source/ui/inc/spelleng.hxx
index cec0676..2add815 100644
--- a/sc/source/ui/inc/spelleng.hxx
+++ b/sc/source/ui/inc/spelleng.hxx
@@ -28,6 +28,8 @@ class ScDocShell;
class ScDocument;
class SfxItemPool;
namespace weld { class Window; }
/** Base class for special type of edit engines, i.e. for spell checker and text conversion. */
class ScConversionEngineBase : public ScEditEngineDefaulter
{
@@ -119,7 +121,7 @@ protected:
private:
/** Returns the spelling dialog if it is open. */
vcl::Window* GetDialogParent();
weld::Window* GetDialogParent();
};
/** Edit engine for text conversion. */
diff --git a/sc/source/ui/view/cellsh.cxx b/sc/source/ui/view/cellsh.cxx
index 26020a8..3d21cd9 100644
--- a/sc/source/ui/view/cellsh.cxx
+++ b/sc/source/ui/view/cellsh.cxx
@@ -1209,8 +1209,8 @@ void ScCellShell::GetState(SfxItemSet &rSet)
if ( pViewFrame && pViewFrame->HasChildWindow( nWhich ) )
{
SfxChildWindow* pChild = pViewFrame->GetChildWindow( nWhich );
vcl::Window* pWin = ( pChild ? pChild->GetWindow() : nullptr );
if ( pWin && pWin->IsVisible() )
std::shared_ptr<SfxDialogController> xController = pChild ? pChild->GetController() : nullptr;
if (xController && xController->getDialog()->get_visible())
{
bVisible = true;
}
diff --git a/sc/source/ui/view/spelleng.cxx b/sc/source/ui/view/spelleng.cxx
index 49c076c..af1ea81 100644
--- a/sc/source/ui/view/spelleng.cxx
+++ b/sc/source/ui/view/spelleng.cxx
@@ -305,10 +305,10 @@ bool ScSpellingEngine::NeedsConversion()
bool ScSpellingEngine::ShowTableWrapDialog()
{
vcl::Window* pParent = GetDialogParent();
ScWaitCursorOff aWaitOff( pParent );
weld::Window* pParent = GetDialogParent();
weld::WaitObject aWaitOff(pParent);
std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(pParent ? pParent->GetFrameWeld() : nullptr,
std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(pParent,
VclMessageType::Question, VclButtonsType::YesNo,
ScResId(STR_SPELLING_BEGIN_TAB))); // "delete data?"
xBox->set_title(ScResId(STR_MSSG_DOSUBTOTALS_0));
@@ -318,26 +318,37 @@ bool ScSpellingEngine::ShowTableWrapDialog()
void ScSpellingEngine::ShowFinishDialog()
{
vcl::Window* pParent = GetDialogParent();
ScWaitCursorOff aWaitOff( pParent );
std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(pParent ? pParent->GetFrameWeld() : nullptr,
weld::Window* pParent = GetDialogParent();
weld::WaitObject aWaitOff(pParent);
std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(pParent,
VclMessageType::Info, VclButtonsType::Ok,
ScResId(STR_SPELLING_STOP_OK)));
xInfoBox->run();
}
vcl::Window* ScSpellingEngine::GetDialogParent()
weld::Window* ScSpellingEngine::GetDialogParent()
{
sal_uInt16 nWinId = ScSpellDialogChildWindow::GetChildWindowId();
SfxViewFrame* pViewFrm = mrViewData.GetViewShell()->GetViewFrame();
if( pViewFrm->HasChildWindow( nWinId ) )
{
if( SfxChildWindow* pChild = pViewFrm->GetChildWindow( nWinId ) )
if( vcl::Window* pWin = pChild->GetWindow() )
if( pWin->IsVisible() )
return pWin;
{
auto xController = pChild->GetController();
if (xController)
{
if (weld::Window *pRet = xController->getDialog())
{
if (pRet->get_visible())
return pRet;
}
}
}
}
// fall back to standard dialog parent
return ScDocShell::GetActiveDialogParent();
vcl::Window* pWin = ScDocShell::GetActiveDialogParent();
return pWin ? pWin->GetFrameWeld() : nullptr;
}
ScConversionParam::ScConversionParam( ScConversionType eConvType ) :
diff --git a/sd/inc/Outliner.hxx b/sd/inc/Outliner.hxx
index 5f4056f..47c3b5d 100644
--- a/sd/inc/Outliner.hxx
+++ b/sd/inc/Outliner.hxx
@@ -30,6 +30,10 @@ class SdrObject;
class SdrTextObj;
class SdDrawDocument;
namespace weld {
class Window;
}
namespace sd {
class View;
@@ -516,7 +520,7 @@ private:
that the otherwise non-modal search or spell dialogs, if visible, are
locked, too.
*/
VclPtr<vcl::Window> GetMessageBoxParent();
weld::Window* GetMessageBoxParent();
};
#endif
diff --git a/sd/source/ui/view/Outliner.cxx b/sd/source/ui/view/Outliner.cxx
index a98ad3c..a91d5f7 100644
--- a/sd/source/ui/view/Outliner.cxx
+++ b/sd/source/ui/view/Outliner.cxx
@@ -1205,8 +1205,8 @@ void SdOutliner::ShowEndOfSearchDialog()
aString = SdResId(STR_END_SPELLING);
// Show the message in an info box that is modal with respect to the whole application.
VclPtr<vcl::Window> xParent(GetMessageBoxParent());
std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(xParent ? xParent->GetFrameWeld() : nullptr,
weld::Window* pParent = GetMessageBoxParent();
std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(pParent,
VclMessageType::Info, VclButtonsType::Ok, aString));
xInfoBox->run();
}
@@ -1246,8 +1246,8 @@ bool SdOutliner::ShowWrapArroundDialog()
// Pop up question box that asks the user whether to wrap around.
// The dialog is made modal with respect to the whole application.
VclPtr<vcl::Window> xParent(GetMessageBoxParent());
std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(xParent ? xParent->GetFrameWeld() : nullptr,
weld::Window* pParent = GetMessageBoxParent();
std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(pParent,
VclMessageType::Question, VclButtonsType::YesNo, SdResId(pStringId)));
sal_uInt16 nBoxResult = xQueryBox->run();
@@ -1691,7 +1691,7 @@ bool SdOutliner::ConvertNextDocument()
return !mbEndOfSearch;
}
VclPtr<vcl::Window> SdOutliner::GetMessageBoxParent()
weld::Window* SdOutliner::GetMessageBoxParent()
{
// We assume that the parent of the given message box is NULL, i.e. it is
// modal with respect to the top application window. However, this
@@ -1699,7 +1699,7 @@ VclPtr<vcl::Window> SdOutliner::GetMessageBoxParent()
// while the message box is being shown. We also have to take into
// account that we are called during a spell check and the search dialog
// is not available.
vcl::Window* pSearchDialog = nullptr;
weld::Window* pSearchDialog = nullptr;
SfxChildWindow* pChildWindow = nullptr;
switch (meMode)
{
@@ -1720,13 +1720,17 @@ VclPtr<vcl::Window> SdOutliner::GetMessageBoxParent()
}
if (pChildWindow != nullptr)
pSearchDialog = pChildWindow->GetWindow();
{
auto xController = pChildWindow->GetController();
pSearchDialog = xController ? xController->getDialog() : nullptr;
}
if (pSearchDialog)
return pSearchDialog;
std::shared_ptr<sd::ViewShell> pViewShell (mpWeakViewShell.lock());
return pViewShell->GetActiveWindow();
auto pWin = pViewShell->GetActiveWindow();
return pWin ? pWin->GetFrameWeld() : nullptr;
}
//===== SdOutliner::Implementation ==============================================
diff --git a/sfx2/source/appl/appinit.cxx b/sfx2/source/appl/appinit.cxx
index 5432007..89e1ea9 100644
--- a/sfx2/source/appl/appinit.cxx
+++ b/sfx2/source/appl/appinit.cxx
@@ -142,7 +142,7 @@ Sequence< OUString > SAL_CALL SfxTerminateListener_Impl::getSupportedServiceName
}
typedef bool ( *PFunc_getSpecialCharsForEdit)( vcl::Window const * i_pParent, const vcl::Font& i_rFont, OUString& o_rOutString );
typedef bool (*PFunc_getSpecialCharsForEdit)(weld::Widget* i_pParent, const vcl::Font& i_rFont, OUString& o_rOutString);
// Lazy binding of the GetSpecialCharsForEdit function as it resides in
@@ -155,11 +155,11 @@ extern "C" { static void thisModule() {} }
#else
extern "C" bool GetSpecialCharsForEdit( vcl::Window const * i_pParent, const vcl::Font& i_rFont, OUString& o_rOutString );
extern "C" bool GetSpecialCharsForEdit(weld::Widget* i_pParent, const vcl::Font& i_rFont, OUString& o_rOutString);
#endif
static OUString SfxGetSpecialCharsForEdit(vcl::Window* pParent, const vcl::Font& rFont)
static OUString SfxGetSpecialCharsForEdit(weld::Widget* pParent, const vcl::Font& rFont)
{
static bool bDetermineFunction = false;
static PFunc_getSpecialCharsForEdit pfunc_getSpecialCharsForEdit = nullptr;
diff --git a/sfx2/source/dialog/basedlgs.cxx b/sfx2/source/dialog/basedlgs.cxx
index f902196..e1f7463 100644
--- a/sfx2/source/dialog/basedlgs.cxx
+++ b/sfx2/source/dialog/basedlgs.cxx
@@ -386,9 +386,12 @@ void SfxModelessDialogController::Init(SfxBindings *pBindinx, SfxChildWindow *pC
If a ModelessDialog is enabled its ViewFrame will be activated.
This is necessary by PluginInFrames.
*/
IMPL_LINK_NOARG(SfxDialogController, FocusInHdl, weld::Widget&, void)
IMPL_LINK_NOARG(SfxDialogController, FocusChangeHdl, weld::Widget&, void)
{
Activate();
if (m_xDialog->has_toplevel_focus())
Activate();
else
Deactivate();
}
void SfxModelessDialogController::Activate()
@@ -399,11 +402,6 @@ void SfxModelessDialogController::Activate()
m_xImpl->pMgr->Activate_Impl();
}
IMPL_LINK_NOARG(SfxDialogController, FocusOutHdl, weld::Widget&, void)
{
Deactivate();
}
void SfxModelessDialogController::Deactivate()
{
if (!m_xImpl)
@@ -676,8 +674,7 @@ SfxDialogController::SfxDialogController(weld::Widget* pParent, const OUString&
: GenericDialogController(pParent, rUIFile, rDialogId)
{
m_xDialog->SetInstallLOKNotifierHdl(LINK(this, SfxDialogController, InstallLOKNotifierHdl));
m_xDialog->connect_focus_in(LINK(this, SfxDialogController, FocusInHdl));
m_xDialog->connect_focus_out(LINK(this, SfxDialogController, FocusOutHdl));
m_xDialog->connect_toplevel_focus_changed(LINK(this, SfxDialogController, FocusChangeHdl));
}
IMPL_STATIC_LINK_NOARG(SfxDialogController, InstallLOKNotifierHdl, void*, vcl::ILibreOfficeKitNotifier*)
diff --git a/solenv/bin/native-code.py b/solenv/bin/native-code.py
index 9ebf741..d8b940d 100755
--- a/solenv/bin/native-code.py
+++ b/solenv/bin/native-code.py
@@ -485,7 +485,6 @@ custom_widgets = [
'SdPageObjsTLB',
'SearchBox',
'SearchResultsBox',
'SentenceEditWindow',
'ShowNupOrderWindow',
'ShowNupOrderWindow',
'SidebarDialControl',
diff --git a/svx/source/dialog/SpellDialogChildWindow.cxx b/svx/source/dialog/SpellDialogChildWindow.cxx
index 51bd2fc..ae82769 100644
--- a/svx/source/dialog/SpellDialogChildWindow.cxx
+++ b/svx/source/dialog/SpellDialogChildWindow.cxx
@@ -32,10 +32,10 @@ SpellDialogChildWindow::SpellDialogChildWindow (
: SfxChildWindow (_pParent, nId)
{
SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
m_xAbstractSpellDialog = pFact->CreateSvxSpellDialog(_pParent,
m_xAbstractSpellDialog = pFact->CreateSvxSpellDialog(_pParent->GetFrameWeld(),
pBindings,
this );
SetWindow( m_xAbstractSpellDialog->GetWindow() );
SetController(m_xAbstractSpellDialog->GetController());
SetHideNotDelete(true);
}
@@ -54,7 +54,7 @@ void SpellDialogChildWindow::InvalidateSpellDialog()
{
OSL_ASSERT (m_xAbstractSpellDialog);
if (m_xAbstractSpellDialog)
m_xAbstractSpellDialog->Invalidate();
m_xAbstractSpellDialog->InvalidateDialog();
}
bool SpellDialogChildWindow::HasAutoCorrection()
diff --git a/svx/source/dialog/rubydialog.cxx b/svx/source/dialog/rubydialog.cxx
index 7856b12..5f0a6e5 100644
--- a/svx/source/dialog/rubydialog.cxx
+++ b/svx/source/dialog/rubydialog.cxx
@@ -280,9 +280,9 @@ void SvxRubyDialog::Close()
{
if (IsClosing())
return;
SfxViewShell* pViewShell = SfxViewShell::Current();
if (pViewShell)
pViewShell->GetViewFrame()->ToggleChildWindow(SID_RUBY_DIALOG);
SfxViewFrame* pViewFrame = SfxViewFrame::Current();
if (pViewFrame)
pViewFrame->ToggleChildWindow(SID_RUBY_DIALOG);
}
void SvxRubyDialog::Activate()
diff --git a/svx/source/dialog/srchdlg.cxx b/svx/source/dialog/srchdlg.cxx
index 7911163..48dbc88 100644
--- a/svx/source/dialog/srchdlg.cxx
+++ b/svx/source/dialog/srchdlg.cxx
@@ -523,9 +523,9 @@ void SvxSearchDialog::Close()
rBindings.GetDispatcher()->Execute( FID_SEARCH_OFF, SfxCallMode::SLOT, ppArgs );
rBindings.Invalidate(SID_SEARCH_DLG);
SfxViewShell* pViewShell = SfxViewShell::Current();
if (pViewShell)
pViewShell->GetViewFrame()->ToggleChildWindow(SID_SEARCH_DLG);
SfxViewFrame* pViewFrame = SfxViewFrame::Current();
if (pViewFrame)
pViewFrame->ToggleChildWindow(SID_SEARCH_DLG);
}
TransliterationFlags SvxSearchDialog::GetTransliterationFlags() const
diff --git a/sw/source/uibase/dialog/SwSpellDialogChildWindow.cxx b/sw/source/uibase/dialog/SwSpellDialogChildWindow.cxx
index d8c927c..918d484 100644
--- a/sw/source/uibase/dialog/SwSpellDialogChildWindow.cxx
+++ b/sw/source/uibase/dialog/SwSpellDialogChildWindow.cxx
@@ -383,7 +383,7 @@ The code below would only be part of the solution.
if(m_pSpellState->m_xStartRange.is())
{
LockFocusNotification( true );
std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(GetWindow()->GetFrameWeld(),
std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(GetController()->getDialog(),
VclMessageType::Question, VclButtonsType::YesNo, SwResId(STR_QUERY_SPELL_CONTINUE)));
sal_uInt16 nRet = xBox->run();
if (RET_YES == nRet)
@@ -411,10 +411,10 @@ The code below would only be part of the solution.
{
LockFocusNotification( true );
OUString sInfo( SwResId( bNoDictionaryAvailable ? STR_DICTIONARY_UNAVAILABLE : STR_SPELLING_COMPLETED ) );
vcl::Window* pThisWindow = GetWindow();
auto xSpellController = GetController();
// #i84610#
std::unique_ptr<weld::MessageDialog> xBox(
Application::CreateMessageDialog( pThisWindow->GetFrameWeld(),
Application::CreateMessageDialog( xSpellController->getDialog(),
VclMessageType::Info,
VclButtonsType::Ok,
sInfo ) );
@@ -422,8 +422,7 @@ The code below would only be part of the solution.
LockFocusNotification( false );
// take care that the now valid selection is stored
LoseFocus();
if( pThisWindow )
pThisWindow->GrabFocus();
xSpellController->getDialog()->grab_focus();
}
}
return aRet;
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index fadd560..b17e021 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -695,9 +695,9 @@ public:
void SalInstanceWidget::HandleEventListener(VclWindowEvent& rEvent)
{
if (rEvent.GetId() == VclEventId::WindowGetFocus || rEvent.GetId() == VclEventId::WindowActivate)
if (rEvent.GetId() == VclEventId::WindowGetFocus)
m_aFocusInHdl.Call(*this);
else if (rEvent.GetId() == VclEventId::WindowLoseFocus || rEvent.GetId() == VclEventId::WindowDeactivate)
else if (rEvent.GetId() == VclEventId::WindowLoseFocus)
m_aFocusOutHdl.Call(*this);
else if (rEvent.GetId() == VclEventId::WindowResize)
m_aSizeAllocateHdl.Call(m_xWidget->GetSizePixel());
@@ -1140,6 +1140,22 @@ public:
return *m_xWindow->GetSystemData();
}
virtual void connect_toplevel_focus_changed(const Link<weld::Widget&, void>& rLink) override
{
ensure_event_listener();
weld::Window::connect_toplevel_focus_changed(rLink);
}
virtual void HandleEventListener(VclWindowEvent& rEvent) override
{
if (rEvent.GetId() == VclEventId::WindowActivate || rEvent.GetId() == VclEventId::WindowDeactivate)
{
signal_toplevel_focus_changed();
return;
}
SalInstanceContainer::HandleEventListener(rEvent);
}
virtual ~SalInstanceWindow() override
{
clear_child_help(m_xWindow);
@@ -1893,6 +1909,7 @@ public:
m_xMenuButton->SetSelectHdl(LINK(this, SalInstanceMenuButton, MenuSelectHdl));
if (PopupMenu* pMenu = m_xMenuButton->GetPopupMenu())
{
pMenu->SetMenuFlags(MenuFlags::NoAutoMnemonics);
const auto nCount = pMenu->GetItemCount();
m_nLastId = nCount ? pMenu->GetItemId(nCount-1) : 0;
}
@@ -1947,6 +1964,12 @@ public:
pMenu->RemoveItem(pMenu->GetItemPos(pMenu->GetItemId(rId)));
}
virtual void clear() override
{
PopupMenu* pMenu = m_xMenuButton->GetPopupMenu();
pMenu->Clear();
}
virtual void set_item_active(const OString& rIdent, bool bActive) override
{
PopupMenu* pMenu = m_xMenuButton->GetPopupMenu();
@@ -1959,6 +1982,12 @@ public:
pMenu->SetItemText(pMenu->GetItemId(rIdent), rText);
}
virtual OUString get_item_label(const OString& rIdent) const override
{
PopupMenu* pMenu = m_xMenuButton->GetPopupMenu();
return pMenu->GetItemText(pMenu->GetItemId(rIdent));
}
virtual void set_item_visible(const OString& rIdent, bool bShow) override
{
PopupMenu* pMenu = m_xMenuButton->GetPopupMenu();
diff --git a/vcl/source/control/edit.cxx b/vcl/source/control/edit.cxx
index 57d0375..926bc31 100644
--- a/vcl/source/control/edit.cxx
+++ b/vcl/source/control/edit.cxx
@@ -1467,7 +1467,7 @@ bool Edit::ImplHandleKeyEvent( const KeyEvent& rKEvt )
if ( pImplFncGetSpecialChars )
{
Selection aSaveSel = GetSelection(); // if someone changes the selection in Get/LoseFocus, e.g. URL bar
OUString aChars = pImplFncGetSpecialChars( this, GetFont() );
OUString aChars = pImplFncGetSpecialChars( GetFrameWeld(), GetFont() );
SetSelection( aSaveSel );
if ( !aChars.isEmpty() )
{
@@ -2028,7 +2028,7 @@ void Edit::Command( const CommandEvent& rCEvt )
}
else if (sCommand == "specialchar" && pImplFncGetSpecialChars)
{
OUString aChars = pImplFncGetSpecialChars( this, GetFont() );
OUString aChars = pImplFncGetSpecialChars(GetFrameWeld(), GetFont());
SetSelection( aSaveSel );
if (!aChars.isEmpty())
{
diff --git a/vcl/source/edit/vclmedit.cxx b/vcl/source/edit/vclmedit.cxx
index df9e236..faa8e18 100644
--- a/vcl/source/edit/vclmedit.cxx
+++ b/vcl/source/edit/vclmedit.cxx
@@ -715,7 +715,7 @@ void TextWindow::KeyInput( const KeyEvent& rKEvent )
{
// to maintain the selection
mbActivePopup = true;
OUString aChars = Edit::GetGetSpecialCharsFunction()( this, GetFont() );
OUString aChars = Edit::GetGetSpecialCharsFunction()(GetFrameWeld(), GetFont());
if (!aChars.isEmpty())
{
mpExtTextView->InsertText( aChars );
@@ -829,7 +829,7 @@ void TextWindow::Command( const CommandEvent& rCEvt )
}
else if (sCommand == "specialchar")
{
OUString aChars = Edit::GetGetSpecialCharsFunction()( this, GetFont() );
OUString aChars = Edit::GetGetSpecialCharsFunction()(GetFrameWeld(), GetFont());
if (!aChars.isEmpty())
{
mpExtTextView->InsertText( aChars );
diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx
index 06f49b7..712dd51 100644
--- a/vcl/unx/gtk3/gtk3gtkinst.cxx
+++ b/vcl/unx/gtk3/gtk3gtkinst.cxx
@@ -2421,7 +2421,7 @@ public:
bool bCheck)
{
GtkWidget* pImage = nullptr;
if (pIconName)
if (pIconName && !pIconName->isEmpty())
{
GdkPixbuf* pixbuf = load_icon_by_name(*pIconName);
if (!pixbuf)
@@ -2497,6 +2497,12 @@ public:
gtk_menu_item_set_label(m_aMap[rIdent], MapToGtkAccelerator(rText).getStr());
}
OUString get_item_label(const OString& rIdent) const
{
const gchar* pText = gtk_menu_item_get_label(m_aMap.find(rIdent)->second);
return OUString(pText, pText ? strlen(pText) : 0, RTL_TEXTENCODING_UTF8);
}
void set_item_help_id(const OString& rIdent, const OString& rHelpId)
{
set_help_id(GTK_WIDGET(m_aMap[rIdent]), rHelpId);
@@ -2634,18 +2640,27 @@ class GtkInstanceWindow : public GtkInstanceContainer, public virtual weld::Wind
private:
GtkWindow* m_pWindow;
rtl::Reference<SalGtkXWindow> m_xWindow; //uno api
gulong m_nToplevelFocusChangedSignalId;
static void help_pressed(GtkAccelGroup*, GObject*, guint, GdkModifierType, gpointer widget)
{
GtkInstanceWindow* pThis = static_cast<GtkInstanceWindow*>(widget);
pThis->help();
}
static void signalToplevelFocusChanged(GtkWindow*, GParamSpec*, gpointer widget)
{
GtkInstanceWindow* pThis = static_cast<GtkInstanceWindow*>(widget);
pThis->signal_toplevel_focus_changed();
}
protected:
void help();
public:
GtkInstanceWindow(GtkWindow* pWindow, GtkInstanceBuilder* pBuilder, bool bTakeOwnership)
: GtkInstanceContainer(GTK_CONTAINER(pWindow), pBuilder, bTakeOwnership)
, m_pWindow(pWindow)
, m_nToplevelFocusChangedSignalId(0)
{
//hook up F1 to show help
GtkAccelGroup *pGroup = gtk_accel_group_new();
@@ -2801,8 +2816,31 @@ public:
return ImplWindowStateToStr(aData);
}
virtual void connect_toplevel_focus_changed(const Link<weld::Widget&, void>& rLink) override
{
assert(!m_nToplevelFocusChangedSignalId);
m_nToplevelFocusChangedSignalId = g_signal_connect(m_pWindow, "notify::has-toplevel-focus", G_CALLBACK(signalToplevelFocusChanged), this);
weld::Window::connect_toplevel_focus_changed(rLink);
}
virtual void disable_notify_events() override
{
if (m_nToplevelFocusChangedSignalId)
g_signal_handler_block(m_pWidget, m_nToplevelFocusChangedSignalId);
GtkInstanceContainer::disable_notify_events();
}
virtual void enable_notify_events() override
{
GtkInstanceContainer::enable_notify_events();
if (m_nToplevelFocusChangedSignalId)
g_signal_handler_unblock(m_pWidget, m_nToplevelFocusChangedSignalId);
}
virtual ~GtkInstanceWindow() override
{
if (m_nToplevelFocusChangedSignalId)
g_signal_handler_disconnect(m_pWindow, m_nToplevelFocusChangedSignalId);
if (m_xWindow.is())
m_xWindow->clear();
}
@@ -5214,6 +5252,11 @@ public:
MenuHelper::remove_item(rId);
}
virtual void clear() override
{
clear_items();
}
virtual void set_item_active(const OString& rIdent, bool bActive) override
{
MenuHelper::set_item_active(rIdent, bActive);
@@ -5229,6 +5272,11 @@ public:
MenuHelper::set_item_label(rIdent, rLabel);
}
virtual OUString get_item_label(const OString& rIdent) const override
{
return MenuHelper::get_item_label(rIdent);
}
virtual void set_item_visible(const OString& rIdent, bool bVisible) override
{
MenuHelper::set_item_visible(rIdent, bVisible);