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