1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20 #include <sal/config.h>
21
22 #include <i18nutil/unicode.hxx>
23 #include <o3tl/safeint.hxx>
24 #include <utility>
25 #include <vcl/event.hxx>
26 #include <vcl/keycodes.hxx>
27 #include <vcl/settings.hxx>
28 #include <vcl/transfer.hxx>
29 #include <sfx2/app.hxx>
30 #include <sfx2/objsh.hxx>
31 #include <sfx2/viewsh.hxx>
32 #include <unotools/charclass.hxx>
33 #include <unotools/collatorwrapper.hxx>
34 #include <comphelper/processfactory.hxx>
35 #include <vcl/svapp.hxx>
36 #include <sfx2/module.hxx>
37 #include <svl/eitem.hxx>
38 #include <svl/cjkoptions.hxx>
39 #include <svl/ctloptions.hxx>
40 #include <svx/SmartTagMgr.hxx>
41 #include <com/sun/star/smarttags/XSmartTagRecognizer.hpp>
42 #include <rtl/strbuf.hxx>
43 #include <o3tl/temporary.hxx>
44 #include <osl/diagnose.h>
45 #include <tools/debug.hxx>
46
47 #include <autocdlg.hxx>
48 #include <editeng/acorrcfg.hxx>
49 #include <editeng/svxacorr.hxx>
50 #include <svx/cuicharmap.hxx>
51 #include <strings.hrc>
52 #include <dialmgr.hxx>
53 #include <svx/svxids.hrc>
54
55 static LanguageType eLastDialogLanguage = LANGUAGE_SYSTEM;
56
57 using namespace ::com::sun::star;
58
OfaAutoCorrDlg(weld::Window * pParent,const SfxItemSet * _pSet)59 OfaAutoCorrDlg::OfaAutoCorrDlg(weld::Window* pParent, const SfxItemSet* _pSet )
60 : SfxTabDialogController(pParent, u"cui/ui/autocorrectdialog.ui"_ustr, u"AutoCorrectDialog"_ustr, _pSet)
61 , m_xLanguageBox(m_xBuilder->weld_widget(u"langbox"_ustr))
62 , m_xLanguageLB(new SvxLanguageBox(m_xBuilder->weld_combo_box(u"lang"_ustr)))
63 {
64 bool bShowSWOptions = false;
65 bool bOpenSmartTagOptions = false;
66
67 if ( _pSet )
68 {
69 const SfxBoolItem* pItem = SfxItemSet::GetItem<SfxBoolItem>(_pSet, SID_AUTO_CORRECT_DLG, false);
70 if ( pItem && pItem->GetValue() )
71 bShowSWOptions = true;
72
73 const SfxBoolItem* pItem2 = SfxItemSet::GetItem<SfxBoolItem>(_pSet, SID_OPEN_SMARTTAGOPTIONS, false);
74 if ( pItem2 && pItem2->GetValue() )
75 bOpenSmartTagOptions = true;
76 }
77
78 AddTabPage(u"options"_ustr, OfaAutocorrOptionsPage::Create, nullptr);
79 AddTabPage(u"applypage"_ustr, OfaSwAutoFmtOptionsPage::Create, nullptr);
80 AddTabPage(u"wordcompletion"_ustr, OfaAutoCompleteTabPage::Create, nullptr);
81 AddTabPage(u"smarttags"_ustr, OfaSmartTagOptionsTabPage::Create, nullptr);
82
83 if (!bShowSWOptions)
84 {
85 RemoveTabPage(u"applypage"_ustr);
86 RemoveTabPage(u"wordcompletion"_ustr);
87 RemoveTabPage(u"smarttags"_ustr);
88 }
89 else
90 {
91 // remove smart tag tab page if no extensions are installed
92 SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
93 SvxSwAutoFormatFlags& rOpt = pAutoCorrect->GetSwFlags();
94 if (!rOpt.pSmartTagMgr || 0 == rOpt.pSmartTagMgr->NumberOfRecognizers())
95 RemoveTabPage(u"smarttags"_ustr);
96
97 RemoveTabPage(u"options"_ustr);
98 }
99
100 AddTabPage(u"replace"_ustr, OfaAutocorrReplacePage::Create, nullptr);
101 AddTabPage(u"exceptions"_ustr, OfaAutocorrExceptPage::Create, nullptr);
102 AddTabPage(u"localized"_ustr, OfaQuoteTabPage::Create, nullptr);
103
104 // initialize languages
105 //! LANGUAGE_NONE is displayed as '[All]' and the LanguageType
106 //! will be set to LANGUAGE_UNDETERMINED
107 SvxLanguageListFlags nLangList = SvxLanguageListFlags::WESTERN;
108
109 if( SvtCTLOptions::IsCTLFontEnabled() )
110 nLangList |= SvxLanguageListFlags::CTL;
111 if( SvtCJKOptions::IsCJKFontEnabled() )
112 nLangList |= SvxLanguageListFlags::CJK;
113 m_xLanguageLB->SetLanguageList( nLangList, true, true );
114 m_xLanguageLB->set_active_id( LANGUAGE_NONE );
115 int nPos = m_xLanguageLB->get_active();
116 DBG_ASSERT(nPos != -1, "listbox entry missing" );
117 m_xLanguageLB->set_id(nPos, LANGUAGE_UNDETERMINED);
118
119 // Initializing doesn't work for static on linux - therefore here
120 if (LANGUAGE_SYSTEM == eLastDialogLanguage)
121 eLastDialogLanguage = Application::GetSettings().GetLanguageTag().getLanguageType();
122
123 LanguageType nSelectLang = LANGUAGE_UNDETERMINED;
124 nPos = m_xLanguageLB->find_id(eLastDialogLanguage);
125 if (nPos != -1)
126 nSelectLang = eLastDialogLanguage;
127 m_xLanguageLB->set_active_id(nSelectLang);
128
129 m_xLanguageLB->connect_changed(LINK(this, OfaAutoCorrDlg, SelectLanguageHdl));
130
131 if ( bOpenSmartTagOptions )
132 SetCurPageId(u"smarttags"_ustr);
133 }
134
~OfaAutoCorrDlg()135 OfaAutoCorrDlg::~OfaAutoCorrDlg()
136 {
137 }
138
EnableLanguage(bool bEnable)139 void OfaAutoCorrDlg::EnableLanguage(bool bEnable)
140 {
141 m_xLanguageBox->set_sensitive(bEnable);
142 }
143
lcl_FindEntry(weld::TreeView & rLB,const OUString & rEntry,CollatorWrapper const & rCmpClass)144 static bool lcl_FindEntry(weld::TreeView& rLB, const OUString& rEntry,
145 CollatorWrapper const & rCmpClass)
146 {
147 int nCount = rLB.n_children();
148 int nSelPos = rLB.get_selected_index();
149 for (int i = 0; i < nCount; i++)
150 {
151 if (0 == rCmpClass.compareString(rEntry, rLB.get_text(i)))
152 {
153 rLB.select(i);
154 return true;
155 }
156 }
157 if (nSelPos != -1)
158 rLB.unselect(nSelPos);
159 return false;
160 }
161
IMPL_LINK_NOARG(OfaAutoCorrDlg,SelectLanguageHdl,weld::ComboBox &,void)162 IMPL_LINK_NOARG(OfaAutoCorrDlg, SelectLanguageHdl, weld::ComboBox&, void)
163 {
164 LanguageType eNewLang = m_xLanguageLB->get_active_id();
165 // save old settings and fill anew
166 if(eNewLang == eLastDialogLanguage)
167 return;
168
169 OUString sPageId = GetCurPageId();
170 if (sPageId == "replace")
171 {
172 OfaAutocorrReplacePage* pPage = static_cast<OfaAutocorrReplacePage*>(GetTabPage(sPageId));
173 assert(pPage);
174 pPage->SetLanguage(eNewLang);
175 }
176 else if (sPageId == "exceptions")
177 {
178 OfaAutocorrExceptPage* pPage = static_cast<OfaAutocorrExceptPage*>(GetTabPage(sPageId));
179 assert(pPage);
180 pPage->SetLanguage(eNewLang);
181 }
182 }
183
OfaAutocorrOptionsPage(weld::Container * pPage,weld::DialogController * pController,const SfxItemSet & rSet)184 OfaAutocorrOptionsPage::OfaAutocorrOptionsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
185 : SfxTabPage(pPage, pController, u"cui/ui/acoroptionspage.ui"_ustr, u"AutocorrectOptionsPage"_ustr, &rSet)
186 , m_sInput(CuiResId(RID_CUISTR_USE_REPLACE))
187 , m_sDoubleCaps(CuiResId(RID_CUISTR_CPTL_STT_WORD))
188 , m_sStartCap(CuiResId(RID_CUISTR_CPTL_STT_SENT))
189 , m_sBoldUnderline(CuiResId(RID_CUISTR_BOLD_UNDER))
190 , m_sURL(CuiResId(RID_CUISTR_DETECT_URL))
191 , m_sDOI(CuiResId(RID_CUISTR_DETECT_DOI))
192 , m_sNoDblSpaces(CuiResId(RID_CUISTR_NO_DBL_SPACES))
193 , m_sDash(CuiResId(RID_CUISTR_DASH))
194 , m_sAccidentalCaps(CuiResId(RID_CUISTR_CORRECT_ACCIDENTAL_CAPS_LOCK))
195 , m_xCheckLB(m_xBuilder->weld_tree_view(u"checklist"_ustr))
196 {
197 m_xCheckLB->enable_toggle_buttons(weld::ColumnToggleType::Check);
198 m_xCheckLB->set_size_request(-1, m_xCheckLB->get_height_rows(10));
199 }
200
~OfaAutocorrOptionsPage()201 OfaAutocorrOptionsPage::~OfaAutocorrOptionsPage()
202 {
203 }
204
Create(weld::Container * pPage,weld::DialogController * pController,const SfxItemSet * rSet)205 std::unique_ptr<SfxTabPage> OfaAutocorrOptionsPage::Create(weld::Container* pPage, weld::DialogController* pController,
206 const SfxItemSet* rSet)
207 {
208 return std::make_unique<OfaAutocorrOptionsPage>(pPage, pController, *rSet);
209 }
210
211 #define CBCOL_FIRST 0
212 #define CBCOL_SECOND 1
213 #define CBCOL_BOTH 2
214
FillItemSet(SfxItemSet *)215 bool OfaAutocorrOptionsPage::FillItemSet( SfxItemSet* )
216 {
217 SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
218 ACFlags nFlags = pAutoCorrect->GetFlags();
219
220 int nPos = 0;
221 pAutoCorrect->SetAutoCorrFlag(ACFlags::Autocorrect, m_xCheckLB->get_toggle(nPos++) == TRISTATE_TRUE);
222 pAutoCorrect->SetAutoCorrFlag(ACFlags::CapitalStartWord, m_xCheckLB->get_toggle(nPos++) == TRISTATE_TRUE);
223 pAutoCorrect->SetAutoCorrFlag(ACFlags::CapitalStartSentence, m_xCheckLB->get_toggle(nPos++) == TRISTATE_TRUE);
224 pAutoCorrect->SetAutoCorrFlag(ACFlags::ChgWeightUnderl, m_xCheckLB->get_toggle(nPos++) == TRISTATE_TRUE);
225 pAutoCorrect->SetAutoCorrFlag(ACFlags::SetINetAttr, m_xCheckLB->get_toggle(nPos++) == TRISTATE_TRUE);
226 pAutoCorrect->SetAutoCorrFlag(ACFlags::SetDOIAttr, m_xCheckLB->get_toggle(nPos++) == TRISTATE_TRUE);
227 pAutoCorrect->SetAutoCorrFlag(ACFlags::ChgToEnEmDash, m_xCheckLB->get_toggle(nPos++) == TRISTATE_TRUE);
228 pAutoCorrect->SetAutoCorrFlag(ACFlags::IgnoreDoubleSpace, m_xCheckLB->get_toggle(nPos++) == TRISTATE_TRUE);
229 pAutoCorrect->SetAutoCorrFlag(ACFlags::CorrectCapsLock, m_xCheckLB->get_toggle(nPos++) == TRISTATE_TRUE);
230
231 bool bReturn = nFlags != pAutoCorrect->GetFlags();
232 if(bReturn )
233 {
234 SvxAutoCorrCfg& rCfg = SvxAutoCorrCfg::Get();
235 rCfg.SetModified();
236 rCfg.Commit();
237 }
238 return bReturn;
239 }
240
ActivatePage(const SfxItemSet &)241 void OfaAutocorrOptionsPage::ActivatePage( const SfxItemSet& )
242 {
243 static_cast<OfaAutoCorrDlg*>(GetDialogController())->EnableLanguage(false);
244 }
245
InsertEntry(const OUString & rTxt)246 void OfaAutocorrOptionsPage::InsertEntry(const OUString& rTxt)
247 {
248 m_xCheckLB->append();
249 const int nRow = m_xCheckLB->n_children() - 1;
250 m_xCheckLB->set_toggle(nRow, TRISTATE_FALSE);
251 m_xCheckLB->set_text(nRow, rTxt, 0);
252 }
253
Reset(const SfxItemSet *)254 void OfaAutocorrOptionsPage::Reset( const SfxItemSet* )
255 {
256 SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
257 const ACFlags nFlags = pAutoCorrect->GetFlags();
258
259 m_xCheckLB->freeze();
260 m_xCheckLB->clear();
261
262 InsertEntry(m_sInput);
263 InsertEntry(m_sDoubleCaps);
264 InsertEntry(m_sStartCap);
265 InsertEntry(m_sBoldUnderline);
266 InsertEntry(m_sURL);
267 InsertEntry(m_sDOI);
268 InsertEntry(m_sDash);
269 InsertEntry(m_sNoDblSpaces);
270 InsertEntry(m_sAccidentalCaps);
271
272 int nPos = 0;
273 m_xCheckLB->set_toggle( nPos++, bool(nFlags & ACFlags::Autocorrect) ? TRISTATE_TRUE : TRISTATE_FALSE );
274 m_xCheckLB->set_toggle( nPos++, bool(nFlags & ACFlags::CapitalStartWord) ? TRISTATE_TRUE : TRISTATE_FALSE );
275 m_xCheckLB->set_toggle( nPos++, bool(nFlags & ACFlags::CapitalStartSentence) ? TRISTATE_TRUE : TRISTATE_FALSE );
276 m_xCheckLB->set_toggle( nPos++, bool(nFlags & ACFlags::ChgWeightUnderl) ? TRISTATE_TRUE : TRISTATE_FALSE );
277 m_xCheckLB->set_toggle( nPos++, bool(nFlags & ACFlags::SetINetAttr) ? TRISTATE_TRUE : TRISTATE_FALSE );
278 m_xCheckLB->set_toggle( nPos++, bool(nFlags & ACFlags::SetDOIAttr) ? TRISTATE_TRUE : TRISTATE_FALSE );
279 m_xCheckLB->set_toggle( nPos++, bool(nFlags & ACFlags::ChgToEnEmDash) ? TRISTATE_TRUE : TRISTATE_FALSE );
280 m_xCheckLB->set_toggle( nPos++, bool(nFlags & ACFlags::IgnoreDoubleSpace) ? TRISTATE_TRUE : TRISTATE_FALSE );
281 m_xCheckLB->set_toggle( nPos++, bool(nFlags & ACFlags::CorrectCapsLock) ? TRISTATE_TRUE : TRISTATE_FALSE );
282
283 m_xCheckLB->thaw();
284 }
285
286 /*********************************************************************/
287 /* */
288 /* helping struct for dUserData of the Checklistbox */
289 /* */
290 /*********************************************************************/
291
292 namespace {
293
294 struct ImpUserData
295 {
296 OUString *pString;
297 vcl::Font *pFont;
298
ImpUserData__anonffeffcef0111::ImpUserData299 ImpUserData(OUString* pText, vcl::Font* pFnt)
300 { pString = pText; pFont = pFnt;}
301 };
302
303
304 /*********************************************************************/
305 /* */
306 /* dialog for per cent settings */
307 /* */
308 /*********************************************************************/
309
310 class OfaAutoFmtPrcntSet : public weld::GenericDialogController
311 {
312 std::unique_ptr<weld::MetricSpinButton> m_xPrcntMF;
313 public:
OfaAutoFmtPrcntSet(weld::Window * pParent)314 explicit OfaAutoFmtPrcntSet(weld::Window* pParent)
315 : GenericDialogController(pParent, u"cui/ui/percentdialog.ui"_ustr, u"PercentDialog"_ustr)
316 , m_xPrcntMF(m_xBuilder->weld_metric_spin_button(u"margin"_ustr, FieldUnit::PERCENT))
317 {
318 }
319
GetPrcntFld()320 weld::MetricSpinButton& GetPrcntFld()
321 {
322 return *m_xPrcntMF;
323 }
324 };
325
326 /*********************************************************************/
327 /* */
328 /* use TabPage autoformat */
329 /* */
330 /*********************************************************************/
331
332 enum OfaAutoFmtOptions
333 {
334 USE_REPLACE_TABLE,
335 CORR_UPPER,
336 BEGIN_UPPER,
337 BOLD_UNDERLINE,
338 DETECT_URL,
339 DETECT_DOI,
340 REPLACE_DASHES,
341 DEL_SPACES_AT_STT_END,
342 DEL_SPACES_BETWEEN_LINES,
343 IGNORE_DBLSPACE,
344 CORRECT_CAPS_LOCK,
345 APPLY_NUMBERING,
346 APPLY_NUMBERING_AFTER_SPACE,
347 INSERT_BORDER,
348 CREATE_TABLE,
349 REPLACE_STYLES,
350 DEL_EMPTY_NODE,
351 REPLACE_USER_COLL,
352 REPLACE_BULLETS,
353 MERGE_SINGLE_LINE_PARA
354 };
355
356 }
357
OfaSwAutoFmtOptionsPage(weld::Container * pPage,weld::DialogController * pController,const SfxItemSet & rSet)358 OfaSwAutoFmtOptionsPage::OfaSwAutoFmtOptionsPage(weld::Container* pPage, weld::DialogController* pController,
359 const SfxItemSet& rSet )
360 : SfxTabPage(pPage, pController, u"cui/ui/applyautofmtpage.ui"_ustr, u"ApplyAutoFmtPage"_ustr, &rSet)
361 , sDeleteEmptyPara(CuiResId(RID_CUISTR_DEL_EMPTY_PARA))
362 , sUseReplaceTbl(CuiResId(RID_CUISTR_USE_REPLACE))
363 , sCapitalStartWord(CuiResId(RID_CUISTR_CPTL_STT_WORD))
364 , sCapitalStartSentence(CuiResId(RID_CUISTR_CPTL_STT_SENT))
365 , sUserStyle(CuiResId(RID_CUISTR_USER_STYLE))
366 , sBullet(CuiResId(RID_CUISTR_BULLET))
367 , sBoldUnder(CuiResId(RID_CUISTR_BOLD_UNDER))
368 , sNoDblSpaces(CuiResId(RID_CUISTR_NO_DBL_SPACES))
369 , sCorrectCapsLock(CuiResId(RID_CUISTR_CORRECT_ACCIDENTAL_CAPS_LOCK))
370 , sDetectURL(CuiResId(RID_CUISTR_DETECT_URL))
371 , sDetectDOI(CuiResId(RID_CUISTR_DETECT_DOI))
372 , sDash(CuiResId(RID_CUISTR_DASH))
373 , sRightMargin(CuiResId(RID_CUISTR_RIGHT_MARGIN))
374 , sNum(CuiResId(RID_CUISTR_NUM))
375 , sBulletsAfterSpace(CuiResId(RID_SVXSTR_NUM_FORMAT_AFTER_SPACE))
376 , sBorder(CuiResId(RID_CUISTR_BORDER))
377 , sTable(CuiResId(RID_CUISTR_CREATE_TABLE))
378 , sReplaceTemplates(CuiResId(RID_CUISTR_REPLACE_TEMPLATES))
379 , sDelSpaceAtSttEnd(CuiResId(RID_CUISTR_DEL_SPACES_AT_STT_END))
380 , sDelSpaceBetweenLines(CuiResId(RID_CUISTR_DEL_SPACES_BETWEEN_LINES))
381 , nPercent(50)
382 , m_xCheckLB(m_xBuilder->weld_tree_view(u"list"_ustr))
383 , m_xEditPB(m_xBuilder->weld_button(u"edit"_ustr))
384 {
385 m_xCheckLB->connect_changed(LINK(this, OfaSwAutoFmtOptionsPage, SelectHdl));
386 m_xCheckLB->connect_row_activated(LINK(this, OfaSwAutoFmtOptionsPage, DoubleClickEditHdl));
387
388 std::vector<int> aWidths
389 {
390 o3tl::narrowing<int>(m_xCheckLB->get_pixel_size(m_xCheckLB->get_column_title(0)).Width() * 2),
391 o3tl::narrowing<int>(m_xCheckLB->get_pixel_size(m_xCheckLB->get_column_title(1)).Width() * 2)
392 };
393 m_xCheckLB->set_column_fixed_widths(aWidths);
394
395 m_xEditPB->connect_clicked(LINK(this, OfaSwAutoFmtOptionsPage, EditHdl));
396 }
397
CreateEntry(const OUString & rTxt,sal_uInt16 nCol)398 void OfaSwAutoFmtOptionsPage::CreateEntry(const OUString& rTxt, sal_uInt16 nCol)
399 {
400 m_xCheckLB->append();
401 const int nRow = m_xCheckLB->n_children() - 1;
402 if (nCol == CBCOL_FIRST || nCol == CBCOL_BOTH)
403 m_xCheckLB->set_toggle(nRow, TRISTATE_FALSE, CBCOL_FIRST);
404 if (nCol == CBCOL_SECOND || nCol == CBCOL_BOTH)
405 m_xCheckLB->set_toggle(nRow, TRISTATE_FALSE, CBCOL_SECOND);
406 m_xCheckLB->set_text(nRow, rTxt, 2);
407 }
408
~OfaSwAutoFmtOptionsPage()409 OfaSwAutoFmtOptionsPage::~OfaSwAutoFmtOptionsPage()
410 {
411 delete weld::fromId<ImpUserData*>(m_xCheckLB->get_id(REPLACE_BULLETS));
412 delete weld::fromId<ImpUserData*>(m_xCheckLB->get_id(APPLY_NUMBERING));
413 delete weld::fromId<ImpUserData*>(m_xCheckLB->get_id(MERGE_SINGLE_LINE_PARA));
414 }
415
Create(weld::Container * pPage,weld::DialogController * pController,const SfxItemSet * rAttrSet)416 std::unique_ptr<SfxTabPage> OfaSwAutoFmtOptionsPage::Create(weld::Container* pPage, weld::DialogController* pController,
417 const SfxItemSet* rAttrSet)
418 {
419 return std::make_unique<OfaSwAutoFmtOptionsPage>(pPage, pController, *rAttrSet);
420 }
421
FillItemSet(SfxItemSet *)422 bool OfaSwAutoFmtOptionsPage::FillItemSet( SfxItemSet* )
423 {
424 bool bModified = false;
425 SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
426 SvxSwAutoFormatFlags *pOpt = &pAutoCorrect->GetSwFlags();
427 ACFlags nFlags = pAutoCorrect->GetFlags();
428
429 bool bCheck = m_xCheckLB->get_toggle(USE_REPLACE_TABLE, CBCOL_FIRST) == TRISTATE_TRUE;
430 bModified |= pOpt->bAutoCorrect != bCheck;
431 pOpt->bAutoCorrect = bCheck;
432 pAutoCorrect->SetAutoCorrFlag(ACFlags::Autocorrect,
433 m_xCheckLB->get_toggle(USE_REPLACE_TABLE, CBCOL_SECOND) == TRISTATE_TRUE);
434
435 bCheck = m_xCheckLB->get_toggle(CORR_UPPER, CBCOL_FIRST) == TRISTATE_TRUE;
436 bModified |= pOpt->bCapitalStartWord != bCheck;
437 pOpt->bCapitalStartWord = bCheck;
438 pAutoCorrect->SetAutoCorrFlag(ACFlags::CapitalStartWord,
439 m_xCheckLB->get_toggle(CORR_UPPER, CBCOL_SECOND) == TRISTATE_TRUE);
440
441 bCheck = m_xCheckLB->get_toggle(BEGIN_UPPER, CBCOL_FIRST) == TRISTATE_TRUE;
442 bModified |= pOpt->bCapitalStartSentence != bCheck;
443 pOpt->bCapitalStartSentence = bCheck;
444 pAutoCorrect->SetAutoCorrFlag(ACFlags::CapitalStartSentence,
445 m_xCheckLB->get_toggle(BEGIN_UPPER, CBCOL_SECOND) == TRISTATE_TRUE);
446
447 bCheck = m_xCheckLB->get_toggle(BOLD_UNDERLINE, CBCOL_FIRST) == TRISTATE_TRUE;
448 bModified |= pOpt->bChgWeightUnderl != bCheck;
449 pOpt->bChgWeightUnderl = bCheck;
450 pAutoCorrect->SetAutoCorrFlag(ACFlags::ChgWeightUnderl,
451 m_xCheckLB->get_toggle(BOLD_UNDERLINE, CBCOL_SECOND) == TRISTATE_TRUE);
452
453 pAutoCorrect->SetAutoCorrFlag(ACFlags::IgnoreDoubleSpace,
454 m_xCheckLB->get_toggle(IGNORE_DBLSPACE, CBCOL_SECOND) == TRISTATE_TRUE);
455
456 pAutoCorrect->SetAutoCorrFlag(ACFlags::CorrectCapsLock,
457 m_xCheckLB->get_toggle(CORRECT_CAPS_LOCK, CBCOL_SECOND) == TRISTATE_TRUE);
458
459 bCheck = m_xCheckLB->get_toggle(DETECT_URL, CBCOL_FIRST) == TRISTATE_TRUE;
460 bModified |= pOpt->bSetINetAttr != bCheck;
461 pOpt->bSetINetAttr = bCheck;
462 pAutoCorrect->SetAutoCorrFlag(ACFlags::SetINetAttr,
463 m_xCheckLB->get_toggle(DETECT_URL, CBCOL_SECOND) == TRISTATE_TRUE);
464
465 bCheck = m_xCheckLB->get_toggle(DETECT_DOI, CBCOL_FIRST) == TRISTATE_TRUE;
466 bModified |= pOpt->bSetDOIAttr != bCheck;
467 pOpt->bSetDOIAttr = bCheck;
468 pAutoCorrect->SetAutoCorrFlag(ACFlags::SetDOIAttr,
469 m_xCheckLB->get_toggle(DETECT_DOI, CBCOL_SECOND) == TRISTATE_TRUE);
470
471 bCheck = m_xCheckLB->get_toggle(DEL_EMPTY_NODE, CBCOL_FIRST) == TRISTATE_TRUE;
472 bModified |= pOpt->bDelEmptyNode != bCheck;
473 pOpt->bDelEmptyNode = bCheck;
474
475 bCheck = m_xCheckLB->get_toggle(REPLACE_USER_COLL, CBCOL_FIRST) == TRISTATE_TRUE;
476 bModified |= pOpt->bChgUserColl != bCheck;
477 pOpt->bChgUserColl = bCheck;
478
479 bCheck = m_xCheckLB->get_toggle(REPLACE_BULLETS, CBCOL_FIRST) == TRISTATE_TRUE;
480 bModified |= pOpt->bChgEnumNum != bCheck;
481 pOpt->bChgEnumNum = bCheck;
482 bModified |= aBulletFont != pOpt->aBulletFont;
483 pOpt->aBulletFont = aBulletFont;
484 bModified |= sBulletChar != OUString(&pOpt->cBullet, 1);
485 pOpt->cBullet = sBulletChar.iterateCodePoints(&o3tl::temporary(sal_Int32(0)));
486
487 bModified |= aByInputBulletFont != pOpt->aByInputBulletFont;
488 bModified |= sByInputBulletChar != OUString(&pOpt->cByInputBullet, 1);
489 pOpt->aByInputBulletFont = aByInputBulletFont;
490 pOpt->cByInputBullet = sByInputBulletChar.iterateCodePoints(&o3tl::temporary(sal_Int32(0)));
491
492 bCheck = m_xCheckLB->get_toggle(MERGE_SINGLE_LINE_PARA, CBCOL_FIRST) == TRISTATE_TRUE;
493 bModified |= pOpt->bRightMargin != bCheck;
494 pOpt->bRightMargin = bCheck;
495 bModified |= nPercent != pOpt->nRightMargin;
496 pOpt->nRightMargin = static_cast<sal_uInt8>(nPercent);
497
498 bCheck = m_xCheckLB->get_toggle(APPLY_NUMBERING, CBCOL_SECOND) == TRISTATE_TRUE;
499 bModified |= pOpt->bSetNumRule != bCheck;
500 pOpt->bSetNumRule = bCheck;
501
502 bCheck = m_xCheckLB->get_toggle(APPLY_NUMBERING_AFTER_SPACE, CBCOL_SECOND) == TRISTATE_TRUE;
503 bModified |= pOpt->bSetNumRuleAfterSpace != bCheck;
504 pOpt->bSetNumRuleAfterSpace = bCheck;
505
506 bCheck = m_xCheckLB->get_toggle(INSERT_BORDER, CBCOL_SECOND) == TRISTATE_TRUE;
507 bModified |= pOpt->bSetBorder != bCheck;
508 pOpt->bSetBorder = bCheck;
509
510 bCheck = m_xCheckLB->get_toggle(CREATE_TABLE, CBCOL_SECOND) == TRISTATE_TRUE;
511 bModified |= pOpt->bCreateTable != bCheck;
512 pOpt->bCreateTable = bCheck;
513
514 bCheck = m_xCheckLB->get_toggle(REPLACE_STYLES, CBCOL_SECOND) == TRISTATE_TRUE;
515 bModified |= pOpt->bReplaceStyles != bCheck;
516 pOpt->bReplaceStyles = bCheck;
517
518 bCheck = m_xCheckLB->get_toggle(REPLACE_DASHES, CBCOL_FIRST) == TRISTATE_TRUE;
519 bModified |= pOpt->bChgToEnEmDash != bCheck;
520 pOpt->bChgToEnEmDash = bCheck;
521 pAutoCorrect->SetAutoCorrFlag(ACFlags::ChgToEnEmDash,
522 m_xCheckLB->get_toggle(REPLACE_DASHES, CBCOL_SECOND) == TRISTATE_TRUE);
523
524 bCheck = m_xCheckLB->get_toggle(DEL_SPACES_AT_STT_END, CBCOL_FIRST) == TRISTATE_TRUE;
525 bModified |= pOpt->bAFormatDelSpacesAtSttEnd != bCheck;
526 pOpt->bAFormatDelSpacesAtSttEnd = bCheck;
527 bCheck = m_xCheckLB->get_toggle(DEL_SPACES_AT_STT_END, CBCOL_SECOND) == TRISTATE_TRUE;
528 bModified |= pOpt->bAFormatByInpDelSpacesAtSttEnd != bCheck;
529 pOpt->bAFormatByInpDelSpacesAtSttEnd = bCheck;
530
531 bCheck = m_xCheckLB->get_toggle(DEL_SPACES_BETWEEN_LINES, CBCOL_FIRST) == TRISTATE_TRUE;
532 bModified |= pOpt->bAFormatDelSpacesBetweenLines != bCheck;
533 pOpt->bAFormatDelSpacesBetweenLines = bCheck;
534 bCheck = m_xCheckLB->get_toggle(DEL_SPACES_BETWEEN_LINES, CBCOL_SECOND) == TRISTATE_TRUE;
535 bModified |= pOpt->bAFormatByInpDelSpacesBetweenLines != bCheck;
536 pOpt->bAFormatByInpDelSpacesBetweenLines = bCheck;
537
538 if(bModified || nFlags != pAutoCorrect->GetFlags())
539 {
540 SvxAutoCorrCfg& rCfg = SvxAutoCorrCfg::Get();
541 rCfg.SetModified();
542 rCfg.Commit();
543 }
544
545 return true;
546 }
547
ActivatePage(const SfxItemSet &)548 void OfaSwAutoFmtOptionsPage::ActivatePage( const SfxItemSet& )
549 {
550 static_cast<OfaAutoCorrDlg*>(GetDialogController())->EnableLanguage(false);
551 }
552
Reset(const SfxItemSet *)553 void OfaSwAutoFmtOptionsPage::Reset( const SfxItemSet* )
554 {
555 SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
556 SvxSwAutoFormatFlags *pOpt = &pAutoCorrect->GetSwFlags();
557 const ACFlags nFlags = pAutoCorrect->GetFlags();
558
559 aBulletFont = pOpt->aBulletFont;
560 sBulletChar = OUString(&pOpt->cBullet, 1);
561
562 aByInputBulletFont = pOpt->aByInputBulletFont;
563 sByInputBulletChar = OUString(&pOpt->cByInputBullet, 1);
564
565 nPercent = pOpt->nRightMargin;
566 sMargin = unicode::formatPercent(nPercent, Application::GetSettings().GetUILanguageTag());
567
568 m_xCheckLB->freeze();
569 m_xCheckLB->clear();
570
571 // The following entries have to be inserted in the same order
572 // as in the OfaAutoFmtOptions-enum!
573 CreateEntry(sUseReplaceTbl, CBCOL_BOTH );
574 CreateEntry(sCapitalStartWord, CBCOL_BOTH );
575 CreateEntry(sCapitalStartSentence, CBCOL_BOTH );
576 CreateEntry(sBoldUnder, CBCOL_BOTH );
577 CreateEntry(sDetectURL, CBCOL_BOTH );
578 CreateEntry(sDetectDOI, CBCOL_BOTH );
579 CreateEntry(sDash, CBCOL_BOTH );
580 CreateEntry(sDelSpaceAtSttEnd, CBCOL_BOTH );
581 CreateEntry(sDelSpaceBetweenLines, CBCOL_BOTH );
582
583 CreateEntry(sNoDblSpaces, CBCOL_SECOND);
584 CreateEntry(sCorrectCapsLock, CBCOL_SECOND);
585 CreateEntry(sNum.replaceFirst("%1", sBulletChar), CBCOL_SECOND);
586 CreateEntry(sBulletsAfterSpace, CBCOL_SECOND);
587 CreateEntry(sBorder, CBCOL_SECOND);
588 CreateEntry(sTable, CBCOL_SECOND);
589 CreateEntry(sReplaceTemplates, CBCOL_SECOND);
590 CreateEntry(sDeleteEmptyPara, CBCOL_FIRST );
591 CreateEntry(sUserStyle, CBCOL_FIRST );
592 CreateEntry(sBullet.replaceFirst("%1", sByInputBulletChar), CBCOL_FIRST);
593 CreateEntry(sRightMargin.replaceFirst("%1", sMargin), CBCOL_FIRST);
594
595 m_xCheckLB->set_toggle(USE_REPLACE_TABLE, pOpt->bAutoCorrect ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
596 m_xCheckLB->set_toggle(USE_REPLACE_TABLE, bool(nFlags & ACFlags::Autocorrect) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
597 m_xCheckLB->set_toggle(CORR_UPPER, pOpt->bCapitalStartWord ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
598 m_xCheckLB->set_toggle(CORR_UPPER, bool(nFlags & ACFlags::CapitalStartWord) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
599 m_xCheckLB->set_toggle(BEGIN_UPPER, pOpt->bCapitalStartSentence ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
600 m_xCheckLB->set_toggle(BEGIN_UPPER, bool(nFlags & ACFlags::CapitalStartSentence) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
601 m_xCheckLB->set_toggle(BOLD_UNDERLINE, pOpt->bChgWeightUnderl ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
602 m_xCheckLB->set_toggle(BOLD_UNDERLINE, bool(nFlags & ACFlags::ChgWeightUnderl) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
603 m_xCheckLB->set_toggle(DETECT_URL, pOpt->bSetINetAttr ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
604 m_xCheckLB->set_toggle(DETECT_URL, bool(nFlags & ACFlags::SetINetAttr) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
605 m_xCheckLB->set_toggle(DETECT_DOI, pOpt->bSetDOIAttr ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
606 m_xCheckLB->set_toggle(DETECT_DOI, bool(nFlags & ACFlags::SetDOIAttr) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
607 m_xCheckLB->set_toggle(REPLACE_DASHES, pOpt->bChgToEnEmDash ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
608 m_xCheckLB->set_toggle(REPLACE_DASHES, bool(nFlags & ACFlags::ChgToEnEmDash) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
609 m_xCheckLB->set_toggle(DEL_SPACES_AT_STT_END, pOpt->bAFormatDelSpacesAtSttEnd ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
610 m_xCheckLB->set_toggle(DEL_SPACES_AT_STT_END, pOpt->bAFormatByInpDelSpacesAtSttEnd ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
611 m_xCheckLB->set_toggle(DEL_SPACES_BETWEEN_LINES, pOpt->bAFormatDelSpacesBetweenLines ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
612 m_xCheckLB->set_toggle(DEL_SPACES_BETWEEN_LINES, pOpt->bAFormatByInpDelSpacesBetweenLines ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
613 m_xCheckLB->set_toggle(IGNORE_DBLSPACE, bool(nFlags & ACFlags::IgnoreDoubleSpace) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
614 m_xCheckLB->set_toggle(CORRECT_CAPS_LOCK, bool(nFlags & ACFlags::CorrectCapsLock) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
615 m_xCheckLB->set_toggle(APPLY_NUMBERING, pOpt->bSetNumRule ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
616 m_xCheckLB->set_toggle(APPLY_NUMBERING_AFTER_SPACE, pOpt->bSetNumRuleAfterSpace ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
617 m_xCheckLB->set_toggle(INSERT_BORDER, pOpt->bSetBorder ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
618 m_xCheckLB->set_toggle(CREATE_TABLE, pOpt->bCreateTable ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
619 m_xCheckLB->set_toggle(REPLACE_STYLES, pOpt->bReplaceStyles ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
620 m_xCheckLB->set_toggle(DEL_EMPTY_NODE, pOpt->bDelEmptyNode ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
621 m_xCheckLB->set_toggle(REPLACE_USER_COLL, pOpt->bChgUserColl ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
622 m_xCheckLB->set_toggle(REPLACE_BULLETS, pOpt->bChgEnumNum ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
623 m_xCheckLB->set_toggle(MERGE_SINGLE_LINE_PARA, pOpt->bRightMargin ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
624
625 ImpUserData* pUserData = new ImpUserData(&sBulletChar, &aBulletFont);
626 OUString sId(weld::toId(pUserData));
627 m_xCheckLB->set_id(REPLACE_BULLETS, sId);
628
629 pUserData = new ImpUserData(&sMargin, nullptr);
630 sId = weld::toId(pUserData);
631 m_xCheckLB->set_id(MERGE_SINGLE_LINE_PARA, sId);
632
633 ImpUserData* pUserData2 = new ImpUserData(&sByInputBulletChar, &aByInputBulletFont);
634 sId = weld::toId(pUserData2);
635 m_xCheckLB->set_id(APPLY_NUMBERING, sId);
636
637 m_xCheckLB->thaw();
638 }
639
IMPL_LINK(OfaSwAutoFmtOptionsPage,SelectHdl,weld::TreeView &,rBox,void)640 IMPL_LINK(OfaSwAutoFmtOptionsPage, SelectHdl, weld::TreeView&, rBox, void)
641 {
642 m_xEditPB->set_sensitive(rBox.get_selected_id().toInt64() != 0);
643 }
644
IMPL_LINK_NOARG(OfaSwAutoFmtOptionsPage,DoubleClickEditHdl,weld::TreeView &,bool)645 IMPL_LINK_NOARG(OfaSwAutoFmtOptionsPage, DoubleClickEditHdl, weld::TreeView&, bool)
646 {
647 EditHdl(*m_xEditPB);
648 return true;
649 }
650
IMPL_LINK_NOARG(OfaSwAutoFmtOptionsPage,EditHdl,weld::Button &,void)651 IMPL_LINK_NOARG(OfaSwAutoFmtOptionsPage, EditHdl, weld::Button&, void)
652 {
653 int nSelEntryPos = m_xCheckLB->get_selected_index();
654 if (nSelEntryPos == REPLACE_BULLETS || nSelEntryPos == APPLY_NUMBERING)
655 {
656 SvxCharacterMap aMapDlg(GetFrameWeld(), nullptr, nullptr);
657 ImpUserData* pUserData = weld::fromId<ImpUserData*>(m_xCheckLB->get_id(nSelEntryPos));
658 aMapDlg.SetCharFont(*pUserData->pFont);
659 aMapDlg.SetChar( (*pUserData->pString)[0] );
660 if (RET_OK == aMapDlg.run())
661 {
662 const vcl::Font& aFont(aMapDlg.GetCharFont());
663 *pUserData->pFont = aFont;
664 sal_UCS4 aChar = aMapDlg.GetChar();
665 // using the UCS4 constructor
666 OUString aOUStr( &aChar, 1 );
667 *pUserData->pString = aOUStr;
668 if (nSelEntryPos == REPLACE_BULLETS)
669 m_xCheckLB->set_text(nSelEntryPos, sNum.replaceFirst("%1", aOUStr), 2);
670 else
671 m_xCheckLB->set_text(nSelEntryPos, sBullet.replaceFirst("%1", aOUStr), 2);
672 }
673 }
674 else if( MERGE_SINGLE_LINE_PARA == nSelEntryPos )
675 {
676 // dialog for per cent settings
677 OfaAutoFmtPrcntSet aDlg(GetFrameWeld());
678 aDlg.GetPrcntFld().set_value(nPercent, FieldUnit::PERCENT);
679 if (aDlg.run() == RET_OK)
680 {
681 nPercent = static_cast<sal_uInt16>(aDlg.GetPrcntFld().get_value(FieldUnit::PERCENT));
682 sMargin = unicode::formatPercent(nPercent, Application::GetSettings().GetUILanguageTag());
683 m_xCheckLB->set_text(nSelEntryPos, sRightMargin.replaceFirst("%1", sMargin), 2);
684 }
685 }
686 }
687
688
OfaAutocorrReplacePage(weld::Container * pPage,weld::DialogController * pController,const SfxItemSet & rSet)689 OfaAutocorrReplacePage::OfaAutocorrReplacePage(weld::Container* pPage, weld::DialogController* pController,
690 const SfxItemSet& rSet)
691 : SfxTabPage(pPage, pController, u"cui/ui/acorreplacepage.ui"_ustr, u"AcorReplacePage"_ustr, &rSet)
692 , maCompareClass(comphelper::getProcessComponentContext())
693 , eLang(eLastDialogLanguage)
694 , bHasSelectionText(false)
695 , bFirstSelect(true)
696 , bReplaceEditChanged(false)
697 , bSWriter(true)
698 , m_xTextOnlyCB(m_xBuilder->weld_check_button(u"textonly"_ustr))
699 , m_xShortED(m_xBuilder->weld_entry(u"origtext"_ustr))
700 , m_xReplaceED(m_xBuilder->weld_entry(u"newtext"_ustr))
701 , m_xReplaceTLB(m_xBuilder->weld_tree_view(u"tabview"_ustr))
702 , m_xNewReplacePB(m_xBuilder->weld_button(u"new"_ustr))
703 , m_xReplacePB(m_xBuilder->weld_button(u"replace"_ustr))
704 , m_xDeleteReplacePB(m_xBuilder->weld_button(u"delete"_ustr))
705 , m_xButtonBox(m_xBuilder->weld_container(u"buttonbox"_ustr))
706 {
707 sNew = m_xNewReplacePB->get_label();
708 sModify = m_xReplacePB->get_label();
709
710 // lock down the width of the button box to its max
711 // desired width
712 auto nMaxWidth = m_xButtonBox->get_preferred_size().Width();
713 m_xButtonBox->set_size_request(nMaxWidth, -1);
714 m_xReplacePB->hide();
715
716 // tdf#125348 set some small but fixed initial width size, final width will
717 // depend on the size of the entry boxes
718 m_xReplaceTLB->set_size_request(42, m_xReplaceTLB->get_height_rows(10));
719
720 SfxModule *pMod = SfxApplication::GetModule(SfxToolsModule::Writer);
721 bSWriter = pMod == SfxModule::GetActiveModule();
722
723 LanguageTag aLanguageTag( eLastDialogLanguage );
724 maCompareClass.loadDefaultCollator( aLanguageTag.getLocale(), 0 );
725 pCharClass.reset( new CharClass( std::move(aLanguageTag) ) );
726
727 auto nColWidth = m_xReplaceTLB->get_approximate_digit_width() * 32;
728 m_aReplaceFixedWidths.push_back(nColWidth);
729 m_aReplaceFixedWidths.push_back(nColWidth);
730
731 m_xReplaceTLB->connect_changed( LINK(this, OfaAutocorrReplacePage, SelectHdl) );
732 m_xNewReplacePB->connect_clicked( LINK(this, OfaAutocorrReplacePage, NewDelButtonHdl) );
733 m_xDeleteReplacePB->connect_clicked( LINK(this, OfaAutocorrReplacePage, NewDelButtonHdl) );
734 m_xShortED->connect_changed( LINK(this, OfaAutocorrReplacePage, ModifyHdl) );
735 m_xReplaceED->connect_changed( LINK(this, OfaAutocorrReplacePage, ModifyHdl) );
736 m_xShortED->connect_activate( LINK(this, OfaAutocorrReplacePage, NewDelActionHdl) );
737 m_xReplaceED->connect_activate( LINK(this, OfaAutocorrReplacePage, NewDelActionHdl) );
738 m_xShortED->connect_size_allocate(LINK(this, OfaAutocorrReplacePage, EntrySizeAllocHdl));
739 m_xReplaceED->connect_size_allocate(LINK(this, OfaAutocorrReplacePage, EntrySizeAllocHdl));
740 }
741
~OfaAutocorrReplacePage()742 OfaAutocorrReplacePage::~OfaAutocorrReplacePage()
743 {
744 aDoubleStringTable.clear();
745 aChangesTable.clear();
746
747 pCharClass.reset();
748 }
749
Create(weld::Container * pPage,weld::DialogController * pController,const SfxItemSet * rSet)750 std::unique_ptr<SfxTabPage> OfaAutocorrReplacePage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
751 {
752 return std::make_unique<OfaAutocorrReplacePage>(pPage, pController, *rSet);
753 }
754
ActivatePage(const SfxItemSet &)755 void OfaAutocorrReplacePage::ActivatePage( const SfxItemSet& )
756 {
757 if(eLang != eLastDialogLanguage)
758 SetLanguage(eLastDialogLanguage);
759 static_cast<OfaAutoCorrDlg*>(GetDialogController())->EnableLanguage(true);
760 }
761
DeactivatePage(SfxItemSet *)762 DeactivateRC OfaAutocorrReplacePage::DeactivatePage( SfxItemSet* )
763 {
764 return DeactivateRC::LeavePage;
765 }
766
FillItemSet(SfxItemSet *)767 bool OfaAutocorrReplacePage::FillItemSet( SfxItemSet* )
768 {
769 SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
770
771 for (StringChangeTable::reverse_iterator it = aChangesTable.rbegin(); it != aChangesTable.rend(); ++it)
772 {
773 LanguageType eCurrentLang = it->first;
774 StringChangeList& rStringChangeList = it->second;
775 std::vector<SvxAutocorrWord> aDeleteWords;
776 std::vector<SvxAutocorrWord> aNewWords;
777
778 aDeleteWords.reserve( rStringChangeList.aDeletedEntries.size() );
779 for (const DoubleString & deleteEntry : rStringChangeList.aDeletedEntries)
780 {
781 SvxAutocorrWord aDeleteWord( deleteEntry.sShort, deleteEntry.sLong );
782 aDeleteWords.push_back( aDeleteWord );
783 }
784
785 aNewWords.reserve( rStringChangeList.aNewEntries.size() );
786 for (const DoubleString & newEntry : rStringChangeList.aNewEntries)
787 {
788 //fdo#67697 if the user data is set then we want to retain the
789 //source formatting of the entry, so don't use the optimized
790 //text-only MakeCombinedChanges for this entry
791 bool bKeepSourceFormatting = newEntry.pUserData == &bHasSelectionText;
792 if (bKeepSourceFormatting)
793 {
794 if (SfxObjectShell* pSh = SfxObjectShell::Current())
795 pAutoCorrect->PutText(newEntry.sShort, *pSh, eCurrentLang);
796 continue;
797 }
798
799 SvxAutocorrWord aNewWord( newEntry.sShort, newEntry.sLong );
800 aNewWords.push_back( aNewWord );
801 }
802 pAutoCorrect->MakeCombinedChanges( aNewWords, aDeleteWords, eCurrentLang );
803 }
804 aChangesTable.clear();
805 return false;
806 }
807
RefillReplaceBox(bool bFromReset,LanguageType eOldLanguage,LanguageType eNewLanguage)808 void OfaAutocorrReplacePage::RefillReplaceBox(bool bFromReset,
809 LanguageType eOldLanguage,
810 LanguageType eNewLanguage)
811 {
812 eLang = eNewLanguage;
813 if(bFromReset)
814 {
815 aDoubleStringTable.clear();
816 aChangesTable.clear();
817 }
818 else
819 {
820 DoubleStringArray* pArray;
821 if(aDoubleStringTable.find(eOldLanguage) != aDoubleStringTable.end())
822 {
823 pArray = &aDoubleStringTable[eOldLanguage];
824 pArray->clear();
825 }
826 else
827 {
828 pArray = &aDoubleStringTable[eOldLanguage]; // create new array
829 }
830
831 m_xReplaceTLB->all_foreach([this, &pArray](weld::TreeIter& rIter) {
832 pArray->push_back(DoubleString(m_xReplaceTLB->get_text(rIter, 0),
833 m_xReplaceTLB->get_text(rIter, 1)));
834 DoubleString& rDouble = pArray->back();
835 rDouble.pUserData = weld::fromId<void*>(m_xReplaceTLB->get_id(rIter));
836 return false;
837 });
838 }
839
840 if( !bSWriter )
841 aFormatText.clear();
842
843 if (aDoubleStringTable.find(eLang) != aDoubleStringTable.end())
844 {
845 DoubleStringArray& rArray = aDoubleStringTable[eNewLanguage];
846
847 m_xReplaceTLB->bulk_insert_for_each(rArray.size(), [this, &rArray](weld::TreeIter& rIter, int nIndex) {
848 DoubleString &rDouble = rArray[nIndex];
849 bool bTextOnly = nullptr == rDouble.pUserData;
850 // formatted text is only in Writer
851 if (bSWriter || bTextOnly)
852 {
853 if (!bTextOnly)
854 {
855 // that means: with format info or even with selection text
856 OUString sId = weld::toId(rDouble.pUserData);
857 m_xReplaceTLB->set_id(rIter, sId);
858 }
859 m_xReplaceTLB->set_text(rIter, rDouble.sShort, 0);
860 m_xReplaceTLB->set_text(rIter, rDouble.sLong, 1);
861 }
862 else
863 {
864 aFormatText.insert(rDouble.sShort);
865 }
866 }, nullptr, &m_aReplaceFixedWidths);
867 }
868 else
869 {
870 SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
871 SvxAutocorrWordList* pWordList = pAutoCorrect->LoadAutocorrWordList(eLang);
872 const SvxAutocorrWordList::AutocorrWordSetType & rContent = pWordList->getSortedContent();
873 m_xReplaceTLB->bulk_insert_for_each(rContent.size(), [this, rContent](weld::TreeIter& rIter, int nIndex) {
874 auto const& elem = rContent[nIndex];
875 bool bTextOnly = elem.IsTextOnly();
876 // formatted text is only in Writer
877 if (bSWriter || bTextOnly)
878 {
879 if (!bTextOnly)
880 {
881 // that means: with format info or even with selection text
882 OUString sId = weld::toId(m_xTextOnlyCB.get());
883 m_xReplaceTLB->set_id(rIter, sId);
884 }
885 m_xReplaceTLB->set_text(rIter, elem.GetShort(), 0);
886 m_xReplaceTLB->set_text(rIter, elem.GetLong(), 1);
887 }
888 else
889 {
890 aFormatText.insert(elem.GetShort());
891 }
892 }, nullptr, &m_aReplaceFixedWidths);
893 m_xNewReplacePB->set_sensitive(false);
894 m_xDeleteReplacePB->set_sensitive(false);
895 }
896
897 SfxViewShell* pViewShell = SfxViewShell::Current();
898 if (pViewShell && pViewShell->HasSelection())
899 {
900 bHasSelectionText = true;
901 const OUString sSelection( pViewShell->GetSelectionText() );
902 m_xReplaceED->set_text(sSelection);
903 m_xTextOnlyCB->set_active(!bSWriter);
904 m_xTextOnlyCB->set_sensitive(bSWriter && !sSelection.isEmpty());
905 }
906 else
907 {
908 m_xTextOnlyCB->set_active(true);
909 m_xTextOnlyCB->set_sensitive(false);
910 }
911 }
912
Reset(const SfxItemSet *)913 void OfaAutocorrReplacePage::Reset( const SfxItemSet* )
914 {
915 RefillReplaceBox(true, eLang, eLang);
916 m_xShortED->grab_focus();
917 }
918
SetLanguage(LanguageType eSet)919 void OfaAutocorrReplacePage::SetLanguage(LanguageType eSet)
920 {
921 //save old settings and refill
922 if(eSet != eLang)
923 {
924 RefillReplaceBox(false, eLang, eSet);
925 eLastDialogLanguage = eSet;
926
927 LanguageTag aLanguageTag( eLastDialogLanguage );
928 maCompareClass = CollatorWrapper( comphelper::getProcessComponentContext() );
929 maCompareClass.loadDefaultCollator( aLanguageTag.getLocale(), 0 );
930 pCharClass.reset( new CharClass( std::move(aLanguageTag) ) );
931 ModifyHdl(*m_xShortED);
932 }
933 }
934
IMPL_LINK(OfaAutocorrReplacePage,SelectHdl,weld::TreeView &,rBox,void)935 IMPL_LINK(OfaAutocorrReplacePage, SelectHdl, weld::TreeView&, rBox, void)
936 {
937 if(!bFirstSelect || !bHasSelectionText)
938 {
939 int nEntry = rBox.get_selected_index();
940 OUString sTmpShort(rBox.get_text(nEntry, 0));
941 // if the text is set via ModifyHdl, the cursor is always at the beginning
942 // of a word, although you're editing here
943 bool bSameContent = 0 == maCompareClass.compareString(sTmpShort, m_xShortED->get_text());
944 int nStartPos, nEndPos;
945 m_xShortED->get_selection_bounds(nStartPos, nEndPos);
946 if (m_xShortED->get_text() != sTmpShort)
947 {
948 m_xShortED->set_text(sTmpShort);
949 // if it was only a different notation, the selection has to be set again
950 if (bSameContent)
951 {
952 m_xShortED->select_region(nStartPos, nEndPos);
953 }
954 }
955 m_xReplaceED->set_text(rBox.get_text(nEntry, 1));
956 // with UserData there is a Formatinfo
957 m_xTextOnlyCB->set_active(rBox.get_id(nEntry).isEmpty());
958 }
959 else
960 {
961 bFirstSelect = false;
962 }
963
964 m_xNewReplacePB->set_sensitive(false);
965 m_xDeleteReplacePB->set_sensitive(true);
966 };
967
NewEntry(const OUString & sShort,const OUString & sLong,bool bKeepSourceFormatting)968 void OfaAutocorrReplacePage::NewEntry(const OUString& sShort, const OUString& sLong, bool bKeepSourceFormatting)
969 {
970 DoubleStringArray& rNewArray = aChangesTable[eLang].aNewEntries;
971 for (size_t i = 0; i < rNewArray.size(); i++)
972 {
973 if (rNewArray[i].sShort == sShort)
974 {
975 rNewArray.erase(rNewArray.begin() + i);
976 break;
977 }
978 }
979
980 DoubleStringArray& rDeletedArray = aChangesTable[eLang].aDeletedEntries;
981 for (size_t i = 0; i < rDeletedArray.size(); i++)
982 {
983 if (rDeletedArray[i].sShort == sShort)
984 {
985 rDeletedArray.erase(rDeletedArray.begin() + i);
986 break;
987 }
988 }
989
990 DoubleString aNewString(sShort, sLong);
991 rNewArray.push_back(aNewString);
992 if (bKeepSourceFormatting)
993 rNewArray.back().pUserData = &bHasSelectionText;
994 }
995
DeleteEntry(const OUString & sShort,const OUString & sLong)996 void OfaAutocorrReplacePage::DeleteEntry(const OUString& sShort, const OUString& sLong)
997 {
998 DoubleStringArray& rNewArray = aChangesTable[eLang].aNewEntries;
999 for (size_t i = 0; i < rNewArray.size(); i++)
1000 {
1001 if (rNewArray[i].sShort == sShort)
1002 {
1003 rNewArray.erase(rNewArray.begin() + i);
1004 break;
1005 }
1006 }
1007
1008 DoubleStringArray& rDeletedArray = aChangesTable[eLang].aDeletedEntries;
1009 for (size_t i = 0; i < rDeletedArray.size(); i++)
1010 {
1011 if (rDeletedArray[i].sShort == sShort)
1012 {
1013 rDeletedArray.erase(rDeletedArray.begin() + i);
1014 break;
1015 }
1016 }
1017
1018 DoubleString aDeletedString(sShort, sLong);
1019 rDeletedArray.push_back(aDeletedString);
1020 }
1021
IMPL_LINK(OfaAutocorrReplacePage,NewDelButtonHdl,weld::Button &,rBtn,void)1022 IMPL_LINK(OfaAutocorrReplacePage, NewDelButtonHdl, weld::Button&, rBtn, void)
1023 {
1024 NewDelHdl(&rBtn);
1025 }
1026
IMPL_LINK(OfaAutocorrReplacePage,NewDelActionHdl,weld::Entry &,rEdit,bool)1027 IMPL_LINK(OfaAutocorrReplacePage, NewDelActionHdl, weld::Entry&, rEdit, bool)
1028 {
1029 return NewDelHdl(&rEdit);
1030 }
1031
IMPL_LINK_NOARG(OfaAutocorrReplacePage,EntrySizeAllocHdl,const Size &,void)1032 IMPL_LINK_NOARG(OfaAutocorrReplacePage, EntrySizeAllocHdl, const Size&, void)
1033 {
1034 m_aReplaceFixedWidths.clear();
1035 int x, y, width, height;
1036 if (m_xReplaceED->get_extents_relative_to(*m_xReplaceTLB, x, y, width, height))
1037 {
1038 m_aReplaceFixedWidths.push_back(x);
1039 m_aReplaceFixedWidths.push_back(width - 1);
1040 m_xReplaceTLB->set_column_fixed_widths(m_aReplaceFixedWidths);
1041 }
1042 }
1043
NewDelHdl(const weld::Widget * pBtn)1044 bool OfaAutocorrReplacePage::NewDelHdl(const weld::Widget* pBtn)
1045 {
1046 int nEntry = m_xReplaceTLB->get_selected_index();
1047 if (pBtn == m_xDeleteReplacePB.get())
1048 {
1049 DBG_ASSERT( nEntry != -1, "no entry selected" );
1050 if (nEntry != -1)
1051 {
1052 DeleteEntry(m_xReplaceTLB->get_text(nEntry, 0), m_xReplaceTLB->get_text(nEntry, 1));
1053 m_xReplaceTLB->remove(nEntry);
1054 ModifyHdl(*m_xShortED);
1055 return true;
1056 }
1057 }
1058
1059 if (pBtn == m_xNewReplacePB.get() || m_xNewReplacePB->get_sensitive())
1060 {
1061 OUString sEntry(m_xShortED->get_text());
1062 if (!sEntry.isEmpty() && (!m_xReplaceED->get_text().isEmpty() ||
1063 ( bHasSelectionText && bSWriter ) ))
1064 {
1065 bool bKeepSourceFormatting = !bReplaceEditChanged && !m_xTextOnlyCB->get_active();
1066
1067 NewEntry(m_xShortED->get_text(), m_xReplaceED->get_text(), bKeepSourceFormatting);
1068 m_xReplaceTLB->freeze();
1069 int nPos = -1;
1070 if (nEntry != -1)
1071 {
1072 nPos = nEntry;
1073 m_xReplaceTLB->remove(nEntry);
1074 }
1075 else
1076 {
1077 int j;
1078 int nCount = m_xReplaceTLB->n_children();
1079 for (j = 0; j < nCount; ++j)
1080 {
1081 if (0 >= maCompareClass.compareString(sEntry, m_xReplaceTLB->get_text(j, 0)))
1082 break;
1083 }
1084 nPos = j;
1085 }
1086
1087 OUString sId;
1088 if (bKeepSourceFormatting)
1089 {
1090 sId = weld::toId(&bHasSelectionText); // new formatted text
1091 }
1092
1093 m_xReplaceTLB->insert(nPos, sEntry, &sId, nullptr, nullptr);
1094 m_xReplaceTLB->set_text(nPos, m_xReplaceED->get_text(), 1);
1095 m_xReplaceTLB->thaw();
1096 m_xReplaceTLB->scroll_to_row(nPos);
1097 // if the request came from the ReplaceEdit, give focus to the ShortEdit
1098 if (m_xReplaceED->has_focus())
1099 {
1100 m_xShortED->grab_focus();
1101 }
1102 }
1103 }
1104 else
1105 {
1106 // this can only be an enter in one of the two edit fields
1107 // which means EndDialog() - has to be evaluated in KeyInput
1108 return false;
1109 }
1110 ModifyHdl(*m_xShortED);
1111 return true;
1112 }
1113
IMPL_LINK(OfaAutocorrReplacePage,ModifyHdl,weld::Entry &,rEdt,void)1114 IMPL_LINK(OfaAutocorrReplacePage, ModifyHdl, weld::Entry&, rEdt, void)
1115 {
1116 std::unique_ptr<weld::TreeIter> xFirstSel(m_xReplaceTLB->make_iterator());
1117 bool bFirstSelIterSet = m_xReplaceTLB->get_selected(xFirstSel.get());
1118 bool bShort = &rEdt == m_xShortED.get();
1119 const OUString rEntry = rEdt.get_text();
1120 const OUString rRepString = m_xReplaceED->get_text();
1121 OUString aWordStr(pCharClass->lowercase(rEntry));
1122
1123 if(bShort)
1124 {
1125 if(!rEntry.isEmpty())
1126 {
1127 bool bFound = false;
1128 bool bTmpSelEntry=false;
1129
1130 m_xReplaceTLB->all_foreach([this, &rEntry, &rRepString, &bFound,
1131 &bTmpSelEntry, &bFirstSelIterSet,
1132 &xFirstSel, &aWordStr](weld::TreeIter& rIter){
1133 OUString aTestStr = m_xReplaceTLB->get_text(rIter, 0);
1134 if( maCompareClass.compareString(rEntry, aTestStr ) == 0 )
1135 {
1136 if (!rRepString.isEmpty())
1137 bFirstSelect = true;
1138 m_xReplaceTLB->set_cursor(rIter);
1139 m_xReplaceTLB->copy_iterator(rIter, *xFirstSel);
1140 bFirstSelIterSet = true;
1141 m_xNewReplacePB->set_label(sModify);
1142 bFound = true;
1143 return true;
1144 }
1145 else
1146 {
1147 aTestStr = pCharClass->lowercase( aTestStr );
1148 if( !bTmpSelEntry && ( aTestStr.startsWith(aWordStr)
1149 // find also with ".*" and between :colons:
1150 || aTestStr.replaceAll(".*","").replaceAll(":", "").startsWith(aWordStr) ) )
1151 {
1152 m_xReplaceTLB->scroll_to_row(rIter);
1153 bTmpSelEntry = true;
1154 }
1155 }
1156 return false;
1157 });
1158 if( !bFound )
1159 {
1160 m_xReplaceTLB->select(-1);
1161 bFirstSelIterSet = false;
1162 m_xNewReplacePB->set_label(sNew);
1163 if( bReplaceEditChanged )
1164 m_xTextOnlyCB->set_sensitive(false);
1165 }
1166 m_xDeleteReplacePB->set_sensitive(bFound);
1167 }
1168 else if (m_xReplaceTLB->n_children() > 0)
1169 {
1170 m_xReplaceTLB->scroll_to_row(0);
1171 }
1172
1173 }
1174 else if( !bShort )
1175 {
1176 bReplaceEditChanged = true;
1177 if (bFirstSelIterSet)
1178 {
1179 m_xNewReplacePB->set_label(sModify);
1180 }
1181 }
1182
1183 const OUString& rShortTxt = m_xShortED->get_text();
1184 bool bEnableNew = !rShortTxt.isEmpty() &&
1185 ( !rRepString.isEmpty() ||
1186 ( bHasSelectionText && bSWriter )) &&
1187 ( !bFirstSelIterSet || rRepString !=
1188 m_xReplaceTLB->get_text(*xFirstSel, 1) );
1189 if( bEnableNew )
1190 {
1191 for (auto const& elem : aFormatText)
1192 {
1193 if(elem == rShortTxt)
1194 {
1195 bEnableNew = false;
1196 break;
1197 }
1198 }
1199 }
1200 m_xNewReplacePB->set_sensitive(bEnableNew);
1201 }
1202
lcl_FindInArray(std::vector<OUString> & rStrings,std::u16string_view rString)1203 static bool lcl_FindInArray(std::vector<OUString>& rStrings, std::u16string_view rString)
1204 {
1205 for (auto const& elem : rStrings)
1206 {
1207 if(elem == rString)
1208 {
1209 return true;
1210 }
1211 }
1212 return false;
1213 }
1214
OfaAutocorrExceptPage(weld::Container * pPage,weld::DialogController * pController,const SfxItemSet & rSet)1215 OfaAutocorrExceptPage::OfaAutocorrExceptPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
1216 : SfxTabPage(pPage, pController, u"cui/ui/acorexceptpage.ui"_ustr, u"AcorExceptPage"_ustr, &rSet)
1217 , maCompareClass(comphelper::getProcessComponentContext())
1218 , eLang(eLastDialogLanguage)
1219 , m_xAbbrevED(m_xBuilder->weld_entry(u"abbrev"_ustr))
1220 , m_xAbbrevLB(m_xBuilder->weld_tree_view(u"abbrevlist"_ustr))
1221 , m_xNewAbbrevPB(m_xBuilder->weld_button(u"newabbrev"_ustr))
1222 , m_xDelAbbrevPB(m_xBuilder->weld_button(u"delabbrev"_ustr))
1223 , m_xAutoAbbrevCB(m_xBuilder->weld_check_button(u"autoabbrev"_ustr))
1224 , m_xDoubleCapsED(m_xBuilder->weld_entry(u"double"_ustr))
1225 , m_xDoubleCapsLB(m_xBuilder->weld_tree_view(u"doublelist"_ustr))
1226 , m_xNewDoublePB(m_xBuilder->weld_button(u"newdouble"_ustr))
1227 , m_xDelDoublePB(m_xBuilder->weld_button(u"deldouble"_ustr))
1228 , m_xAutoCapsCB(m_xBuilder->weld_check_button(u"autodouble"_ustr))
1229 {
1230 m_xAbbrevLB->make_sorted();
1231 m_xAbbrevLB->set_size_request(-1, m_xAbbrevLB->get_height_rows(6));
1232
1233 m_xDoubleCapsLB->make_sorted();
1234 m_xDoubleCapsLB->set_size_request(-1, m_xDoubleCapsLB->get_height_rows(6));
1235
1236 css::lang::Locale aLcl( LanguageTag::convertToLocale(eLastDialogLanguage ));
1237 maCompareClass.loadDefaultCollator( aLcl, 0 );
1238
1239 m_xNewAbbrevPB->connect_clicked(LINK(this, OfaAutocorrExceptPage, NewDelButtonHdl));
1240 m_xDelAbbrevPB->connect_clicked(LINK(this, OfaAutocorrExceptPage, NewDelButtonHdl));
1241 m_xNewDoublePB->connect_clicked(LINK(this, OfaAutocorrExceptPage, NewDelButtonHdl));
1242 m_xDelDoublePB->connect_clicked(LINK(this, OfaAutocorrExceptPage, NewDelButtonHdl));
1243
1244 m_xAbbrevLB->connect_changed(LINK(this, OfaAutocorrExceptPage, SelectHdl));
1245 m_xDoubleCapsLB->connect_changed(LINK(this, OfaAutocorrExceptPage, SelectHdl));
1246 m_xAbbrevED->connect_changed(LINK(this, OfaAutocorrExceptPage, ModifyHdl));
1247 m_xDoubleCapsED->connect_changed(LINK(this, OfaAutocorrExceptPage, ModifyHdl));
1248
1249 m_xAbbrevED->connect_activate(LINK(this, OfaAutocorrExceptPage, NewDelActionHdl));
1250 m_xDoubleCapsED->connect_activate(LINK(this, OfaAutocorrExceptPage, NewDelActionHdl));
1251 }
1252
~OfaAutocorrExceptPage()1253 OfaAutocorrExceptPage::~OfaAutocorrExceptPage()
1254 {
1255 aStringsTable.clear();
1256 }
1257
Create(weld::Container * pPage,weld::DialogController * pController,const SfxItemSet * rSet)1258 std::unique_ptr<SfxTabPage> OfaAutocorrExceptPage::Create(weld::Container* pPage, weld::DialogController* pController,
1259 const SfxItemSet* rSet)
1260 {
1261 return std::make_unique<OfaAutocorrExceptPage>(pPage, pController, *rSet);
1262 }
1263
ActivatePage(const SfxItemSet &)1264 void OfaAutocorrExceptPage::ActivatePage( const SfxItemSet& )
1265 {
1266 if(eLang != eLastDialogLanguage)
1267 SetLanguage(eLastDialogLanguage);
1268 static_cast<OfaAutoCorrDlg*>(GetDialogController())->EnableLanguage(true);
1269 }
1270
DeactivatePage(SfxItemSet *)1271 DeactivateRC OfaAutocorrExceptPage::DeactivatePage( SfxItemSet* )
1272 {
1273 return DeactivateRC::LeavePage;
1274 }
1275
FillItemSet(SfxItemSet *)1276 bool OfaAutocorrExceptPage::FillItemSet( SfxItemSet* )
1277 {
1278 SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
1279 for(StringsTable::reverse_iterator it1 = aStringsTable.rbegin(); it1 != aStringsTable.rend(); ++it1)
1280 {
1281 LanguageType eCurLang = it1->first;
1282 StringsArrays& rArrays = it1->second;
1283 if(eCurLang != eLang) // current language is treated later
1284 {
1285 SvStringsISortDtor* pWrdList = pAutoCorrect->LoadWordStartExceptList(eCurLang);
1286
1287 if(pWrdList)
1288 {
1289 size_t nCount = pWrdList->size();
1290 size_t i;
1291 for( i = nCount; i; )
1292 {
1293 OUString aString = (*pWrdList)[ --i ];
1294
1295 if( !lcl_FindInArray(rArrays.aDoubleCapsStrings, aString))
1296 {
1297 pWrdList->erase_at(i);
1298 }
1299 }
1300
1301 for (auto const& elem : rArrays.aDoubleCapsStrings)
1302 {
1303 pWrdList->insert(elem);
1304 }
1305 pAutoCorrect->SaveWordStartExceptList(eCurLang);
1306 }
1307
1308 SvStringsISortDtor* pCplList = pAutoCorrect->LoadCplSttExceptList(eCurLang);
1309
1310 if(pCplList)
1311 {
1312 size_t nCount = pCplList->size();
1313 size_t i;
1314 for( i = nCount; i; )
1315 {
1316 OUString aString = (*pCplList)[ --i ];
1317 if( !lcl_FindInArray(rArrays.aAbbrevStrings, aString))
1318 {
1319 pCplList->erase_at(i);
1320 }
1321 }
1322
1323 for (auto const& elem : rArrays.aAbbrevStrings)
1324 {
1325 pCplList->insert(elem);
1326 }
1327
1328 pAutoCorrect->SaveCplSttExceptList(eCurLang);
1329 }
1330 }
1331 }
1332 aStringsTable.clear();
1333
1334 SvStringsISortDtor* pWrdList = pAutoCorrect->LoadWordStartExceptList(eLang);
1335
1336 if(pWrdList)
1337 {
1338 size_t nCount = pWrdList->size();
1339 size_t i;
1340 for( i = nCount; i; )
1341 {
1342 OUString aString = (*pWrdList)[ --i ];
1343 if (m_xDoubleCapsLB->find_text(aString) == -1)
1344 {
1345 pWrdList->erase_at(i);
1346 }
1347 }
1348 nCount = m_xDoubleCapsLB->n_children();
1349 for( i = 0; i < nCount; ++i )
1350 {
1351 pWrdList->insert(m_xDoubleCapsLB->get_text(i));
1352 }
1353 pAutoCorrect->SaveWordStartExceptList(eLang);
1354 }
1355
1356 SvStringsISortDtor* pCplList = pAutoCorrect->LoadCplSttExceptList(eLang);
1357
1358 if(pCplList)
1359 {
1360 size_t nCount = pCplList->size();
1361 for( size_t i = nCount; i; )
1362 {
1363 OUString aString = (*pCplList)[ --i ];
1364 if (m_xAbbrevLB->find_text(aString) == -1)
1365 {
1366 pCplList->erase_at(i);
1367 }
1368 }
1369 sal_Int32 nAbbrevCount = m_xAbbrevLB->n_children();
1370 for( sal_Int32 ia = 0; ia < nAbbrevCount; ++ia )
1371 {
1372 pCplList->insert(m_xAbbrevLB->get_text(ia));
1373 }
1374 pAutoCorrect->SaveCplSttExceptList(eLang);
1375 }
1376 if (m_xAutoAbbrevCB->get_state_changed_from_saved())
1377 pAutoCorrect->SetAutoCorrFlag( ACFlags::SaveWordCplSttLst, m_xAutoAbbrevCB->get_active());
1378 if (m_xAutoCapsCB->get_state_changed_from_saved())
1379 pAutoCorrect->SetAutoCorrFlag( ACFlags::SaveWordWordStartLst, m_xAutoCapsCB->get_active());
1380 return false;
1381 }
1382
SetLanguage(LanguageType eSet)1383 void OfaAutocorrExceptPage::SetLanguage(LanguageType eSet)
1384 {
1385 if(eLang != eSet)
1386 {
1387 // save old settings and fill anew
1388 RefillReplaceBoxes(false, eLang, eSet);
1389 eLastDialogLanguage = eSet;
1390 maCompareClass = CollatorWrapper( comphelper::getProcessComponentContext() );
1391 maCompareClass.loadDefaultCollator( LanguageTag::convertToLocale( eLastDialogLanguage ), 0 );
1392 ModifyHdl(*m_xAbbrevED);
1393 ModifyHdl(*m_xDoubleCapsED);
1394 }
1395 }
1396
RefillReplaceBoxes(bool bFromReset,LanguageType eOldLanguage,LanguageType eNewLanguage)1397 void OfaAutocorrExceptPage::RefillReplaceBoxes(bool bFromReset,
1398 LanguageType eOldLanguage,
1399 LanguageType eNewLanguage)
1400 {
1401 eLang = eNewLanguage;
1402 if(bFromReset)
1403 {
1404 aStringsTable.clear();
1405 }
1406 else
1407 {
1408 StringsArrays* pArrays;
1409 if(aStringsTable.find(eOldLanguage) != aStringsTable.end())
1410 {
1411 pArrays = &aStringsTable[eOldLanguage];
1412 pArrays->aAbbrevStrings.clear();
1413 pArrays->aDoubleCapsStrings.clear();
1414 }
1415 else
1416 {
1417 pArrays = &aStringsTable[eOldLanguage]; // create new array
1418 }
1419
1420 sal_Int32 i, nCount;
1421 nCount = m_xAbbrevLB->n_children();
1422 for(i = 0; i < nCount; i++)
1423 pArrays->aAbbrevStrings.push_back(m_xAbbrevLB->get_text(i));
1424
1425 nCount = m_xDoubleCapsLB->n_children();
1426 for(i = 0; i < nCount; i++)
1427 pArrays->aDoubleCapsStrings.push_back(m_xDoubleCapsLB->get_text(i));
1428 }
1429 m_xDoubleCapsLB->clear();
1430 m_xAbbrevLB->clear();
1431 m_xAbbrevED->set_text(u""_ustr);
1432 m_xDoubleCapsED->set_text(u""_ustr);
1433
1434 if(aStringsTable.find(eLang) != aStringsTable.end())
1435 {
1436 StringsArrays& rArrays = aStringsTable[eLang];
1437 for (auto const& elem : rArrays.aAbbrevStrings)
1438 m_xAbbrevLB->append_text(elem);
1439
1440 for (auto const& elem : rArrays.aDoubleCapsStrings)
1441 m_xDoubleCapsLB->append_text(elem);
1442 }
1443 else
1444 {
1445 SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
1446 const SvStringsISortDtor* pCplList = pAutoCorrect->GetCplSttExceptList(eLang);
1447 const SvStringsISortDtor* pWrdList = pAutoCorrect->GetWordStartExceptList(eLang);
1448 size_t i;
1449 for( i = 0; i < pCplList->size(); i++ )
1450 {
1451 m_xAbbrevLB->append_text((*pCplList)[i]);
1452 }
1453 for( i = 0; i < pWrdList->size(); i++ )
1454 {
1455 m_xDoubleCapsLB->append_text((*pWrdList)[i]);
1456 }
1457 }
1458 }
1459
Reset(const SfxItemSet *)1460 void OfaAutocorrExceptPage::Reset( const SfxItemSet* )
1461 {
1462 SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
1463 RefillReplaceBoxes(true, eLang, eLang);
1464 m_xAutoAbbrevCB->set_active(pAutoCorrect->IsAutoCorrFlag( ACFlags::SaveWordCplSttLst));
1465 m_xAutoCapsCB->set_active(pAutoCorrect->IsAutoCorrFlag( ACFlags::SaveWordWordStartLst));
1466 m_xAutoAbbrevCB->save_state();
1467 m_xAutoCapsCB->save_state();
1468 }
1469
IMPL_LINK(OfaAutocorrExceptPage,NewDelButtonHdl,weld::Button &,rBtn,void)1470 IMPL_LINK(OfaAutocorrExceptPage, NewDelButtonHdl, weld::Button&, rBtn, void)
1471 {
1472 NewDelHdl(&rBtn);
1473 }
1474
IMPL_LINK(OfaAutocorrExceptPage,NewDelActionHdl,weld::Entry &,rEdit,bool)1475 IMPL_LINK(OfaAutocorrExceptPage, NewDelActionHdl, weld::Entry&, rEdit, bool)
1476 {
1477 return NewDelHdl(&rEdit);
1478 }
1479
NewDelHdl(const weld::Widget * pBtn)1480 bool OfaAutocorrExceptPage::NewDelHdl(const weld::Widget* pBtn)
1481 {
1482 if ((pBtn == m_xNewAbbrevPB.get() || pBtn == m_xAbbrevED.get())
1483 && !m_xAbbrevED->get_text().isEmpty() && m_xNewAbbrevPB->get_sensitive())
1484 {
1485 m_xAbbrevLB->append_text(m_xAbbrevED->get_text());
1486 ModifyHdl(*m_xAbbrevED);
1487 }
1488 else if(pBtn == m_xDelAbbrevPB.get())
1489 {
1490 m_xAbbrevLB->remove_text(m_xAbbrevED->get_text());
1491 ModifyHdl(*m_xAbbrevED);
1492 }
1493 else if((pBtn == m_xNewDoublePB.get() || pBtn == m_xDoubleCapsED.get() )
1494 && !m_xDoubleCapsED->get_text().isEmpty() && m_xNewDoublePB->get_sensitive())
1495 {
1496 m_xDoubleCapsLB->append_text(m_xDoubleCapsED->get_text());
1497 ModifyHdl(*m_xDoubleCapsED);
1498 }
1499 else if (pBtn == m_xDelDoublePB.get())
1500 {
1501 m_xDoubleCapsLB->remove_text(m_xDoubleCapsED->get_text());
1502 ModifyHdl(*m_xDoubleCapsED);
1503 }
1504 else
1505 {
1506 // we didn't do anything, if this was because of 'activate' in an
1507 // entry then let it continue to close the dialog like the replace
1508 // page does
1509 return false;
1510 }
1511 return true;
1512 }
1513
IMPL_LINK(OfaAutocorrExceptPage,SelectHdl,weld::TreeView &,rBox,void)1514 IMPL_LINK(OfaAutocorrExceptPage, SelectHdl, weld::TreeView&, rBox, void)
1515 {
1516 if (&rBox == m_xAbbrevLB.get())
1517 {
1518 m_xAbbrevED->set_text(rBox.get_selected_text());
1519 m_xNewAbbrevPB->set_sensitive(false);
1520 m_xDelAbbrevPB->set_sensitive(true);
1521 }
1522 else
1523 {
1524 m_xDoubleCapsED->set_text(rBox.get_selected_text());
1525 m_xNewDoublePB->set_sensitive(false);
1526 m_xDelDoublePB->set_sensitive(true);
1527 }
1528 }
1529
IMPL_LINK(OfaAutocorrExceptPage,ModifyHdl,weld::Entry &,rEdt,void)1530 IMPL_LINK(OfaAutocorrExceptPage, ModifyHdl, weld::Entry&, rEdt, void)
1531 {
1532 const OUString& sEntry = rEdt.get_text();
1533 bool bEntryLen = !sEntry.isEmpty();
1534 if (&rEdt == m_xAbbrevED.get())
1535 {
1536 bool bSame = lcl_FindEntry(*m_xAbbrevLB, sEntry, maCompareClass);
1537 if(bSame && sEntry != m_xAbbrevLB->get_selected_text())
1538 rEdt.set_text(m_xAbbrevLB->get_selected_text());
1539 m_xNewAbbrevPB->set_sensitive(!bSame && bEntryLen);
1540 m_xDelAbbrevPB->set_sensitive(bSame && bEntryLen);
1541 }
1542 else
1543 {
1544 bool bSame = lcl_FindEntry(*m_xDoubleCapsLB, sEntry, maCompareClass);
1545 if(bSame && sEntry != m_xDoubleCapsLB->get_selected_text())
1546 rEdt.set_text(m_xDoubleCapsLB->get_selected_text());
1547 m_xNewDoublePB->set_sensitive(!bSame && bEntryLen);
1548 m_xDelDoublePB->set_sensitive(bSame && bEntryLen);
1549 }
1550 }
1551
1552 namespace {
1553
1554 enum OfaQuoteOptions
1555 {
1556 ADD_NONBRK_SPACE,
1557 REPLACE_1ST,
1558 TRANSLITERATE_RTL,
1559 REPLACE_ANGLE_QUOTES
1560 };
1561
1562 }
1563
CreateEntry(weld::TreeView & rCheckLB,const OUString & rTxt,sal_uInt16 nCol,sal_uInt16 nTextCol)1564 void OfaQuoteTabPage::CreateEntry(weld::TreeView& rCheckLB, const OUString& rTxt, sal_uInt16 nCol, sal_uInt16 nTextCol)
1565 {
1566 rCheckLB.append();
1567 const int nRow = rCheckLB.n_children() - 1;
1568 if (nCol == CBCOL_FIRST || nCol == CBCOL_BOTH)
1569 rCheckLB.set_toggle(nRow, TRISTATE_FALSE, CBCOL_FIRST);
1570 if (nCol == CBCOL_SECOND || nCol == CBCOL_BOTH)
1571 rCheckLB.set_toggle(nRow, TRISTATE_FALSE, CBCOL_SECOND);
1572 rCheckLB.set_text(nRow, rTxt, nTextCol);
1573 }
1574
OfaQuoteTabPage(weld::Container * pPage,weld::DialogController * pController,const SfxItemSet & rSet)1575 OfaQuoteTabPage::OfaQuoteTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
1576 : SfxTabPage(pPage, pController, u"cui/ui/applylocalizedpage.ui"_ustr, u"ApplyLocalizedPage"_ustr, &rSet)
1577 , sNonBrkSpace(CuiResId(RID_CUISTR_NON_BREAK_SPACE))
1578 , sOrdinal(CuiResId(RID_CUISTR_ORDINAL))
1579 , sTransliterateRTL(CuiResId(RID_CUISTR_OLD_HUNGARIAN))
1580 , sAngleQuotes(CuiResId(RID_CUISTR_ANGLE_QUOTES))
1581 , cSglStartQuote(0)
1582 , cSglEndQuote(0)
1583 , cStartQuote(0)
1584 , cEndQuote(0)
1585 , m_xSingleTypoCB(m_xBuilder->weld_check_button(u"singlereplace"_ustr))
1586 , m_xSglStartQuotePB(m_xBuilder->weld_button(u"startsingle"_ustr))
1587 , m_xSglStartExFT(m_xBuilder->weld_label(u"singlestartex"_ustr))
1588 , m_xSglEndQuotePB(m_xBuilder->weld_button(u"endsingle"_ustr))
1589 , m_xSglEndExFT(m_xBuilder->weld_label(u"singleendex"_ustr))
1590 , m_xSglStandardPB(m_xBuilder->weld_button(u"defaultsingle"_ustr))
1591 , m_xDoubleTypoCB(m_xBuilder->weld_check_button(u"doublereplace"_ustr))
1592 , m_xDblStartQuotePB(m_xBuilder->weld_button(u"startdouble"_ustr))
1593 , m_xDblStartExFT(m_xBuilder->weld_label(u"doublestartex"_ustr))
1594 , m_xDblEndQuotePB(m_xBuilder->weld_button(u"enddouble"_ustr))
1595 , m_xDblEndExFT(m_xBuilder->weld_label(u"doubleendex"_ustr))
1596 , m_xDblStandardPB(m_xBuilder->weld_button(u"defaultdouble"_ustr))
1597 , m_sStandard(m_xSglStartExFT->get_label())
1598 , m_xCheckLB(m_xBuilder->weld_tree_view(u"checklist"_ustr))
1599 , m_xSwCheckLB(m_xBuilder->weld_tree_view(u"list"_ustr))
1600 {
1601 m_xSwCheckLB->set_size_request(m_xSwCheckLB->get_approximate_digit_width() * 50,
1602 m_xSwCheckLB->get_height_rows(6));
1603
1604 bool bShowSWOptions = false;
1605
1606 const SfxBoolItem* pItem = rSet.GetItem<SfxBoolItem>(SID_AUTO_CORRECT_DLG, false);
1607 if ( pItem && pItem->GetValue() )
1608 bShowSWOptions = true;
1609
1610 if ( bShowSWOptions )
1611 {
1612 std::vector<int> aWidths
1613 {
1614 o3tl::narrowing<int>(m_xSwCheckLB->get_pixel_size(m_xSwCheckLB->get_column_title(0)).Width() * 2),
1615 o3tl::narrowing<int>(m_xSwCheckLB->get_pixel_size(m_xSwCheckLB->get_column_title(1)).Width() * 2)
1616 };
1617 m_xSwCheckLB->set_column_fixed_widths(aWidths);
1618 m_xCheckLB->hide();
1619 }
1620 else
1621 {
1622 m_xCheckLB->enable_toggle_buttons(weld::ColumnToggleType::Check);
1623 m_xSwCheckLB->hide();
1624 }
1625
1626 m_xDblStartQuotePB->connect_clicked(LINK(this, OfaQuoteTabPage, QuoteHdl));
1627 m_xDblEndQuotePB->connect_clicked(LINK(this, OfaQuoteTabPage, QuoteHdl));
1628 m_xSglStartQuotePB->connect_clicked(LINK(this, OfaQuoteTabPage, QuoteHdl));
1629 m_xSglEndQuotePB->connect_clicked(LINK(this, OfaQuoteTabPage, QuoteHdl));
1630 m_xDblStandardPB->connect_clicked(LINK(this, OfaQuoteTabPage, StdQuoteHdl));
1631 m_xSglStandardPB->connect_clicked(LINK(this, OfaQuoteTabPage, StdQuoteHdl));
1632 }
1633
~OfaQuoteTabPage()1634 OfaQuoteTabPage::~OfaQuoteTabPage()
1635 {
1636 }
1637
Create(weld::Container * pPage,weld::DialogController * pController,const SfxItemSet * rAttrSet)1638 std::unique_ptr<SfxTabPage> OfaQuoteTabPage::Create(weld::Container* pPage, weld::DialogController* pController,
1639 const SfxItemSet* rAttrSet)
1640 {
1641 return std::make_unique<OfaQuoteTabPage>(pPage, pController, *rAttrSet);
1642 }
1643
FillItemSet(SfxItemSet *)1644 bool OfaQuoteTabPage::FillItemSet( SfxItemSet* )
1645 {
1646 SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
1647
1648 ACFlags nFlags = pAutoCorrect->GetFlags();
1649
1650 if (m_xCheckLB->get_visible())
1651 {
1652 int nPos = 0;
1653 pAutoCorrect->SetAutoCorrFlag(ACFlags::AddNonBrkSpace, m_xCheckLB->get_toggle(nPos++) == TRISTATE_TRUE);
1654 pAutoCorrect->SetAutoCorrFlag(ACFlags::ChgOrdinalNumber, m_xCheckLB->get_toggle(nPos++) == TRISTATE_TRUE);
1655 pAutoCorrect->SetAutoCorrFlag(ACFlags::TransliterateRTL, m_xCheckLB->get_toggle(nPos++) == TRISTATE_TRUE);
1656 pAutoCorrect->SetAutoCorrFlag(ACFlags::ChgAngleQuotes, m_xCheckLB->get_toggle(nPos++) == TRISTATE_TRUE);
1657 }
1658
1659 bool bModified = false;
1660 if (m_xSwCheckLB->get_visible())
1661 {
1662 SvxSwAutoFormatFlags *pOpt = &pAutoCorrect->GetSwFlags();
1663
1664 bool bCheck = m_xSwCheckLB->get_toggle(ADD_NONBRK_SPACE, CBCOL_FIRST) == TRISTATE_TRUE;
1665 bModified |= pOpt->bAddNonBrkSpace != bCheck;
1666 pOpt->bAddNonBrkSpace = bCheck;
1667 pAutoCorrect->SetAutoCorrFlag(ACFlags::AddNonBrkSpace,
1668 m_xSwCheckLB->get_toggle(ADD_NONBRK_SPACE, CBCOL_SECOND) == TRISTATE_TRUE);
1669
1670 bCheck = m_xSwCheckLB->get_toggle(REPLACE_1ST, CBCOL_FIRST) == TRISTATE_TRUE;
1671 bModified |= pOpt->bChgOrdinalNumber != bCheck;
1672 pOpt->bChgOrdinalNumber = bCheck;
1673 pAutoCorrect->SetAutoCorrFlag(ACFlags::ChgOrdinalNumber,
1674 m_xSwCheckLB->get_toggle(REPLACE_1ST, CBCOL_SECOND) == TRISTATE_TRUE);
1675
1676 bCheck = m_xSwCheckLB->get_toggle(TRANSLITERATE_RTL, CBCOL_FIRST) == TRISTATE_TRUE;
1677 bModified |= pOpt->bTransliterateRTL != bCheck;
1678 pOpt->bTransliterateRTL = bCheck;
1679 pAutoCorrect->SetAutoCorrFlag(ACFlags::TransliterateRTL,
1680 m_xSwCheckLB->get_toggle(TRANSLITERATE_RTL, CBCOL_SECOND) == TRISTATE_TRUE);
1681
1682 bCheck = m_xSwCheckLB->get_toggle(REPLACE_ANGLE_QUOTES, CBCOL_FIRST) == TRISTATE_TRUE;
1683 bModified |= pOpt->bChgAngleQuotes != bCheck;
1684 pOpt->bChgAngleQuotes = bCheck;
1685 pAutoCorrect->SetAutoCorrFlag(ACFlags::ChgAngleQuotes,
1686 m_xSwCheckLB->get_toggle(REPLACE_ANGLE_QUOTES, CBCOL_SECOND) == TRISTATE_TRUE);
1687 }
1688
1689 pAutoCorrect->SetAutoCorrFlag(ACFlags::ChgQuotes, m_xDoubleTypoCB->get_active());
1690 pAutoCorrect->SetAutoCorrFlag(ACFlags::ChgSglQuotes, m_xSingleTypoCB->get_active());
1691 bool bReturn = nFlags != pAutoCorrect->GetFlags();
1692 if(cStartQuote != pAutoCorrect->GetStartDoubleQuote())
1693 {
1694 bReturn = true;
1695 sal_Unicode cUCS2 = static_cast<sal_Unicode>(cStartQuote); //TODO
1696 pAutoCorrect->SetStartDoubleQuote(cUCS2);
1697 }
1698 if(cEndQuote != pAutoCorrect->GetEndDoubleQuote())
1699 {
1700 bReturn = true;
1701 sal_Unicode cUCS2 = static_cast<sal_Unicode>(cEndQuote); //TODO
1702 pAutoCorrect->SetEndDoubleQuote(cUCS2);
1703 }
1704 if(cSglStartQuote != pAutoCorrect->GetStartSingleQuote())
1705 {
1706 bReturn = true;
1707 sal_Unicode cUCS2 = static_cast<sal_Unicode>(cSglStartQuote); //TODO
1708 pAutoCorrect->SetStartSingleQuote(cUCS2);
1709 }
1710 if(cSglEndQuote != pAutoCorrect->GetEndSingleQuote())
1711 {
1712 bReturn = true;
1713 sal_Unicode cUCS2 = static_cast<sal_Unicode>(cSglEndQuote); //TODO
1714 pAutoCorrect->SetEndSingleQuote(cUCS2);
1715 }
1716
1717 if( bModified || bReturn )
1718 {
1719 SvxAutoCorrCfg& rCfg = SvxAutoCorrCfg::Get();
1720 rCfg.SetModified();
1721 rCfg.Commit();
1722 }
1723 return bReturn;
1724 }
1725
ActivatePage(const SfxItemSet &)1726 void OfaQuoteTabPage::ActivatePage( const SfxItemSet& )
1727 {
1728 static_cast<OfaAutoCorrDlg*>(GetDialogController())->EnableLanguage(false);
1729 }
1730
Reset(const SfxItemSet *)1731 void OfaQuoteTabPage::Reset( const SfxItemSet* )
1732 {
1733 SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
1734 const ACFlags nFlags = pAutoCorrect->GetFlags();
1735
1736 // Initialize the Sw options
1737 if (m_xSwCheckLB->get_visible())
1738 {
1739 SvxSwAutoFormatFlags *pOpt = &pAutoCorrect->GetSwFlags();
1740
1741 m_xSwCheckLB->freeze();
1742 m_xSwCheckLB->clear();
1743
1744 CreateEntry(*m_xSwCheckLB, sNonBrkSpace, CBCOL_BOTH, 2);
1745 CreateEntry(*m_xSwCheckLB, sOrdinal, CBCOL_BOTH, 2);
1746 CreateEntry(*m_xSwCheckLB, sTransliterateRTL, CBCOL_BOTH, 2);
1747 CreateEntry(*m_xSwCheckLB, sAngleQuotes, CBCOL_BOTH, 2);
1748
1749 m_xSwCheckLB->set_toggle(ADD_NONBRK_SPACE, pOpt->bAddNonBrkSpace ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
1750 m_xSwCheckLB->set_toggle(ADD_NONBRK_SPACE, bool(nFlags & ACFlags::AddNonBrkSpace) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
1751 m_xSwCheckLB->set_toggle(REPLACE_1ST, pOpt->bChgOrdinalNumber ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
1752 m_xSwCheckLB->set_toggle(REPLACE_1ST, bool(nFlags & ACFlags::ChgOrdinalNumber) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
1753 m_xSwCheckLB->set_toggle(TRANSLITERATE_RTL, pOpt->bTransliterateRTL ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
1754 m_xSwCheckLB->set_toggle(TRANSLITERATE_RTL, bool(nFlags & ACFlags::TransliterateRTL) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
1755 m_xSwCheckLB->set_toggle(REPLACE_ANGLE_QUOTES, pOpt->bChgAngleQuotes ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
1756 m_xSwCheckLB->set_toggle(REPLACE_ANGLE_QUOTES, bool(nFlags & ACFlags::ChgAngleQuotes) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
1757
1758 m_xSwCheckLB->thaw();
1759 }
1760
1761 // Initialize the non Sw options
1762 if (m_xCheckLB->get_visible())
1763 {
1764 m_xCheckLB->freeze();
1765 m_xCheckLB->clear();
1766
1767 int nPos = 0;
1768 m_xCheckLB->append();
1769 m_xCheckLB->set_toggle(nPos, bool(nFlags & ACFlags::AddNonBrkSpace) ? TRISTATE_TRUE : TRISTATE_FALSE);
1770 m_xCheckLB->set_text(nPos++, sNonBrkSpace, 0);
1771 m_xCheckLB->append();
1772 m_xCheckLB->set_toggle(nPos, bool(nFlags & ACFlags::ChgOrdinalNumber) ? TRISTATE_TRUE : TRISTATE_FALSE);
1773 m_xCheckLB->set_text(nPos++, sOrdinal, 0);
1774 m_xCheckLB->append();
1775 m_xCheckLB->set_toggle(nPos, bool(nFlags & ACFlags::TransliterateRTL) ? TRISTATE_TRUE : TRISTATE_FALSE);
1776 m_xCheckLB->set_text(nPos++, sTransliterateRTL, 0);
1777 m_xCheckLB->append();
1778 m_xCheckLB->set_toggle(nPos, bool(nFlags & ACFlags::ChgAngleQuotes) ? TRISTATE_TRUE : TRISTATE_FALSE);
1779 m_xCheckLB->set_text(nPos++, sAngleQuotes, 0);
1780
1781 m_xCheckLB->thaw();
1782 }
1783
1784 // Initialize the quote stuffs
1785 m_xDoubleTypoCB->set_active(bool(nFlags & ACFlags::ChgQuotes));
1786 m_xSingleTypoCB->set_active(bool(nFlags & ACFlags::ChgSglQuotes));
1787 m_xDoubleTypoCB->save_state();
1788 m_xSingleTypoCB->save_state();
1789
1790 cStartQuote = pAutoCorrect->GetStartDoubleQuote();
1791 cEndQuote = pAutoCorrect->GetEndDoubleQuote();
1792 cSglStartQuote = pAutoCorrect->GetStartSingleQuote();
1793 cSglEndQuote = pAutoCorrect->GetEndSingleQuote();
1794
1795 m_xSglStartExFT->set_label(ChangeStringExt_Impl(cSglStartQuote));
1796 m_xSglEndExFT->set_label(ChangeStringExt_Impl(cSglEndQuote));
1797 m_xDblStartExFT->set_label(ChangeStringExt_Impl(cStartQuote));
1798 m_xDblEndExFT->set_label(ChangeStringExt_Impl(cEndQuote));
1799 }
1800
1801 #define SGL_START 0
1802 #define DBL_START 1
1803 #define SGL_END 2
1804 #define DBL_END 3
1805
1806
IMPL_LINK(OfaQuoteTabPage,QuoteHdl,weld::Button &,rBtn,void)1807 IMPL_LINK(OfaQuoteTabPage, QuoteHdl, weld::Button&, rBtn, void)
1808 {
1809 sal_uInt16 nMode = SGL_START;
1810 if (&rBtn == m_xSglEndQuotePB.get())
1811 nMode = SGL_END;
1812 else if (&rBtn == m_xDblStartQuotePB.get())
1813 nMode = DBL_START;
1814 else if (&rBtn == m_xDblEndQuotePB.get())
1815 nMode = DBL_END;
1816 // start character selection dialog
1817 SvxCharacterMap aMap(GetFrameWeld(), nullptr, nullptr);
1818 aMap.SetCharFont( OutputDevice::GetDefaultFont(DefaultFontType::LATIN_TEXT,
1819 LANGUAGE_ENGLISH_US, GetDefaultFontFlags::OnlyOne ));
1820 aMap.set_title(nMode < SGL_END ? CuiResId(RID_CUISTR_STARTQUOTE) : CuiResId(RID_CUISTR_ENDQUOTE));
1821 sal_UCS4 cDlg;
1822 SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
1823 LanguageType eLang = Application::GetSettings().GetLanguageTag().getLanguageType();
1824 switch( nMode )
1825 {
1826 case SGL_START:
1827 cDlg = cSglStartQuote;
1828 if(cDlg == 0)
1829 cDlg = pAutoCorrect->GetQuote('\'', true, eLang);
1830 break;
1831 case SGL_END:
1832 cDlg = cSglEndQuote;
1833 if(cDlg == 0)
1834 cDlg = pAutoCorrect->GetQuote('\'', false, eLang);
1835 break;
1836 case DBL_START:
1837 cDlg = cStartQuote;
1838 if(cDlg == 0)
1839 cDlg = pAutoCorrect->GetQuote('\"', true, eLang);
1840 break;
1841 case DBL_END:
1842 cDlg = cEndQuote;
1843 if(cDlg == 0)
1844 cDlg = pAutoCorrect->GetQuote('\"', false, eLang);
1845 break;
1846 default:
1847 OSL_FAIL("svx::OfaQuoteTabPage::QuoteHdl(), how to initialize cDlg?" );
1848 cDlg = 0;
1849 break;
1850
1851 }
1852 aMap.SetChar( cDlg );
1853 aMap.DisableFontSelection();
1854 if (aMap.run() != RET_OK)
1855 return;
1856
1857 sal_UCS4 cNewChar = aMap.GetChar();
1858 switch( nMode )
1859 {
1860 case SGL_START:
1861 cSglStartQuote = cNewChar;
1862 m_xSglStartExFT->set_label(ChangeStringExt_Impl(cNewChar));
1863 break;
1864 case SGL_END:
1865 cSglEndQuote = cNewChar;
1866 m_xSglEndExFT->set_label(ChangeStringExt_Impl(cNewChar));
1867 break;
1868 case DBL_START:
1869 cStartQuote = cNewChar;
1870 m_xDblStartExFT->set_label(ChangeStringExt_Impl(cNewChar));
1871 break;
1872 case DBL_END:
1873 cEndQuote = cNewChar;
1874 m_xDblEndExFT->set_label(ChangeStringExt_Impl(cNewChar));
1875 break;
1876 }
1877 }
1878
IMPL_LINK(OfaQuoteTabPage,StdQuoteHdl,weld::Button &,rBtn,void)1879 IMPL_LINK(OfaQuoteTabPage, StdQuoteHdl, weld::Button&, rBtn, void)
1880 {
1881 if (&rBtn == m_xDblStandardPB.get())
1882 {
1883 cStartQuote = 0;
1884 m_xDblStartExFT->set_label(ChangeStringExt_Impl(0));
1885 cEndQuote = 0;
1886 m_xDblEndExFT->set_label(ChangeStringExt_Impl(0));
1887
1888 }
1889 else
1890 {
1891 cSglStartQuote = 0;
1892 m_xSglStartExFT->set_label(ChangeStringExt_Impl(0));
1893 cSglEndQuote = 0;
1894 m_xSglEndExFT->set_label(ChangeStringExt_Impl(0));
1895 }
1896 }
1897
ChangeStringExt_Impl(sal_UCS4 cChar)1898 OUString OfaQuoteTabPage::ChangeStringExt_Impl( sal_UCS4 cChar )
1899 {
1900 if (!cChar)
1901 return m_sStandard;
1902
1903 // convert codepoint value to unicode-hex string
1904 sal_UCS4 aStrCodes[32] = { 0, ' ', '(', 'U', '+', '0' };
1905 aStrCodes[0] = cChar;
1906 int nFullLen = 5;
1907 int nHexLen = 4;
1908 while( (cChar >> (4*nHexLen)) != 0 )
1909 ++nHexLen;
1910 for( int i = nHexLen; --i >= 0;)
1911 {
1912 sal_UCS4 cHexDigit = ((cChar >> (4*i)) & 0x0f) + '0';
1913 if( cHexDigit > '9' )
1914 cHexDigit += 'A' - ('9' + 1);
1915 aStrCodes[ nFullLen++ ] = cHexDigit;
1916 }
1917 aStrCodes[ nFullLen++ ] = ')';
1918 // using the new UCS4 constructor
1919 OUString aOUStr( aStrCodes, nFullLen );
1920 return aOUStr;
1921 }
1922
OfaAutoCompleteTabPage(weld::Container * pPage,weld::DialogController * pController,const SfxItemSet & rSet)1923 OfaAutoCompleteTabPage::OfaAutoCompleteTabPage(weld::Container* pPage, weld::DialogController* pController,
1924 const SfxItemSet& rSet)
1925 : SfxTabPage(pPage, pController, u"cui/ui/wordcompletionpage.ui"_ustr,
1926 u"WordCompletionPage"_ustr, &rSet)
1927 , m_pAutoCompleteList(nullptr)
1928 , m_nAutoCmpltListCnt(0)
1929 , m_xCBActiv(m_xBuilder->weld_check_button(u"enablewordcomplete"_ustr))
1930 , m_xCBAppendSpace(m_xBuilder->weld_check_button(u"appendspace"_ustr))
1931 , m_xCBAsTip(m_xBuilder->weld_check_button(u"showastip"_ustr))
1932 , m_xCBCollect(m_xBuilder->weld_check_button(u"collectwords"_ustr))
1933 , m_xCBRemoveList(m_xBuilder->weld_check_button(u"whenclosing"_ustr))
1934 , m_xDCBExpandKey(m_xBuilder->weld_combo_box(u"acceptwith"_ustr))
1935 , m_xNFMinWordlen(m_xBuilder->weld_spin_button(u"minwordlen"_ustr))
1936 , m_xNFMaxEntries(m_xBuilder->weld_spin_button(u"maxentries"_ustr))
1937 , m_xLBEntries(m_xBuilder->weld_tree_view(u"entries"_ustr))
1938 , m_xPBEntries(m_xBuilder->weld_button(u"delete"_ustr))
1939 {
1940 //fdo#65595, we need height-for-width support here, but for now we can
1941 //bodge it
1942 Size aPrefSize(m_xCBRemoveList->get_preferred_size());
1943 int nMaxWidth = m_xCBRemoveList->get_approximate_digit_width() * 40;
1944 if (aPrefSize.Width() > nMaxWidth)
1945 {
1946 m_xCBRemoveList->set_label_wrap(true);
1947 m_xCBRemoveList->set_size_request(nMaxWidth, -1);
1948 }
1949
1950 m_xLBEntries->set_size_request(m_xLBEntries->get_approximate_digit_width() * 30,
1951 m_xLBEntries->get_height_rows(10));
1952 m_xLBEntries->set_selection_mode(SelectionMode::Multiple);
1953
1954 // the defined KEYs
1955 static const sal_uInt16 aKeyCodes[] = {
1956 KEY_END,
1957 KEY_RETURN,
1958 KEY_SPACE,
1959 KEY_RIGHT,
1960 KEY_TAB,
1961 0
1962 };
1963
1964 for( const sal_uInt16* pKeys = aKeyCodes; *pKeys; ++pKeys )
1965 {
1966 vcl::KeyCode aKCode(*pKeys);
1967 m_xDCBExpandKey->append(OUString::number(static_cast<sal_Int32>(*pKeys)), aKCode.GetName());
1968 if (KEY_RETURN == *pKeys) // default to RETURN
1969 m_xDCBExpandKey->set_active(std::distance(aKeyCodes, pKeys));
1970 }
1971
1972 m_xPBEntries->connect_clicked(LINK(this, OfaAutoCompleteTabPage, DeleteHdl));
1973 m_xCBActiv->connect_toggled(LINK(this, OfaAutoCompleteTabPage, CheckHdl));
1974 m_xCBCollect->connect_toggled(LINK(this, OfaAutoCompleteTabPage, CheckHdl));
1975 m_xLBEntries->connect_key_release(LINK(this, OfaAutoCompleteTabPage, KeyReleaseHdl));
1976 }
1977
~OfaAutoCompleteTabPage()1978 OfaAutoCompleteTabPage::~OfaAutoCompleteTabPage()
1979 {
1980 }
1981
Create(weld::Container * pPage,weld::DialogController * pController,const SfxItemSet * rSet)1982 std::unique_ptr<SfxTabPage> OfaAutoCompleteTabPage::Create(weld::Container* pPage, weld::DialogController* pController,
1983 const SfxItemSet* rSet)
1984 {
1985 return std::make_unique<OfaAutoCompleteTabPage>(pPage, pController, *rSet);
1986 }
1987
FillItemSet(SfxItemSet *)1988 bool OfaAutoCompleteTabPage::FillItemSet( SfxItemSet* )
1989 {
1990 bool bModified = false, bCheck;
1991 SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
1992 SvxSwAutoFormatFlags *pOpt = &pAutoCorrect->GetSwFlags();
1993
1994 bCheck = m_xCBActiv->get_active();
1995 bModified |= pOpt->bAutoCompleteWords != bCheck;
1996 pOpt->bAutoCompleteWords = bCheck;
1997 bCheck = m_xCBCollect->get_active();
1998 bModified |= pOpt->bAutoCmpltCollectWords != bCheck;
1999 pOpt->bAutoCmpltCollectWords = bCheck;
2000 bCheck = !m_xCBRemoveList->get_active(); // inverted value!
2001 bModified |= pOpt->bAutoCmpltKeepList != bCheck;
2002 pOpt->bAutoCmpltKeepList = bCheck;
2003 bCheck = m_xCBAppendSpace->get_active();
2004 bModified |= pOpt->bAutoCmpltAppendBlank != bCheck;
2005 pOpt->bAutoCmpltAppendBlank = bCheck;
2006 bCheck = m_xCBAsTip->get_active();
2007 bModified |= pOpt->bAutoCmpltShowAsTip != bCheck;
2008 pOpt->bAutoCmpltShowAsTip = bCheck;
2009
2010 sal_uInt16 nVal = static_cast<sal_uInt16>(m_xNFMinWordlen->get_value());
2011 bModified |= nVal != pOpt->nAutoCmpltWordLen;
2012 pOpt->nAutoCmpltWordLen = nVal;
2013
2014 sal_uInt32 nList = static_cast<sal_uInt32>(m_xNFMaxEntries->get_value());
2015 bModified |= nList != pOpt->nAutoCmpltListLen;
2016 pOpt->nAutoCmpltListLen = nList;
2017
2018 const int nPos = m_xDCBExpandKey->get_active();
2019 if (nPos != -1)
2020 {
2021 sal_Int32 nKey = m_xDCBExpandKey->get_id(nPos).toInt32();
2022 bModified |= nKey != pOpt->nAutoCmpltExpandKey;
2023 pOpt->nAutoCmpltExpandKey = static_cast<sal_uInt16>(nKey);
2024 }
2025
2026 if (m_pAutoCompleteList && m_nAutoCmpltListCnt != m_xLBEntries->n_children())
2027 {
2028 bModified = true;
2029 pOpt->m_pAutoCompleteList = m_pAutoCompleteList;
2030 }
2031 if( bModified )
2032 {
2033 SvxAutoCorrCfg& rCfg = SvxAutoCorrCfg::Get();
2034 rCfg.SetModified();
2035 rCfg.Commit();
2036 }
2037 return true;
2038 }
2039
Reset(const SfxItemSet *)2040 void OfaAutoCompleteTabPage::Reset( const SfxItemSet* )
2041 {
2042 SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
2043 SvxSwAutoFormatFlags *pOpt = &pAutoCorrect->GetSwFlags();
2044
2045 m_xCBActiv->set_active( pOpt->bAutoCompleteWords );
2046 m_xCBCollect->set_active( pOpt->bAutoCmpltCollectWords );
2047 m_xCBRemoveList->set_active( !pOpt->bAutoCmpltKeepList ); //inverted value!
2048 m_xCBAppendSpace->set_active( pOpt->bAutoCmpltAppendBlank );
2049 m_xCBAsTip->set_active( pOpt->bAutoCmpltShowAsTip );
2050
2051 m_xNFMinWordlen->set_value( pOpt->nAutoCmpltWordLen );
2052 m_xNFMaxEntries->set_value( pOpt->nAutoCmpltListLen );
2053
2054 // select the specific KeyCode:
2055 {
2056 sal_Int32 nKey = pOpt->nAutoCmpltExpandKey;
2057 for (int n = 0, nCnt = m_xDCBExpandKey->get_count(); n < nCnt; ++n)
2058 {
2059 if (nKey == m_xDCBExpandKey->get_id(n).toInt32())
2060 {
2061 m_xDCBExpandKey->set_active(n);
2062 break;
2063 }
2064 }
2065 }
2066
2067 if (pOpt->m_pAutoCompleteList && !pOpt->m_pAutoCompleteList->empty())
2068 {
2069 m_pAutoCompleteList = const_cast<editeng::SortedAutoCompleteStrings*>(
2070 pOpt->m_pAutoCompleteList);
2071 pOpt->m_pAutoCompleteList = nullptr;
2072 m_nAutoCmpltListCnt = m_pAutoCompleteList->size();
2073 for (size_t n = 0; n < m_nAutoCmpltListCnt; ++n)
2074 {
2075 const OUString* pStr =
2076 &(*m_pAutoCompleteList)[n]->GetAutoCompleteString();
2077 OUString sId(weld::toId(pStr));
2078 m_xLBEntries->append(sId, *pStr);
2079 }
2080 }
2081 else
2082 {
2083 m_xLBEntries->set_sensitive(false);
2084 m_xPBEntries->set_sensitive(false);
2085 }
2086
2087 CheckHdl(*m_xCBActiv);
2088 CheckHdl(*m_xCBCollect);
2089 }
2090
ActivatePage(const SfxItemSet &)2091 void OfaAutoCompleteTabPage::ActivatePage( const SfxItemSet& )
2092 {
2093 static_cast<OfaAutoCorrDlg*>(GetDialogController())->EnableLanguage( false );
2094 }
2095
IMPL_LINK_NOARG(OfaAutoCompleteTabPage,DeleteHdl,weld::Button &,void)2096 IMPL_LINK_NOARG(OfaAutoCompleteTabPage, DeleteHdl, weld::Button&, void)
2097 {
2098 auto rows = m_xLBEntries->get_selected_rows();
2099 std::sort(rows.begin(), rows.end());
2100 while (!rows.empty())
2101 {
2102 sal_Int32 nPos = rows.back();
2103 OUString* pStr = weld::fromId<OUString*>(m_xLBEntries->get_id(nPos));
2104 m_xLBEntries->remove(nPos);
2105 editeng::IAutoCompleteString hack(*pStr); // UGLY
2106 m_pAutoCompleteList->erase(&hack);
2107 rows.pop_back();
2108 }
2109 }
2110
IMPL_LINK(OfaAutoCompleteTabPage,CheckHdl,weld::Toggleable &,rBox,void)2111 IMPL_LINK(OfaAutoCompleteTabPage, CheckHdl, weld::Toggleable&, rBox, void)
2112 {
2113 bool bEnable = rBox.get_active();
2114 if (&rBox == m_xCBActiv.get())
2115 {
2116 m_xCBAppendSpace->set_sensitive(bEnable);
2117 m_xCBAppendSpace->set_sensitive(bEnable);
2118 m_xCBAsTip->set_sensitive(bEnable);
2119 m_xDCBExpandKey->set_sensitive(bEnable);
2120 }
2121 else if (&rBox == m_xCBCollect.get())
2122 m_xCBRemoveList->set_sensitive(bEnable);
2123 }
2124
CopyToClipboard() const2125 void OfaAutoCompleteTabPage::CopyToClipboard() const
2126 {
2127 auto rows = m_xLBEntries->get_selected_rows();
2128 if (!m_pAutoCompleteList || rows.empty())
2129 return;
2130
2131 rtl::Reference<TransferDataContainer> pCntnr = new TransferDataContainer;
2132
2133 OStringBuffer sData;
2134
2135 rtl_TextEncoding nEncode = osl_getThreadTextEncoding();
2136
2137 for (auto a : rows)
2138 {
2139 sData.append(OUStringToOString(m_xLBEntries->get_text(a), nEncode) + SAL_NEWLINE_STRING);
2140 }
2141 pCntnr->CopyByteString( SotClipboardFormatId::STRING, sData.makeStringAndClear() );
2142 pCntnr->CopyToClipboard(m_xLBEntries->get_clipboard());
2143 }
2144
IMPL_LINK(OfaAutoCompleteTabPage,KeyReleaseHdl,const KeyEvent &,rEvent,bool)2145 IMPL_LINK(OfaAutoCompleteTabPage, KeyReleaseHdl, const KeyEvent&, rEvent, bool)
2146 {
2147 bool bHandled = false;
2148 const vcl::KeyCode& rKeyCode = rEvent.GetKeyCode();
2149 switch (rKeyCode.GetModifier() | rKeyCode.GetCode())
2150 {
2151 case KEY_DELETE:
2152 DeleteHdl(*m_xPBEntries);
2153 bHandled = true;
2154 break;
2155 default:
2156 if (KeyFuncType::COPY == rKeyCode.GetFunction())
2157 {
2158 CopyToClipboard();
2159 bHandled = true;
2160 }
2161 break;
2162 }
2163 return bHandled;
2164 }
2165
2166 // class OfaSmartTagOptionsTabPage ---------------------------------------------
2167
OfaSmartTagOptionsTabPage(weld::Container * pPage,weld::DialogController * pController,const SfxItemSet & rSet)2168 OfaSmartTagOptionsTabPage::OfaSmartTagOptionsTabPage(weld::Container* pPage, weld::DialogController* pController,
2169 const SfxItemSet& rSet )
2170 : SfxTabPage(pPage, pController, u"cui/ui/smarttagoptionspage.ui"_ustr, u"SmartTagOptionsPage"_ustr, &rSet)
2171 , m_xMainCB(m_xBuilder->weld_check_button(u"main"_ustr))
2172 , m_xSmartTagTypesLB(m_xBuilder->weld_tree_view(u"list"_ustr))
2173 , m_xPropertiesPB(m_xBuilder->weld_button(u"properties"_ustr))
2174 {
2175 m_xSmartTagTypesLB->set_size_request(m_xSmartTagTypesLB->get_approximate_digit_width() * 50,
2176 m_xSmartTagTypesLB->get_height_rows(6));
2177
2178 m_xSmartTagTypesLB->enable_toggle_buttons(weld::ColumnToggleType::Check);
2179
2180 // set the handlers:
2181 m_xMainCB->connect_toggled(LINK(this, OfaSmartTagOptionsTabPage, CheckHdl));
2182 m_xPropertiesPB->connect_clicked(LINK(this, OfaSmartTagOptionsTabPage, ClickHdl));
2183 m_xSmartTagTypesLB->connect_changed(LINK(this, OfaSmartTagOptionsTabPage, SelectHdl));
2184 }
2185
~OfaSmartTagOptionsTabPage()2186 OfaSmartTagOptionsTabPage::~OfaSmartTagOptionsTabPage()
2187 {
2188 }
2189
Create(weld::Container * pPage,weld::DialogController * pController,const SfxItemSet * rSet)2190 std::unique_ptr<SfxTabPage> OfaSmartTagOptionsTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
2191 {
2192 return std::make_unique<OfaSmartTagOptionsTabPage>(pPage, pController, *rSet);
2193 }
2194
2195 namespace {
2196
2197 /** This struct is used to associate list box entries with smart tag data
2198 */
2199 struct ImplSmartTagLBUserData
2200 {
2201 OUString maSmartTagType;
2202 uno::Reference< smarttags::XSmartTagRecognizer > mxRec;
2203 sal_Int32 mnSmartTagIdx;
2204
ImplSmartTagLBUserData__anonffeffcef0711::ImplSmartTagLBUserData2205 ImplSmartTagLBUserData( OUString aSmartTagType,
2206 uno::Reference< smarttags::XSmartTagRecognizer > xRec,
2207 sal_Int32 nSmartTagIdx ) :
2208 maSmartTagType(std::move( aSmartTagType )),
2209 mxRec(std::move( xRec )),
2210 mnSmartTagIdx( nSmartTagIdx ) {}
2211 };
2212
2213 }
2214
2215 /** Clears m_xSmartTagTypesLB
2216 */
ClearListBox()2217 void OfaSmartTagOptionsTabPage::ClearListBox()
2218 {
2219 const int nCount = m_xSmartTagTypesLB->n_children();
2220 for (int i = 0; i < nCount; ++i)
2221 {
2222 const ImplSmartTagLBUserData* pUserData = weld::fromId<ImplSmartTagLBUserData*>(m_xSmartTagTypesLB->get_id(i));
2223 delete pUserData;
2224 }
2225
2226 m_xSmartTagTypesLB->clear();
2227 }
2228
2229 /** Inserts items into m_xSmartTagTypesLB
2230 */
FillListBox(const SmartTagMgr & rSmartTagMgr)2231 void OfaSmartTagOptionsTabPage::FillListBox( const SmartTagMgr& rSmartTagMgr )
2232 {
2233 // first we have to clear the list box:
2234 ClearListBox();
2235
2236 // fill list box:
2237 const sal_uInt32 nNumberOfRecognizers = rSmartTagMgr.NumberOfRecognizers();
2238 const lang::Locale aLocale( LanguageTag::convertToLocale( eLastDialogLanguage ) );
2239
2240 for ( sal_uInt32 i = 0; i < nNumberOfRecognizers; ++i )
2241 {
2242 const uno::Reference< smarttags::XSmartTagRecognizer >& xRec = rSmartTagMgr.GetRecognizer(i);
2243
2244 const OUString aName = xRec->getName( aLocale );
2245 const sal_Int32 nNumberOfSupportedSmartTags = xRec->getSmartTagCount();
2246
2247 for ( sal_Int32 j = 0; j < nNumberOfSupportedSmartTags; ++j )
2248 {
2249 const OUString aSmartTagType = xRec->getSmartTagName(j);
2250 OUString aSmartTagCaption = rSmartTagMgr.GetSmartTagCaption( aSmartTagType, aLocale );
2251
2252 if ( aSmartTagCaption.isEmpty() )
2253 aSmartTagCaption = aSmartTagType;
2254
2255 const OUString aLBEntry = aSmartTagCaption + " (" + aName + ")";
2256
2257 m_xSmartTagTypesLB->append();
2258 const int nRow = m_xSmartTagTypesLB->n_children() - 1;
2259 const bool bCheck = rSmartTagMgr.IsSmartTagTypeEnabled( aSmartTagType );
2260 m_xSmartTagTypesLB->set_toggle(nRow, bCheck ? TRISTATE_TRUE : TRISTATE_FALSE);
2261 m_xSmartTagTypesLB->set_text(nRow, aLBEntry, 0);
2262 m_xSmartTagTypesLB->set_id(nRow, weld::toId(new ImplSmartTagLBUserData(aSmartTagType, xRec, j)));
2263 }
2264 }
2265 }
2266
2267 /** Handler for the push button
2268 */
IMPL_LINK_NOARG(OfaSmartTagOptionsTabPage,ClickHdl,weld::Button &,void)2269 IMPL_LINK_NOARG(OfaSmartTagOptionsTabPage, ClickHdl, weld::Button&, void)
2270 {
2271 const int nPos = m_xSmartTagTypesLB->get_selected_index();
2272 const ImplSmartTagLBUserData* pUserData = weld::fromId<ImplSmartTagLBUserData*>(m_xSmartTagTypesLB->get_id(nPos));
2273 uno::Reference< smarttags::XSmartTagRecognizer > xRec = pUserData->mxRec;
2274 const sal_Int32 nSmartTagIdx = pUserData->mnSmartTagIdx;
2275
2276 const lang::Locale aLocale( LanguageTag::convertToLocale( eLastDialogLanguage ) );
2277 if ( xRec->hasPropertyPage( nSmartTagIdx, aLocale ) )
2278 xRec->displayPropertyPage( nSmartTagIdx, aLocale );
2279 }
2280
2281 /** Handler for the check box
2282 */
IMPL_LINK_NOARG(OfaSmartTagOptionsTabPage,CheckHdl,weld::Toggleable &,void)2283 IMPL_LINK_NOARG(OfaSmartTagOptionsTabPage, CheckHdl, weld::Toggleable&, void)
2284 {
2285 const bool bEnable = m_xMainCB->get_active();
2286 m_xSmartTagTypesLB->set_sensitive(bEnable);
2287 m_xPropertiesPB->set_sensitive(false);
2288
2289 // if the controls are currently enabled, we still have to check
2290 // if the properties button should be disabled because the currently
2291 // selected smart tag type does not have a properties dialog.
2292 // We do this by calling SelectHdl:
2293 if (bEnable)
2294 SelectHdl(*m_xSmartTagTypesLB);
2295 }
2296
2297 /** Handler for the list box
2298 */
IMPL_LINK_NOARG(OfaSmartTagOptionsTabPage,SelectHdl,weld::TreeView &,void)2299 IMPL_LINK_NOARG(OfaSmartTagOptionsTabPage, SelectHdl, weld::TreeView&, void)
2300 {
2301 const int nPos = m_xSmartTagTypesLB->get_selected_index();
2302 if (nPos == -1)
2303 return;
2304 const ImplSmartTagLBUserData* pUserData = weld::fromId<ImplSmartTagLBUserData*>(m_xSmartTagTypesLB->get_id(nPos));
2305 uno::Reference< smarttags::XSmartTagRecognizer > xRec = pUserData->mxRec;
2306 const sal_Int32 nSmartTagIdx = pUserData->mnSmartTagIdx;
2307
2308 const lang::Locale aLocale( LanguageTag::convertToLocale( eLastDialogLanguage ) );
2309 if ( xRec->hasPropertyPage( nSmartTagIdx, aLocale ) )
2310 m_xPropertiesPB->set_sensitive(true);
2311 else
2312 m_xPropertiesPB->set_sensitive(false);
2313 }
2314
2315 /** Propagates the current settings to the smart tag manager.
2316 */
FillItemSet(SfxItemSet *)2317 bool OfaSmartTagOptionsTabPage::FillItemSet( SfxItemSet* )
2318 {
2319 SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
2320 SvxSwAutoFormatFlags *pOpt = &pAutoCorrect->GetSwFlags();
2321 SmartTagMgr* pSmartTagMgr = pOpt->pSmartTagMgr;
2322
2323 // robust!
2324 if ( !pSmartTagMgr )
2325 return false;
2326
2327 bool bModifiedSmartTagTypes = false;
2328 std::vector< OUString > aDisabledSmartTagTypes;
2329
2330 const int nCount = m_xSmartTagTypesLB->n_children();
2331
2332 for (int i = 0; i < nCount; ++i)
2333 {
2334 const ImplSmartTagLBUserData* pUserData = weld::fromId<ImplSmartTagLBUserData*>(m_xSmartTagTypesLB->get_id(i));
2335 const bool bChecked = m_xSmartTagTypesLB->get_toggle(i) == TRISTATE_TRUE;
2336 const bool bIsCurrentlyEnabled = pSmartTagMgr->IsSmartTagTypeEnabled( pUserData->maSmartTagType );
2337
2338 bModifiedSmartTagTypes = bModifiedSmartTagTypes || ( !bChecked != !bIsCurrentlyEnabled );
2339
2340 if ( !bChecked )
2341 aDisabledSmartTagTypes.push_back( pUserData->maSmartTagType );
2342
2343 delete pUserData;
2344 }
2345
2346 const bool bModifiedRecognize = ( !m_xMainCB->get_active() != !pSmartTagMgr->IsLabelTextWithSmartTags() );
2347 if ( bModifiedSmartTagTypes || bModifiedRecognize )
2348 {
2349 bool bLabelTextWithSmartTags = m_xMainCB->get_active();
2350 pSmartTagMgr->WriteConfiguration( bModifiedRecognize ? &bLabelTextWithSmartTags : nullptr,
2351 bModifiedSmartTagTypes ? &aDisabledSmartTagTypes : nullptr );
2352 }
2353
2354 return true;
2355 }
2356
2357 /** Sets the controls based on the current settings at SmartTagMgr.
2358 */
Reset(const SfxItemSet *)2359 void OfaSmartTagOptionsTabPage::Reset( const SfxItemSet* )
2360 {
2361 SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
2362 SvxSwAutoFormatFlags *pOpt = &pAutoCorrect->GetSwFlags();
2363 const SmartTagMgr* pSmartTagMgr = pOpt->pSmartTagMgr;
2364
2365 // robust, should not happen!
2366 if ( !pSmartTagMgr )
2367 return;
2368
2369 FillListBox(*pSmartTagMgr);
2370 m_xSmartTagTypesLB->select(0);
2371 m_xMainCB->set_active(pSmartTagMgr->IsLabelTextWithSmartTags());
2372 CheckHdl(*m_xMainCB);
2373 }
2374
ActivatePage(const SfxItemSet &)2375 void OfaSmartTagOptionsTabPage::ActivatePage( const SfxItemSet& )
2376 {
2377 static_cast<OfaAutoCorrDlg*>(GetDialogController())->EnableLanguage( false );
2378 }
2379
2380 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
2381