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