bump product version to 6.3.0.0.beta1
[LibreOffice.git] / cui / source / tabpages / autocdlg.cxx
blob9b2a98e20584172aebcc097cd06f41dacc5e2add
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <i18nutil/unicode.hxx>
21 #include <vcl/event.hxx>
22 #include <vcl/field.hxx>
23 #include <vcl/keycodes.hxx>
24 #include <vcl/settings.hxx>
25 #include <sot/exchange.hxx>
26 #include <vcl/transfer.hxx>
27 #include <unotools/syslocale.hxx>
28 #include <sfx2/app.hxx>
29 #include <sfx2/objsh.hxx>
30 #include <sfx2/viewsh.hxx>
31 #include <unotools/charclass.hxx>
32 #include <unotools/collatorwrapper.hxx>
33 #include <com/sun/star/i18n/CollatorOptions.hpp>
34 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
35 #include <comphelper/processfactory.hxx>
36 #include <comphelper/string.hxx>
37 #include <vcl/svapp.hxx>
38 #include <sfx2/module.hxx>
39 #include <sfx2/request.hxx>
40 #include <sfx2/sfxsids.hrc>
41 #include <svl/eitem.hxx>
42 #include <svl/languageoptions.hxx>
43 #include <svx/SmartTagMgr.hxx>
44 #include <svx/ucsubset.hxx>
45 #include <com/sun/star/smarttags/XSmartTagRecognizer.hpp>
46 #include <com/sun/star/smarttags/XSmartTagAction.hpp>
47 #include <rtl/strbuf.hxx>
48 #include <osl/diagnose.h>
50 #include <autocdlg.hxx>
51 #include <editeng/acorrcfg.hxx>
52 #include <editeng/svxacorr.hxx>
53 #include <cui/cuicharmap.hxx>
54 #include <strings.hrc>
55 #include <editeng/unolingu.hxx>
56 #include <dialmgr.hxx>
57 #include <svx/svxids.hrc>
59 static LanguageType eLastDialogLanguage = LANGUAGE_SYSTEM;
61 using namespace ::com::sun::star::util;
62 using namespace ::com::sun::star;
64 OfaAutoCorrDlg::OfaAutoCorrDlg(weld::Window* pParent, const SfxItemSet* _pSet )
65 : SfxTabDialogController(pParent, "cui/ui/autocorrectdialog.ui", "AutoCorrectDialog", _pSet)
66 , m_xLanguageBox(m_xBuilder->weld_widget("langbox"))
67 , m_xLanguageLB(new LanguageBox(m_xBuilder->weld_combo_box("lang")))
69 bool bShowSWOptions = false;
70 bool bOpenSmartTagOptions = false;
72 if ( _pSet )
74 const SfxBoolItem* pItem = SfxItemSet::GetItem<SfxBoolItem>(_pSet, SID_AUTO_CORRECT_DLG, false);
75 if ( pItem && pItem->GetValue() )
76 bShowSWOptions = true;
78 const SfxBoolItem* pItem2 = SfxItemSet::GetItem<SfxBoolItem>(_pSet, SID_OPEN_SMARTTAGOPTIONS, false);
79 if ( pItem2 && pItem2->GetValue() )
80 bOpenSmartTagOptions = true;
83 AddTabPage("options", OfaAutocorrOptionsPage::Create, nullptr);
84 AddTabPage("applypage", OfaSwAutoFmtOptionsPage::Create, nullptr);
85 AddTabPage("wordcompletion", OfaAutoCompleteTabPage::Create, nullptr);
86 AddTabPage("smarttags", OfaSmartTagOptionsTabPage::Create, nullptr);
88 if (!bShowSWOptions)
90 RemoveTabPage("applypage");
91 RemoveTabPage("wordcompletion");
92 RemoveTabPage("smarttags");
94 else
96 // remove smart tag tab page if no extensions are installed
97 SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
98 SvxSwAutoFormatFlags& rOpt = pAutoCorrect->GetSwFlags();
99 if (!rOpt.pSmartTagMgr || 0 == rOpt.pSmartTagMgr->NumberOfRecognizers())
100 RemoveTabPage("smarttags");
102 RemoveTabPage("options");
105 AddTabPage("replace", OfaAutocorrReplacePage::Create, nullptr);
106 AddTabPage("exceptions", OfaAutocorrExceptPage::Create, nullptr);
107 AddTabPage("localized", OfaQuoteTabPage::Create, nullptr);
109 // initialize languages
110 //! LANGUAGE_NONE is displayed as '[All]' and the LanguageType
111 //! will be set to LANGUAGE_UNDETERMINED
112 SvxLanguageListFlags nLangList = SvxLanguageListFlags::WESTERN;
114 if( SvtLanguageOptions().IsCTLFontEnabled() )
115 nLangList |= SvxLanguageListFlags::CTL;
116 if( SvtLanguageOptions().IsCJKFontEnabled() )
117 nLangList |= SvxLanguageListFlags::CJK;
118 m_xLanguageLB->SetLanguageList( nLangList, true, true );
119 m_xLanguageLB->set_active_id( LANGUAGE_NONE );
120 int nPos = m_xLanguageLB->get_active();
121 DBG_ASSERT(nPos != -1, "listbox entry missing" );
122 m_xLanguageLB->set_id(nPos, LANGUAGE_UNDETERMINED);
124 // Initializing doesn't work for static on linux - therefore here
125 if (LANGUAGE_SYSTEM == eLastDialogLanguage)
126 eLastDialogLanguage = Application::GetSettings().GetLanguageTag().getLanguageType();
128 LanguageType nSelectLang = LANGUAGE_UNDETERMINED;
129 nPos = m_xLanguageLB->find_id(eLastDialogLanguage);
130 if (nPos != -1)
131 nSelectLang = eLastDialogLanguage;
132 m_xLanguageLB->set_active_id(nSelectLang);
134 m_xLanguageLB->connect_changed(LINK(this, OfaAutoCorrDlg, SelectLanguageHdl));
136 if ( bOpenSmartTagOptions )
137 SetCurPageId("smarttags");
140 OfaAutoCorrDlg::~OfaAutoCorrDlg()
144 void OfaAutoCorrDlg::EnableLanguage(bool bEnable)
146 m_xLanguageBox->set_sensitive(bEnable);
149 static bool lcl_FindEntry(weld::TreeView& rLB, const OUString& rEntry,
150 CollatorWrapper const & rCmpClass)
152 int nCount = rLB.n_children();
153 int nSelPos = rLB.get_selected_index();
154 for (int i = 0; i < nCount; i++)
156 if (0 == rCmpClass.compareString(rEntry, rLB.get_text(i)))
158 rLB.select(i);
159 return true;
162 if (nSelPos != -1)
163 rLB.unselect(nSelPos);
164 return false;
167 IMPL_LINK_NOARG(OfaAutoCorrDlg, SelectLanguageHdl, weld::ComboBox&, void)
169 LanguageType eNewLang = m_xLanguageLB->get_active_id();
170 // save old settings and fill anew
171 if(eNewLang != eLastDialogLanguage)
173 OString sPageId = GetCurPageId();
174 if (sPageId == "replace")
175 static_cast<OfaAutocorrReplacePage*>(GetTabPage(sPageId))->SetLanguage(eNewLang);
176 else if (sPageId == "exceptions")
177 static_cast<OfaAutocorrExceptPage*>(GetTabPage(sPageId))->SetLanguage(eNewLang);
181 OfaAutocorrOptionsPage::OfaAutocorrOptionsPage(TabPageParent pParent, const SfxItemSet& rSet)
182 : SfxTabPage(pParent, "cui/ui/acoroptionspage.ui", "AutocorrectOptionsPage", &rSet)
183 , m_sInput(CuiResId(RID_SVXSTR_USE_REPLACE))
184 , m_sDoubleCaps(CuiResId(RID_SVXSTR_CPTL_STT_WORD))
185 , m_sStartCap(CuiResId(RID_SVXSTR_CPTL_STT_SENT))
186 , m_sBoldUnderline(CuiResId(RID_SVXSTR_BOLD_UNDER))
187 , m_sURL(CuiResId(RID_SVXSTR_DETECT_URL))
188 , m_sNoDblSpaces(CuiResId(RID_SVXSTR_NO_DBL_SPACES))
189 , m_sDash(CuiResId(RID_SVXSTR_DASH))
190 , m_sAccidentalCaps(CuiResId(RID_SVXSTR_CORRECT_ACCIDENTAL_CAPS_LOCK))
191 , m_xCheckLB(m_xBuilder->weld_tree_view("checklist"))
193 std::vector<int> aWidths;
194 aWidths.push_back(m_xCheckLB->get_checkbox_column_width());
195 m_xCheckLB->set_column_fixed_widths(aWidths);
196 m_xCheckLB->set_size_request(-1, m_xCheckLB->get_height_rows(10));
199 OfaAutocorrOptionsPage::~OfaAutocorrOptionsPage()
201 disposeOnce();
204 VclPtr<SfxTabPage> OfaAutocorrOptionsPage::Create(TabPageParent pParent,
205 const SfxItemSet* rSet)
207 return VclPtr<OfaAutocorrOptionsPage>::Create(pParent, *rSet);
210 #define CBCOL_FIRST 0
211 #define CBCOL_SECOND 1
212 #define CBCOL_BOTH 2
214 bool OfaAutocorrOptionsPage::FillItemSet( SfxItemSet* )
216 SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
217 ACFlags nFlags = pAutoCorrect->GetFlags();
219 int nPos = 0;
220 pAutoCorrect->SetAutoCorrFlag(ACFlags::Autocorrect, m_xCheckLB->get_toggle(nPos++, CBCOL_FIRST) == TRISTATE_TRUE);
221 pAutoCorrect->SetAutoCorrFlag(ACFlags::CapitalStartWord, m_xCheckLB->get_toggle(nPos++, CBCOL_FIRST) == TRISTATE_TRUE);
222 pAutoCorrect->SetAutoCorrFlag(ACFlags::CapitalStartSentence, m_xCheckLB->get_toggle(nPos++, CBCOL_FIRST) == TRISTATE_TRUE);
223 pAutoCorrect->SetAutoCorrFlag(ACFlags::ChgWeightUnderl, m_xCheckLB->get_toggle(nPos++, CBCOL_FIRST) == TRISTATE_TRUE);
224 pAutoCorrect->SetAutoCorrFlag(ACFlags::SetINetAttr, m_xCheckLB->get_toggle(nPos++, CBCOL_FIRST) == TRISTATE_TRUE);
225 pAutoCorrect->SetAutoCorrFlag(ACFlags::ChgToEnEmDash, m_xCheckLB->get_toggle(nPos++, CBCOL_FIRST) == TRISTATE_TRUE);
226 pAutoCorrect->SetAutoCorrFlag(ACFlags::IgnoreDoubleSpace, m_xCheckLB->get_toggle(nPos++, CBCOL_FIRST) == TRISTATE_TRUE);
227 pAutoCorrect->SetAutoCorrFlag(ACFlags::CorrectCapsLock, m_xCheckLB->get_toggle(nPos++, CBCOL_FIRST) == TRISTATE_TRUE);
229 bool bReturn = nFlags != pAutoCorrect->GetFlags();
230 if(bReturn )
232 SvxAutoCorrCfg& rCfg = SvxAutoCorrCfg::Get();
233 rCfg.SetModified();
234 rCfg.Commit();
236 return bReturn;
239 void OfaAutocorrOptionsPage::ActivatePage( const SfxItemSet& )
241 static_cast<OfaAutoCorrDlg*>(GetDialogController())->EnableLanguage(false);
244 void OfaAutocorrOptionsPage::InsertEntry(const OUString& rTxt)
246 m_xCheckLB->append();
247 const int nRow = m_xCheckLB->n_children() - 1;
248 m_xCheckLB->set_toggle(nRow, TRISTATE_FALSE, CBCOL_FIRST);
249 m_xCheckLB->set_text(nRow, rTxt, 1);
252 void OfaAutocorrOptionsPage::Reset( const SfxItemSet* )
254 SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
255 const ACFlags nFlags = pAutoCorrect->GetFlags();
257 m_xCheckLB->freeze();
258 m_xCheckLB->clear();
260 InsertEntry(m_sInput);
261 InsertEntry(m_sDoubleCaps);
262 InsertEntry(m_sStartCap);
263 InsertEntry(m_sBoldUnderline);
264 InsertEntry(m_sURL);
265 InsertEntry(m_sDash);
266 InsertEntry(m_sNoDblSpaces);
267 InsertEntry(m_sAccidentalCaps);
269 int nPos = 0;
270 m_xCheckLB->set_toggle( nPos++, bool(nFlags & ACFlags::Autocorrect) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST );
271 m_xCheckLB->set_toggle( nPos++, bool(nFlags & ACFlags::CapitalStartWord) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST );
272 m_xCheckLB->set_toggle( nPos++, bool(nFlags & ACFlags::CapitalStartSentence) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST );
273 m_xCheckLB->set_toggle( nPos++, bool(nFlags & ACFlags::ChgWeightUnderl) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST );
274 m_xCheckLB->set_toggle( nPos++, bool(nFlags & ACFlags::SetINetAttr) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST );
275 m_xCheckLB->set_toggle( nPos++, bool(nFlags & ACFlags::ChgToEnEmDash) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST );
276 m_xCheckLB->set_toggle( nPos++, bool(nFlags & ACFlags::IgnoreDoubleSpace) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST );
277 m_xCheckLB->set_toggle( nPos++, bool(nFlags & ACFlags::CorrectCapsLock) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST );
279 m_xCheckLB->thaw();
282 /*********************************************************************/
283 /* */
284 /* helping struct for dUserData of the Checklistbox */
285 /* */
286 /*********************************************************************/
288 struct ImpUserData
290 OUString *pString;
291 vcl::Font *pFont;
293 ImpUserData(OUString* pText, vcl::Font* pFnt)
294 { pString = pText; pFont = pFnt;}
298 /*********************************************************************/
299 /* */
300 /* dialog for per cent settings */
301 /* */
302 /*********************************************************************/
304 class OfaAutoFmtPrcntSet : public weld::GenericDialogController
306 std::unique_ptr<weld::MetricSpinButton> m_xPrcntMF;
307 public:
308 explicit OfaAutoFmtPrcntSet(weld::Window* pParent)
309 : GenericDialogController(pParent, "cui/ui/percentdialog.ui", "PercentDialog")
310 , m_xPrcntMF(m_xBuilder->weld_metric_spin_button("margin", FieldUnit::PERCENT))
314 weld::MetricSpinButton& GetPrcntFld()
316 return *m_xPrcntMF;
320 /*********************************************************************/
321 /* */
322 /* use TabPage autoformat */
323 /* */
324 /*********************************************************************/
326 enum OfaAutoFmtOptions
328 USE_REPLACE_TABLE,
329 CORR_UPPER,
330 BEGIN_UPPER,
331 BOLD_UNDERLINE,
332 DETECT_URL,
333 REPLACE_DASHES,
334 DEL_SPACES_AT_STT_END,
335 DEL_SPACES_BETWEEN_LINES,
336 IGNORE_DBLSPACE,
337 CORRECT_CAPS_LOCK,
338 APPLY_NUMBERING,
339 INSERT_BORDER,
340 CREATE_TABLE,
341 REPLACE_STYLES,
342 DEL_EMPTY_NODE,
343 REPLACE_USER_COLL,
344 REPLACE_BULLETS,
345 MERGE_SINGLE_LINE_PARA
348 OfaSwAutoFmtOptionsPage::OfaSwAutoFmtOptionsPage(TabPageParent pParent,
349 const SfxItemSet& rSet )
350 : SfxTabPage(pParent, "cui/ui/applyautofmtpage.ui", "ApplyAutoFmtPage", &rSet)
351 , sDeleteEmptyPara(CuiResId(RID_SVXSTR_DEL_EMPTY_PARA))
352 , sUseReplaceTbl(CuiResId(RID_SVXSTR_USE_REPLACE))
353 , sCapitalStartWord(CuiResId(RID_SVXSTR_CPTL_STT_WORD))
354 , sCapitalStartSentence(CuiResId(RID_SVXSTR_CPTL_STT_SENT))
355 , sUserStyle(CuiResId(RID_SVXSTR_USER_STYLE))
356 , sBullet(CuiResId(RID_SVXSTR_BULLET))
357 , sBoldUnder(CuiResId(RID_SVXSTR_BOLD_UNDER))
358 , sNoDblSpaces(CuiResId(RID_SVXSTR_NO_DBL_SPACES))
359 , sCorrectCapsLock(CuiResId(RID_SVXSTR_CORRECT_ACCIDENTAL_CAPS_LOCK))
360 , sDetectURL(CuiResId(RID_SVXSTR_DETECT_URL))
361 , sDash(CuiResId(RID_SVXSTR_DASH))
362 , sRightMargin(CuiResId(RID_SVXSTR_RIGHT_MARGIN))
363 , sNum(CuiResId(RID_SVXSTR_NUM))
364 , sBorder(CuiResId(RID_SVXSTR_BORDER))
365 , sTable(CuiResId(RID_SVXSTR_CREATE_TABLE))
366 , sReplaceTemplates(CuiResId(RID_SVXSTR_REPLACE_TEMPLATES))
367 , sDelSpaceAtSttEnd(CuiResId(RID_SVXSTR_DEL_SPACES_AT_STT_END))
368 , sDelSpaceBetweenLines(CuiResId(RID_SVXSTR_DEL_SPACES_BETWEEN_LINES))
369 , nPercent(50)
370 , m_xCheckLB(m_xBuilder->weld_tree_view("list"))
371 , m_xEditPB(m_xBuilder->weld_button("edit"))
373 m_xCheckLB->connect_changed(LINK(this, OfaSwAutoFmtOptionsPage, SelectHdl));
374 m_xCheckLB->connect_row_activated(LINK(this, OfaSwAutoFmtOptionsPage, DoubleClickEditHdl));
376 std::vector<int> aWidths;
377 aWidths.push_back(m_xCheckLB->get_pixel_size(m_xCheckLB->get_column_title(0)).Width() * 2);
378 aWidths.push_back(m_xCheckLB->get_pixel_size(m_xCheckLB->get_column_title(1)).Width() * 2);
379 m_xCheckLB->set_column_fixed_widths(aWidths);
381 m_xEditPB->connect_clicked(LINK(this, OfaSwAutoFmtOptionsPage, EditHdl));
384 void OfaSwAutoFmtOptionsPage::CreateEntry(const OUString& rTxt, sal_uInt16 nCol)
386 m_xCheckLB->append();
387 const int nRow = m_xCheckLB->n_children() - 1;
388 if (nCol == CBCOL_FIRST || nCol == CBCOL_BOTH)
389 m_xCheckLB->set_toggle(nRow, TRISTATE_FALSE, CBCOL_FIRST);
390 if (nCol == CBCOL_SECOND || nCol == CBCOL_BOTH)
391 m_xCheckLB->set_toggle(nRow, TRISTATE_FALSE, CBCOL_SECOND);
392 m_xCheckLB->set_text(nRow, rTxt, 2);
395 OfaSwAutoFmtOptionsPage::~OfaSwAutoFmtOptionsPage()
397 disposeOnce();
400 VclPtr<SfxTabPage> OfaSwAutoFmtOptionsPage::Create(TabPageParent pParent,
401 const SfxItemSet* rAttrSet)
403 return VclPtr<OfaSwAutoFmtOptionsPage>::Create(pParent, *rAttrSet);
406 bool OfaSwAutoFmtOptionsPage::FillItemSet( SfxItemSet* )
408 bool bModified = false;
409 SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
410 SvxSwAutoFormatFlags *pOpt = &pAutoCorrect->GetSwFlags();
411 ACFlags nFlags = pAutoCorrect->GetFlags();
413 bool bCheck = m_xCheckLB->get_toggle(USE_REPLACE_TABLE, CBCOL_FIRST) == TRISTATE_TRUE;
414 bModified |= pOpt->bAutoCorrect != bCheck;
415 pOpt->bAutoCorrect = bCheck;
416 pAutoCorrect->SetAutoCorrFlag(ACFlags::Autocorrect,
417 m_xCheckLB->get_toggle(USE_REPLACE_TABLE, CBCOL_SECOND) == TRISTATE_TRUE);
419 bCheck = m_xCheckLB->get_toggle(CORR_UPPER, CBCOL_FIRST) == TRISTATE_TRUE;
420 bModified |= pOpt->bCapitalStartWord != bCheck;
421 pOpt->bCapitalStartWord = bCheck;
422 pAutoCorrect->SetAutoCorrFlag(ACFlags::CapitalStartWord,
423 m_xCheckLB->get_toggle(CORR_UPPER, CBCOL_SECOND) == TRISTATE_TRUE);
425 bCheck = m_xCheckLB->get_toggle(BEGIN_UPPER, CBCOL_FIRST) == TRISTATE_TRUE;
426 bModified |= pOpt->bCapitalStartSentence != bCheck;
427 pOpt->bCapitalStartSentence = bCheck;
428 pAutoCorrect->SetAutoCorrFlag(ACFlags::CapitalStartSentence,
429 m_xCheckLB->get_toggle(BEGIN_UPPER, CBCOL_SECOND) == TRISTATE_TRUE);
431 bCheck = m_xCheckLB->get_toggle(BOLD_UNDERLINE, CBCOL_FIRST) == TRISTATE_TRUE;
432 bModified |= pOpt->bChgWeightUnderl != bCheck;
433 pOpt->bChgWeightUnderl = bCheck;
434 pAutoCorrect->SetAutoCorrFlag(ACFlags::ChgWeightUnderl,
435 m_xCheckLB->get_toggle(BOLD_UNDERLINE, CBCOL_SECOND) == TRISTATE_TRUE);
437 pAutoCorrect->SetAutoCorrFlag(ACFlags::IgnoreDoubleSpace,
438 m_xCheckLB->get_toggle(IGNORE_DBLSPACE, CBCOL_SECOND) == TRISTATE_TRUE);
440 pAutoCorrect->SetAutoCorrFlag(ACFlags::CorrectCapsLock,
441 m_xCheckLB->get_toggle(CORRECT_CAPS_LOCK, CBCOL_SECOND) == TRISTATE_TRUE);
443 bCheck = m_xCheckLB->get_toggle(DETECT_URL, CBCOL_FIRST) == TRISTATE_TRUE;
444 bModified |= pOpt->bSetINetAttr != bCheck;
445 pOpt->bSetINetAttr = bCheck;
446 pAutoCorrect->SetAutoCorrFlag(ACFlags::SetINetAttr,
447 m_xCheckLB->get_toggle(DETECT_URL, CBCOL_SECOND) == TRISTATE_TRUE);
449 bCheck = m_xCheckLB->get_toggle(DEL_EMPTY_NODE, CBCOL_FIRST) == TRISTATE_TRUE;
450 bModified |= pOpt->bDelEmptyNode != bCheck;
451 pOpt->bDelEmptyNode = bCheck;
453 bCheck = m_xCheckLB->get_toggle(REPLACE_USER_COLL, CBCOL_FIRST) == TRISTATE_TRUE;
454 bModified |= pOpt->bChgUserColl != bCheck;
455 pOpt->bChgUserColl = bCheck;
457 bCheck = m_xCheckLB->get_toggle(REPLACE_BULLETS, CBCOL_FIRST) == TRISTATE_TRUE;
458 bModified |= pOpt->bChgEnumNum != bCheck;
459 pOpt->bChgEnumNum = bCheck;
460 bModified |= aBulletFont != pOpt->aBulletFont;
461 pOpt->aBulletFont = aBulletFont;
462 bModified |= !comphelper::string::equals(sBulletChar, pOpt->cBullet);
463 pOpt->cBullet = sBulletChar[0];
465 bModified |= aByInputBulletFont != pOpt->aByInputBulletFont;
466 bModified |= !comphelper::string::equals(sByInputBulletChar, pOpt->cByInputBullet);
467 pOpt->aByInputBulletFont = aByInputBulletFont;
468 pOpt->cByInputBullet = sByInputBulletChar[0];
470 bCheck = m_xCheckLB->get_toggle(MERGE_SINGLE_LINE_PARA, CBCOL_FIRST) == TRISTATE_TRUE;
471 bModified |= pOpt->bRightMargin != bCheck;
472 pOpt->bRightMargin = bCheck;
473 bModified |= nPercent != pOpt->nRightMargin;
474 pOpt->nRightMargin = static_cast<sal_uInt8>(nPercent);
476 bCheck = m_xCheckLB->get_toggle(APPLY_NUMBERING, CBCOL_SECOND) == TRISTATE_TRUE;
477 bModified |= pOpt->bSetNumRule != bCheck;
478 pOpt->bSetNumRule = bCheck;
480 bCheck = m_xCheckLB->get_toggle(INSERT_BORDER, CBCOL_SECOND) == TRISTATE_TRUE;
481 bModified |= pOpt->bSetBorder != bCheck;
482 pOpt->bSetBorder = bCheck;
484 bCheck = m_xCheckLB->get_toggle(CREATE_TABLE, CBCOL_SECOND) == TRISTATE_TRUE;
485 bModified |= pOpt->bCreateTable != bCheck;
486 pOpt->bCreateTable = bCheck;
488 bCheck = m_xCheckLB->get_toggle(REPLACE_STYLES, CBCOL_SECOND) == TRISTATE_TRUE;
489 bModified |= pOpt->bReplaceStyles != bCheck;
490 pOpt->bReplaceStyles = bCheck;
492 bCheck = m_xCheckLB->get_toggle(REPLACE_DASHES, CBCOL_FIRST) == TRISTATE_TRUE;
493 bModified |= pOpt->bChgToEnEmDash != bCheck;
494 pOpt->bChgToEnEmDash = bCheck;
495 pAutoCorrect->SetAutoCorrFlag(ACFlags::ChgToEnEmDash,
496 m_xCheckLB->get_toggle(REPLACE_DASHES, CBCOL_SECOND) == TRISTATE_TRUE);
498 bCheck = m_xCheckLB->get_toggle(DEL_SPACES_AT_STT_END, CBCOL_FIRST) == TRISTATE_TRUE;
499 bModified |= pOpt->bAFormatDelSpacesAtSttEnd != bCheck;
500 pOpt->bAFormatDelSpacesAtSttEnd = bCheck;
501 bCheck = m_xCheckLB->get_toggle(DEL_SPACES_AT_STT_END, CBCOL_SECOND) == TRISTATE_TRUE;
502 bModified |= pOpt->bAFormatByInpDelSpacesAtSttEnd != bCheck;
503 pOpt->bAFormatByInpDelSpacesAtSttEnd = bCheck;
505 bCheck = m_xCheckLB->get_toggle(DEL_SPACES_BETWEEN_LINES, CBCOL_FIRST) == TRISTATE_TRUE;
506 bModified |= pOpt->bAFormatDelSpacesBetweenLines != bCheck;
507 pOpt->bAFormatDelSpacesBetweenLines = bCheck;
508 bCheck = m_xCheckLB->get_toggle(DEL_SPACES_BETWEEN_LINES, CBCOL_SECOND) == TRISTATE_TRUE;
509 bModified |= pOpt->bAFormatByInpDelSpacesBetweenLines != bCheck;
510 pOpt->bAFormatByInpDelSpacesBetweenLines = bCheck;
512 if(bModified || nFlags != pAutoCorrect->GetFlags())
514 SvxAutoCorrCfg& rCfg = SvxAutoCorrCfg::Get();
515 rCfg.SetModified();
516 rCfg.Commit();
519 return true;
522 void OfaSwAutoFmtOptionsPage::ActivatePage( const SfxItemSet& )
524 static_cast<OfaAutoCorrDlg*>(GetDialogController())->EnableLanguage(false);
527 void OfaSwAutoFmtOptionsPage::Reset( const SfxItemSet* )
529 SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
530 SvxSwAutoFormatFlags *pOpt = &pAutoCorrect->GetSwFlags();
531 const ACFlags nFlags = pAutoCorrect->GetFlags();
533 aBulletFont = pOpt->aBulletFont;
534 sBulletChar = OUString(pOpt->cBullet);
536 aByInputBulletFont = pOpt->aByInputBulletFont;
537 sByInputBulletChar = OUString( pOpt->cByInputBullet );
539 nPercent = pOpt->nRightMargin;
540 sMargin = unicode::formatPercent(nPercent, Application::GetSettings().GetUILanguageTag());
542 m_xCheckLB->freeze();
543 m_xCheckLB->clear();
545 // The following entries have to be inserted in the same order
546 // as in the OfaAutoFmtOptions-enum!
547 CreateEntry(sUseReplaceTbl, CBCOL_BOTH );
548 CreateEntry(sCapitalStartWord, CBCOL_BOTH );
549 CreateEntry(sCapitalStartSentence, CBCOL_BOTH );
550 CreateEntry(sBoldUnder, CBCOL_BOTH );
551 CreateEntry(sDetectURL, CBCOL_BOTH );
552 CreateEntry(sDash, CBCOL_BOTH );
553 CreateEntry(sDelSpaceAtSttEnd, CBCOL_BOTH );
554 CreateEntry(sDelSpaceBetweenLines, CBCOL_BOTH );
556 CreateEntry(sNoDblSpaces, CBCOL_SECOND);
557 CreateEntry(sCorrectCapsLock, CBCOL_SECOND);
558 CreateEntry(sNum.replaceFirst("%1", sBulletChar), CBCOL_SECOND);
559 CreateEntry(sBorder, CBCOL_SECOND);
560 CreateEntry(sTable, CBCOL_SECOND);
561 CreateEntry(sReplaceTemplates, CBCOL_SECOND);
562 CreateEntry(sDeleteEmptyPara, CBCOL_FIRST );
563 CreateEntry(sUserStyle, CBCOL_FIRST );
564 CreateEntry(sBullet.replaceFirst("%1", sByInputBulletChar), CBCOL_FIRST);
565 CreateEntry(sRightMargin.replaceFirst("%1", sMargin), CBCOL_FIRST);
567 m_xCheckLB->set_toggle(USE_REPLACE_TABLE, pOpt->bAutoCorrect ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
568 m_xCheckLB->set_toggle(USE_REPLACE_TABLE, bool(nFlags & ACFlags::Autocorrect) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
569 m_xCheckLB->set_toggle(CORR_UPPER, pOpt->bCapitalStartWord ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
570 m_xCheckLB->set_toggle(CORR_UPPER, bool(nFlags & ACFlags::CapitalStartWord) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
571 m_xCheckLB->set_toggle(BEGIN_UPPER, pOpt->bCapitalStartSentence ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
572 m_xCheckLB->set_toggle(BEGIN_UPPER, bool(nFlags & ACFlags::CapitalStartSentence) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
573 m_xCheckLB->set_toggle(BOLD_UNDERLINE, pOpt->bChgWeightUnderl ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
574 m_xCheckLB->set_toggle(BOLD_UNDERLINE, bool(nFlags & ACFlags::ChgWeightUnderl) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
575 m_xCheckLB->set_toggle(DETECT_URL, pOpt->bSetINetAttr ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
576 m_xCheckLB->set_toggle(DETECT_URL, bool(nFlags & ACFlags::SetINetAttr) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
577 m_xCheckLB->set_toggle(REPLACE_DASHES, pOpt->bChgToEnEmDash ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
578 m_xCheckLB->set_toggle(REPLACE_DASHES, bool(nFlags & ACFlags::ChgToEnEmDash) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
579 m_xCheckLB->set_toggle(DEL_SPACES_AT_STT_END, pOpt->bAFormatDelSpacesAtSttEnd ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
580 m_xCheckLB->set_toggle(DEL_SPACES_AT_STT_END, pOpt->bAFormatByInpDelSpacesAtSttEnd ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
581 m_xCheckLB->set_toggle(DEL_SPACES_BETWEEN_LINES, pOpt->bAFormatDelSpacesBetweenLines ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
582 m_xCheckLB->set_toggle(DEL_SPACES_BETWEEN_LINES, pOpt->bAFormatByInpDelSpacesBetweenLines ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
583 m_xCheckLB->set_toggle(IGNORE_DBLSPACE, bool(nFlags & ACFlags::IgnoreDoubleSpace) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
584 m_xCheckLB->set_toggle(CORRECT_CAPS_LOCK, bool(nFlags & ACFlags::CorrectCapsLock) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
585 m_xCheckLB->set_toggle(APPLY_NUMBERING, pOpt->bSetNumRule ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
586 m_xCheckLB->set_toggle(INSERT_BORDER, pOpt->bSetBorder ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
587 m_xCheckLB->set_toggle(CREATE_TABLE, pOpt->bCreateTable ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
588 m_xCheckLB->set_toggle(REPLACE_STYLES, pOpt->bReplaceStyles ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
589 m_xCheckLB->set_toggle(DEL_EMPTY_NODE, pOpt->bDelEmptyNode ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
590 m_xCheckLB->set_toggle(REPLACE_USER_COLL, pOpt->bChgUserColl ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
591 m_xCheckLB->set_toggle(REPLACE_BULLETS, pOpt->bChgEnumNum ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
592 m_xCheckLB->set_toggle(MERGE_SINGLE_LINE_PARA, pOpt->bRightMargin ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
594 ImpUserData* pUserData = new ImpUserData(&sBulletChar, &aBulletFont);
595 OUString sId(OUString::number(reinterpret_cast<sal_Int64>(pUserData)));
596 m_xCheckLB->set_id(REPLACE_BULLETS, sId);
598 pUserData = new ImpUserData(&sMargin, nullptr);
599 sId = OUString::number(reinterpret_cast<sal_Int64>(pUserData));
600 m_xCheckLB->set_id(MERGE_SINGLE_LINE_PARA, sId);
602 ImpUserData* pUserData2 = new ImpUserData(&sByInputBulletChar, &aByInputBulletFont);
603 sId = OUString::number(reinterpret_cast<sal_Int64>(pUserData2));
604 m_xCheckLB->set_id(APPLY_NUMBERING, sId);
606 m_xCheckLB->thaw();
609 IMPL_LINK(OfaSwAutoFmtOptionsPage, SelectHdl, weld::TreeView&, rBox, void)
611 m_xEditPB->set_sensitive(rBox.get_selected_id().toInt64() != 0);
614 IMPL_LINK_NOARG(OfaSwAutoFmtOptionsPage, DoubleClickEditHdl, weld::TreeView&, void)
616 EditHdl(*m_xEditPB);
619 IMPL_LINK_NOARG(OfaSwAutoFmtOptionsPage, EditHdl, weld::Button&, void)
621 int nSelEntryPos = m_xCheckLB->get_selected_index();
622 if (nSelEntryPos == REPLACE_BULLETS || nSelEntryPos == APPLY_NUMBERING)
624 SvxCharacterMap aMapDlg(GetDialogFrameWeld(), nullptr, nullptr);
625 ImpUserData* pUserData = reinterpret_cast<ImpUserData*>(m_xCheckLB->get_id(nSelEntryPos).toInt64());
626 aMapDlg.SetCharFont(*pUserData->pFont);
627 aMapDlg.SetChar( (*pUserData->pString)[0] );
628 if (RET_OK == aMapDlg.run())
630 const vcl::Font& aFont(aMapDlg.GetCharFont());
631 *pUserData->pFont = aFont;
632 sal_UCS4 aChar = aMapDlg.GetChar();
633 // using the UCS4 constructor
634 OUString aOUStr( &aChar, 1 );
635 *pUserData->pString = aOUStr;
636 if (nSelEntryPos == REPLACE_BULLETS)
637 m_xCheckLB->set_text(nSelEntryPos, sNum.replaceFirst("%1", aOUStr), 2);
638 else
639 m_xCheckLB->set_text(nSelEntryPos, sBullet.replaceFirst("%1", aOUStr), 2);
642 else if( MERGE_SINGLE_LINE_PARA == nSelEntryPos )
644 // dialog for per cent settings
645 OfaAutoFmtPrcntSet aDlg(GetDialogFrameWeld());
646 aDlg.GetPrcntFld().set_value(nPercent, FieldUnit::PERCENT);
647 if (aDlg.run() == RET_OK)
649 nPercent = static_cast<sal_uInt16>(aDlg.GetPrcntFld().get_value(FieldUnit::PERCENT));
650 sMargin = unicode::formatPercent(nPercent, Application::GetSettings().GetUILanguageTag());
651 m_xCheckLB->set_text(nSelEntryPos, sRightMargin.replaceFirst("%1", sMargin), 2);
657 OfaAutocorrReplacePage::OfaAutocorrReplacePage(TabPageParent pParent,
658 const SfxItemSet& rSet)
659 : SfxTabPage(pParent, "cui/ui/acorreplacepage.ui", "AcorReplacePage", &rSet)
660 , eLang(eLastDialogLanguage)
661 , bHasSelectionText(false)
662 , bFirstSelect(true)
663 , bReplaceEditChanged(false)
664 , bSWriter(true)
665 , m_xTextOnlyCB(m_xBuilder->weld_check_button("textonly"))
666 , m_xShortED(m_xBuilder->weld_entry("origtext"))
667 , m_xReplaceED(m_xBuilder->weld_entry("newtext"))
668 , m_xReplaceTLB(m_xBuilder->weld_tree_view("tabview"))
669 , m_xNewReplacePB(m_xBuilder->weld_button("new"))
670 , m_xReplacePB(m_xBuilder->weld_button("replace"))
671 , m_xDeleteReplacePB(m_xBuilder->weld_button("delete"))
673 sNew = m_xNewReplacePB->get_label();
674 sModify = m_xReplacePB->get_label();
675 // tdf#125348 set some small but fixed initial width size, final width will
676 // depend on the size of the entry boxes
677 m_xReplaceTLB->set_size_request(42, m_xReplaceTLB->get_height_rows(10));
679 SfxModule *pMod = SfxApplication::GetModule(SfxToolsModule::Writer);
680 bSWriter = pMod == SfxModule::GetActiveModule();
682 LanguageTag aLanguageTag( eLastDialogLanguage );
683 pCompareClass.reset( new CollatorWrapper( comphelper::getProcessComponentContext() ) );
684 pCompareClass->loadDefaultCollator( aLanguageTag.getLocale(), 0 );
685 pCharClass.reset( new CharClass( aLanguageTag ) );
687 auto nColWidth = m_xReplaceTLB->get_approximate_digit_width() * 32;
688 m_aReplaceFixedWidths.push_back(nColWidth);
689 m_aReplaceFixedWidths.push_back(nColWidth);
691 m_xReplaceTLB->connect_changed( LINK(this, OfaAutocorrReplacePage, SelectHdl) );
692 m_xNewReplacePB->connect_clicked( LINK(this, OfaAutocorrReplacePage, NewDelButtonHdl) );
693 m_xDeleteReplacePB->connect_clicked( LINK(this, OfaAutocorrReplacePage, NewDelButtonHdl) );
694 m_xShortED->connect_changed( LINK(this, OfaAutocorrReplacePage, ModifyHdl) );
695 m_xReplaceED->connect_changed( LINK(this, OfaAutocorrReplacePage, ModifyHdl) );
696 m_xShortED->connect_activate( LINK(this, OfaAutocorrReplacePage, NewDelActionHdl) );
697 m_xReplaceED->connect_activate( LINK(this, OfaAutocorrReplacePage, NewDelActionHdl) );
698 m_xShortED->connect_size_allocate(LINK(this, OfaAutocorrReplacePage, EntrySizeAllocHdl));
699 m_xReplaceED->connect_size_allocate(LINK(this, OfaAutocorrReplacePage, EntrySizeAllocHdl));
702 OfaAutocorrReplacePage::~OfaAutocorrReplacePage()
704 disposeOnce();
707 void OfaAutocorrReplacePage::dispose()
709 aDoubleStringTable.clear();
710 aChangesTable.clear();
712 pCompareClass.reset();
713 pCharClass.reset();
715 SfxTabPage::dispose();
718 VclPtr<SfxTabPage> OfaAutocorrReplacePage::Create(TabPageParent pParent, const SfxItemSet* rSet)
720 return VclPtr<OfaAutocorrReplacePage>::Create(pParent, *rSet);
723 void OfaAutocorrReplacePage::ActivatePage( const SfxItemSet& )
725 if(eLang != eLastDialogLanguage)
726 SetLanguage(eLastDialogLanguage);
727 static_cast<OfaAutoCorrDlg*>(GetDialogController())->EnableLanguage(true);
730 DeactivateRC OfaAutocorrReplacePage::DeactivatePage( SfxItemSet* )
732 return DeactivateRC::LeavePage;
735 bool OfaAutocorrReplacePage::FillItemSet( SfxItemSet* )
737 SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
739 for (StringChangeTable::reverse_iterator it = aChangesTable.rbegin(); it != aChangesTable.rend(); ++it)
741 LanguageType eCurrentLang = it->first;
742 StringChangeList& rStringChangeList = it->second;
743 std::vector<SvxAutocorrWord> aDeleteWords;
744 std::vector<SvxAutocorrWord> aNewWords;
746 for (DoubleString & deleteEntry : rStringChangeList.aDeletedEntries)
748 SvxAutocorrWord aDeleteWord( deleteEntry.sShort, deleteEntry.sLong );
749 aDeleteWords.push_back( aDeleteWord );
752 for (DoubleString & newEntry : rStringChangeList.aNewEntries)
754 //fdo#67697 if the user data is set then we want to retain the
755 //source formatting of the entry, so don't use the optimized
756 //text-only MakeCombinedChanges for this entry
757 bool bKeepSourceFormatting = newEntry.pUserData == &bHasSelectionText;
758 if (bKeepSourceFormatting)
760 pAutoCorrect->PutText(newEntry.sShort, *SfxObjectShell::Current(), eCurrentLang);
761 continue;
764 SvxAutocorrWord aNewWord( newEntry.sShort, newEntry.sLong );
765 aNewWords.push_back( aNewWord );
767 pAutoCorrect->MakeCombinedChanges( aNewWords, aDeleteWords, eCurrentLang );
769 aChangesTable.clear();
770 return false;
773 void OfaAutocorrReplacePage::RefillReplaceBox(bool bFromReset,
774 LanguageType eOldLanguage,
775 LanguageType eNewLanguage)
777 eLang = eNewLanguage;
778 if(bFromReset)
780 aDoubleStringTable.clear();
781 aChangesTable.clear();
783 else
785 DoubleStringArray* pArray;
786 if(aDoubleStringTable.find(eOldLanguage) != aDoubleStringTable.end())
788 pArray = &aDoubleStringTable[eOldLanguage];
789 pArray->clear();
791 else
793 pArray = &aDoubleStringTable[eOldLanguage]; // create new array
796 sal_uInt32 nListBoxCount = m_xReplaceTLB->n_children();
797 sal_uInt32 i;
798 for(i = 0; i < nListBoxCount; i++)
800 pArray->push_back(DoubleString());
801 DoubleString& rDouble = (*pArray)[pArray->size() - 1];
802 rDouble.sShort = m_xReplaceTLB->get_text(i, 0);
803 rDouble.sLong = m_xReplaceTLB->get_text(i, 1);
804 rDouble.pUserData = reinterpret_cast<void*>(m_xReplaceTLB->get_id(i).toInt64());
808 if( !bSWriter )
809 aFormatText.clear();
811 if (aDoubleStringTable.find(eLang) != aDoubleStringTable.end())
813 DoubleStringArray& rArray = aDoubleStringTable[eNewLanguage];
815 m_xReplaceTLB->bulk_insert_for_each(rArray.size(), [this, &rArray](weld::TreeIter& rIter, int nIndex) {
816 DoubleString &rDouble = rArray[nIndex];
817 bool bTextOnly = nullptr == rDouble.pUserData;
818 // formatted text is only in Writer
819 if (bSWriter || bTextOnly)
821 if (!bTextOnly)
823 // that means: with format info or even with selection text
824 OUString sId = OUString::number(reinterpret_cast<sal_Int64>(rDouble.pUserData));
825 m_xReplaceTLB->set_id(rIter, sId);
827 m_xReplaceTLB->set_text(rIter, rDouble.sShort, 0);
828 m_xReplaceTLB->set_text(rIter, rDouble.sLong, 1);
830 else
832 aFormatText.insert(rDouble.sShort);
834 }, &m_aReplaceFixedWidths);
836 else
838 SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
839 SvxAutocorrWordList* pWordList = pAutoCorrect->LoadAutocorrWordList(eLang);
840 SvxAutocorrWordList::Content aContent = pWordList->getSortedContent();
841 m_xReplaceTLB->bulk_insert_for_each(aContent.size(), [this, &aContent](weld::TreeIter& rIter, int nIndex) {
842 auto const& elem = aContent[nIndex];
843 bool bTextOnly = elem->IsTextOnly();
844 // formatted text is only in Writer
845 if (bSWriter || bTextOnly)
847 if (!bTextOnly)
849 // that means: with format info or even with selection text
850 OUString sId = OUString::number(reinterpret_cast<sal_Int64>(m_xTextOnlyCB.get()));
851 m_xReplaceTLB->set_id(rIter, sId);
853 m_xReplaceTLB->set_text(rIter, elem->GetShort(), 0);
854 m_xReplaceTLB->set_text(rIter, elem->GetLong(), 1);
856 else
858 aFormatText.insert(elem->GetShort());
860 }, &m_aReplaceFixedWidths);
861 m_xNewReplacePB->set_sensitive(false);
862 m_xDeleteReplacePB->set_sensitive(false);
865 SfxViewShell* pViewShell = SfxViewShell::Current();
866 if (pViewShell && pViewShell->HasSelection())
868 bHasSelectionText = true;
869 const OUString sSelection( pViewShell->GetSelectionText() );
870 m_xReplaceED->set_text(sSelection);
871 m_xTextOnlyCB->set_active(!bSWriter);
872 m_xTextOnlyCB->set_sensitive(bSWriter && !sSelection.isEmpty());
874 else
876 m_xTextOnlyCB->set_active(true);
877 m_xTextOnlyCB->set_sensitive(false);
881 void OfaAutocorrReplacePage::Reset( const SfxItemSet* )
883 RefillReplaceBox(true, eLang, eLang);
884 m_xShortED->grab_focus();
887 void OfaAutocorrReplacePage::SetLanguage(LanguageType eSet)
889 //save old settings and refill
890 if(eSet != eLang)
892 RefillReplaceBox(false, eLang, eSet);
893 eLastDialogLanguage = eSet;
895 LanguageTag aLanguageTag( eLastDialogLanguage );
896 pCompareClass.reset( new CollatorWrapper( comphelper::getProcessComponentContext() ) );
897 pCompareClass->loadDefaultCollator( aLanguageTag.getLocale(), 0 );
898 pCharClass.reset( new CharClass( aLanguageTag ) );
899 ModifyHdl(*m_xShortED);
903 IMPL_LINK(OfaAutocorrReplacePage, SelectHdl, weld::TreeView&, rBox, void)
905 if(!bFirstSelect || !bHasSelectionText)
907 int nEntry = rBox.get_selected_index();
908 OUString sTmpShort(rBox.get_text(nEntry, 0));
909 // if the text is set via ModifyHdl, the cursor is always at the beginning
910 // of a word, although you're editing here
911 bool bSameContent = 0 == pCompareClass->compareString(sTmpShort, m_xShortED->get_text());
912 int nStartPos, nEndPos;
913 m_xShortED->get_selection_bounds(nStartPos, nEndPos);
914 if (m_xShortED->get_text() != sTmpShort)
916 m_xShortED->set_text(sTmpShort);
917 // if it was only a different notation, the selection has to be set again
918 if (bSameContent)
920 m_xShortED->select_region(nStartPos, nEndPos);
923 m_xReplaceED->set_text(rBox.get_text(nEntry, 1));
924 // with UserData there is a Formatinfo
925 m_xTextOnlyCB->set_active(rBox.get_id(nEntry).isEmpty());
927 else
929 bFirstSelect = false;
932 m_xNewReplacePB->set_sensitive(false);
933 m_xDeleteReplacePB->set_sensitive(true);
936 void OfaAutocorrReplacePage::NewEntry(const OUString& sShort, const OUString& sLong, bool bKeepSourceFormatting)
938 DoubleStringArray& rNewArray = aChangesTable[eLang].aNewEntries;
939 for (size_t i = 0; i < rNewArray.size(); i++)
941 if (rNewArray[i].sShort == sShort)
943 rNewArray.erase(rNewArray.begin() + i);
944 break;
948 DoubleStringArray& rDeletedArray = aChangesTable[eLang].aDeletedEntries;
949 for (size_t i = 0; i < rDeletedArray.size(); i++)
951 if (rDeletedArray[i].sShort == sShort)
953 rDeletedArray.erase(rDeletedArray.begin() + i);
954 break;
958 DoubleString aNewString = DoubleString();
959 aNewString.sShort = sShort;
960 aNewString.sLong = sLong;
961 rNewArray.push_back(aNewString);
962 if (bKeepSourceFormatting)
963 rNewArray.back().pUserData = &bHasSelectionText;
966 void OfaAutocorrReplacePage::DeleteEntry(const OUString& sShort, const OUString& sLong)
968 DoubleStringArray& rNewArray = aChangesTable[eLang].aNewEntries;
969 for (size_t i = 0; i < rNewArray.size(); i++)
971 if (rNewArray[i].sShort == sShort)
973 rNewArray.erase(rNewArray.begin() + i);
974 break;
978 DoubleStringArray& rDeletedArray = aChangesTable[eLang].aDeletedEntries;
979 for (size_t i = 0; i < rDeletedArray.size(); i++)
981 if (rDeletedArray[i].sShort == sShort)
983 rDeletedArray.erase(rDeletedArray.begin() + i);
984 break;
988 DoubleString aDeletedString = DoubleString();
989 aDeletedString.sShort = sShort;
990 aDeletedString.sLong = sLong;
991 rDeletedArray.push_back(aDeletedString);
994 IMPL_LINK(OfaAutocorrReplacePage, NewDelButtonHdl, weld::Button&, rBtn, void)
996 NewDelHdl(&rBtn);
999 IMPL_LINK(OfaAutocorrReplacePage, NewDelActionHdl, weld::Entry&, rEdit, bool)
1001 return NewDelHdl(&rEdit);
1004 IMPL_LINK_NOARG(OfaAutocorrReplacePage, EntrySizeAllocHdl, const Size&, void)
1006 m_aReplaceFixedWidths.clear();
1007 int x, y, width, height;
1008 if (m_xReplaceED->get_extents_relative_to(*m_xReplaceTLB, x, y, width, height))
1010 m_aReplaceFixedWidths.push_back(x);
1011 m_aReplaceFixedWidths.push_back(width - 1);
1012 m_xReplaceTLB->set_column_fixed_widths(m_aReplaceFixedWidths);
1016 bool OfaAutocorrReplacePage::NewDelHdl(const weld::Widget* pBtn)
1018 int nEntry = m_xReplaceTLB->get_selected_index();
1019 if (pBtn == m_xDeleteReplacePB.get())
1021 DBG_ASSERT( nEntry != -1, "no entry selected" );
1022 if (nEntry != -1)
1024 DeleteEntry(m_xReplaceTLB->get_text(nEntry, 0), m_xReplaceTLB->get_text(nEntry, 1));
1025 m_xReplaceTLB->remove(nEntry);
1026 ModifyHdl(*m_xShortED);
1027 return false;
1031 if (pBtn == m_xNewReplacePB.get() || m_xNewReplacePB->get_sensitive())
1033 OUString sEntry(m_xShortED->get_text());
1034 if (!sEntry.isEmpty() && (!m_xReplaceED->get_text().isEmpty() ||
1035 ( bHasSelectionText && bSWriter ) ))
1037 bool bKeepSourceFormatting = !bReplaceEditChanged && !m_xTextOnlyCB->get_active();
1039 NewEntry(m_xShortED->get_text(), m_xReplaceED->get_text(), bKeepSourceFormatting);
1040 m_xReplaceTLB->freeze();
1041 int nPos = -1;
1042 if (nEntry != -1)
1044 nPos = nEntry;
1045 m_xReplaceTLB->remove(nEntry);
1047 else
1049 int j;
1050 int nCount = m_xReplaceTLB->n_children();
1051 for (j = 0; j < nCount; ++j)
1053 if (0 >= pCompareClass->compareString(sEntry, m_xReplaceTLB->get_text(j, 0)))
1054 break;
1056 nPos = j;
1059 OUString sId;
1060 if (bKeepSourceFormatting)
1062 sId = OUString::number(reinterpret_cast<sal_Int64>(&bHasSelectionText)); // new formatted text
1065 m_xReplaceTLB->insert(nPos, sEntry, &sId, nullptr, nullptr);
1066 m_xReplaceTLB->set_text(nPos, m_xReplaceED->get_text(), 1);
1067 m_xReplaceTLB->thaw();
1068 m_xReplaceTLB->scroll_to_row(nPos);
1069 // if the request came from the ReplaceEdit, give focus to the ShortEdit
1070 if (m_xReplaceED->has_focus())
1072 m_xShortED->grab_focus();
1076 else
1078 // this can only be an enter in one of the two edit fields
1079 // which means EndDialog() - has to be evaluated in KeyInput
1080 return false;
1082 ModifyHdl(*m_xShortED);
1083 return true;
1086 IMPL_LINK(OfaAutocorrReplacePage, ModifyHdl, weld::Entry&, rEdt, void)
1088 std::unique_ptr<weld::TreeIter> xFirstSel(m_xReplaceTLB->make_iterator());
1089 bool bFirstSelIterSet = m_xReplaceTLB->get_selected(xFirstSel.get());
1090 bool bShort = &rEdt == m_xShortED.get();
1091 const OUString rEntry = rEdt.get_text();
1092 const OUString rRepString = m_xReplaceED->get_text();
1093 OUString aWordStr(pCharClass->lowercase(rEntry));
1095 if(bShort)
1097 if(!rEntry.isEmpty())
1099 bool bFound = false;
1100 bool bTmpSelEntry=false;
1102 m_xReplaceTLB->all_foreach([this, &rEntry, &rRepString, &bFound,
1103 &bTmpSelEntry, &bFirstSelIterSet,
1104 &xFirstSel, &aWordStr](weld::TreeIter& rIter){
1105 OUString aTestStr = m_xReplaceTLB->get_text(rIter, 0);
1106 if( pCompareClass->compareString(rEntry, aTestStr ) == 0 )
1108 if (!rRepString.isEmpty())
1109 bFirstSelect = true;
1110 m_xReplaceTLB->set_cursor(rIter);
1111 m_xReplaceTLB->copy_iterator(rIter, *xFirstSel);
1112 bFirstSelIterSet = true;
1113 m_xNewReplacePB->set_label(sModify);
1114 bFound = true;
1115 return true;
1117 else
1119 aTestStr = pCharClass->lowercase( aTestStr );
1120 if( aTestStr.startsWith(aWordStr) && !bTmpSelEntry )
1122 m_xReplaceTLB->scroll_to_row(rIter);
1123 bTmpSelEntry = true;
1126 return false;
1128 if( !bFound )
1130 m_xReplaceTLB->select(-1);
1131 bFirstSelIterSet = false;
1132 m_xNewReplacePB->set_label(sNew);
1133 if( bReplaceEditChanged )
1134 m_xTextOnlyCB->set_sensitive(false);
1136 m_xDeleteReplacePB->set_sensitive(bFound);
1138 else if (m_xReplaceTLB->n_children() > 0)
1140 m_xReplaceTLB->scroll_to_row(0);
1144 else if( !bShort )
1146 bReplaceEditChanged = true;
1147 if (bFirstSelIterSet)
1149 m_xNewReplacePB->set_label(sModify);
1153 const OUString& rShortTxt = m_xShortED->get_text();
1154 bool bEnableNew = !rShortTxt.isEmpty() &&
1155 ( !rRepString.isEmpty() ||
1156 ( bHasSelectionText && bSWriter )) &&
1157 ( !bFirstSelIterSet || rRepString !=
1158 m_xReplaceTLB->get_text(*xFirstSel, 1) );
1159 if( bEnableNew )
1161 for (auto const& elem : aFormatText)
1163 if(elem == rShortTxt)
1165 bEnableNew = false;
1166 break;
1170 m_xNewReplacePB->set_sensitive(bEnableNew);
1173 static bool lcl_FindInArray(std::vector<OUString>& rStrings, const OUString& rString)
1175 for (auto const& elem : rStrings)
1177 if(elem == rString)
1179 return true;
1182 return false;
1185 OfaAutocorrExceptPage::OfaAutocorrExceptPage(TabPageParent pParent, const SfxItemSet& rSet)
1186 : SfxTabPage(pParent, "cui/ui/acorexceptpage.ui", "AcorExceptPage", &rSet)
1187 , eLang(eLastDialogLanguage)
1188 , m_xAbbrevED(m_xBuilder->weld_entry("abbrev"))
1189 , m_xAbbrevLB(m_xBuilder->weld_tree_view("abbrevlist"))
1190 , m_xNewAbbrevPB(m_xBuilder->weld_button("newabbrev"))
1191 , m_xDelAbbrevPB(m_xBuilder->weld_button("delabbrev"))
1192 , m_xAutoAbbrevCB(m_xBuilder->weld_check_button("autoabbrev"))
1193 , m_xDoubleCapsED(m_xBuilder->weld_entry("double"))
1194 , m_xDoubleCapsLB(m_xBuilder->weld_tree_view("doublelist"))
1195 , m_xNewDoublePB(m_xBuilder->weld_button("newdouble"))
1196 , m_xDelDoublePB(m_xBuilder->weld_button("deldouble"))
1197 , m_xAutoCapsCB(m_xBuilder->weld_check_button("autodouble"))
1199 m_xAbbrevLB->make_sorted();
1200 m_xAbbrevLB->set_size_request(-1, m_xAbbrevLB->get_height_rows(6));
1202 m_xDoubleCapsLB->make_sorted();
1203 m_xDoubleCapsLB->set_size_request(-1, m_xDoubleCapsLB->get_height_rows(6));
1205 css::lang::Locale aLcl( LanguageTag::convertToLocale(eLastDialogLanguage ));
1206 pCompareClass.reset( new CollatorWrapper( comphelper::getProcessComponentContext() ) );
1207 pCompareClass->loadDefaultCollator( aLcl, 0 );
1209 m_xNewAbbrevPB->connect_clicked(LINK(this, OfaAutocorrExceptPage, NewDelButtonHdl));
1210 m_xDelAbbrevPB->connect_clicked(LINK(this, OfaAutocorrExceptPage, NewDelButtonHdl));
1211 m_xNewDoublePB->connect_clicked(LINK(this, OfaAutocorrExceptPage, NewDelButtonHdl));
1212 m_xDelDoublePB->connect_clicked(LINK(this, OfaAutocorrExceptPage, NewDelButtonHdl));
1214 m_xAbbrevLB->connect_changed(LINK(this, OfaAutocorrExceptPage, SelectHdl));
1215 m_xDoubleCapsLB->connect_changed(LINK(this, OfaAutocorrExceptPage, SelectHdl));
1216 m_xAbbrevED->connect_changed(LINK(this, OfaAutocorrExceptPage, ModifyHdl));
1217 m_xDoubleCapsED->connect_changed(LINK(this, OfaAutocorrExceptPage, ModifyHdl));
1219 m_xAbbrevED->connect_activate(LINK(this, OfaAutocorrExceptPage, NewDelActionHdl));
1220 m_xDoubleCapsED->connect_activate(LINK(this, OfaAutocorrExceptPage, NewDelActionHdl));
1223 OfaAutocorrExceptPage::~OfaAutocorrExceptPage()
1225 disposeOnce();
1228 void OfaAutocorrExceptPage::dispose()
1230 aStringsTable.clear();
1231 pCompareClass.reset();
1232 SfxTabPage::dispose();
1235 VclPtr<SfxTabPage> OfaAutocorrExceptPage::Create(TabPageParent pParent,
1236 const SfxItemSet* rSet)
1238 return VclPtr<OfaAutocorrExceptPage>::Create(pParent, *rSet);
1241 void OfaAutocorrExceptPage::ActivatePage( const SfxItemSet& )
1243 if(eLang != eLastDialogLanguage)
1244 SetLanguage(eLastDialogLanguage);
1245 static_cast<OfaAutoCorrDlg*>(GetDialogController())->EnableLanguage(true);
1248 DeactivateRC OfaAutocorrExceptPage::DeactivatePage( SfxItemSet* )
1250 return DeactivateRC::LeavePage;
1253 bool OfaAutocorrExceptPage::FillItemSet( SfxItemSet* )
1255 SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
1256 for(StringsTable::reverse_iterator it1 = aStringsTable.rbegin(); it1 != aStringsTable.rend(); ++it1)
1258 LanguageType eCurLang = it1->first;
1259 StringsArrays& rArrays = it1->second;
1260 if(eCurLang != eLang) // current language is treated later
1262 SvStringsISortDtor* pWrdList = pAutoCorrect->LoadWrdSttExceptList(eCurLang);
1264 if(pWrdList)
1266 size_t nCount = pWrdList->size();
1267 size_t i;
1268 for( i = nCount; i; )
1270 OUString aString = (*pWrdList)[ --i ];
1272 if( !lcl_FindInArray(rArrays.aDoubleCapsStrings, aString))
1274 pWrdList->erase(i);
1278 for (auto const& elem : rArrays.aDoubleCapsStrings)
1280 pWrdList->insert(elem);
1282 pAutoCorrect->SaveWrdSttExceptList(eCurLang);
1285 SvStringsISortDtor* pCplList = pAutoCorrect->LoadCplSttExceptList(eCurLang);
1287 if(pCplList)
1289 size_t nCount = pCplList->size();
1290 size_t i;
1291 for( i = nCount; i; )
1293 OUString aString = (*pCplList)[ --i ];
1294 if( !lcl_FindInArray(rArrays.aAbbrevStrings, aString))
1296 pCplList->erase(i);
1300 for (auto const& elem : rArrays.aAbbrevStrings)
1302 pCplList->insert(elem);
1305 pAutoCorrect->SaveCplSttExceptList(eCurLang);
1309 aStringsTable.clear();
1311 SvStringsISortDtor* pWrdList = pAutoCorrect->LoadWrdSttExceptList(eLang);
1313 if(pWrdList)
1315 size_t nCount = pWrdList->size();
1316 size_t i;
1317 for( i = nCount; i; )
1319 OUString aString = (*pWrdList)[ --i ];
1320 if (m_xDoubleCapsLB->find_text(aString) == -1)
1322 pWrdList->erase(i);
1325 nCount = m_xDoubleCapsLB->n_children();
1326 for( i = 0; i < nCount; ++i )
1328 pWrdList->insert(m_xDoubleCapsLB->get_text(i));
1330 pAutoCorrect->SaveWrdSttExceptList(eLang);
1333 SvStringsISortDtor* pCplList = pAutoCorrect->LoadCplSttExceptList(eLang);
1335 if(pCplList)
1337 size_t nCount = pCplList->size();
1338 for( size_t i = nCount; i; )
1340 OUString aString = (*pCplList)[ --i ];
1341 if (m_xAbbrevLB->find_text(aString) == -1)
1343 pCplList->erase(i);
1346 sal_Int32 nAbbrevCount = m_xAbbrevLB->n_children();
1347 for( sal_Int32 ia = 0; ia < nAbbrevCount; ++ia )
1349 pCplList->insert(m_xAbbrevLB->get_text(ia));
1351 pAutoCorrect->SaveCplSttExceptList(eLang);
1353 if (m_xAutoAbbrevCB->get_state_changed_from_saved())
1354 pAutoCorrect->SetAutoCorrFlag( ACFlags::SaveWordCplSttLst, m_xAutoAbbrevCB->get_active());
1355 if (m_xAutoCapsCB->get_state_changed_from_saved())
1356 pAutoCorrect->SetAutoCorrFlag( ACFlags::SaveWordWrdSttLst, m_xAutoCapsCB->get_active());
1357 return false;
1360 void OfaAutocorrExceptPage::SetLanguage(LanguageType eSet)
1362 if(eLang != eSet)
1364 // save old settings and fill anew
1365 RefillReplaceBoxes(false, eLang, eSet);
1366 eLastDialogLanguage = eSet;
1367 pCompareClass.reset( new CollatorWrapper( comphelper::getProcessComponentContext() ) );
1368 pCompareClass->loadDefaultCollator( LanguageTag::convertToLocale( eLastDialogLanguage ), 0 );
1369 ModifyHdl(*m_xAbbrevED);
1370 ModifyHdl(*m_xDoubleCapsED);
1374 void OfaAutocorrExceptPage::RefillReplaceBoxes(bool bFromReset,
1375 LanguageType eOldLanguage,
1376 LanguageType eNewLanguage)
1378 eLang = eNewLanguage;
1379 if(bFromReset)
1381 aStringsTable.clear();
1383 else
1385 StringsArrays* pArrays;
1386 if(aStringsTable.find(eOldLanguage) != aStringsTable.end())
1388 pArrays = &aStringsTable[eOldLanguage];
1389 pArrays->aAbbrevStrings.clear();
1390 pArrays->aDoubleCapsStrings.clear();
1392 else
1394 pArrays = &aStringsTable[eOldLanguage]; // create new array
1397 sal_Int32 i, nCount;
1398 nCount = m_xAbbrevLB->n_children();
1399 for(i = 0; i < nCount; i++)
1400 pArrays->aAbbrevStrings.push_back(m_xAbbrevLB->get_text(i));
1402 nCount = m_xDoubleCapsLB->n_children();
1403 for(i = 0; i < nCount; i++)
1404 pArrays->aDoubleCapsStrings.push_back(m_xDoubleCapsLB->get_text(i));
1406 m_xDoubleCapsLB->clear();
1407 m_xAbbrevLB->clear();
1408 OUString sTemp;
1409 m_xAbbrevED->set_text(sTemp);
1410 m_xDoubleCapsED->set_text(sTemp);
1412 if(aStringsTable.find(eLang) != aStringsTable.end())
1414 StringsArrays& rArrays = aStringsTable[eLang];
1415 for (auto const& elem : rArrays.aAbbrevStrings)
1416 m_xAbbrevLB->append_text(elem);
1418 for (auto const& elem : rArrays.aDoubleCapsStrings)
1419 m_xDoubleCapsLB->append_text(elem);
1421 else
1423 SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
1424 const SvStringsISortDtor* pCplList = pAutoCorrect->GetCplSttExceptList(eLang);
1425 const SvStringsISortDtor* pWrdList = pAutoCorrect->GetWrdSttExceptList(eLang);
1426 size_t i;
1427 for( i = 0; i < pCplList->size(); i++ )
1429 m_xAbbrevLB->append_text((*pCplList)[i]);
1431 for( i = 0; i < pWrdList->size(); i++ )
1433 m_xDoubleCapsLB->append_text((*pWrdList)[i]);
1438 void OfaAutocorrExceptPage::Reset( const SfxItemSet* )
1440 SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
1441 RefillReplaceBoxes(true, eLang, eLang);
1442 m_xAutoAbbrevCB->set_active(pAutoCorrect->IsAutoCorrFlag( ACFlags::SaveWordCplSttLst));
1443 m_xAutoCapsCB->set_active(pAutoCorrect->IsAutoCorrFlag( ACFlags::SaveWordWrdSttLst));
1444 m_xAutoAbbrevCB->save_state();
1445 m_xAutoCapsCB->save_state();
1448 IMPL_LINK(OfaAutocorrExceptPage, NewDelButtonHdl, weld::Button&, rBtn, void)
1450 NewDelHdl(&rBtn);
1453 IMPL_LINK(OfaAutocorrExceptPage, NewDelActionHdl, weld::Entry&, rEdit, bool)
1455 NewDelHdl(&rEdit);
1456 return false;
1459 void OfaAutocorrExceptPage::NewDelHdl(const weld::Widget* pBtn)
1461 if ((pBtn == m_xNewAbbrevPB.get() || pBtn == m_xAbbrevED.get())
1462 && !m_xAbbrevED->get_text().isEmpty())
1464 m_xAbbrevLB->append_text(m_xAbbrevED->get_text());
1465 ModifyHdl(*m_xAbbrevED);
1467 else if(pBtn == m_xDelAbbrevPB.get())
1469 m_xAbbrevLB->remove_text(m_xAbbrevED->get_text());
1470 ModifyHdl(*m_xAbbrevED);
1472 else if((pBtn == m_xNewDoublePB.get() || pBtn == m_xDoubleCapsED.get() )
1473 && !m_xDoubleCapsED->get_text().isEmpty())
1475 m_xDoubleCapsLB->append_text(m_xDoubleCapsED->get_text());
1476 ModifyHdl(*m_xDoubleCapsED);
1478 else if (pBtn == m_xDelDoublePB.get())
1480 m_xDoubleCapsLB->remove_text(m_xDoubleCapsED->get_text());
1481 ModifyHdl(*m_xDoubleCapsED);
1485 IMPL_LINK(OfaAutocorrExceptPage, SelectHdl, weld::TreeView&, rBox, void)
1487 if (&rBox == m_xAbbrevLB.get())
1489 m_xAbbrevED->set_text(rBox.get_selected_text());
1490 m_xNewAbbrevPB->set_sensitive(false);
1491 m_xDelAbbrevPB->set_sensitive(true);
1493 else
1495 m_xDoubleCapsED->set_text(rBox.get_selected_text());
1496 m_xNewDoublePB->set_sensitive(false);
1497 m_xDelDoublePB->set_sensitive(true);
1501 IMPL_LINK(OfaAutocorrExceptPage, ModifyHdl, weld::Entry&, rEdt, void)
1503 const OUString& sEntry = rEdt.get_text();
1504 bool bEntryLen = !sEntry.isEmpty();
1505 if (&rEdt == m_xAbbrevED.get())
1507 bool bSame = lcl_FindEntry(*m_xAbbrevLB, sEntry, *pCompareClass);
1508 if(bSame && sEntry != m_xAbbrevLB->get_selected_text())
1509 rEdt.set_text(m_xAbbrevLB->get_selected_text());
1510 m_xNewAbbrevPB->set_sensitive(!bSame && bEntryLen);
1511 m_xDelAbbrevPB->set_sensitive(bSame && bEntryLen);
1513 else
1515 bool bSame = lcl_FindEntry(*m_xDoubleCapsLB, sEntry, *pCompareClass);
1516 if(bSame && sEntry != m_xDoubleCapsLB->get_selected_text())
1517 rEdt.set_text(m_xDoubleCapsLB->get_selected_text());
1518 m_xNewDoublePB->set_sensitive(!bSame && bEntryLen);
1519 m_xDelDoublePB->set_sensitive(bSame && bEntryLen);
1523 enum OfaQuoteOptions
1525 ADD_NONBRK_SPACE,
1526 REPLACE_1ST
1529 void OfaQuoteTabPage::CreateEntry(weld::TreeView& rCheckLB, const OUString& rTxt, sal_uInt16 nCol, sal_uInt16 nTextCol)
1531 rCheckLB.append();
1532 const int nRow = rCheckLB.n_children() - 1;
1533 if (nCol == CBCOL_FIRST || nCol == CBCOL_BOTH)
1534 rCheckLB.set_toggle(nRow, TRISTATE_FALSE, CBCOL_FIRST);
1535 if (nCol == CBCOL_SECOND || nCol == CBCOL_BOTH)
1536 rCheckLB.set_toggle(nRow, TRISTATE_FALSE, CBCOL_SECOND);
1537 rCheckLB.set_text(nRow, rTxt, nTextCol);
1540 OfaQuoteTabPage::OfaQuoteTabPage(TabPageParent pParent, const SfxItemSet& rSet)
1541 : SfxTabPage(pParent, "cui/ui/applylocalizedpage.ui", "ApplyLocalizedPage", &rSet)
1542 , sNonBrkSpace(CuiResId(RID_SVXSTR_NON_BREAK_SPACE))
1543 , sOrdinal(CuiResId(RID_SVXSTR_ORDINAL))
1544 , cSglStartQuote(0)
1545 , cSglEndQuote(0)
1546 , cStartQuote(0)
1547 , cEndQuote(0)
1548 , m_xSingleTypoCB(m_xBuilder->weld_check_button("singlereplace"))
1549 , m_xSglStartQuotePB(m_xBuilder->weld_button("startsingle"))
1550 , m_xSglStartExFT(m_xBuilder->weld_label("singlestartex"))
1551 , m_xSglEndQuotePB(m_xBuilder->weld_button("endsingle"))
1552 , m_xSglEndExFT(m_xBuilder->weld_label("singleendex"))
1553 , m_xSglStandardPB(m_xBuilder->weld_button("defaultsingle"))
1554 , m_xDoubleTypoCB(m_xBuilder->weld_check_button("doublereplace"))
1555 , m_xDblStartQuotePB(m_xBuilder->weld_button("startdouble"))
1556 , m_xDblStartExFT(m_xBuilder->weld_label("doublestartex"))
1557 , m_xDblEndQuotePB(m_xBuilder->weld_button("enddouble"))
1558 , m_xDblEndExFT(m_xBuilder->weld_label("doubleendex"))
1559 , m_xDblStandardPB(m_xBuilder->weld_button("defaultdouble"))
1560 , m_xStandard(m_xBuilder->weld_label("singlestartex"))
1561 , m_xCheckLB(m_xBuilder->weld_tree_view("checklist"))
1562 , m_xSwCheckLB(m_xBuilder->weld_tree_view("list"))
1564 m_xSwCheckLB->set_size_request(m_xSwCheckLB->get_approximate_digit_width() * 50,
1565 m_xSwCheckLB->get_height_rows(6));
1567 bool bShowSWOptions = false;
1569 const SfxBoolItem* pItem = rSet.GetItem<SfxBoolItem>(SID_AUTO_CORRECT_DLG, false);
1570 if ( pItem && pItem->GetValue() )
1571 bShowSWOptions = true;
1573 if ( bShowSWOptions )
1575 std::vector<int> aWidths;
1576 aWidths.push_back(m_xSwCheckLB->get_pixel_size(m_xSwCheckLB->get_column_title(0)).Width() * 2);
1577 aWidths.push_back(m_xSwCheckLB->get_pixel_size(m_xSwCheckLB->get_column_title(1)).Width() * 2);
1578 m_xSwCheckLB->set_column_fixed_widths(aWidths);
1579 m_xCheckLB->hide();
1581 else
1583 std::vector<int> aWidths;
1584 aWidths.push_back(m_xSwCheckLB->get_checkbox_column_width());
1585 m_xCheckLB->set_column_fixed_widths(aWidths);
1586 m_xSwCheckLB->hide();
1589 m_xDblStartQuotePB->connect_clicked(LINK(this, OfaQuoteTabPage, QuoteHdl));
1590 m_xDblEndQuotePB->connect_clicked(LINK(this, OfaQuoteTabPage, QuoteHdl));
1591 m_xSglStartQuotePB->connect_clicked(LINK(this, OfaQuoteTabPage, QuoteHdl));
1592 m_xSglEndQuotePB->connect_clicked(LINK(this, OfaQuoteTabPage, QuoteHdl));
1593 m_xDblStandardPB->connect_clicked(LINK(this, OfaQuoteTabPage, StdQuoteHdl));
1594 m_xSglStandardPB->connect_clicked(LINK(this, OfaQuoteTabPage, StdQuoteHdl));
1597 OfaQuoteTabPage::~OfaQuoteTabPage()
1599 disposeOnce();
1602 VclPtr<SfxTabPage> OfaQuoteTabPage::Create(TabPageParent pParent,
1603 const SfxItemSet* rAttrSet)
1605 return VclPtr<OfaQuoteTabPage>::Create(pParent, *rAttrSet);
1608 bool OfaQuoteTabPage::FillItemSet( SfxItemSet* )
1610 SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
1612 ACFlags nFlags = pAutoCorrect->GetFlags();
1614 if (m_xCheckLB->get_visible())
1616 int nPos = 0;
1617 pAutoCorrect->SetAutoCorrFlag(ACFlags::AddNonBrkSpace, m_xCheckLB->get_toggle(nPos++, CBCOL_FIRST) == TRISTATE_TRUE);
1618 pAutoCorrect->SetAutoCorrFlag(ACFlags::ChgOrdinalNumber, m_xCheckLB->get_toggle(nPos++, CBCOL_FIRST) == TRISTATE_TRUE);
1621 bool bModified = false;
1622 if (m_xSwCheckLB->get_visible())
1624 SvxSwAutoFormatFlags *pOpt = &pAutoCorrect->GetSwFlags();
1626 bool bCheck = m_xSwCheckLB->get_toggle(ADD_NONBRK_SPACE, CBCOL_FIRST) == TRISTATE_TRUE;
1627 bModified |= pOpt->bAddNonBrkSpace != bCheck;
1628 pOpt->bAddNonBrkSpace = bCheck;
1629 pAutoCorrect->SetAutoCorrFlag(ACFlags::AddNonBrkSpace,
1630 m_xSwCheckLB->get_toggle(ADD_NONBRK_SPACE, CBCOL_SECOND) == TRISTATE_TRUE);
1632 bCheck = m_xSwCheckLB->get_toggle(REPLACE_1ST, CBCOL_FIRST) == TRISTATE_TRUE;
1633 bModified |= pOpt->bChgOrdinalNumber != bCheck;
1634 pOpt->bChgOrdinalNumber = bCheck;
1635 pAutoCorrect->SetAutoCorrFlag(ACFlags::ChgOrdinalNumber,
1636 m_xSwCheckLB->get_toggle(REPLACE_1ST, CBCOL_SECOND) == TRISTATE_TRUE);
1639 pAutoCorrect->SetAutoCorrFlag(ACFlags::ChgQuotes, m_xDoubleTypoCB->get_active());
1640 pAutoCorrect->SetAutoCorrFlag(ACFlags::ChgSglQuotes, m_xSingleTypoCB->get_active());
1641 bool bReturn = nFlags != pAutoCorrect->GetFlags();
1642 if(cStartQuote != pAutoCorrect->GetStartDoubleQuote())
1644 bReturn = true;
1645 sal_Unicode cUCS2 = static_cast<sal_Unicode>(cStartQuote); //TODO
1646 pAutoCorrect->SetStartDoubleQuote(cUCS2);
1648 if(cEndQuote != pAutoCorrect->GetEndDoubleQuote())
1650 bReturn = true;
1651 sal_Unicode cUCS2 = static_cast<sal_Unicode>(cEndQuote); //TODO
1652 pAutoCorrect->SetEndDoubleQuote(cUCS2);
1654 if(cSglStartQuote != pAutoCorrect->GetStartSingleQuote())
1656 bReturn = true;
1657 sal_Unicode cUCS2 = static_cast<sal_Unicode>(cSglStartQuote); //TODO
1658 pAutoCorrect->SetStartSingleQuote(cUCS2);
1660 if(cSglEndQuote != pAutoCorrect->GetEndSingleQuote())
1662 bReturn = true;
1663 sal_Unicode cUCS2 = static_cast<sal_Unicode>(cSglEndQuote); //TODO
1664 pAutoCorrect->SetEndSingleQuote(cUCS2);
1667 if( bModified || bReturn )
1669 SvxAutoCorrCfg& rCfg = SvxAutoCorrCfg::Get();
1670 rCfg.SetModified();
1671 rCfg.Commit();
1673 return bReturn;
1676 void OfaQuoteTabPage::ActivatePage( const SfxItemSet& )
1678 static_cast<OfaAutoCorrDlg*>(GetDialogController())->EnableLanguage(false);
1681 void OfaQuoteTabPage::Reset( const SfxItemSet* )
1683 SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
1684 const ACFlags nFlags = pAutoCorrect->GetFlags();
1686 // Initialize the Sw options
1687 if (m_xSwCheckLB->get_visible())
1689 SvxSwAutoFormatFlags *pOpt = &pAutoCorrect->GetSwFlags();
1691 m_xSwCheckLB->freeze();
1692 m_xSwCheckLB->clear();
1694 CreateEntry(*m_xSwCheckLB, sNonBrkSpace, CBCOL_BOTH, 2);
1695 CreateEntry(*m_xSwCheckLB, sOrdinal, CBCOL_BOTH, 2);
1697 m_xSwCheckLB->set_toggle(ADD_NONBRK_SPACE, pOpt->bAddNonBrkSpace ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
1698 m_xSwCheckLB->set_toggle(ADD_NONBRK_SPACE, bool(nFlags & ACFlags::AddNonBrkSpace) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
1699 m_xSwCheckLB->set_toggle(REPLACE_1ST, pOpt->bChgOrdinalNumber ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
1700 m_xSwCheckLB->set_toggle(REPLACE_1ST, bool(nFlags & ACFlags::ChgOrdinalNumber) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
1702 m_xSwCheckLB->thaw();
1705 // Initialize the non Sw options
1706 if (m_xCheckLB->get_visible())
1708 m_xCheckLB->freeze();
1709 m_xCheckLB->clear();
1711 CreateEntry(*m_xCheckLB, sNonBrkSpace, CBCOL_FIRST, 1);
1712 CreateEntry(*m_xCheckLB, sOrdinal, CBCOL_FIRST, 1);
1714 int nPos = 0;
1715 m_xCheckLB->set_toggle(nPos++, bool(nFlags & ACFlags::AddNonBrkSpace) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
1716 m_xCheckLB->set_toggle(nPos++, bool(nFlags & ACFlags::ChgOrdinalNumber) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
1718 m_xCheckLB->thaw();
1721 // Initialize the quote stuffs
1722 m_xDoubleTypoCB->set_active(bool(nFlags & ACFlags::ChgQuotes));
1723 m_xSingleTypoCB->set_active(bool(nFlags & ACFlags::ChgSglQuotes));
1724 m_xDoubleTypoCB->save_state();
1725 m_xSingleTypoCB->save_state();
1727 cStartQuote = pAutoCorrect->GetStartDoubleQuote();
1728 cEndQuote = pAutoCorrect->GetEndDoubleQuote();
1729 cSglStartQuote = pAutoCorrect->GetStartSingleQuote();
1730 cSglEndQuote = pAutoCorrect->GetEndSingleQuote();
1732 m_xSglStartExFT->set_label(ChangeStringExt_Impl(cSglStartQuote));
1733 m_xSglEndExFT->set_label(ChangeStringExt_Impl(cSglEndQuote));
1734 m_xDblStartExFT->set_label(ChangeStringExt_Impl(cStartQuote));
1735 m_xDblEndExFT->set_label(ChangeStringExt_Impl(cEndQuote));
1738 #define SGL_START 0
1739 #define DBL_START 1
1740 #define SGL_END 2
1741 #define DBL_END 3
1744 IMPL_LINK(OfaQuoteTabPage, QuoteHdl, weld::Button&, rBtn, void)
1746 sal_uInt16 nMode = SGL_START;
1747 if (&rBtn == m_xSglEndQuotePB.get())
1748 nMode = SGL_END;
1749 else if (&rBtn == m_xDblStartQuotePB.get())
1750 nMode = DBL_START;
1751 else if (&rBtn == m_xDblEndQuotePB.get())
1752 nMode = DBL_END;
1753 // start character selection dialog
1754 SvxCharacterMap aMap(GetDialogFrameWeld(), nullptr, nullptr);
1755 aMap.SetCharFont( OutputDevice::GetDefaultFont(DefaultFontType::LATIN_TEXT,
1756 LANGUAGE_ENGLISH_US, GetDefaultFontFlags::OnlyOne ));
1757 aMap.set_title(nMode < SGL_END ? CuiResId(RID_SVXSTR_STARTQUOTE) : CuiResId(RID_SVXSTR_ENDQUOTE));
1758 sal_UCS4 cDlg;
1759 SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
1760 LanguageType eLang = Application::GetSettings().GetLanguageTag().getLanguageType();
1761 switch( nMode )
1763 case SGL_START:
1764 cDlg = cSglStartQuote;
1765 if(cDlg == 0)
1766 cDlg = pAutoCorrect->GetQuote('\'', true, eLang);
1767 break;
1768 case SGL_END:
1769 cDlg = cSglEndQuote;
1770 if(cDlg == 0)
1771 cDlg = pAutoCorrect->GetQuote('\'', false, eLang);
1772 break;
1773 case DBL_START:
1774 cDlg = cStartQuote;
1775 if(cDlg == 0)
1776 cDlg = pAutoCorrect->GetQuote('\"', true, eLang);
1777 break;
1778 case DBL_END:
1779 cDlg = cEndQuote;
1780 if(cDlg == 0)
1781 cDlg = pAutoCorrect->GetQuote('\"', false, eLang);
1782 break;
1783 default:
1784 OSL_FAIL("svx::OfaQuoteTabPage::QuoteHdl(), how to initialize cDlg?" );
1785 cDlg = 0;
1786 break;
1789 aMap.SetChar( cDlg );
1790 aMap.DisableFontSelection();
1791 if (aMap.run() == RET_OK)
1793 sal_UCS4 cNewChar = aMap.GetChar();
1794 switch( nMode )
1796 case SGL_START:
1797 cSglStartQuote = cNewChar;
1798 m_xSglStartExFT->set_label(ChangeStringExt_Impl(cNewChar));
1799 break;
1800 case SGL_END:
1801 cSglEndQuote = cNewChar;
1802 m_xSglEndExFT->set_label(ChangeStringExt_Impl(cNewChar));
1803 break;
1804 case DBL_START:
1805 cStartQuote = cNewChar;
1806 m_xDblStartExFT->set_label(ChangeStringExt_Impl(cNewChar));
1807 break;
1808 case DBL_END:
1809 cEndQuote = cNewChar;
1810 m_xDblEndExFT->set_label(ChangeStringExt_Impl(cNewChar));
1811 break;
1816 IMPL_LINK(OfaQuoteTabPage, StdQuoteHdl, weld::Button&, rBtn, void)
1818 if (&rBtn == m_xDblStandardPB.get())
1820 cStartQuote = 0;
1821 m_xDblStartExFT->set_label(ChangeStringExt_Impl(0));
1822 cEndQuote = 0;
1823 m_xDblEndExFT->set_label(ChangeStringExt_Impl(0));
1826 else
1828 cSglStartQuote = 0;
1829 m_xSglStartExFT->set_label(ChangeStringExt_Impl(0));
1830 cSglEndQuote = 0;
1831 m_xSglEndExFT->set_label(ChangeStringExt_Impl(0));
1835 OUString OfaQuoteTabPage::ChangeStringExt_Impl( sal_UCS4 cChar )
1837 if (!cChar)
1838 return m_xStandard->get_label();
1840 // convert codepoint value to unicode-hex string
1841 sal_UCS4 aStrCodes[32] = { 0, ' ', '(', 'U', '+', '0' };
1842 aStrCodes[0] = cChar;
1843 int nFullLen = 5;
1844 int nHexLen = 4;
1845 while( (cChar >> (4*nHexLen)) != 0 )
1846 ++nHexLen;
1847 for( int i = nHexLen; --i >= 0;)
1849 sal_UCS4 cHexDigit = ((cChar >> (4*i)) & 0x0f) + '0';
1850 if( cHexDigit > '9' )
1851 cHexDigit += 'A' - ('9' + 1);
1852 aStrCodes[ nFullLen++ ] = cHexDigit;
1854 aStrCodes[ nFullLen++ ] = ')';
1855 // using the new UCS4 constructor
1856 OUString aOUStr( aStrCodes, nFullLen );
1857 return aOUStr;
1860 OfaAutoCompleteTabPage::OfaAutoCompleteTabPage(TabPageParent pParent,
1861 const SfxItemSet& rSet)
1862 : SfxTabPage(pParent, "cui/ui/wordcompletionpage.ui",
1863 "WordCompletionPage", &rSet)
1864 , m_pAutoCompleteList(nullptr)
1865 , m_nAutoCmpltListCnt(0)
1866 , m_xCBActiv(m_xBuilder->weld_check_button("enablewordcomplete"))
1867 , m_xCBAppendSpace(m_xBuilder->weld_check_button("appendspace"))
1868 , m_xCBAsTip(m_xBuilder->weld_check_button("showastip"))
1869 , m_xCBCollect(m_xBuilder->weld_check_button("collectwords"))
1870 , m_xCBRemoveList(m_xBuilder->weld_check_button("whenclosing"))
1871 , m_xDCBExpandKey(m_xBuilder->weld_combo_box("acceptwith"))
1872 , m_xNFMinWordlen(m_xBuilder->weld_spin_button("minwordlen"))
1873 , m_xNFMaxEntries(m_xBuilder->weld_spin_button("maxentries"))
1874 , m_xLBEntries(m_xBuilder->weld_tree_view("entries"))
1875 , m_xPBEntries(m_xBuilder->weld_button("delete"))
1877 //fdo#65595, we need height-for-width support here, but for now we can
1878 //bodge it
1879 Size aPrefSize(m_xCBRemoveList->get_preferred_size());
1880 int nMaxWidth = m_xCBRemoveList->get_approximate_digit_width() * 40;
1881 if (aPrefSize.Width() > nMaxWidth)
1883 m_xCBRemoveList->set_label_line_wrap(true);
1884 m_xCBRemoveList->set_size_request(nMaxWidth, -1);
1887 m_xLBEntries->set_size_request(m_xLBEntries->get_approximate_digit_width() * 30,
1888 m_xLBEntries->get_height_rows(10));
1890 // the defined KEYs
1891 static const sal_uInt16 aKeyCodes[] = {
1892 KEY_END,
1893 KEY_RETURN,
1894 KEY_SPACE,
1895 KEY_RIGHT,
1896 KEY_TAB,
1900 for( const sal_uInt16* pKeys = aKeyCodes; *pKeys; ++pKeys )
1902 vcl::KeyCode aKCode(*pKeys);
1903 m_xDCBExpandKey->append(OUString::number(static_cast<sal_Int32>(*pKeys)), aKCode.GetName());
1904 if (KEY_RETURN == *pKeys) // default to RETURN
1905 m_xDCBExpandKey->set_active(std::distance(aKeyCodes, pKeys));
1908 m_xPBEntries->connect_clicked(LINK(this, OfaAutoCompleteTabPage, DeleteHdl));
1909 m_xCBActiv->connect_toggled(LINK(this, OfaAutoCompleteTabPage, CheckHdl));
1910 m_xCBCollect->connect_toggled(LINK(this, OfaAutoCompleteTabPage, CheckHdl));
1911 m_xLBEntries->connect_key_release(LINK(this, OfaAutoCompleteTabPage, KeyReleaseHdl));
1914 OfaAutoCompleteTabPage::~OfaAutoCompleteTabPage()
1916 disposeOnce();
1919 void OfaSwAutoFmtOptionsPage::dispose()
1921 delete reinterpret_cast<ImpUserData*>(m_xCheckLB->get_id(REPLACE_BULLETS).toInt64());
1922 delete reinterpret_cast<ImpUserData*>(m_xCheckLB->get_id(APPLY_NUMBERING).toInt64());
1923 delete reinterpret_cast<ImpUserData*>(m_xCheckLB->get_id(MERGE_SINGLE_LINE_PARA).toInt64());
1924 SfxTabPage::dispose();
1927 VclPtr<SfxTabPage> OfaAutoCompleteTabPage::Create(TabPageParent pParent,
1928 const SfxItemSet* rSet)
1930 return VclPtr<OfaAutoCompleteTabPage>::Create(pParent, *rSet);
1933 bool OfaAutoCompleteTabPage::FillItemSet( SfxItemSet* )
1935 bool bModified = false, bCheck;
1936 SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
1937 SvxSwAutoFormatFlags *pOpt = &pAutoCorrect->GetSwFlags();
1938 sal_uInt16 nVal;
1940 bCheck = m_xCBActiv->get_active();
1941 bModified |= pOpt->bAutoCompleteWords != bCheck;
1942 pOpt->bAutoCompleteWords = bCheck;
1943 bCheck = m_xCBCollect->get_active();
1944 bModified |= pOpt->bAutoCmpltCollectWords != bCheck;
1945 pOpt->bAutoCmpltCollectWords = bCheck;
1946 bCheck = !m_xCBRemoveList->get_active(); // inverted value!
1947 bModified |= pOpt->bAutoCmpltKeepList != bCheck;
1948 pOpt->bAutoCmpltKeepList = bCheck;
1949 bCheck = m_xCBAppendSpace->get_active();
1950 bModified |= pOpt->bAutoCmpltAppendBlanc != bCheck;
1951 pOpt->bAutoCmpltAppendBlanc = bCheck;
1952 bCheck = m_xCBAsTip->get_active();
1953 bModified |= pOpt->bAutoCmpltShowAsTip != bCheck;
1954 pOpt->bAutoCmpltShowAsTip = bCheck;
1956 nVal = static_cast<sal_uInt16>(m_xNFMinWordlen->get_value());
1957 bModified |= nVal != pOpt->nAutoCmpltWordLen;
1958 pOpt->nAutoCmpltWordLen = nVal;
1960 nVal = static_cast<sal_uInt16>(m_xNFMaxEntries->get_value());
1961 bModified |= nVal != pOpt->nAutoCmpltListLen;
1962 pOpt->nAutoCmpltListLen = nVal;
1964 const int nPos = m_xDCBExpandKey->get_active();
1965 if (nPos != -1)
1967 sal_Int32 nKey = m_xDCBExpandKey->get_id(nPos).toInt32();
1968 bModified |= nKey != pOpt->nAutoCmpltExpandKey;
1969 pOpt->nAutoCmpltExpandKey = static_cast<sal_uInt16>(nKey);
1972 if (m_pAutoCompleteList && m_nAutoCmpltListCnt != m_xLBEntries->n_children())
1974 bModified = true;
1975 pOpt->m_pAutoCompleteList = m_pAutoCompleteList;
1977 if( bModified )
1979 SvxAutoCorrCfg& rCfg = SvxAutoCorrCfg::Get();
1980 rCfg.SetModified();
1981 rCfg.Commit();
1983 return true;
1986 void OfaAutoCompleteTabPage::Reset( const SfxItemSet* )
1988 SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
1989 SvxSwAutoFormatFlags *pOpt = &pAutoCorrect->GetSwFlags();
1991 m_xCBActiv->set_active( pOpt->bAutoCompleteWords );
1992 m_xCBCollect->set_active( pOpt->bAutoCmpltCollectWords );
1993 m_xCBRemoveList->set_active( !pOpt->bAutoCmpltKeepList ); //inverted value!
1994 m_xCBAppendSpace->set_active( pOpt->bAutoCmpltAppendBlanc );
1995 m_xCBAsTip->set_active( pOpt->bAutoCmpltShowAsTip );
1997 m_xNFMinWordlen->set_value( pOpt->nAutoCmpltWordLen );
1998 m_xNFMaxEntries->set_value( pOpt->nAutoCmpltListLen );
2000 // select the specific KeyCode:
2002 sal_Int32 nKey = pOpt->nAutoCmpltExpandKey;
2003 for (int n = 0, nCnt = m_xDCBExpandKey->get_count(); n < nCnt; ++n)
2005 if (nKey == m_xDCBExpandKey->get_id(n).toInt32())
2007 m_xDCBExpandKey->set_active(n);
2008 break;
2013 if (pOpt->m_pAutoCompleteList && !pOpt->m_pAutoCompleteList->empty())
2015 m_pAutoCompleteList = const_cast<editeng::SortedAutoCompleteStrings*>(
2016 pOpt->m_pAutoCompleteList);
2017 pOpt->m_pAutoCompleteList = nullptr;
2018 m_nAutoCmpltListCnt = m_pAutoCompleteList->size();
2019 for (size_t n = 0; n < m_nAutoCmpltListCnt; ++n)
2021 const OUString* pStr =
2022 &(*m_pAutoCompleteList)[n]->GetAutoCompleteString();
2023 OUString sId(OUString::number(reinterpret_cast<sal_Int64>(pStr)));
2024 m_xLBEntries->append(sId, *pStr);
2027 else
2029 m_xLBEntries->set_sensitive(false);
2030 m_xPBEntries->set_sensitive(false);
2033 CheckHdl(*m_xCBActiv);
2034 CheckHdl(*m_xCBCollect);
2037 void OfaAutoCompleteTabPage::ActivatePage( const SfxItemSet& )
2039 static_cast<OfaAutoCorrDlg*>(GetDialogController())->EnableLanguage( false );
2042 IMPL_LINK_NOARG(OfaAutoCompleteTabPage, DeleteHdl, weld::Button&, void)
2044 auto rows = m_xLBEntries->get_selected_rows();
2045 std::sort(rows.begin(), rows.end());
2046 while (!rows.empty())
2048 sal_Int32 nPos = rows.back();
2049 OUString* pStr = reinterpret_cast<OUString*>(m_xLBEntries->get_id(nPos).toInt64());
2050 m_xLBEntries->remove(nPos);
2051 editeng::IAutoCompleteString hack(*pStr); // UGLY
2052 m_pAutoCompleteList->erase(&hack);
2053 rows.pop_back();
2057 IMPL_LINK(OfaAutoCompleteTabPage, CheckHdl, weld::ToggleButton&, rBox, void)
2059 bool bEnable = rBox.get_active();
2060 if (&rBox == m_xCBActiv.get())
2062 m_xCBAppendSpace->set_sensitive(bEnable);
2063 m_xCBAppendSpace->set_sensitive(bEnable);
2064 m_xCBAsTip->set_sensitive(bEnable);
2065 m_xDCBExpandKey->set_sensitive(bEnable);
2067 else if (&rBox == m_xCBCollect.get())
2068 m_xCBRemoveList->set_sensitive(bEnable);
2071 void OfaAutoCompleteTabPage::CopyToClipboard() const
2073 auto rows = m_xLBEntries->get_selected_rows();
2074 if (m_pAutoCompleteList && !rows.empty())
2076 rtl::Reference<TransferDataContainer> pCntnr = new TransferDataContainer;
2078 OStringBuffer sData;
2080 rtl_TextEncoding nEncode = osl_getThreadTextEncoding();
2082 for (auto a : rows)
2084 sData.append(OUStringToOString(m_xLBEntries->get_text(a), nEncode));
2085 #if defined(_WIN32)
2086 sData.append("\015\012");
2087 #else
2088 sData.append("\012");
2089 #endif
2091 pCntnr->CopyByteString( SotClipboardFormatId::STRING, sData.makeStringAndClear() );
2092 pCntnr->CopyToClipboard( static_cast<vcl::Window*>(const_cast<OfaAutoCompleteTabPage *>(this)) );
2096 IMPL_LINK(OfaAutoCompleteTabPage, KeyReleaseHdl, const KeyEvent&, rEvent, bool)
2098 bool bHandled = false;
2099 const vcl::KeyCode& rKeyCode = rEvent.GetKeyCode();
2100 switch (rKeyCode.GetModifier() | rKeyCode.GetCode())
2102 case KEY_DELETE:
2103 DeleteHdl(*m_xPBEntries);
2104 bHandled = true;
2105 break;
2106 default:
2107 if (KeyFuncType::COPY == rKeyCode.GetFunction())
2109 CopyToClipboard();
2110 bHandled = true;
2112 break;
2114 return bHandled;
2117 // class OfaSmartTagOptionsTabPage ---------------------------------------------
2119 OfaSmartTagOptionsTabPage::OfaSmartTagOptionsTabPage(TabPageParent pParent,
2120 const SfxItemSet& rSet )
2121 : SfxTabPage(pParent, "cui/ui/smarttagoptionspage.ui", "SmartTagOptionsPage", &rSet)
2122 , m_xMainCB(m_xBuilder->weld_check_button("main"))
2123 , m_xSmartTagTypesLB(m_xBuilder->weld_tree_view("list"))
2124 , m_xPropertiesPB(m_xBuilder->weld_button("properties"))
2126 m_xSmartTagTypesLB->set_size_request(m_xSmartTagTypesLB->get_approximate_digit_width() * 50,
2127 m_xSmartTagTypesLB->get_height_rows(6));
2129 std::vector<int> aWidths;
2130 aWidths.push_back(m_xSmartTagTypesLB->get_checkbox_column_width());
2131 m_xSmartTagTypesLB->set_column_fixed_widths(aWidths);
2133 // set the handlers:
2134 m_xMainCB->connect_toggled(LINK(this, OfaSmartTagOptionsTabPage, CheckHdl));
2135 m_xPropertiesPB->connect_clicked(LINK(this, OfaSmartTagOptionsTabPage, ClickHdl));
2136 m_xSmartTagTypesLB->connect_changed(LINK(this, OfaSmartTagOptionsTabPage, SelectHdl));
2139 OfaSmartTagOptionsTabPage::~OfaSmartTagOptionsTabPage()
2141 disposeOnce();
2144 VclPtr<SfxTabPage> OfaSmartTagOptionsTabPage::Create(TabPageParent pParent, const SfxItemSet* rSet)
2146 return VclPtr<OfaSmartTagOptionsTabPage>::Create(pParent, *rSet);
2149 /** This struct is used to associate list box entries with smart tag data
2151 struct ImplSmartTagLBUserData
2153 OUString maSmartTagType;
2154 uno::Reference< smarttags::XSmartTagRecognizer > mxRec;
2155 sal_Int32 mnSmartTagIdx;
2157 ImplSmartTagLBUserData( const OUString& rSmartTagType,
2158 uno::Reference< smarttags::XSmartTagRecognizer > const & xRec,
2159 sal_Int32 nSmartTagIdx ) :
2160 maSmartTagType( rSmartTagType ),
2161 mxRec( xRec ),
2162 mnSmartTagIdx( nSmartTagIdx ) {}
2165 /** Clears m_xSmartTagTypesLB
2167 void OfaSmartTagOptionsTabPage::ClearListBox()
2169 const int nCount = m_xSmartTagTypesLB->n_children();
2170 for (int i = 0; i < nCount; ++i)
2172 const ImplSmartTagLBUserData* pUserData = reinterpret_cast<ImplSmartTagLBUserData*>(m_xSmartTagTypesLB->get_id(i).toInt64());
2173 delete pUserData;
2176 m_xSmartTagTypesLB->clear();
2179 /** Inserts items into m_xSmartTagTypesLB
2181 void OfaSmartTagOptionsTabPage::FillListBox( const SmartTagMgr& rSmartTagMgr )
2183 // first we have to clear the list box:
2184 ClearListBox();
2186 // fill list box:
2187 const sal_uInt32 nNumberOfRecognizers = rSmartTagMgr.NumberOfRecognizers();
2188 const lang::Locale aLocale( LanguageTag::convertToLocale( eLastDialogLanguage ) );
2190 for ( sal_uInt32 i = 0; i < nNumberOfRecognizers; ++i )
2192 const uno::Reference< smarttags::XSmartTagRecognizer >& xRec = rSmartTagMgr.GetRecognizer(i);
2194 const OUString aName = xRec->getName( aLocale );
2195 const sal_Int32 nNumberOfSupportedSmartTags = xRec->getSmartTagCount();
2197 for ( sal_Int32 j = 0; j < nNumberOfSupportedSmartTags; ++j )
2199 const OUString aSmartTagType = xRec->getSmartTagName(j);
2200 OUString aSmartTagCaption = rSmartTagMgr.GetSmartTagCaption( aSmartTagType, aLocale );
2202 if ( aSmartTagCaption.isEmpty() )
2203 aSmartTagCaption = aSmartTagType;
2205 const OUString aLBEntry = aSmartTagCaption + " (" + aName + ")";
2207 m_xSmartTagTypesLB->append();
2208 const int nRow = m_xSmartTagTypesLB->n_children() - 1;
2209 const bool bCheck = rSmartTagMgr.IsSmartTagTypeEnabled( aSmartTagType );
2210 m_xSmartTagTypesLB->set_toggle(nRow, bCheck ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
2211 m_xSmartTagTypesLB->set_text(nRow, aLBEntry, 1);
2212 m_xSmartTagTypesLB->set_id(nRow, OUString::number(reinterpret_cast<sal_Int64>(new ImplSmartTagLBUserData(aSmartTagType, xRec, j))));
2217 /** Handler for the push button
2219 IMPL_LINK_NOARG(OfaSmartTagOptionsTabPage, ClickHdl, weld::Button&, void)
2221 const int nPos = m_xSmartTagTypesLB->get_selected_index();
2222 const ImplSmartTagLBUserData* pUserData = reinterpret_cast<ImplSmartTagLBUserData*>(m_xSmartTagTypesLB->get_id(nPos).toInt64());
2223 uno::Reference< smarttags::XSmartTagRecognizer > xRec = pUserData->mxRec;
2224 const sal_Int32 nSmartTagIdx = pUserData->mnSmartTagIdx;
2226 const lang::Locale aLocale( LanguageTag::convertToLocale( eLastDialogLanguage ) );
2227 if ( xRec->hasPropertyPage( nSmartTagIdx, aLocale ) )
2228 xRec->displayPropertyPage( nSmartTagIdx, aLocale );
2231 /** Handler for the check box
2233 IMPL_LINK_NOARG(OfaSmartTagOptionsTabPage, CheckHdl, weld::ToggleButton&, void)
2235 const bool bEnable = m_xMainCB->get_active();
2236 m_xSmartTagTypesLB->set_sensitive(bEnable);
2237 m_xPropertiesPB->set_sensitive(false);
2239 // if the controls are currently enabled, we still have to check
2240 // if the properties button should be disabled because the currently
2241 // selected smart tag type does not have a properties dialog.
2242 // We do this by calling SelectHdl:
2243 if (bEnable)
2244 SelectHdl(*m_xSmartTagTypesLB);
2247 /** Handler for the list box
2249 IMPL_LINK_NOARG(OfaSmartTagOptionsTabPage, SelectHdl, weld::TreeView&, void)
2251 const int nPos = m_xSmartTagTypesLB->get_selected_index();
2252 if (nPos == -1)
2253 return;
2254 const ImplSmartTagLBUserData* pUserData = reinterpret_cast<ImplSmartTagLBUserData*>(m_xSmartTagTypesLB->get_id(nPos).toInt64());
2255 uno::Reference< smarttags::XSmartTagRecognizer > xRec = pUserData->mxRec;
2256 const sal_Int32 nSmartTagIdx = pUserData->mnSmartTagIdx;
2258 const lang::Locale aLocale( LanguageTag::convertToLocale( eLastDialogLanguage ) );
2259 if ( xRec->hasPropertyPage( nSmartTagIdx, aLocale ) )
2260 m_xPropertiesPB->set_sensitive(true);
2261 else
2262 m_xPropertiesPB->set_sensitive(false);
2265 /** Propagates the current settings to the smart tag manager.
2267 bool OfaSmartTagOptionsTabPage::FillItemSet( SfxItemSet* )
2269 SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
2270 SvxSwAutoFormatFlags *pOpt = &pAutoCorrect->GetSwFlags();
2271 SmartTagMgr* pSmartTagMgr = pOpt->pSmartTagMgr;
2273 // robust!
2274 if ( !pSmartTagMgr )
2275 return false;
2277 bool bModifiedSmartTagTypes = false;
2278 std::vector< OUString > aDisabledSmartTagTypes;
2280 const int nCount = m_xSmartTagTypesLB->n_children();
2282 for (int i = 0; i < nCount; ++i)
2284 const ImplSmartTagLBUserData* pUserData = reinterpret_cast<ImplSmartTagLBUserData*>(m_xSmartTagTypesLB->get_id(i).toInt64());
2285 const bool bChecked = m_xSmartTagTypesLB->get_toggle(i, CBCOL_FIRST) == TRISTATE_TRUE;
2286 const bool bIsCurrentlyEnabled = pSmartTagMgr->IsSmartTagTypeEnabled( pUserData->maSmartTagType );
2288 bModifiedSmartTagTypes = bModifiedSmartTagTypes || ( !bChecked != !bIsCurrentlyEnabled );
2290 if ( !bChecked )
2291 aDisabledSmartTagTypes.push_back( pUserData->maSmartTagType );
2293 delete pUserData;
2296 const bool bModifiedRecognize = ( !m_xMainCB->get_active() != !pSmartTagMgr->IsLabelTextWithSmartTags() );
2297 if ( bModifiedSmartTagTypes || bModifiedRecognize )
2299 bool bLabelTextWithSmartTags = m_xMainCB->get_active();
2300 pSmartTagMgr->WriteConfiguration( bModifiedRecognize ? &bLabelTextWithSmartTags : nullptr,
2301 bModifiedSmartTagTypes ? &aDisabledSmartTagTypes : nullptr );
2304 return true;
2307 /** Sets the controls based on the current settings at SmartTagMgr.
2309 void OfaSmartTagOptionsTabPage::Reset( const SfxItemSet* )
2311 SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
2312 SvxSwAutoFormatFlags *pOpt = &pAutoCorrect->GetSwFlags();
2313 const SmartTagMgr* pSmartTagMgr = pOpt->pSmartTagMgr;
2315 // robust, should not happen!
2316 if ( !pSmartTagMgr )
2317 return;
2319 FillListBox(*pSmartTagMgr);
2320 m_xSmartTagTypesLB->select(0);
2321 m_xMainCB->set_active(pSmartTagMgr->IsLabelTextWithSmartTags());
2322 CheckHdl(*m_xMainCB);
2325 void OfaSmartTagOptionsTabPage::ActivatePage( const SfxItemSet& )
2327 static_cast<OfaAutoCorrDlg*>(GetDialogController())->EnableLanguage( false );
2330 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */