bump product version to 5.0.4.1
[LibreOffice.git] / cui / source / options / optdict.cxx
blob5b79a08ad60aaad07315a3f01869bedaaab0eefc
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <editeng/unolingu.hxx>
21 #include <svx/dlgutil.hxx>
22 #include <sfx2/sfxuno.hxx>
23 #include <svl/eitem.hxx>
24 #include <com/sun/star/frame/XStorable.hpp>
25 #include <comphelper/processfactory.hxx>
26 #include <comphelper/string.hxx>
27 #include <unotools/intlwrapper.hxx>
28 #include <vcl/svapp.hxx>
29 #include <vcl/layout.hxx>
30 #include <vcl/settings.hxx>
31 #include <vcl/builderfactory.hxx>
32 #include <svx/dialogs.hrc>
34 #include <linguistic/misc.hxx>
35 #include <cuires.hrc>
36 #include "optdict.hxx"
37 #include <dialmgr.hxx>
38 #include <svx/svxerr.hxx>
40 using namespace ::com::sun::star;
41 using namespace ::com::sun::star::uno;
42 using namespace ::com::sun::star::linguistic2;
43 using namespace linguistic;
45 // static ----------------------------------------------------------------
47 static const short NOACTDICT = -1;
49 static long nStaticTabs[]=
51 2,10,71,120
54 // static function -------------------------------------------------------
56 static OUString getNormDicEntry_Impl(const OUString &rText)
58 OUString aTmp(comphelper::string::stripEnd(rText, '.'));
59 // non-standard hyphenation
60 if (aTmp.indexOf('[') > -1)
62 OUStringBuffer aTmp2 ( aTmp.getLength() );
63 bool bSkip = false;
64 for (sal_Int32 i = 0; i < aTmp.getLength(); i++)
66 sal_Unicode cTmp = aTmp[i];
67 if (cTmp == '[')
68 bSkip = true;
69 else if (!bSkip)
70 aTmp2.append( cTmp );
71 else if (cTmp == ']')
72 bSkip = false;
74 aTmp = aTmp2.makeStringAndClear();
76 return comphelper::string::remove(aTmp, '=');
79 // Compare Dictionary Entry result
80 enum CDE_RESULT { CDE_EQUAL, CDE_SIMILAR, CDE_DIFFERENT };
82 static CDE_RESULT cmpDicEntry_Impl( const OUString &rText1, const OUString &rText2 )
84 CDE_RESULT eRes = CDE_DIFFERENT;
86 if (rText1 == rText2)
87 eRes = CDE_EQUAL;
88 else
89 { // similar = equal up to trailing '.' and hyphenation positions
90 // marked with '=' and '[' + alternative spelling pattern + ']'
91 if (getNormDicEntry_Impl( rText1 ) == getNormDicEntry_Impl( rText2 ))
92 eRes = CDE_SIMILAR;
95 return eRes;
98 // class SvxNewDictionaryDialog -------------------------------------------
100 SvxNewDictionaryDialog::SvxNewDictionaryDialog( vcl::Window* pParent,
101 Reference< XSpellChecker1 > &xSpl ) :
103 ModalDialog( pParent, "OptNewDictionaryDialog" , "cui/ui/optnewdictionarydialog.ui" ),
105 xSpell( xSpl )
107 get(pNameEdit,"nameedit");
108 get(pLanguageLB,"language");
109 get(pExceptBtn,"except");
110 get(pOKBtn,"ok");
111 // install handler
112 pNameEdit->SetModifyHdl(
113 LINK( this, SvxNewDictionaryDialog, ModifyHdl_Impl ) );
114 pOKBtn->SetClickHdl( LINK( this, SvxNewDictionaryDialog, OKHdl_Impl ) );
116 // display languages
117 pLanguageLB->SetLanguageList( SvxLanguageListFlags::ALL, true, true );
118 pLanguageLB->SelectEntryPos(0);
121 SvxNewDictionaryDialog::~SvxNewDictionaryDialog()
123 disposeOnce();
126 void SvxNewDictionaryDialog::dispose()
128 pNameEdit.clear();
129 pLanguageLB.clear();
130 pExceptBtn.clear();
131 pOKBtn.clear();
132 ModalDialog::dispose();
136 IMPL_LINK_NOARG(SvxNewDictionaryDialog, OKHdl_Impl)
138 OUString sDict = comphelper::string::stripEnd(pNameEdit->GetText(), ' ');
139 // add extension for personal dictionaries
140 sDict += ".dic";
142 Reference< XSearchableDictionaryList > xDicList( SvxGetDictionaryList() );
144 Sequence< Reference< XDictionary > > aDics;
145 if (xDicList.is())
146 aDics = xDicList->getDictionaries();
147 const Reference< XDictionary > *pDic = aDics.getConstArray();
148 sal_Int32 nCount = aDics.getLength();
150 bool bFound = false;
151 sal_Int32 i;
152 for (i = 0; !bFound && i < nCount; ++i )
153 if ( sDict.equalsIgnoreAsciiCase( pDic[i]->getName()) )
154 bFound = true;
156 if ( bFound )
158 // duplicate names?
159 ScopedVclPtrInstance<MessageDialog>::Create(this, CUI_RESSTR(RID_SVXSTR_OPT_DOUBLE_DICTS), VCL_MESSAGE_INFO)->Execute();
160 pNameEdit->GrabFocus();
161 return 0;
164 // create and add
165 sal_uInt16 nLang = pLanguageLB->GetSelectLanguage();
168 // create new dictionary
169 DictionaryType eType = pExceptBtn->IsChecked() ?
170 DictionaryType_NEGATIVE : DictionaryType_POSITIVE;
171 if (xDicList.is())
173 lang::Locale aLocale( LanguageTag::convertToLocale(nLang) );
174 OUString aURL( linguistic::GetWritableDictionaryURL( sDict ) );
175 xNewDic = Reference< XDictionary > (
176 xDicList->createDictionary( sDict, aLocale, eType, aURL ) , UNO_QUERY );
177 xNewDic->setActive( sal_True );
179 DBG_ASSERT(xNewDic.is(), "NULL pointer");
181 catch(...)
183 xNewDic = NULL;
185 // error: couldn't create new dictionary
186 SfxErrorContext aContext( ERRCTX_SVX_LINGU_DICTIONARY, OUString(),
187 this, RID_SVXERRCTX, &CUI_MGR() );
188 ErrorHandler::HandleError( *new StringErrorInfo(
189 ERRCODE_SVX_LINGU_DICT_NOTWRITEABLE, sDict ) );
191 EndDialog( RET_CANCEL );
194 if (xDicList.is() && xNewDic.is())
196 xDicList->addDictionary( Reference< XDictionary > ( xNewDic, UNO_QUERY ) );
198 // refresh list of dictionaries
199 //! dictionaries may have been added/removed elsewhere too.
200 aDics = xDicList->getDictionaries();
204 EndDialog( RET_OK );
205 return 0;
210 IMPL_LINK_NOARG(SvxNewDictionaryDialog, ModifyHdl_Impl)
212 if ( !pNameEdit->GetText().isEmpty() )
213 pOKBtn->Enable();
214 else
215 pOKBtn->Disable();
216 return 0;
219 // class SvxEditDictionaryDialog -------------------------------------------
221 VCL_BUILDER_FACTORY_ARGS(SvxDictEdit, WB_LEFT|WB_VCENTER|WB_BORDER|WB_3DLOOK)
223 SvxEditDictionaryDialog::SvxEditDictionaryDialog(
224 vcl::Window* pParent,
225 const OUString& rName,
226 Reference< XSpellChecker1 > &xSpl ) :
228 ModalDialog( pParent, "EditDictionaryDialog" ,"cui/ui/editdictionarydialog.ui" ),
230 sModify (CUI_RESSTR(STR_MODIFY)),
231 aDecoView ( this),
232 xSpell ( xSpl ),
233 nOld ( NOACTDICT ),
234 bFirstSelect (true),
235 bDoNothing (false),
236 bDicIsReadonly (false)
239 get(pAllDictsLB,"book");
240 get(pLangFT,"lang_label");
241 get(pLangLB,"lang");
243 get(pWordED,"word");
244 get(pReplaceFT,"replace_label");
245 get(pReplaceED,"replace");
246 get(pWordsLB,"words");
247 pWordsLB->set_height_request(pWordsLB->GetTextHeight() * 8);
248 get(pNewReplacePB,"newreplace");
249 get(pDeletePB,"delete");
251 sNew=pNewReplacePB->GetText();
252 if (SvxGetDictionaryList().is())
253 aDics = SvxGetDictionaryList()->getDictionaries();
255 pWordsLB->SetSelectHdl(LINK(this, SvxEditDictionaryDialog, SelectHdl));
256 pWordsLB->SetTabs(nStaticTabs);
258 //! we use an algorithm of our own to insert elements sorted
259 pWordsLB->SetStyle(pWordsLB->GetStyle()|/*WB_SORT|*/WB_HSCROLL|WB_CLIPCHILDREN);
262 nWidth=pWordED->GetSizePixel().Width();
263 // install handler
264 pNewReplacePB->SetClickHdl(
265 LINK( this, SvxEditDictionaryDialog, NewDelHdl));
266 pDeletePB->SetClickHdl(
267 LINK( this, SvxEditDictionaryDialog, NewDelHdl));
269 pLangLB->SetSelectHdl(
270 LINK( this, SvxEditDictionaryDialog, SelectLangHdl_Impl ) );
271 pAllDictsLB->SetSelectHdl(
272 LINK( this, SvxEditDictionaryDialog, SelectBookHdl_Impl ) );
274 pWordED->SetModifyHdl(LINK(this, SvxEditDictionaryDialog, ModifyHdl));
275 pReplaceED->SetModifyHdl(LINK(this, SvxEditDictionaryDialog, ModifyHdl));
276 pWordED->SetActionHdl(LINK(this, SvxEditDictionaryDialog, NewDelHdl));
277 pReplaceED->SetActionHdl(LINK(this, SvxEditDictionaryDialog, NewDelHdl));
279 // fill listbox with all available WB's
280 const Reference< XDictionary > *pDic = aDics.getConstArray();
281 sal_Int32 nCount = aDics.getLength();
283 OUString aLookUpEntry;
284 for ( sal_Int32 i = 0; i < nCount; ++i )
286 Reference< XDictionary > xDic( pDic[i], UNO_QUERY );
287 if (xDic.is())
289 bool bNegative = xDic->getDictionaryType() == DictionaryType_NEGATIVE;
290 OUString aDicName( xDic->getName() );
291 const OUString aTxt( ::GetDicInfoStr( aDicName,
292 LanguageTag( xDic->getLocale() ).getLanguageType(), bNegative ) );
293 pAllDictsLB->InsertEntry( aTxt );
295 if (rName == aDicName)
296 aLookUpEntry = aTxt;
300 pLangLB->SetLanguageList( SvxLanguageListFlags::ALL, true, true );
302 pReplaceED->SetSpaces(true);
303 pWordED->SetSpaces(true);
305 if ( nCount > 0 )
307 pAllDictsLB->SelectEntry( aLookUpEntry );
308 sal_Int32 nPos = pAllDictsLB->GetSelectEntryPos();
310 if ( nPos == LISTBOX_ENTRY_NOTFOUND )
312 nPos = 0;
313 pAllDictsLB->SelectEntryPos( nPos );
315 Reference< XDictionary > xDic;
316 if (nPos != LISTBOX_ENTRY_NOTFOUND)
317 xDic = Reference< XDictionary > ( aDics.getConstArray()[ nPos ], UNO_QUERY );
318 if (xDic.is())
319 SetLanguage_Impl( LanguageTag( xDic->getLocale() ).getLanguageType() );
321 // check if dictionary is read-only
322 SetDicReadonly_Impl(xDic);
323 bool bEnable = !IsDicReadonly_Impl();
324 pNewReplacePB->Enable( false );
325 pDeletePB->Enable( false );
326 pLangFT->Enable( bEnable );
327 pLangLB->Enable( bEnable );
328 ShowWords_Impl( nPos );
331 else
333 pNewReplacePB->Disable();
334 pDeletePB->Disable();
338 SvxEditDictionaryDialog::~SvxEditDictionaryDialog()
340 disposeOnce();
343 void SvxEditDictionaryDialog::dispose()
345 pAllDictsLB.clear();
346 pLangFT.clear();
347 pLangLB.clear();
348 pWordED.clear();
349 pReplaceFT.clear();
350 pReplaceED.clear();
351 pWordsLB.clear();
352 pNewReplacePB.clear();
353 pDeletePB.clear();
354 ModalDialog::dispose();
359 void SvxEditDictionaryDialog::Paint( const Rectangle& rRect )
361 ModalDialog::Paint(rRect );
363 //Rectangle aRect(aEditDictsBox.GetPosPixel(),aEditDictsBox.GetSizePixel());
365 sal_uInt16 nStyle=DrawButtonFlags::NoFill;
366 // aDecoView.DrawButton( aRect, nStyle);
371 void SvxEditDictionaryDialog::SetDicReadonly_Impl(
372 Reference< XDictionary > &xDic )
374 // enable or disable new and delete button according to file attributes
375 bDicIsReadonly = true;
376 if (xDic.is())
378 Reference< frame::XStorable > xStor( xDic, UNO_QUERY );
379 if ( !xStor.is() // non persistent dictionary
380 || !xStor->hasLocation() // not yet persistent
381 || !xStor->isReadonly() )
383 bDicIsReadonly = false;
390 void SvxEditDictionaryDialog::SetLanguage_Impl( util::Language nLanguage )
392 // select language
393 pLangLB->SelectLanguage( nLanguage );
396 sal_uLong SvxEditDictionaryDialog::GetLBInsertPos(const OUString &rDicWord)
398 sal_uLong nPos = TREELIST_ENTRY_NOTFOUND;
400 IntlWrapper aIntlWrapper( Application::GetSettings().GetLanguageTag() );
401 const CollatorWrapper* pCollator = aIntlWrapper.getCollator();
402 sal_uLong j;
403 for( j = 0; j < pWordsLB->GetEntryCount(); j++ )
405 SvTreeListEntry* pEntry = pWordsLB->GetEntry(j);
406 DBG_ASSERT( pEntry, "NULL pointer");
407 OUString aNormEntry( getNormDicEntry_Impl( rDicWord ) );
408 sal_Int32 nCmpRes = pCollator->
409 compareString( aNormEntry, getNormDicEntry_Impl( SvTabListBox::GetEntryText(pEntry, 0) ) );
410 if (nCmpRes < 0)
411 break;
413 if (j < pWordsLB->GetEntryCount()) // entry found?
414 nPos = j;
416 return nPos;
419 void SvxEditDictionaryDialog::RemoveDictEntry(SvTreeListEntry* pEntry)
421 sal_Int32 nLBPos = pAllDictsLB->GetSelectEntryPos();
423 if ( pEntry != NULL && nLBPos != LISTBOX_ENTRY_NOTFOUND )
425 OUString sTmpShort(SvTabListBox::GetEntryText(pEntry, 0));
427 Reference< XDictionary > xDic = aDics.getConstArray()[ nLBPos ];
428 if (xDic->remove( sTmpShort )) // sal_True on success
430 pWordsLB->GetModel()->Remove(pEntry);
437 IMPL_LINK_NOARG(SvxEditDictionaryDialog, SelectBookHdl_Impl)
439 sal_Int32 nPos = pAllDictsLB->GetSelectEntryPos();
441 if ( nPos != LISTBOX_ENTRY_NOTFOUND )
443 pNewReplacePB->Enable( false );
444 pDeletePB->Enable( false );
445 // display dictionary
446 ShowWords_Impl( nPos );
447 // enable or disable new and delete button according to file attributes
448 Reference< XDictionary > xDic( aDics.getConstArray()[ nPos ], UNO_QUERY );
449 if (xDic.is())
450 SetLanguage_Impl( LanguageTag( xDic->getLocale() ).getLanguageType() );
452 SetDicReadonly_Impl(xDic);
453 bool bEnable = !IsDicReadonly_Impl();
454 pLangFT->Enable( bEnable );
455 pLangLB->Enable( bEnable );
457 return 0;
462 IMPL_LINK_NOARG(SvxEditDictionaryDialog, SelectLangHdl_Impl)
464 sal_Int32 nDicPos = pAllDictsLB->GetSelectEntryPos();
465 sal_Int32 nLang = pLangLB->GetSelectLanguage();
466 Reference< XDictionary > xDic( aDics.getConstArray()[ nDicPos ], UNO_QUERY );
467 sal_Int16 nOldLang = LanguageTag( xDic->getLocale() ).getLanguageType();
469 if ( nLang != nOldLang )
471 ScopedVclPtrInstance< MessageDialog > aBox(this, CUI_RES( RID_SVXSTR_CONFIRM_SET_LANGUAGE), VCL_MESSAGE_QUESTION, VCL_BUTTONS_YES_NO);
472 OUString sTxt(aBox->get_primary_text());
473 sTxt = sTxt.replaceFirst( "%1", pAllDictsLB->GetSelectEntry() );
474 aBox->set_primary_text(sTxt);
476 if ( aBox->Execute() == RET_YES )
478 xDic->setLocale( LanguageTag::convertToLocale( nLang ) );
479 bool bNegativ = xDic->getDictionaryType() == DictionaryType_NEGATIVE;
481 const OUString sName(
482 ::GetDicInfoStr( xDic->getName(),
483 LanguageTag( xDic->getLocale() ).getLanguageType(),
484 bNegativ ) );
485 pAllDictsLB->RemoveEntry( nDicPos );
486 pAllDictsLB->InsertEntry( sName, nDicPos );
487 pAllDictsLB->SelectEntryPos( nDicPos );
489 else
490 SetLanguage_Impl( nOldLang );
492 return 1;
497 void SvxEditDictionaryDialog::ShowWords_Impl( sal_uInt16 nId )
499 Reference< XDictionary > xDic = aDics.getConstArray()[ nId ];
501 nOld = nId;
502 EnterWait();
504 OUString aStr;
506 pWordED->SetText(aStr);
507 pReplaceED->SetText(aStr);
509 if(xDic->getDictionaryType() != DictionaryType_POSITIVE)
511 nStaticTabs[0]=2;
513 // make controls for replacement text active
514 if(!pReplaceFT->IsVisible())
516 Size aSize=pWordED->GetSizePixel();
517 aSize.Width()=nWidth;
518 pWordED->SetSizePixel(aSize);
519 pReplaceFT->Show();
520 pReplaceED->Show();
523 else
525 nStaticTabs[0]=1;
527 // deactivate controls for replacement text
528 if(pReplaceFT->IsVisible())
530 Size aSize=pWordED->GetSizePixel();
531 aSize.Width()=pWordsLB->GetSizePixel().Width();
532 pWordED->SetSizePixel(aSize);
533 pReplaceFT->Hide();
534 pReplaceED->Hide();
539 pWordsLB->SetTabs(nStaticTabs);
540 pWordsLB->Clear();
542 Sequence< Reference< XDictionaryEntry > > aEntries( xDic->getEntries() );
543 const Reference< XDictionaryEntry > *pEntry = aEntries.getConstArray();
544 sal_Int32 nCount = aEntries.getLength();
546 for (sal_Int32 i = 0; i < nCount; i++)
548 aStr = pEntry[i]->getDictionaryWord();
549 sal_uLong nPos = GetLBInsertPos( aStr );
550 if(pEntry[i]->isNegative())
552 aStr += "\t";
553 aStr += pEntry[i]->getReplacementText();
555 pWordsLB->InsertEntry(aStr, 0, false, nPos == TREELIST_ENTRY_NOTFOUND ? TREELIST_APPEND : nPos);
558 if (pWordsLB->GetEntryCount())
560 pWordED->SetText( pWordsLB->GetEntryText((sal_uLong)0, 0) );
561 pReplaceED->SetText( pWordsLB->GetEntryText((sal_uLong)0, 1) );
564 LeaveWait();
569 IMPL_LINK(SvxEditDictionaryDialog, SelectHdl, SvTabListBox*, pBox)
571 if(!bDoNothing)
573 if(!bFirstSelect)
575 SvTreeListEntry* pEntry = pBox->FirstSelected();
576 OUString sTmpShort(SvTabListBox::GetEntryText(pEntry, 0));
577 // without this the curser is always at the beginning of a word, if the text
578 // is set over the ModifyHdl, although you're editing there at the moment
579 if(pWordED->GetText() != sTmpShort)
580 pWordED->SetText(sTmpShort);
581 pReplaceED->SetText(SvTabListBox::GetEntryText(pEntry, 1));
583 else
584 bFirstSelect = false;
586 // entries in the list box should exactly correspond to those from the
587 // dictionary. Thus:
588 pNewReplacePB->Enable(false);
589 pDeletePB->Enable( true && !IsDicReadonly_Impl() );
591 return 0;
596 IMPL_LINK(SvxEditDictionaryDialog, NewDelHdl, PushButton*, pBtn)
598 SvTreeListEntry* pEntry = pWordsLB->FirstSelected();
600 if(pBtn == pDeletePB)
602 DBG_ASSERT(pEntry, "keine Eintrag selektiert");
603 OUString aStr;
605 pWordED->SetText(aStr);
606 pReplaceED->SetText(aStr);
607 pDeletePB->Disable();
609 RemoveDictEntry(pEntry); // remove entry from dic and list-box
611 if(pBtn == pNewReplacePB || pNewReplacePB->IsEnabled())
613 SvTreeListEntry* _pEntry = pWordsLB->FirstSelected();
614 OUString aNewWord(pWordED->GetText());
615 OUString sEntry(aNewWord);
616 OUString aReplaceStr(pReplaceED->GetText());
618 DictionaryError nAddRes = DictionaryError::UNKNOWN;
619 sal_Int32 nPos = pAllDictsLB->GetSelectEntryPos();
620 if ( nPos != LISTBOX_ENTRY_NOTFOUND && !aNewWord.isEmpty())
622 DBG_ASSERT(nPos < aDics.getLength(), "invalid dictionary index");
623 Reference< XDictionary > xDic( aDics.getConstArray()[ nPos ], UNO_QUERY );
624 if (xDic.is())
626 // make changes in dic
628 //! ...IsVisible should reflect whether the dictionary is a negativ
629 //! or not (hopefully...)
630 bool bIsNegEntry = pReplaceFT->IsVisible();
631 OUString aRplcText;
632 if(bIsNegEntry)
633 aRplcText = aReplaceStr;
635 if (_pEntry) // entry selected in pWordsLB ie action = modify entry
636 xDic->remove( SvTabListBox::GetEntryText( _pEntry, 0 ) );
637 // if remove has failed the following add should fail too
638 // and thus a warning message should be triggered...
640 nAddRes = linguistic::AddEntryToDic( xDic,
641 aNewWord, bIsNegEntry,
642 aRplcText, LanguageTag( xDic->getLocale() ).getLanguageType(), false );
645 if (DictionaryError::NONE != nAddRes)
646 SvxDicError( this, nAddRes );
648 if(DictionaryError::NONE == nAddRes && !sEntry.isEmpty())
650 // insert new entry in list-box etc...
652 pWordsLB->SetUpdateMode(false);
653 sal_uLong _nPos = TREELIST_ENTRY_NOTFOUND;
655 if(pReplaceFT->IsVisible())
657 sEntry += "\t";
658 sEntry += aReplaceStr;
661 SvTreeListEntry* pNewEntry = NULL;
662 if(_pEntry) // entry selected in pWordsLB ie action = modify entry
664 pWordsLB->SetEntryText( sEntry, _pEntry );
665 pNewEntry = _pEntry;
667 else
669 _nPos = GetLBInsertPos( aNewWord );
670 SvTreeListEntry* pInsEntry = pWordsLB->InsertEntry(sEntry, 0, false,
671 _nPos == TREELIST_ENTRY_NOTFOUND ? TREELIST_APPEND : _nPos);
672 pNewEntry = pInsEntry;
675 pWordsLB->MakeVisible( pNewEntry );
676 pWordsLB->SetUpdateMode(true);
677 // if the request came from the ReplaceEdit, give focus to the ShortEdit
678 if(pReplaceED->HasFocus())
679 pWordED->GrabFocus();
682 else
684 // this can only be an enter in one of the two edit fields
685 // which means EndDialog() - has to be evaluated in KeyInput
686 return 0;
688 ModifyHdl(pWordED);
689 return 1;
694 IMPL_LINK(SvxEditDictionaryDialog, ModifyHdl, Edit*, pEdt)
696 OUString rEntry = pEdt->GetText();
698 sal_Int32 nWordLen = rEntry.getLength();
699 const OUString& rRepString = pReplaceED->GetText();
701 bool bEnableNewReplace = false;
702 bool bEnableDelete = false;
703 OUString aNewReplaceText = sNew;
705 if(pEdt == pWordED)
707 if(nWordLen>0)
709 bool bFound = false;
710 bool bTmpSelEntry=false;
711 CDE_RESULT eCmpRes = CDE_DIFFERENT;
713 for(sal_uLong i = 0; i < pWordsLB->GetEntryCount(); i++)
715 SvTreeListEntry* pEntry = pWordsLB->GetEntry( i );
716 OUString aTestStr( SvTabListBox::GetEntryText(pEntry, 0) );
717 eCmpRes = cmpDicEntry_Impl( rEntry, aTestStr );
718 if(CDE_DIFFERENT != eCmpRes)
720 if(!rRepString.isEmpty())
721 bFirstSelect = true;
722 bDoNothing=true;
723 pWordsLB->SetCurEntry(pEntry);
724 bDoNothing=false;
725 pReplaceED->SetText(SvTabListBox::GetEntryText(pEntry, 1));
727 if (CDE_SIMILAR == eCmpRes)
729 aNewReplaceText = sModify;
730 bEnableNewReplace = true;
732 bFound= true;
733 break;
735 else if(getNormDicEntry_Impl(aTestStr).indexOf(
736 getNormDicEntry_Impl( rEntry ) ) == 0
737 && !bTmpSelEntry)
739 bDoNothing=true;
740 pWordsLB->MakeVisible(pEntry);
741 bDoNothing=false;
742 bTmpSelEntry=true;
744 aNewReplaceText = sNew;
745 bEnableNewReplace = true;
749 if(!bFound)
751 pWordsLB->SelectAll(false);
753 aNewReplaceText = sNew;
754 bEnableNewReplace = true;
756 bEnableDelete = CDE_DIFFERENT != eCmpRes;
758 else if(pWordsLB->GetEntryCount()>0)
760 SvTreeListEntry* pEntry = pWordsLB->GetEntry( 0 );
761 bDoNothing=true;
762 pWordsLB->MakeVisible(pEntry);
763 bDoNothing=false;
766 else if(pEdt == pReplaceED)
768 OUString aReplaceText;
769 OUString aWordText;
770 SvTreeListEntry* pFirstSel = pWordsLB->FirstSelected();
771 if (pFirstSel) // a pWordsLB entry is selected
773 aWordText = SvTabListBox::GetEntryText( pFirstSel, 0 );
774 aReplaceText = SvTabListBox::GetEntryText( pFirstSel, 1 );
776 aNewReplaceText = sModify;
777 bEnableDelete = true;
779 bool bIsChange =
780 CDE_EQUAL != cmpDicEntry_Impl(pWordED->GetText(), aWordText)
781 || CDE_EQUAL != cmpDicEntry_Impl(pReplaceED->GetText(), aReplaceText);
782 if (!pWordED->GetText().isEmpty() && bIsChange)
783 bEnableNewReplace = true;
786 pNewReplacePB->SetText( aNewReplaceText );
787 pNewReplacePB->Enable( bEnableNewReplace && !IsDicReadonly_Impl() );
788 pDeletePB->Enable( bEnableDelete && !IsDicReadonly_Impl() );
790 return 0;
794 //SvxDictEdit
796 void SvxDictEdit::KeyInput( const KeyEvent& rKEvt )
798 const vcl::KeyCode aKeyCode = rKEvt.GetKeyCode();
799 const sal_uInt16 nModifier = aKeyCode.GetModifier();
800 if( aKeyCode.GetCode() == KEY_RETURN )
802 // if there's nothing done on enter, call the
803 // base class after all to close the dialog
804 if(!nModifier && !aActionLink.Call(this))
805 Edit::KeyInput(rKEvt);
807 else if(bSpaces || aKeyCode.GetCode() != KEY_SPACE)
808 Edit::KeyInput(rKEvt);
812 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */