bump product version to 4.1.6.2
[LibreOffice.git] / cui / source / options / optdict.cxx
blobeab99e44fe66d6fe2624f876b11f50f51067d11c
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 <tools/shl.hxx>
21 #include <editeng/unolingu.hxx>
22 #include <svx/dlgutil.hxx>
23 #include <sfx2/sfxuno.hxx>
24 #include <svl/eitem.hxx>
25 #include <com/sun/star/frame/XStorable.hpp>
26 #include <comphelper/processfactory.hxx>
27 #include <comphelper/string.hxx>
28 #include <unotools/intlwrapper.hxx>
29 #include <vcl/svapp.hxx>
30 #include <vcl/msgbox.hxx>
31 #include <svx/dialogs.hrc>
33 #include <linguistic/misc.hxx>
34 #include <cuires.hrc>
35 #include "optdict.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;
44 // static ----------------------------------------------------------------
46 static const short NOACTDICT = -1;
48 static long nStaticTabs[]=
50 2,10,71,120
53 // static function -------------------------------------------------------
55 static String getNormDicEntry_Impl(const OUString &rText)
57 OUString aTmp(comphelper::string::stripEnd(rText, '.'));
58 return comphelper::string::remove(aTmp, '=');
61 // Compare Dictionary Entry result
62 enum CDE_RESULT { CDE_EQUAL, CDE_SIMILAR, CDE_DIFFERENT };
64 static CDE_RESULT cmpDicEntry_Impl( const String &rText1, const String &rText2 )
66 CDE_RESULT eRes = CDE_DIFFERENT;
68 if (rText1 == rText2)
69 eRes = CDE_EQUAL;
70 else
71 { // similar = equal up to trailing '.' and hyphenation positions
72 // marked with '='
73 if (getNormDicEntry_Impl( rText1 ) == getNormDicEntry_Impl( rText2 ))
74 eRes = CDE_SIMILAR;
77 return eRes;
80 // class SvxNewDictionaryDialog -------------------------------------------
82 SvxNewDictionaryDialog::SvxNewDictionaryDialog( Window* pParent,
83 Reference< XSpellChecker1 > &xSpl ) :
85 ModalDialog( pParent, CUI_RES( RID_SFXDLG_NEWDICT ) ),
87 aNewDictBox ( this, CUI_RES( GB_NEWDICT ) ),
88 aNameText ( this, CUI_RES( FT_DICTNAME ) ),
89 aNameEdit ( this, CUI_RES( ED_DICTNAME ) ),
90 aLanguageText ( this, CUI_RES( FT_DICTLANG ) ),
91 aLanguageLB ( this, CUI_RES( LB_DICTLANG ) ),
92 aExceptBtn ( this, CUI_RES( BTN_EXCEPT ) ),
93 aOKBtn ( this, CUI_RES( BTN_NEWDICT_OK ) ),
94 aCancelBtn ( this, CUI_RES( BTN_NEWDICT_ESC ) ),
95 aHelpBtn ( this, CUI_RES( BTN_NEWDICT_HLP ) ),
96 xSpell( xSpl )
98 // install handler
99 aNameEdit.SetModifyHdl(
100 LINK( this, SvxNewDictionaryDialog, ModifyHdl_Impl ) );
101 aOKBtn.SetClickHdl( LINK( this, SvxNewDictionaryDialog, OKHdl_Impl ) );
103 // display languages
104 aLanguageLB.SetLanguageList( LANG_LIST_ALL, sal_True, sal_True );
105 aLanguageLB.SelectEntryPos(0);
107 aNameText.SetAccessibleRelationMemberOf( &aNewDictBox );
108 aNameEdit.SetAccessibleRelationMemberOf( &aNewDictBox );
109 aLanguageText.SetAccessibleRelationMemberOf( &aNewDictBox );
110 aLanguageLB.SetAccessibleRelationMemberOf( &aNewDictBox );
112 FreeResource();
115 // -----------------------------------------------------------------------
117 IMPL_LINK_NOARG(SvxNewDictionaryDialog, OKHdl_Impl)
119 OUString sDict = comphelper::string::stripEnd(aNameEdit.GetText(), ' ');
120 // add extension for personal dictionaries
121 sDict += ".dic";
123 Reference< XSearchableDictionaryList > xDicList( SvxGetDictionaryList() );
125 Sequence< Reference< XDictionary > > aDics;
126 if (xDicList.is())
127 aDics = xDicList->getDictionaries();
128 const Reference< XDictionary > *pDic = aDics.getConstArray();
129 sal_Int32 nCount = (sal_uInt16) aDics.getLength();
131 sal_Bool bFound = sal_False;
132 sal_uInt16 i;
133 for (i = 0; !bFound && i < nCount; ++i )
134 if ( sDict.equalsIgnoreAsciiCase( pDic[i]->getName()) )
135 bFound = sal_True;
137 if ( bFound )
139 // duplicate names?
140 InfoBox( this, CUI_RESSTR( RID_SVXSTR_OPT_DOUBLE_DICTS ) ).Execute();
141 aNameEdit.GrabFocus();
142 return 0;
145 // create and add
146 sal_uInt16 nLang = aLanguageLB.GetSelectLanguage();
149 // create new dictionary
150 DictionaryType eType = aExceptBtn.IsChecked() ?
151 DictionaryType_NEGATIVE : DictionaryType_POSITIVE;
152 if (xDicList.is())
154 lang::Locale aLocale( LanguageTag(nLang).getLocale() );
155 String aURL( linguistic::GetWritableDictionaryURL( sDict ) );
156 xNewDic = Reference< XDictionary > (
157 xDicList->createDictionary( sDict, aLocale, eType, aURL ) , UNO_QUERY );
158 xNewDic->setActive( sal_True );
160 DBG_ASSERT(xNewDic.is(), "NULL pointer");
162 catch(...)
164 xNewDic = NULL;
166 // error: couldn't create new dictionary
167 SfxErrorContext aContext( ERRCTX_SVX_LINGU_DICTIONARY, String(),
168 this, RID_SVXERRCTX, &CUI_MGR() );
169 ErrorHandler::HandleError( *new StringErrorInfo(
170 ERRCODE_SVX_LINGU_DICT_NOTWRITEABLE, sDict ) );
172 EndDialog( RET_CANCEL );
175 if (xDicList.is() && xNewDic.is())
177 xDicList->addDictionary( Reference< XDictionary > ( xNewDic, UNO_QUERY ) );
179 // refresh list of dictionaries
180 //! dictionaries may have been added/removed elsewhere too.
181 aDics = xDicList->getDictionaries();
183 pDic = aDics.getConstArray();
184 nCount = (sal_uInt16) aDics.getLength();
187 EndDialog( RET_OK );
188 return 0;
191 // -----------------------------------------------------------------------
193 IMPL_LINK_NOARG_INLINE_START(SvxNewDictionaryDialog, ModifyHdl_Impl)
195 if ( !aNameEdit.GetText().isEmpty() )
196 aOKBtn.Enable();
197 else
198 aOKBtn.Disable();
199 return 0;
201 IMPL_LINK_NOARG_INLINE_END(SvxNewDictionaryDialog, ModifyHdl_Impl)
203 //==========================================================================
205 // class SvxEditDictionaryDialog -------------------------------------------
207 //==========================================================================
209 SvxEditDictionaryDialog::SvxEditDictionaryDialog(
210 Window* pParent,
211 const String& rName,
212 Reference< XSpellChecker1 > &xSpl ) :
214 ModalDialog( pParent, CUI_RES( RID_SFXDLG_EDITDICT ) ),
216 aBookFT ( this, CUI_RES( FT_BOOK ) ),
217 aAllDictsLB ( this, CUI_RES( LB_ALLDICTS ) ),
218 aLangFT ( this, CUI_RES( FT_DICTLANG ) ),
219 aLangLB ( this, CUI_RES( LB_DICTLANG ) ),
221 aWordFT ( this, CUI_RES( FT_WORD ) ),
222 aWordED ( this, CUI_RES( ED_WORD ) ),
223 aReplaceFT ( this, CUI_RES( FT_REPLACE ) ),
224 aReplaceED ( this, CUI_RES( ED_REPLACE ) ),
225 aWordsLB ( this, CUI_RES( TLB_REPLACE ) ),
226 aNewReplacePB ( this, CUI_RES( PB_NEW_REPLACE ) ),
227 aDeletePB ( this, CUI_RES( PB_DELETE_REPLACE ) ),
228 aEditDictsBox ( this, CUI_RES( GB_EDITDICTS ) ),
229 aHelpBtn ( this, CUI_RES( BTN_EDITHELP ) ),
230 aCloseBtn ( this, CUI_RES( BTN_EDITCLOSE ) ),
231 sModify (CUI_RES(STR_MODIFY)),
232 sNew (aNewReplacePB.GetText()),
233 aDecoView ( this),
234 xSpell ( xSpl ),
235 nOld ( NOACTDICT ),
236 bFirstSelect (sal_True),
237 bDoNothing (sal_False)
240 if (SvxGetDictionaryList().is())
241 aDics = SvxGetDictionaryList()->getDictionaries();
243 aWordsLB.SetSelectHdl(LINK(this, SvxEditDictionaryDialog, SelectHdl));
244 aWordsLB.SetTabs(nStaticTabs);
246 //! we use an algorithm of our own to insert elements sorted
247 aWordsLB.SetStyle(aWordsLB.GetStyle()|/*WB_SORT|*/WB_HSCROLL|WB_CLIPCHILDREN);
250 nWidth=aWordED.GetSizePixel().Width();
251 // install handler
252 aNewReplacePB.SetClickHdl(
253 LINK( this, SvxEditDictionaryDialog, NewDelHdl));
254 aDeletePB.SetClickHdl(
255 LINK( this, SvxEditDictionaryDialog, NewDelHdl));
257 aLangLB.SetSelectHdl(
258 LINK( this, SvxEditDictionaryDialog, SelectLangHdl_Impl ) );
259 aAllDictsLB.SetSelectHdl(
260 LINK( this, SvxEditDictionaryDialog, SelectBookHdl_Impl ) );
262 aWordED.SetModifyHdl(LINK(this, SvxEditDictionaryDialog, ModifyHdl));
263 aReplaceED.SetModifyHdl(LINK(this, SvxEditDictionaryDialog, ModifyHdl));
264 aWordED.SetActionHdl(LINK(this, SvxEditDictionaryDialog, NewDelHdl));
265 aReplaceED.SetActionHdl(LINK(this, SvxEditDictionaryDialog, NewDelHdl));
267 // fill listbox with all available WB's
268 const Reference< XDictionary > *pDic = aDics.getConstArray();
269 sal_Int32 nCount = aDics.getLength();
271 String aLookUpEntry;
272 for ( sal_Int32 i = 0; i < nCount; ++i )
274 Reference< XDictionary > xDic( pDic[i], UNO_QUERY );
275 if (xDic.is())
277 bool bNegative = xDic->getDictionaryType() == DictionaryType_NEGATIVE;
278 String aDicName( xDic->getName() );
279 const String aTxt( ::GetDicInfoStr( aDicName,
280 LanguageTag( xDic->getLocale() ).getLanguageType(), bNegative ) );
281 aAllDictsLB.InsertEntry( aTxt );
283 if (rName == aDicName)
284 aLookUpEntry = aTxt;
288 aLangLB.SetLanguageList( LANG_LIST_ALL, sal_True, sal_True );
290 aReplaceED.SetSpaces(sal_True);
291 aWordED.SetSpaces(sal_True);
293 if ( nCount > 0 )
295 aAllDictsLB.SelectEntry( aLookUpEntry );
296 sal_uInt16 nPos = aAllDictsLB.GetSelectEntryPos();
298 if ( nPos == LISTBOX_ENTRY_NOTFOUND )
300 nPos = 0;
301 aAllDictsLB.SelectEntryPos( nPos );
303 Reference< XDictionary > xDic;
304 if (nPos != LISTBOX_ENTRY_NOTFOUND)
305 xDic = Reference< XDictionary > ( aDics.getConstArray()[ nPos ], UNO_QUERY );
306 if (xDic.is())
307 SetLanguage_Impl( LanguageTag( xDic->getLocale() ).getLanguageType() );
309 // check if dictionary is read-only
310 SetDicReadonly_Impl(xDic);
311 sal_Bool bEnable = !IsDicReadonly_Impl();
312 aNewReplacePB .Enable( sal_False );
313 aDeletePB .Enable( sal_False );
314 aLangFT.Enable( bEnable );
315 aLangLB.Enable( bEnable );
316 ShowWords_Impl( nPos );
319 else
321 aNewReplacePB.Disable();
322 aDeletePB .Disable();
324 FreeResource();
327 // -----------------------------------------------------------------------
329 SvxEditDictionaryDialog::~SvxEditDictionaryDialog()
333 // -----------------------------------------------------------------------
335 void SvxEditDictionaryDialog::Paint( const Rectangle& rRect )
337 ModalDialog::Paint(rRect );
339 Rectangle aRect(aEditDictsBox.GetPosPixel(),aEditDictsBox.GetSizePixel());
341 sal_uInt16 nStyle=BUTTON_DRAW_NOFILL;
342 aDecoView.DrawButton( aRect, nStyle);
345 // -----------------------------------------------------------------------
347 void SvxEditDictionaryDialog::SetDicReadonly_Impl(
348 Reference< XDictionary > &xDic )
350 // enable or disable new and delete button according to file attributes
351 bDicIsReadonly = sal_True;
352 if (xDic.is())
354 Reference< frame::XStorable > xStor( xDic, UNO_QUERY );
355 if ( !xStor.is() // non persistent dictionary
356 || !xStor->hasLocation() // not yet persistent
357 || !xStor->isReadonly() )
359 bDicIsReadonly = sal_False;
364 // -----------------------------------------------------------------------
366 void SvxEditDictionaryDialog::SetLanguage_Impl( util::Language nLanguage )
368 // select language
369 aLangLB.SelectLanguage( nLanguage );
372 sal_uInt16 SvxEditDictionaryDialog::GetLBInsertPos(const String &rDicWord)
374 sal_uInt16 nPos = USHRT_MAX;
376 IntlWrapper aIntlWrapper( Application::GetSettings().GetLanguageTag() );
377 const CollatorWrapper* pCollator = aIntlWrapper.getCollator();
378 sal_uInt16 j;
379 for( j = 0; j < aWordsLB.GetEntryCount(); j++ )
381 SvTreeListEntry* pEntry = aWordsLB.GetEntry(j);
382 DBG_ASSERT( pEntry, "NULL pointer");
383 String aNormEntry( getNormDicEntry_Impl( rDicWord ) );
384 StringCompare eCmpRes = (StringCompare)pCollator->
385 compareString( aNormEntry, getNormDicEntry_Impl( aWordsLB.GetEntryText(pEntry, 0) ) );
386 if( COMPARE_LESS == eCmpRes )
387 break;
389 if (j < aWordsLB.GetEntryCount()) // entry found?
390 nPos = j;
392 return nPos;
395 void SvxEditDictionaryDialog::RemoveDictEntry(SvTreeListEntry* pEntry)
397 sal_uInt16 nLBPos = aAllDictsLB.GetSelectEntryPos();
399 if ( pEntry != NULL && nLBPos != LISTBOX_ENTRY_NOTFOUND )
401 String sTmpShort(aWordsLB.GetEntryText(pEntry, 0));
403 Reference< XDictionary > xDic = aDics.getConstArray()[ nLBPos ];
404 if (xDic->remove( sTmpShort )) // sal_True on success
406 aWordsLB.GetModel()->Remove(pEntry);
411 // -----------------------------------------------------------------------
413 IMPL_LINK_NOARG(SvxEditDictionaryDialog, SelectBookHdl_Impl)
415 sal_uInt16 nPos = aAllDictsLB.GetSelectEntryPos();
417 if ( nPos != LISTBOX_ENTRY_NOTFOUND )
419 aNewReplacePB.Enable( sal_False );
420 aDeletePB .Enable( sal_False );
421 // display dictionary
422 ShowWords_Impl( nPos );
423 // enable or disable new and delete button according to file attributes
424 Reference< XDictionary > xDic( aDics.getConstArray()[ nPos ], UNO_QUERY );
425 if (xDic.is())
426 SetLanguage_Impl( LanguageTag( xDic->getLocale() ).getLanguageType() );
428 SetDicReadonly_Impl(xDic);
429 sal_Bool bEnable = !IsDicReadonly_Impl();
430 aLangFT.Enable( bEnable );
431 aLangLB.Enable( bEnable );
433 return 0;
436 // -----------------------------------------------------------------------
438 IMPL_LINK_NOARG(SvxEditDictionaryDialog, SelectLangHdl_Impl)
440 sal_uInt16 nDicPos = aAllDictsLB.GetSelectEntryPos();
441 sal_uInt16 nLang = aLangLB.GetSelectLanguage();
442 Reference< XDictionary > xDic( aDics.getConstArray()[ nDicPos ], UNO_QUERY );
443 sal_Int16 nOldLang = LanguageTag( xDic->getLocale() ).getLanguageType();
445 if ( nLang != nOldLang )
447 QueryBox aBox( this, CUI_RES( RID_SFXQB_SET_LANGUAGE ) );
448 String sTxt( aBox.GetMessText() );
449 sTxt.SearchAndReplaceAscii( "%1", aAllDictsLB.GetSelectEntry() );
450 aBox.SetMessText( sTxt );
452 if ( aBox.Execute() == RET_YES )
454 xDic->setLocale( LanguageTag( nLang ).getLocale() );
455 bool bNegativ = xDic->getDictionaryType() == DictionaryType_NEGATIVE;
457 const String sName(
458 ::GetDicInfoStr( xDic->getName(),
459 LanguageTag( xDic->getLocale() ).getLanguageType(),
460 bNegativ ) );
461 aAllDictsLB.RemoveEntry( nDicPos );
462 aAllDictsLB.InsertEntry( sName, nDicPos );
463 aAllDictsLB.SelectEntryPos( nDicPos );
465 else
466 SetLanguage_Impl( nOldLang );
468 return 1;
471 // -----------------------------------------------------------------------
473 void SvxEditDictionaryDialog::ShowWords_Impl( sal_uInt16 nId )
475 Reference< XDictionary > xDic = aDics.getConstArray()[ nId ];
477 nOld = nId;
478 EnterWait();
480 String aStr;
482 aWordED.SetText(aStr);
483 aReplaceED.SetText(aStr);
485 if(xDic->getDictionaryType() != DictionaryType_POSITIVE)
487 nStaticTabs[0]=2;
489 // make controls for replacement text active
490 if(!aReplaceFT.IsVisible())
492 Size aSize=aWordED.GetSizePixel();
493 aSize.Width()=nWidth;
494 aWordED.SetSizePixel(aSize);
495 aReplaceFT.Show();
496 aReplaceED.Show();
499 else
501 nStaticTabs[0]=1;
503 // deactivate controls for replacement text
504 if(aReplaceFT.IsVisible())
506 Size aSize=aWordED.GetSizePixel();
507 aSize.Width()=aWordsLB.GetSizePixel().Width();
508 aWordED.SetSizePixel(aSize);
509 aReplaceFT.Hide();
510 aReplaceED.Hide();
515 aWordsLB.SetTabs(nStaticTabs);
516 aWordsLB.Clear();
518 Sequence< Reference< XDictionaryEntry > > aEntries( xDic->getEntries() );
519 const Reference< XDictionaryEntry > *pEntry = aEntries.getConstArray();
520 sal_Int32 nCount = aEntries.getLength();
522 for (sal_Int32 i = 0; i < nCount; i++)
524 aStr = String(pEntry[i]->getDictionaryWord());
525 sal_uInt16 nPos = GetLBInsertPos( aStr );
526 if(pEntry[i]->isNegative())
528 aStr += '\t';
529 aStr += String(pEntry[i]->getReplacementText());
531 aWordsLB.InsertEntry(aStr, 0, sal_False, nPos == USHRT_MAX ? LIST_APPEND : nPos);
534 if (aWordsLB.GetEntryCount())
536 aWordED .SetText( aWordsLB.GetEntryText((sal_uLong)0, 0) );
537 aReplaceED.SetText( aWordsLB.GetEntryText((sal_uLong)0, 1) );
540 LeaveWait();
543 // -----------------------------------------------------------------------
545 IMPL_LINK(SvxEditDictionaryDialog, SelectHdl, SvTabListBox*, pBox)
547 if(!bDoNothing)
549 if(!bFirstSelect)
551 SvTreeListEntry* pEntry = pBox->FirstSelected();
552 OUString sTmpShort(pBox->GetEntryText(pEntry, 0));
553 // without this the curser is always at the beginning of a word, if the text
554 // is set over the ModifyHdl, although you're editing there at the moment
555 if(aWordED.GetText() != sTmpShort)
556 aWordED.SetText(sTmpShort);
557 aReplaceED.SetText(pBox->GetEntryText(pEntry, 1));
559 else
560 bFirstSelect = sal_False;
562 // entries in the list box should exactly correspond to those from the
563 // dictionary. Thus:
564 aNewReplacePB.Enable(sal_False);
565 aDeletePB .Enable( sal_True && !IsDicReadonly_Impl() );
567 return 0;
570 // -----------------------------------------------------------------------
572 IMPL_LINK(SvxEditDictionaryDialog, NewDelHdl, PushButton*, pBtn)
574 SvTreeListEntry* pEntry = aWordsLB.FirstSelected();
576 if(pBtn == &aDeletePB)
578 DBG_ASSERT(pEntry, "keine Eintrag selektiert");
579 String aStr;
581 aWordED.SetText(aStr);
582 aReplaceED.SetText(aStr);
583 aDeletePB.Disable();
585 RemoveDictEntry(pEntry); // remove entry from dic and list-box
587 if(pBtn == &aNewReplacePB || aNewReplacePB.IsEnabled())
589 SvTreeListEntry* _pEntry = aWordsLB.FirstSelected();
590 OUString aNewWord(aWordED.GetText());
591 OUString sEntry(aNewWord);
592 OUString aReplaceStr(aReplaceED.GetText());
594 sal_Int16 nAddRes = DIC_ERR_UNKNOWN;
595 sal_uInt16 nPos = aAllDictsLB.GetSelectEntryPos();
596 if ( nPos != LISTBOX_ENTRY_NOTFOUND && !aNewWord.isEmpty())
598 DBG_ASSERT(nPos < aDics.getLength(), "invalid dictionary index");
599 Reference< XDictionary > xDic( aDics.getConstArray()[ nPos ], UNO_QUERY );
600 if (xDic.is())
602 // make changes in dic
604 //! ...IsVisible should reflect whether the dictionary is a negativ
605 //! or not (hopefully...)
606 sal_Bool bIsNegEntry = aReplaceFT.IsVisible();
607 OUString aRplcText;
608 if(bIsNegEntry)
609 aRplcText = aReplaceStr;
611 if (_pEntry) // entry selected in aWordsLB ie action = modify entry
612 xDic->remove( aWordsLB.GetEntryText( _pEntry, 0 ) );
613 // if remove has failed the following add should fail too
614 // and thus a warning message should be triggered...
616 Reference<XDictionary> aXDictionary(xDic, UNO_QUERY);
617 nAddRes = linguistic::AddEntryToDic( aXDictionary,
618 aNewWord, bIsNegEntry,
619 aRplcText, LanguageTag( xDic->getLocale() ).getLanguageType(), sal_False );
622 if (DIC_ERR_NONE != nAddRes)
623 SvxDicError( this, nAddRes );
625 if(DIC_ERR_NONE == nAddRes && !sEntry.isEmpty())
627 // insert new entry in list-box etc...
629 aWordsLB.SetUpdateMode(sal_False);
630 sal_uInt16 _nPos = USHRT_MAX;
632 if(aReplaceFT.IsVisible())
634 sEntry += "\t";
635 sEntry += aReplaceStr;
638 SvTreeListEntry* pNewEntry = NULL;
639 if(_pEntry) // entry selected in aWordsLB ie action = modify entry
641 aWordsLB.SetEntryText( sEntry, _pEntry );
642 pNewEntry = _pEntry;
644 else
646 _nPos = GetLBInsertPos( aNewWord );
647 SvTreeListEntry* pInsEntry = aWordsLB.InsertEntry(sEntry, 0, sal_False,
648 _nPos == USHRT_MAX ? LIST_APPEND : (sal_uInt32)_nPos);
649 pNewEntry = pInsEntry;
652 aWordsLB.MakeVisible( pNewEntry );
653 aWordsLB.SetUpdateMode(sal_True);
654 // if the request came from the ReplaceEdit, give focus to the ShortEdit
655 if(aReplaceED.HasFocus())
656 aWordED.GrabFocus();
659 else
661 // this can only be an enter in one of the two edit fields
662 // which means EndDialog() - has to be evaluated in KeyInput
663 return 0;
665 ModifyHdl(&aWordED);
666 return 1;
669 // -----------------------------------------------------------------------
671 IMPL_LINK(SvxEditDictionaryDialog, ModifyHdl, Edit*, pEdt)
673 SvTreeListEntry* pFirstSel = aWordsLB.FirstSelected();
674 String rEntry = pEdt->GetText();
676 xub_StrLen nWordLen=rEntry.Len();
677 const String& rRepString = aReplaceED.GetText();
679 sal_Bool bEnableNewReplace = sal_False;
680 sal_Bool bEnableDelete = sal_False;
681 String aNewReplaceText = sNew;
683 if(pEdt == &aWordED)
685 if(nWordLen>0)
687 sal_Bool bFound = sal_False;
688 sal_Bool bTmpSelEntry=sal_False;
689 CDE_RESULT eCmpRes = CDE_DIFFERENT;
691 for(sal_uInt16 i = 0; i < aWordsLB.GetEntryCount(); i++)
693 SvTreeListEntry* pEntry = aWordsLB.GetEntry( i );
694 String aTestStr( aWordsLB.GetEntryText(pEntry, 0) );
695 eCmpRes = cmpDicEntry_Impl( rEntry, aTestStr );
696 if(CDE_DIFFERENT != eCmpRes)
698 if(rRepString.Len())
699 bFirstSelect = sal_True;
700 bDoNothing=sal_True;
701 aWordsLB.SetCurEntry(pEntry);
702 bDoNothing=sal_False;
703 pFirstSel = pEntry;
704 aReplaceED.SetText(aWordsLB.GetEntryText(pEntry, 1));
706 if (CDE_SIMILAR == eCmpRes)
708 aNewReplaceText = sModify;
709 bEnableNewReplace = sal_True;
711 bFound= sal_True;
712 break;
714 else if(getNormDicEntry_Impl(aTestStr).Search(
715 getNormDicEntry_Impl( rEntry ) ) == 0
716 && !bTmpSelEntry)
718 bDoNothing=sal_True;
719 aWordsLB.MakeVisible(pEntry);
720 bDoNothing=sal_False;
721 bTmpSelEntry=sal_True;
723 aNewReplaceText = sNew;
724 bEnableNewReplace = sal_True;
728 if(!bFound)
730 aWordsLB.SelectAll(sal_False);
731 pFirstSel = 0;
733 aNewReplaceText = sNew;
734 bEnableNewReplace = sal_True;
736 bEnableDelete = CDE_DIFFERENT != eCmpRes;
738 else if(aWordsLB.GetEntryCount()>0)
740 SvTreeListEntry* pEntry = aWordsLB.GetEntry( 0 );
741 bDoNothing=sal_True;
742 aWordsLB.MakeVisible(pEntry);
743 bDoNothing=sal_False;
746 else if(pEdt == &aReplaceED)
748 String aReplaceText;
749 String aWordText;
750 if (pFirstSel) // a aWordsLB entry is selected
752 aWordText = aWordsLB.GetEntryText( pFirstSel, 0 );
753 aReplaceText = aWordsLB.GetEntryText( pFirstSel, 1 );
755 aNewReplaceText = sModify;
756 bEnableDelete = sal_True;
758 sal_Bool bIsChange =
759 CDE_EQUAL != cmpDicEntry_Impl(aWordED.GetText(), aWordText)
760 || CDE_EQUAL != cmpDicEntry_Impl(aReplaceED.GetText(), aReplaceText);
761 if (!aWordED.GetText().isEmpty() && bIsChange)
762 bEnableNewReplace = sal_True;
765 aNewReplacePB.SetText( aNewReplaceText );
766 aNewReplacePB.Enable( bEnableNewReplace && !IsDicReadonly_Impl() );
767 aDeletePB .Enable( bEnableDelete && !IsDicReadonly_Impl() );
769 return 0;
772 //=========================================================
773 //SvxDictEdit
774 //=========================================================
775 void SvxDictEdit::KeyInput( const KeyEvent& rKEvt )
777 const KeyCode aKeyCode = rKEvt.GetKeyCode();
778 const sal_uInt16 nModifier = aKeyCode.GetModifier();
779 if( aKeyCode.GetCode() == KEY_RETURN )
781 // if there's nothing done on enter, call the
782 // base class after all to close the dialog
783 if(!nModifier && !aActionLink.Call(this))
784 Edit::KeyInput(rKEvt);
786 else if(bSpaces || aKeyCode.GetCode() != KEY_SPACE)
787 Edit::KeyInput(rKEvt);
791 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */