LibreOffice Module cui (master) 1
optdict.cxx
Go to the documentation of this file.
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 <editeng/unolingu.hxx>
21#include <o3tl/safeint.hxx>
22#include <svx/dialmgr.hxx>
23#include <com/sun/star/frame/XStorable.hpp>
24#include <com/sun/star/linguistic2/XDictionary.hpp>
25#include <com/sun/star/linguistic2/XSearchableDictionaryList.hpp>
26#include <comphelper/string.hxx>
27#include <tools/debug.hxx>
31#include <vcl/svapp.hxx>
32#include <vcl/weld.hxx>
33
34#include <linguistic/misc.hxx>
35#include <strings.hrc>
36#include <optdict.hxx>
37#include <dialmgr.hxx>
38#include <svx/svxerr.hxx>
39
40using namespace ::com::sun::star;
41using namespace ::com::sun::star::uno;
42using namespace ::com::sun::star::linguistic2;
43using namespace linguistic;
44
45// static function -------------------------------------------------------
46
47static OUString getNormDicEntry_Impl(std::u16string_view rText)
48{
49 OUString aTmp(comphelper::string::stripEnd(rText, '.'));
50 // non-standard hyphenation
51 if (aTmp.indexOf('[') > -1)
52 {
53 OUStringBuffer aTmp2 ( aTmp.getLength() );
54 bool bSkip = false;
55 for (sal_Int32 i = 0; i < aTmp.getLength(); i++)
56 {
57 sal_Unicode cTmp = aTmp[i];
58 if (cTmp == '[')
59 bSkip = true;
60 else if (!bSkip)
61 aTmp2.append( cTmp );
62 else if (cTmp == ']')
63 bSkip = false;
64 }
65 aTmp = aTmp2.makeStringAndClear();
66 }
67 return aTmp.replaceAll("=", "");
68}
69
70namespace {
71
72// Compare Dictionary Entry result
73enum CDE_RESULT { CDE_EQUAL, CDE_SIMILAR, CDE_DIFFERENT };
74
75}
76
77static CDE_RESULT cmpDicEntry_Impl( std::u16string_view rText1, std::u16string_view rText2 )
78{
79 CDE_RESULT eRes = CDE_DIFFERENT;
80
81 if (rText1 == rText2)
82 eRes = CDE_EQUAL;
83 else
84 { // similar = equal up to trailing '.' and hyphenation positions
85 // marked with '=' and '[' + alternative spelling pattern + ']'
86 if (getNormDicEntry_Impl( rText1 ) == getNormDicEntry_Impl( rText2 ))
87 eRes = CDE_SIMILAR;
88 }
89
90 return eRes;
91}
92
93// class SvxNewDictionaryDialog -------------------------------------------
94
96 : GenericDialogController(pParent, "cui/ui/optnewdictionarydialog.ui", "OptNewDictionaryDialog")
97 , m_xNameEdit(m_xBuilder->weld_entry("nameedit"))
98 , m_xLanguageLB(new SvxLanguageBox(m_xBuilder->weld_combo_box("language")))
99 , m_xExceptBtn(m_xBuilder->weld_check_button("except"))
100 , m_xOKBtn(m_xBuilder->weld_button("ok"))
101{
102 // Prevent creation of dictionary without a name.
103 m_xOKBtn->set_sensitive(false);
104
105 // install handler
106 m_xNameEdit->connect_changed(LINK(this, SvxNewDictionaryDialog, ModifyHdl_Impl));
107 m_xOKBtn->connect_clicked(LINK(this, SvxNewDictionaryDialog, OKHdl_Impl));
108
109 // display languages
110 m_xLanguageLB->SetLanguageList(SvxLanguageListFlags::ALL, true, true);
111 m_xLanguageLB->set_active(0);
112}
113
115{
116
117 // add extension for personal dictionaries
118 OUString sDict = comphelper::string::stripEnd(m_xNameEdit->get_text(), ' ') + ".dic";
119
120 Reference< XSearchableDictionaryList > xDicList( LinguMgr::GetDictionaryList() );
121
122 Sequence< Reference< XDictionary > > aDics;
123 if (xDicList.is())
124 aDics = xDicList->getDictionaries();
125 const Reference< XDictionary > *pDic = aDics.getConstArray();
126 sal_Int32 nCount = aDics.getLength();
127
128 bool bFound = false;
129 sal_Int32 i;
130 for (i = 0; !bFound && i < nCount; ++i )
131 if ( sDict.equalsIgnoreAsciiCase( pDic[i]->getName()) )
132 bFound = true;
133
134 if ( sDict.indexOf("/") != -1 || sDict.indexOf("\\") != -1 )
135 {
136 // Detected an invalid character.
137 std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(m_xDialog.get(),
138 VclMessageType::Info, VclButtonsType::Ok,
139 CuiResId(RID_CUISTR_OPT_INVALID_DICT_NAME)));
140 xInfoBox->run();
141 m_xNameEdit->grab_focus();
142 return;
143 }
144
145 if ( bFound )
146 {
147 // duplicate names?
148 std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(m_xDialog.get(),
149 VclMessageType::Info, VclButtonsType::Ok,
150 CuiResId(RID_CUISTR_OPT_DOUBLE_DICTS)));
151 xInfoBox->run();
152 m_xNameEdit->grab_focus();
153 return;
154 }
155
156 // create and add
157 LanguageType nLang = m_xLanguageLB->get_active_id();
158 try
159 {
160 // create new dictionary
161 DictionaryType eType = m_xExceptBtn->get_active() ?
162 DictionaryType_NEGATIVE : DictionaryType_POSITIVE;
163 if (xDicList.is())
164 {
165 lang::Locale aLocale( LanguageTag::convertToLocale(nLang) );
166 OUString aURL( linguistic::GetWritableDictionaryURL( sDict ) );
167 m_xNewDic = xDicList->createDictionary(sDict, aLocale, eType, aURL);
168 m_xNewDic->setActive(true);
169 }
170 DBG_ASSERT(m_xNewDic.is(), "NULL pointer");
171 }
172 catch(...)
173 {
174 m_xNewDic = nullptr;
175 // error: couldn't create new dictionary
176 SfxErrorContext aContext( ERRCTX_SVX_LINGU_DICTIONARY, OUString(),
180 m_xDialog->response(RET_CANCEL);
181 }
182
183 if (xDicList.is() && m_xNewDic.is())
184 {
185 xDicList->addDictionary(m_xNewDic);
186
187 // refresh list of dictionaries
189 aDics = xDicList->getDictionaries();
190 }
191
192 m_xDialog->response(RET_OK);
193}
194
196{
197 m_xOKBtn->set_sensitive(!m_xNameEdit->get_text().isEmpty());
198}
199
200// class SvxEditDictionaryDialog -------------------------------------------
201
203 : GenericDialogController(pParent, "cui/ui/editdictionarydialog.ui", "EditDictionaryDialog")
204 , sModify(CuiResId(STR_MODIFY))
205 , bFirstSelect(false)
206 , bDoNothing(false)
207 , bDicIsReadonly(false)
208 , m_xAllDictsLB(m_xBuilder->weld_combo_box("book"))
209 , m_xLangFT(m_xBuilder->weld_label("lang_label"))
210 , m_xLangLB(new SvxLanguageBox(m_xBuilder->weld_combo_box("lang")))
211 , m_xWordED(m_xBuilder->weld_entry("word"))
212 , m_xReplaceFT(m_xBuilder->weld_label("replace_label"))
213 , m_xReplaceED(m_xBuilder->weld_entry("replace"))
214 , m_xSingleColumnLB(m_xBuilder->weld_tree_view("words"))
215 , m_xDoubleColumnLB(m_xBuilder->weld_tree_view("replaces"))
216 , m_xNewReplacePB(m_xBuilder->weld_button("newreplace"))
217 , m_xDeletePB(m_xBuilder->weld_button("delete"))
218{
219 sReplaceFT_Text = m_xReplaceFT->get_label();
220 m_xSingleColumnLB->set_size_request(-1, m_xSingleColumnLB->get_height_rows(8));
221 m_xDoubleColumnLB->set_size_request(-1, m_xDoubleColumnLB->get_height_rows(8));
223 m_xSingleColumnLB->hide();
224
225 //set to max of both sizes to avoid resizes
226 sNew = m_xNewReplacePB->get_label();
227 auto nNewWidth = m_xNewReplacePB->get_preferred_size().Width();
228 m_xNewReplacePB->set_label(sModify);
229 auto nReplaceWidth = m_xNewReplacePB->get_preferred_size().Width();
230 m_xNewReplacePB->set_label(sNew);
231 m_xNewReplacePB->set_size_request(std::max(nNewWidth, nReplaceWidth), -1);
232
234 aDics = LinguMgr::GetDictionaryList()->getDictionaries();
235
236 m_xSingleColumnLB->connect_changed(LINK(this, SvxEditDictionaryDialog, SelectHdl));
237 m_xDoubleColumnLB->connect_changed(LINK(this, SvxEditDictionaryDialog, SelectHdl));
238
239 std::vector<int> aWidths
240 {
241 o3tl::narrowing<int>(m_xDoubleColumnLB->get_approximate_digit_width() * 22)
242 };
243 m_xDoubleColumnLB->set_column_fixed_widths(aWidths);
244
245 // install handler
246 m_xNewReplacePB->connect_clicked(
247 LINK( this, SvxEditDictionaryDialog, NewDelButtonHdl));
248 m_xDeletePB->connect_clicked(
249 LINK( this, SvxEditDictionaryDialog, NewDelButtonHdl));
250
251 m_xLangLB->connect_changed(
252 LINK( this, SvxEditDictionaryDialog, SelectLangHdl_Impl ) );
253 m_xAllDictsLB->connect_changed(
254 LINK( this, SvxEditDictionaryDialog, SelectBookHdl_Impl ) );
255
256 m_xWordED->connect_changed(LINK(this, SvxEditDictionaryDialog, ModifyHdl));
257 m_xReplaceED->connect_changed(LINK(this, SvxEditDictionaryDialog, ModifyHdl));
258 m_xWordED->connect_activate(LINK(this, SvxEditDictionaryDialog, NewDelActionHdl));
259 m_xReplaceED->connect_activate(LINK(this, SvxEditDictionaryDialog, NewDelActionHdl));
260
261 // fill listbox with all available WB's
262 const Reference< XDictionary > *pDic = aDics.getConstArray();
263 sal_Int32 nCount = aDics.getLength();
264
265 OUString aLookUpEntry;
266 for ( sal_Int32 i = 0; i < nCount; ++i )
267 {
268 Reference< XDictionary > xDic = pDic[i];
269 if (xDic.is())
270 {
271 bool bNegative = xDic->getDictionaryType() == DictionaryType_NEGATIVE;
272 OUString aDicName( xDic->getName() );
273 const OUString aTxt( ::GetDicInfoStr( aDicName,
274 LanguageTag( xDic->getLocale() ).getLanguageType(), bNegative ) );
275 m_xAllDictsLB->append_text(aTxt);
276
277 if (rName == aDicName)
278 aLookUpEntry = aTxt;
279 }
280 }
281
282 m_xLangLB->SetLanguageList( SvxLanguageListFlags::ALL, true, true );
283
284 Link<OUString&,bool> aLink = LINK(this, SvxEditDictionaryDialog, InsertTextHdl);
285 m_xReplaceED->connect_insert_text(aLink);
286 m_xWordED->connect_insert_text(aLink);
287
288 if ( nCount > 0 )
289 {
290 m_xAllDictsLB->set_active_text(aLookUpEntry);
291 int nPos = m_xAllDictsLB->get_active();
292
293 if (nPos == -1)
294 {
295 nPos = 0;
296 m_xAllDictsLB->set_active(nPos);
297 }
298 Reference< XDictionary > xDic;
299 if (nPos != -1)
300 xDic = aDics[ nPos ];
301 if (xDic.is())
302 SetLanguage_Impl( LanguageTag( xDic->getLocale() ).getLanguageType() );
303
304 // check if dictionary is read-only
306 bool bEnable = !IsDicReadonly_Impl();
307 m_xNewReplacePB->set_sensitive( false );
308 m_xDeletePB->set_sensitive( false );
309 m_xLangFT->set_sensitive( bEnable );
310 m_xLangLB->set_sensitive( bEnable );
312 }
313 else
314 {
315 m_xNewReplacePB->set_sensitive(false);
316 m_xDeletePB->set_sensitive(false);
317 }
318
319 m_xWordED->connect_size_allocate(LINK(this, SvxEditDictionaryDialog, EntrySizeAllocHdl));
320 m_xReplaceED->connect_size_allocate(LINK(this, SvxEditDictionaryDialog, EntrySizeAllocHdl));
321}
322
323IMPL_LINK_NOARG(SvxEditDictionaryDialog, EntrySizeAllocHdl, const Size&, void)
324{
325 std::vector<int> aWidths;
326 int x, y, width, height;
327 if (m_xReplaceED->get_extents_relative_to(*m_pWordsLB, x, y, width, height))
328 {
329 aWidths.push_back(x);
330 m_xDoubleColumnLB->set_column_fixed_widths(aWidths);
331 }
332}
333
335{
336}
337
339 Reference< XDictionary > const &xDic )
340{
341 // enable or disable new and delete button according to file attributes
342 bDicIsReadonly = true;
343 if (xDic.is())
344 {
345 Reference< frame::XStorable > xStor( xDic, UNO_QUERY );
346 if ( !xStor.is() // non persistent dictionary
347 || !xStor->hasLocation() // not yet persistent
348 || !xStor->isReadonly() )
349 {
350 bDicIsReadonly = false;
351 }
352 }
353}
354
356{
357 // select language
358 m_xLangLB->set_active_id(nLanguage);
359}
360
361int SvxEditDictionaryDialog::GetLBInsertPos(std::u16string_view rDicWord)
362{
363 IntlWrapper aIntlWrapper(SvtSysLocale().GetUILanguageTag());
364 const CollatorWrapper* pCollator = aIntlWrapper.getCollator();
365 int j;
367 for (j = 0; j < nCount; ++j)
368 {
369 OUString aNormEntry( getNormDicEntry_Impl( rDicWord ) );
370 sal_Int32 nCmpRes = pCollator->
371 compareString( aNormEntry, getNormDicEntry_Impl( m_pWordsLB->get_text(j, 0) ) );
372 if (nCmpRes < 0)
373 break;
374 }
375
376 return j;
377}
378
380{
381 int nLBPos = m_xAllDictsLB->get_active();
382 if (nEntry != -1 && nLBPos != -1)
383 {
384 OUString sTmpShort(m_pWordsLB->get_text(nEntry, 0));
385
386 Reference<XDictionary> xDic = aDics.getConstArray()[nLBPos];
387 if (xDic->remove(sTmpShort)) // sal_True on success
388 {
389 m_pWordsLB->remove(nEntry);
390 SelectHdl(*m_pWordsLB);
391 }
392 }
393}
394
396{
397 int nPos = m_xAllDictsLB->get_active();
398 if (nPos == -1)
399 return;
400
401 m_xNewReplacePB->set_sensitive( false );
402 m_xDeletePB->set_sensitive( false );
403 // display dictionary
404 ShowWords_Impl( nPos );
405 // enable or disable new and delete button according to file attributes
406 Reference< XDictionary > const & xDic = aDics[ nPos ];
407 if (xDic.is())
408 SetLanguage_Impl( LanguageTag( xDic->getLocale() ).getLanguageType() );
409
410 SetDicReadonly_Impl(xDic);
411 bool bEnable = !IsDicReadonly_Impl();
412 m_xLangFT->set_sensitive( bEnable );
413 m_xLangLB->set_sensitive( bEnable );
414}
415
417{
418 int nDicPos = m_xAllDictsLB->get_active();
419 LanguageType nLang = m_xLangLB->get_active_id();
420 Reference< XDictionary > const & xDic = aDics[ nDicPos ];
421 LanguageType nOldLang = LanguageTag( xDic->getLocale() ).getLanguageType();
422
423 if ( nLang == nOldLang )
424 return;
425
426 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xDialog.get(),
427 VclMessageType::Question, VclButtonsType::YesNo,
428 CuiResId(RID_CUISTR_CONFIRM_SET_LANGUAGE)));
429 OUString sTxt(xBox->get_primary_text());
430 sTxt = sTxt.replaceFirst("%1", m_xAllDictsLB->get_active_text());
431 xBox->set_primary_text(sTxt);
432
433 if (xBox->run() == RET_YES)
434 {
435 xDic->setLocale( LanguageTag::convertToLocale( nLang ) );
436 bool bNegativ = xDic->getDictionaryType() == DictionaryType_NEGATIVE;
437
438 const OUString sName(
439 ::GetDicInfoStr( xDic->getName(),
440 LanguageTag( xDic->getLocale() ).getLanguageType(),
441 bNegativ ) );
442 m_xAllDictsLB->remove(nDicPos);
443 m_xAllDictsLB->insert_text(nDicPos, sName);
444 m_xAllDictsLB->set_active(nDicPos);
445 }
446 else
447 SetLanguage_Impl( nOldLang );
448}
449
451{
452 Reference< XDictionary > xDic = aDics.getConstArray()[ nId ];
453
454 weld::WaitObject aWait(m_xDialog.get());
455
456 m_xWordED->set_text(OUString());
457 m_xReplaceED->set_text(OUString());
458
459 bool bIsNegative = xDic->getDictionaryType() != DictionaryType_POSITIVE;
460 bool bLangNone = LanguageTag(
461 xDic->getLocale() ).getLanguageType() == LANGUAGE_NONE;
462
463 // The label is "Replace By" only in negative dictionaries (forbidden
464 // words), otherwise "Grammar By" in language-specific dictionaries
465 // (where the optional second word is the sample word for
466 // the Hunspell based affixation/compounding of the new dictionary word)
467 if (bIsNegative)
468 {
469 m_xReplaceFT->set_label(sReplaceFT_Text);
470 } else if (!bLangNone) {
471 m_xReplaceFT->set_label(CuiResId(RID_CUISTR_OPT_GRAMMAR_BY));
472 }
473
474 if(bIsNegative || !bLangNone)
475 {
476 // make controls for replacement text active
477 if (!m_xReplaceFT->get_visible())
478 {
479 m_xReplaceFT->show();
480 m_xReplaceED->show();
481 m_xSingleColumnLB->hide();
482 m_xDoubleColumnLB->show();
484 }
485 }
486 else
487 {
488 // deactivate controls for replacement text
489 if (m_xReplaceFT->get_visible())
490 {
491 m_xReplaceFT->hide();
492 m_xReplaceED->hide();
493 m_xDoubleColumnLB->hide();
494 m_xSingleColumnLB->show();
496 }
497 }
498
499 m_pWordsLB->clear();
500
501 Sequence< Reference< XDictionaryEntry > > aEntries( xDic->getEntries() );
502 const Reference< XDictionaryEntry > *pEntry = aEntries.getConstArray();
503 sal_Int32 nCount = aEntries.getLength();
504 std::vector<OUString> aSortedDicEntries;
505 aSortedDicEntries.reserve(nCount);
506 for (sal_Int32 i = 0; i < nCount; i++)
507 {
508 OUString aStr = pEntry[i]->getDictionaryWord();
509 if(!pEntry[i]->getReplacementText().isEmpty())
510 {
511 aStr += "\t" + pEntry[i]->getReplacementText();
512 }
513 aSortedDicEntries.push_back(aStr);
514 }
515
516 IntlWrapper aIntlWrapper(SvtSysLocale().GetUILanguageTag());
517 const CollatorWrapper* pCollator = aIntlWrapper.getCollator();
518 std::sort(aSortedDicEntries.begin(), aSortedDicEntries.end(),
519 [&] (OUString const & lhs, OUString const & rhs)
520 {
521 sal_Int32 nCmpRes = pCollator->
522 compareString( getNormDicEntry_Impl(lhs), getNormDicEntry_Impl( rhs ) );
523 return nCmpRes < 0;
524 });
525
526 m_pWordsLB->freeze(); // speed up insert
527 int nRow = 0;
528 for (OUString const & rStr : aSortedDicEntries)
529 {
530 m_pWordsLB->append_text(rStr.getToken(0, '\t'));
531 if (m_pWordsLB == m_xDoubleColumnLB.get())
532 {
533 OUString sReplace = rStr.getToken(1, '\t');
534 m_pWordsLB->set_text(nRow, sReplace, 1);
535 ++nRow;
536 }
537 }
538 m_pWordsLB->thaw();
539
540 if (m_pWordsLB->n_children())
541 {
542 m_pWordsLB->select(0);
544 SelectHdl(*m_pWordsLB);
545 }
546}
547
549{
550 if (bDoNothing)
551 return;
552
553 int nEntry = rBox.get_selected_index();
554
555 if(!bFirstSelect)
556 {
557 if (nEntry != -1)
558 {
559 OUString sTmpShort(rBox.get_text(nEntry, 0));
560 // without this the cursor is always at the beginning of a word, if the text
561 // is set over the ModifyHdl, although you're editing there at the moment
562 if (m_xWordED->get_text() != sTmpShort)
563 m_xWordED->set_text(sTmpShort);
564 if (&rBox == m_xDoubleColumnLB.get())
565 m_xReplaceED->set_text(rBox.get_text(nEntry, 1));
566 }
567 }
568 else
569 bFirstSelect = false;
570
571 // entries in the list box should exactly correspond to those from the
572 // dictionary. Thus:
573 m_xNewReplacePB->set_sensitive(false);
574 m_xDeletePB->set_sensitive(nEntry != -1 && !IsDicReadonly_Impl());
575}
576
577IMPL_LINK(SvxEditDictionaryDialog, NewDelButtonHdl, weld::Button&, rBtn, void)
578{
579 NewDelHdl(&rBtn);
580}
581
582IMPL_LINK(SvxEditDictionaryDialog, NewDelActionHdl, weld::Entry&, rDictEdit, bool)
583{
584 return NewDelHdl(&rDictEdit);
585}
586
588{
589 if (pBtn == m_xDeletePB.get())
590 {
591 m_xWordED->set_text("");
592 m_xReplaceED->set_text("");
593 m_xDeletePB->set_sensitive(false);
594
595 int nEntry = m_pWordsLB->get_selected_index();
596 RemoveDictEntry(nEntry); // remove entry from dic and list-box
597 }
598 if (pBtn == m_xNewReplacePB.get() || m_xNewReplacePB->get_sensitive())
599 {
600 int nEntry = m_pWordsLB->get_selected_index();
601 OUString aNewWord(m_xWordED->get_text());
602 OUString sEntry(aNewWord);
603 OUString aReplaceStr(m_xReplaceED->get_text());
604
605 DictionaryError nAddRes = DictionaryError::UNKNOWN;
606 int nPos = m_xAllDictsLB->get_active();
607 if (nPos != -1 && !aNewWord.isEmpty())
608 {
609 DBG_ASSERT(nPos < aDics.getLength(), "invalid dictionary index");
610 Reference< XDictionary > const & xDic = aDics[ nPos ];
611 if (xDic.is())
612 {
613 // make changes in dic
614
615 bool bIsNegEntry = xDic->getDictionaryType() == DictionaryType_NEGATIVE;
616
617 OUString aRplcText;
618 if(!aReplaceStr.isEmpty())
619 aRplcText = aReplaceStr;
620
621 if (nEntry != -1) // entry selected in m_pWordsLB ie action = modify entry
622 xDic->remove(m_pWordsLB->get_text(nEntry, 0));
623 // if remove has failed the following add should fail too
624 // and thus a warning message should be triggered...
625
626 nAddRes = linguistic::AddEntryToDic( xDic,
627 aNewWord, bIsNegEntry,
628 aRplcText, false );
629 }
630 }
631 if (DictionaryError::NONE != nAddRes)
632 SvxDicError(m_xDialog.get(), nAddRes);
633
634 if (DictionaryError::NONE == nAddRes && !sEntry.isEmpty())
635 {
636 // insert new entry in list-box etc...
638
639 if (nEntry != -1) // entry selected in m_pWordsLB ie action = modify entry
640 {
641 m_pWordsLB->set_text(nEntry, sEntry);
642 if (!aReplaceStr.isEmpty())
643 m_pWordsLB->set_text(nEntry, aReplaceStr, 1);
644 }
645 else
646 {
647 nEntry = GetLBInsertPos(aNewWord);
648 m_pWordsLB->insert_text(nEntry, sEntry);
649 if(!aReplaceStr.isEmpty())
650 m_pWordsLB->set_text(nEntry, aReplaceStr, 1);
651 }
652
653 m_pWordsLB->thaw();
654 m_pWordsLB->scroll_to_row(nEntry);
655
656 // if the request came from the ReplaceEdit, give focus to the ShortEdit
657 if (m_xReplaceED->has_focus())
658 m_xWordED->grab_focus();
659 }
660 }
661 else
662 {
663 // this can only be an enter in one of the two edit fields
664 // which means EndDialog() - has to be evaluated in KeyInput
665 return false;
666 }
667 ModifyHdl(*m_xWordED);
668 return true;
669}
670
672{
673 OUString rEntry = rEdt.get_text();
674
675 sal_Int32 nWordLen = rEntry.getLength();
676 const OUString& rRepString = m_xReplaceED->get_text();
677
678 bool bEnableNewReplace = false;
679 bool bEnableDelete = false;
680 OUString aNewReplaceText = sNew;
681
682 if (&rEdt == m_xWordED.get())
683 {
684 if(nWordLen>0)
685 {
686 bool bFound = false;
687 bool bTmpSelEntry=false;
688 CDE_RESULT eCmpRes = CDE_DIFFERENT;
689
690 bool bDoubleColumn = m_pWordsLB == m_xDoubleColumnLB.get();
691
692 for (int i = 0, nCount = m_pWordsLB->n_children(); i < nCount; ++i)
693 {
694 OUString aTestStr(m_pWordsLB->get_text(i, 0));
695 eCmpRes = cmpDicEntry_Impl( rEntry, aTestStr );
696 if(CDE_DIFFERENT != eCmpRes)
697 {
698 if(!rRepString.isEmpty())
699 bFirstSelect = true;
700 bDoNothing=true;
701 m_pWordsLB->set_cursor(i);
702 bDoNothing=false;
703 if (bDoubleColumn)
704 m_xReplaceED->set_text(m_pWordsLB->get_text(i, 1));
705
706 if (CDE_SIMILAR == eCmpRes)
707 {
708 aNewReplaceText = sModify;
709 bEnableNewReplace = true;
710 }
711 bFound= true;
712 break;
713 }
714 else if(getNormDicEntry_Impl(aTestStr).indexOf(
715 getNormDicEntry_Impl( rEntry ) ) == 0
716 && !bTmpSelEntry)
717 {
718 bDoNothing=true;
719 m_pWordsLB->scroll_to_row(i);
720 bDoNothing=false;
721 bTmpSelEntry=true;
722
723 aNewReplaceText = sNew;
724 bEnableNewReplace = true;
725 }
726 }
727
728 if(!bFound)
729 {
730 m_pWordsLB->unselect_all();
731 aNewReplaceText = sNew;
732 bEnableNewReplace = true;
733 }
734 bEnableDelete = CDE_DIFFERENT != eCmpRes;
735 }
736 else if (m_pWordsLB->n_children() > 0)
737 {
738 bDoNothing=true;
739 m_pWordsLB->scroll_to_row(0);
740 bDoNothing=false;
741 }
742 }
743 else if(&rEdt == m_xReplaceED.get())
744 {
745 OUString aReplaceText;
746 OUString aWordText;
747 int nFirstSel = m_pWordsLB->get_selected_index();
748 if (nFirstSel != -1) // a m_pWordsLB entry is selected
749 {
750 aWordText = m_pWordsLB->get_text(nFirstSel, 0);
751 aReplaceText = m_pWordsLB->get_text(nFirstSel, 1);
752
753 aNewReplaceText = sModify;
754 bEnableDelete = true;
755 }
756 bool bIsChange =
757 CDE_EQUAL != cmpDicEntry_Impl(m_xWordED->get_text(), aWordText)
758 || CDE_EQUAL != cmpDicEntry_Impl(m_xReplaceED->get_text(), aReplaceText);
759 if (!m_xWordED->get_text().isEmpty() && bIsChange)
760 bEnableNewReplace = true;
761 }
762
763 m_xNewReplacePB->set_label(aNewReplaceText);
764 m_xNewReplacePB->set_sensitive(bEnableNewReplace && !IsDicReadonly_Impl());
765 m_xDeletePB->set_sensitive(bEnableDelete && !IsDicReadonly_Impl());
766}
767
768IMPL_STATIC_LINK(SvxEditDictionaryDialog, InsertTextHdl, OUString&, rText, bool)
769{
770 rText = rText.replaceAll(" ", "");
771 return true;
772}
773
774/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Reference< XExecutableDialog > m_xDialog
static weld::MessageDialog * CreateMessageDialog(weld::Widget *pParent, VclMessageType eMessageType, VclButtonsType eButtonType, const OUString &rPrimaryMessage, bool bMobile=false)
static DialogMask HandleError(ErrCode nId, weld::Window *pParent=nullptr, DialogMask nMask=DialogMask::MAX)
const CollatorWrapper * getCollator() const
LanguageType getLanguageType(bool bResolveSystem=true) const
static css::lang::Locale convertToLocale(LanguageType nLangID, bool bResolveSystem=true)
static css::uno::Reference< css::linguistic2::XSearchableDictionaryList > GetDictionaryList()
std::unique_ptr< weld::TreeView > m_xSingleColumnLB
Definition: optdict.hxx:80
void ShowWords_Impl(sal_uInt16 nId)
Definition: optdict.cxx:450
void SetLanguage_Impl(LanguageType nLanguage)
Definition: optdict.cxx:355
int GetLBInsertPos(std::u16string_view rDicWord)
Definition: optdict.cxx:361
virtual ~SvxEditDictionaryDialog() override
Definition: optdict.cxx:334
std::unique_ptr< weld::Label > m_xLangFT
Definition: optdict.hxx:75
css::uno::Sequence< css::uno::Reference< css::linguistic2::XDictionary > > aDics
Definition: optdict.hxx:67
std::unique_ptr< weld::Label > m_xReplaceFT
Definition: optdict.hxx:78
std::unique_ptr< weld::TreeView > m_xDoubleColumnLB
Definition: optdict.hxx:81
void RemoveDictEntry(int nEntry)
Definition: optdict.cxx:379
std::unique_ptr< weld::Button > m_xNewReplacePB
Definition: optdict.hxx:82
SvxEditDictionaryDialog(weld::Window *pParent, std::u16string_view rName)
Definition: optdict.cxx:202
OUString sReplaceFT_Text
Definition: optdict.hxx:63
void SetDicReadonly_Impl(css::uno::Reference< css::linguistic2::XDictionary > const &xDic)
Definition: optdict.cxx:338
bool NewDelHdl(const weld::Widget *)
Definition: optdict.cxx:587
weld::TreeView * m_pWordsLB
Definition: optdict.hxx:73
bool IsDicReadonly_Impl() const
Definition: optdict.hxx:97
std::unique_ptr< weld::Entry > m_xWordED
Definition: optdict.hxx:77
std::unique_ptr< SvxLanguageBox > m_xLangLB
Definition: optdict.hxx:76
std::unique_ptr< weld::ComboBox > m_xAllDictsLB
Definition: optdict.hxx:74
std::unique_ptr< weld::Entry > m_xReplaceED
Definition: optdict.hxx:79
std::unique_ptr< weld::Button > m_xDeletePB
Definition: optdict.hxx:83
std::unique_ptr< SvxLanguageBox > m_xLanguageLB
Definition: optdict.hxx:42
std::unique_ptr< weld::Entry > m_xNameEdit
Definition: optdict.hxx:41
std::unique_ptr< weld::Button > m_xOKBtn
Definition: optdict.hxx:44
SvxNewDictionaryDialog(weld::Window *pParent)
Definition: optdict.cxx:95
std::shared_ptr< weld::Dialog > m_xDialog
virtual void scroll_to_row(int row)=0
virtual void set_text(int row, const OUString &rText, int col=-1)=0
virtual OUString get_text(int row, int col=-1) const=0
void append_text(const OUString &rStr)
virtual int n_children() const=0
virtual void clear()=0
void insert_text(int pos, const OUString &rStr)
virtual void remove(int pos)=0
virtual void select(int pos)=0
virtual void set_cursor(int pos)=0
virtual int get_selected_index() const=0
virtual void freeze()=0
virtual void thaw()=0
OUString CuiResId(TranslateId aKey)
Definition: cuiresmgr.cxx:23
int nCount
#define DBG_ASSERT(sCon, aError)
SVXCORE_DLLPUBLIC std::locale SvxResLocale()
URL aURL
float y
float x
ScXMLEditAttributeMap::Entry const aEntries[]
DocumentType eType
#define LANGUAGE_NONE
sal_uInt16 nPos
aStr
const char * sName
OString stripEnd(const OString &rIn, char c)
int i
OUString GetWritableDictionaryURL(std::u16string_view rDicName)
DictionaryError
DictionaryError AddEntryToDic(uno::Reference< XDictionary > const &rxDic, const OUString &rWord, bool bIsNeg, const OUString &rRplcTxt, bool bStripDot)
sal_Int16 nId
static CDE_RESULT cmpDicEntry_Impl(std::u16string_view rText1, std::u16string_view rText2)
Definition: optdict.cxx:77
static OUString getNormDicEntry_Impl(std::u16string_view rText)
Definition: optdict.cxx:47
IMPL_LINK(SvxEditDictionaryDialog, SelectHdl, weld::TreeView &, rBox, void)
Definition: optdict.cxx:548
IMPL_LINK_NOARG(SvxNewDictionaryDialog, OKHdl_Impl, weld::Button &, void)
Definition: optdict.cxx:114
IMPL_STATIC_LINK(SvxEditDictionaryDialog, InsertTextHdl, OUString &, rText, bool)
Definition: optdict.cxx:768
SVX_DLLPUBLIC const ErrMsgCode RID_SVXERRCTX[]
#define ERRCTX_SVX_LINGU_DICTIONARY
#define ERRCODE_SVX_LINGU_DICT_NOTWRITEABLE
sal_uInt16 sal_Unicode
short SvxDicError(weld::Window *pParent, linguistic::DictionaryError nError)
RET_OK
RET_CANCEL
RET_YES