xref: /AOO41X/main/cui/source/options/optdict.cxx (revision 79aad27f7f29270c03e208e3d687e8e3850af11d)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_cui.hxx"
26 
27 // include ---------------------------------------------------------------
28 #include <tools/shl.hxx>
29 #include <editeng/unolingu.hxx>
30 #include <svx/dlgutil.hxx>
31 #include <sfx2/sfxuno.hxx>
32 #include <svl/eitem.hxx>
33 #include <com/sun/star/frame/XStorable.hpp>
34 #include <comphelper/processfactory.hxx>
35 #include <unotools/intlwrapper.hxx>
36 #include <vcl/svapp.hxx>
37 #include <vcl/msgbox.hxx>
38 #include <svx/dialogs.hrc>
39 
40 #define _SVX_OPTDICT_CXX
41 
42 #include <linguistic/misc.hxx>
43 #include <cuires.hrc>
44 #include "optdict.hrc"
45 #include "optdict.hxx"
46 #include <dialmgr.hxx>
47 #include <svx/svxerr.hxx>
48 
49 using namespace ::com::sun::star;
50 using namespace ::com::sun::star::uno;
51 using namespace ::com::sun::star::linguistic2;
52 
53 // static ----------------------------------------------------------------
54 
55 static const sal_uInt16 nNameLen    = 8;
56 static const short  NOACTDICT   = -1;
57 
58 static long nStaticTabs[]=
59 {
60     2,10,71,120
61 };
62 
63 // static function -------------------------------------------------------
64 
getNormDicEntry_Impl(const String & rText)65 static String getNormDicEntry_Impl( const String &rText )
66 {
67     String aTmp( rText );
68     aTmp.EraseTrailingChars( '.' );
69     aTmp.EraseAllChars( '=' );
70     return aTmp;
71 }
72 
73 
74 // Compare Dictionary Entry  result
75 enum CDE_RESULT { CDE_EQUAL, CDE_SIMILAR, CDE_DIFFERENT };
76 
cmpDicEntry_Impl(const String & rText1,const String & rText2)77 static CDE_RESULT cmpDicEntry_Impl( const String &rText1, const String &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 '='
86         if (getNormDicEntry_Impl( rText1 ) == getNormDicEntry_Impl( rText2 ))
87             eRes = CDE_SIMILAR;
88     }
89 
90     return eRes;
91 }
92 
93 // class SvxNewDictionaryDialog -------------------------------------------
94 
SvxNewDictionaryDialog(Window * pParent,Reference<XSpellChecker1> & xSpl)95 SvxNewDictionaryDialog::SvxNewDictionaryDialog( Window* pParent,
96         Reference< XSpellChecker1 >  &xSpl ) :
97 
98     ModalDialog( pParent, CUI_RES( RID_SFXDLG_NEWDICT ) ),
99 
100     aNewDictBox     ( this, CUI_RES( GB_NEWDICT ) ),
101     aNameText       ( this, CUI_RES( FT_DICTNAME ) ),
102     aNameEdit       ( this, CUI_RES( ED_DICTNAME ) ),
103     aLanguageText   ( this, CUI_RES( FT_DICTLANG ) ),
104     aLanguageLB     ( this, CUI_RES( LB_DICTLANG ) ),
105     aExceptBtn      ( this, CUI_RES( BTN_EXCEPT ) ),
106     aOKBtn          ( this, CUI_RES( BTN_NEWDICT_OK ) ),
107     aCancelBtn      ( this, CUI_RES( BTN_NEWDICT_ESC ) ),
108     aHelpBtn        ( this, CUI_RES( BTN_NEWDICT_HLP ) ),
109     xSpell( xSpl )
110 {
111     // Handler installieren
112     aNameEdit.SetModifyHdl(
113         LINK( this, SvxNewDictionaryDialog, ModifyHdl_Impl ) );
114     aOKBtn.SetClickHdl( LINK( this, SvxNewDictionaryDialog, OKHdl_Impl ) );
115 
116     // Sprachen anzeigen
117     aLanguageLB.SetLanguageList( LANG_LIST_ALL, sal_True, sal_True );
118     aLanguageLB.SelectEntryPos(0);
119 
120     aNameText.SetAccessibleRelationMemberOf( &aNewDictBox );
121     aNameEdit.SetAccessibleRelationMemberOf( &aNewDictBox );
122     aLanguageText.SetAccessibleRelationMemberOf( &aNewDictBox );
123     aLanguageLB.SetAccessibleRelationMemberOf( &aNewDictBox );
124 
125     FreeResource();
126 }
127 
128 // -----------------------------------------------------------------------
129 
IMPL_LINK(SvxNewDictionaryDialog,OKHdl_Impl,Button *,EMPTYARG)130 IMPL_LINK( SvxNewDictionaryDialog, OKHdl_Impl, Button *, EMPTYARG )
131 {
132     String sDict = aNameEdit.GetText();
133     sDict.EraseTrailingChars();
134     // add extension for personal dictionaries
135     sDict.AppendAscii(".dic");
136 
137     Reference< XDictionaryList >  xDicList( SvxGetDictionaryList() );
138 
139     Sequence< Reference< XDictionary >  > aDics;
140     if (xDicList.is())
141         aDics = xDicList->getDictionaries();
142     const Reference< XDictionary >  *pDic = aDics.getConstArray();
143     sal_Int32 nCount = (sal_uInt16) aDics.getLength();
144 
145     sal_Bool bFound = sal_False;
146     sal_uInt16 i;
147     for (i = 0; !bFound && i < nCount; ++i )
148         if ( sDict.EqualsIgnoreCaseAscii( String(pDic[i]->getName()) ))
149             bFound = sal_True;
150 
151     if ( bFound )
152     {
153         // Doppelte Namen?
154         InfoBox( this, CUI_RESSTR( RID_SVXSTR_OPT_DOUBLE_DICTS ) ).Execute();
155         aNameEdit.GrabFocus();
156         return 0;
157     }
158 
159     // Erzeugen und hinzufuegen
160     sal_uInt16 nLang = aLanguageLB.GetSelectLanguage();
161     try
162     {
163         // create new dictionary
164         DictionaryType eType = aExceptBtn.IsChecked() ?
165                 DictionaryType_NEGATIVE : DictionaryType_POSITIVE;
166         if (xDicList.is())
167         {
168             lang::Locale aLocale( SvxCreateLocale(nLang) );
169             String aURL( linguistic::GetWritableDictionaryURL( sDict ) );
170             xNewDic = Reference< XDictionary > (
171                     xDicList->createDictionary( sDict, aLocale, eType, aURL ) , UNO_QUERY );
172             xNewDic->setActive( sal_True );
173         }
174         DBG_ASSERT(xNewDic.is(), "NULL pointer");
175     }
176     catch(...)
177     {
178         xNewDic = NULL;
179 
180         // Fehler: konnte neues W"orterbuch nicht anlegen
181         SfxErrorContext aContext( ERRCTX_SVX_LINGU_DICTIONARY, String(),
182             this, RID_SVXERRCTX, &CUI_MGR() );
183         ErrorHandler::HandleError( *new StringErrorInfo(
184                 ERRCODE_SVX_LINGU_DICT_NOTWRITEABLE, sDict ) );
185 
186         EndDialog( RET_CANCEL );
187     }
188 
189     if (xDicList.is() && xNewDic.is())
190     {
191         xDicList->addDictionary( Reference< XDictionary > ( xNewDic, UNO_QUERY ) );
192 
193         // refresh list of dictionaries
194         //! dictionaries may have been added/removed elsewhere too.
195         aDics = xDicList->getDictionaries();
196     }
197     pDic = aDics.getConstArray();
198     nCount = (sal_uInt16) aDics.getLength();
199 
200 
201     EndDialog( RET_OK );
202     return 0;
203 }
204 
205 // -----------------------------------------------------------------------
206 
IMPL_LINK_INLINE_START(SvxNewDictionaryDialog,ModifyHdl_Impl,Edit *,EMPTYARG)207 IMPL_LINK_INLINE_START( SvxNewDictionaryDialog, ModifyHdl_Impl, Edit *, EMPTYARG )
208 {
209     if ( aNameEdit.GetText().Len() )
210         aOKBtn.Enable();
211     else
212         aOKBtn.Disable();
213     return 0;
214 }
IMPL_LINK_INLINE_END(SvxNewDictionaryDialog,ModifyHdl_Impl,Edit *,EMPTYARG)215 IMPL_LINK_INLINE_END( SvxNewDictionaryDialog, ModifyHdl_Impl, Edit *, EMPTYARG )
216 
217 //==========================================================================
218 //
219 // class SvxEditDictionaryDialog -------------------------------------------
220 //
221 //==========================================================================
222 
223 SvxEditDictionaryDialog::SvxEditDictionaryDialog(
224             Window* pParent,
225             const String& rName,
226             Reference< XSpellChecker1 >  &xSpl ) :
227 
228     ModalDialog( pParent, CUI_RES( RID_SFXDLG_EDITDICT ) ),
229 
230     aBookFT         ( this, CUI_RES( FT_BOOK ) ),
231     aAllDictsLB     ( this, CUI_RES( LB_ALLDICTS ) ),
232     aLangFT         ( this, CUI_RES( FT_DICTLANG ) ),
233     aLangLB         ( this, CUI_RES( LB_DICTLANG ) ),
234 
235     aWordFT         ( this, CUI_RES( FT_WORD ) ),
236     aWordED         ( this, CUI_RES( ED_WORD ) ),
237     aReplaceFT      ( this, CUI_RES( FT_REPLACE ) ),
238     aReplaceED      ( this, CUI_RES( ED_REPLACE ) ),
239     aWordsLB        ( this, CUI_RES( TLB_REPLACE ) ),
240     aNewReplacePB   ( this, CUI_RES( PB_NEW_REPLACE ) ),
241     aDeletePB       ( this, CUI_RES( PB_DELETE_REPLACE ) ),
242     aEditDictsBox   ( this, CUI_RES( GB_EDITDICTS ) ),
243     aHelpBtn        ( this, CUI_RES( BTN_EDITHELP ) ),
244     aCloseBtn       ( this, CUI_RES( BTN_EDITCLOSE ) ),
245     sModify         (CUI_RES(STR_MODIFY)),
246     sNew            (aNewReplacePB.GetText()),
247     aDecoView       ( this),
248     xSpell          ( xSpl ),
249     nOld            ( NOACTDICT ),
250     bFirstSelect    (sal_True),
251     bDoNothing      (sal_False)
252 
253 {
254     if (SvxGetDictionaryList().is())
255         aDics = SvxGetDictionaryList()->getDictionaries();
256 
257     aWordsLB.SetSelectHdl(LINK(this, SvxEditDictionaryDialog, SelectHdl));
258     aWordsLB.SetTabs(nStaticTabs);
259 
260     //! we use an algorithm of our own to insert elements sorted
261     aWordsLB.SetStyle(aWordsLB.GetStyle()|/*WB_SORT|*/WB_HSCROLL|WB_CLIPCHILDREN);
262 
263 
264     nWidth=aWordED.GetSizePixel().Width();
265     // Handler installieren
266     aNewReplacePB.SetClickHdl(
267         LINK( this, SvxEditDictionaryDialog, NewDelHdl));
268     aDeletePB.SetClickHdl(
269         LINK( this, SvxEditDictionaryDialog, NewDelHdl));
270 
271     aLangLB.SetSelectHdl(
272         LINK( this, SvxEditDictionaryDialog, SelectLangHdl_Impl ) );
273     aAllDictsLB.SetSelectHdl(
274         LINK( this, SvxEditDictionaryDialog, SelectBookHdl_Impl ) );
275 
276     aWordED.SetModifyHdl(LINK(this, SvxEditDictionaryDialog, ModifyHdl));
277     aReplaceED.SetModifyHdl(LINK(this, SvxEditDictionaryDialog, ModifyHdl));
278     aWordED.SetActionHdl(LINK(this, SvxEditDictionaryDialog, NewDelHdl));
279     aReplaceED.SetActionHdl(LINK(this, SvxEditDictionaryDialog, NewDelHdl));
280 
281     // Listbox mit allen verfuegbaren WB's fuellen
282     const Reference< XDictionary >  *pDic = aDics.getConstArray();
283     sal_Int32 nCount = aDics.getLength();
284 
285     String aLookUpEntry;
286     for ( sal_Int32 i = 0; i < nCount; ++i )
287     {
288         Reference< XDictionary >  xDic( pDic[i], UNO_QUERY );
289         if (xDic.is())
290         {
291             sal_Bool bNegative = xDic->getDictionaryType() == DictionaryType_NEGATIVE ?
292                                 sal_True : sal_False;
293             String aDicName( xDic->getName() );
294             const String aTxt( ::GetDicInfoStr( aDicName, SvxLocaleToLanguage( xDic->getLocale() ),
295                                                  bNegative ) );
296             aAllDictsLB.InsertEntry( aTxt );
297 
298             if (rName == aDicName)
299                 aLookUpEntry = aTxt;
300         }
301     }
302 
303     aLangLB.SetLanguageList( LANG_LIST_ALL, sal_True, sal_True );
304 
305     aReplaceED.SetSpaces(sal_True);
306     aWordED.SetSpaces(sal_True);
307 
308     if ( nCount > 0 )
309     {
310         aAllDictsLB.SelectEntry( aLookUpEntry );
311         sal_uInt16 nPos = aAllDictsLB.GetSelectEntryPos();
312 
313         if ( nPos == LISTBOX_ENTRY_NOTFOUND )
314         {
315             nPos = 0;
316             aAllDictsLB.SelectEntryPos( nPos );
317         }
318         Reference< XDictionary >  xDic;
319         if (nPos != LISTBOX_ENTRY_NOTFOUND)
320             xDic = Reference< XDictionary > ( aDics.getConstArray()[ nPos ], UNO_QUERY );
321         if (xDic.is())
322             SetLanguage_Impl( SvxLocaleToLanguage( xDic->getLocale() ) );
323 
324         // check if dictionary is read-only
325         SetDicReadonly_Impl(xDic);
326         sal_Bool bEnable = !IsDicReadonly_Impl();
327         aNewReplacePB   .Enable( sal_False );
328         aDeletePB       .Enable( sal_False );
329         aLangFT.Enable( bEnable );
330         aLangLB.Enable( bEnable );
331         ShowWords_Impl( nPos );
332 
333     }
334     else
335     {
336         aNewReplacePB.Disable();
337         aDeletePB    .Disable();
338     }
339     FreeResource();
340 }
341 
342 // -----------------------------------------------------------------------
343 
~SvxEditDictionaryDialog()344 SvxEditDictionaryDialog::~SvxEditDictionaryDialog()
345 {
346 }
347 
348 // -----------------------------------------------------------------------
349 
Paint(const Rectangle & rRect)350 void SvxEditDictionaryDialog::Paint( const Rectangle& rRect )
351 {
352     ModalDialog::Paint(rRect );
353 
354     Rectangle aRect(aEditDictsBox.GetPosPixel(),aEditDictsBox.GetSizePixel());
355 
356     sal_uInt16 nStyle=BUTTON_DRAW_NOFILL;
357     aDecoView.DrawButton( aRect, nStyle);
358 }
359 
360 // -----------------------------------------------------------------------
361 
SetDicReadonly_Impl(Reference<XDictionary> & xDic)362 void SvxEditDictionaryDialog::SetDicReadonly_Impl(
363             Reference< XDictionary >  &xDic )
364 {
365     // enable or disable new and delete button according to file attributes
366     bDicIsReadonly = sal_True;
367     if (xDic.is())
368     {
369         Reference< frame::XStorable >  xStor( xDic, UNO_QUERY );
370         if (   !xStor.is()              // non persistent dictionary
371             || !xStor->hasLocation()    // not yet persistent
372             || !xStor->isReadonly() )
373         {
374             bDicIsReadonly = sal_False;
375         }
376     }
377 }
378 
379 // -----------------------------------------------------------------------
380 
SetLanguage_Impl(util::Language nLanguage)381 void SvxEditDictionaryDialog::SetLanguage_Impl( util::Language nLanguage )
382 {
383     // select language
384     aLangLB.SelectLanguage( nLanguage );
385 }
386 
GetLBInsertPos(const String & rDicWord)387 sal_uInt16 SvxEditDictionaryDialog::GetLBInsertPos(const String &rDicWord)
388 {
389     sal_uInt16 nPos = USHRT_MAX;
390 
391     IntlWrapper aIntlWrapper( ::comphelper::getProcessServiceFactory(), Application::GetSettings().GetLocale() );
392     const CollatorWrapper* pCollator = aIntlWrapper.getCollator();
393     sal_uInt16 j;
394     for( j = 0; j < aWordsLB.GetEntryCount(); j++ )
395     {
396         SvLBoxEntry* pEntry = aWordsLB.GetEntry(j);
397         DBG_ASSERT( pEntry, "NULL pointer");
398         String aNormEntry( getNormDicEntry_Impl( rDicWord ) );
399         StringCompare eCmpRes = (StringCompare)pCollator->
400             compareString( aNormEntry, getNormDicEntry_Impl( aWordsLB.GetEntryText(pEntry, 0) ) );
401         if( COMPARE_LESS == eCmpRes )
402             break;
403     }
404     if (j < aWordsLB.GetEntryCount())   // entry found?
405         nPos = j;
406 
407     return nPos;
408 }
409 
RemoveDictEntry(SvLBoxEntry * pEntry)410 void SvxEditDictionaryDialog::RemoveDictEntry(SvLBoxEntry* pEntry)
411 {
412     sal_uInt16 nLBPos = aAllDictsLB.GetSelectEntryPos();
413 
414     if ( pEntry != NULL && nLBPos != LISTBOX_ENTRY_NOTFOUND )
415     {
416         String sTmpShort(aWordsLB.GetEntryText(pEntry, 0));
417 
418         Reference< XDictionary >  xDic = aDics.getConstArray()[ nLBPos ];
419         if (xDic->remove( sTmpShort ))  // sal_True on success
420         {
421             aWordsLB.GetModel()->Remove(pEntry);
422         }
423     }
424 }
425 
426 // -----------------------------------------------------------------------
427 
IMPL_LINK(SvxEditDictionaryDialog,SelectBookHdl_Impl,ListBox *,EMPTYARG)428 IMPL_LINK( SvxEditDictionaryDialog, SelectBookHdl_Impl, ListBox *, EMPTYARG )
429 {
430     sal_uInt16 nPos = aAllDictsLB.GetSelectEntryPos();
431 
432     if ( nPos != LISTBOX_ENTRY_NOTFOUND )
433     {
434         aNewReplacePB.Enable( sal_False );
435         aDeletePB    .Enable( sal_False );
436         // Dictionary anzeigen
437         ShowWords_Impl( nPos );
438         // enable or disable new and delete button according to file attributes
439         Reference< XDictionary >  xDic( aDics.getConstArray()[ nPos ], UNO_QUERY );
440         if (xDic.is())
441             SetLanguage_Impl( SvxLocaleToLanguage( xDic->getLocale() ) );
442 
443         SetDicReadonly_Impl(xDic);
444         sal_Bool bEnable = !IsDicReadonly_Impl();
445         aLangFT.Enable( bEnable );
446         aLangLB.Enable( bEnable );
447     }
448     return 0;
449 }
450 
451 // -----------------------------------------------------------------------
452 
IMPL_LINK(SvxEditDictionaryDialog,SelectLangHdl_Impl,ListBox *,EMPTYARG)453 IMPL_LINK( SvxEditDictionaryDialog, SelectLangHdl_Impl, ListBox *, EMPTYARG )
454 {
455     sal_uInt16 nDicPos = aAllDictsLB.GetSelectEntryPos();
456     sal_uInt16 nLang = aLangLB.GetSelectLanguage();
457     Reference< XDictionary >  xDic( aDics.getConstArray()[ nDicPos ], UNO_QUERY );
458     sal_Int16 nOldLang = SvxLocaleToLanguage( xDic->getLocale() );
459 
460     if ( nLang != nOldLang )
461     {
462         QueryBox aBox( this, CUI_RES( RID_SFXQB_SET_LANGUAGE ) );
463         String sTxt( aBox.GetMessText() );
464         sTxt.SearchAndReplaceAscii( "%1", aAllDictsLB.GetSelectEntry() );
465         aBox.SetMessText( sTxt );
466 
467         if ( aBox.Execute() == RET_YES )
468         {
469             xDic->setLocale( SvxCreateLocale( nLang ) );
470             sal_Bool bNegativ = xDic->getDictionaryType() == DictionaryType_NEGATIVE;
471 
472             const String sName(
473                 ::GetDicInfoStr( xDic->getName(),
474                                  SvxLocaleToLanguage( xDic->getLocale() ),
475                                  bNegativ ) );
476             aAllDictsLB.RemoveEntry( nDicPos );
477             aAllDictsLB.InsertEntry( sName, nDicPos );
478             aAllDictsLB.SelectEntryPos( nDicPos );
479         }
480         else
481             SetLanguage_Impl( nOldLang );
482     }
483     return 1;
484 }
485 
486 // -----------------------------------------------------------------------
487 
ShowWords_Impl(sal_uInt16 nId)488 void SvxEditDictionaryDialog::ShowWords_Impl( sal_uInt16 nId )
489 {
490     Reference< XDictionary >  xDic = aDics.getConstArray()[ nId ];
491 
492     nOld = nId;
493     EnterWait();
494 
495     String aStr;
496 
497     aWordED.SetText(aStr);
498     aReplaceED.SetText(aStr);
499 
500     if(xDic->getDictionaryType() != DictionaryType_POSITIVE)
501     {
502         nStaticTabs[0]=2;
503 
504         // make controls for replacement text active
505         if(!aReplaceFT.IsVisible())
506         {
507             Size aSize=aWordED.GetSizePixel();
508             aSize.Width()=nWidth;
509             aWordED.SetSizePixel(aSize);
510             aReplaceFT.Show();
511             aReplaceED.Show();
512         }
513     }
514     else
515     {
516         nStaticTabs[0]=1;
517 
518         // deactivate controls for replacement text
519         if(aReplaceFT.IsVisible())
520         {
521             Size aSize=aWordED.GetSizePixel();
522             aSize.Width()=aWordsLB.GetSizePixel().Width();
523             aWordED.SetSizePixel(aSize);
524             aReplaceFT.Hide();
525             aReplaceED.Hide();
526         }
527 
528     }
529 
530     aWordsLB.SetTabs(nStaticTabs);
531     aWordsLB.Clear();
532 
533     Sequence< Reference< XDictionaryEntry >  > aEntries( xDic->getEntries() );
534     const Reference< XDictionaryEntry >  *pEntry = aEntries.getConstArray();
535     sal_Int32 nCount = aEntries.getLength();
536 
537     for (sal_Int32 i = 0;  i < nCount;  i++)
538     {
539         aStr = String(pEntry[i]->getDictionaryWord());
540         sal_uInt16 nPos = GetLBInsertPos( aStr );
541         if(pEntry[i]->isNegative())
542         {
543             aStr += '\t';
544             aStr += String(pEntry[i]->getReplacementText());
545         }
546         aWordsLB.InsertEntry(aStr, 0, sal_False, nPos == USHRT_MAX ?  LIST_APPEND : nPos);
547     }
548 
549     if (aWordsLB.GetEntryCount())
550     {
551         aWordED   .SetText( aWordsLB.GetEntryText(0LU, 0) );
552         aReplaceED.SetText( aWordsLB.GetEntryText(0LU, 1) );
553     }
554 
555     LeaveWait();
556 }
557 
558 // -----------------------------------------------------------------------
559 
IMPL_LINK(SvxEditDictionaryDialog,SelectHdl,SvTabListBox *,pBox)560 IMPL_LINK(SvxEditDictionaryDialog, SelectHdl, SvTabListBox*, pBox)
561 {
562     if(!bDoNothing)
563     {
564         if(!bFirstSelect)
565         {
566             SvLBoxEntry* pEntry = pBox->FirstSelected();
567             String sTmpShort(pBox->GetEntryText(pEntry, 0));
568             // wird der Text ueber den ModifyHdl gesetzt, dann steht der Cursor
569             //sonst immer am Wortanfang, obwohl man gerade hier editiert
570             if(aWordED.GetText() != sTmpShort)
571                 aWordED.SetText(sTmpShort);
572             aReplaceED.SetText(pBox->GetEntryText(pEntry, 1));
573         }
574         else
575             bFirstSelect = sal_False;
576 
577         // entries in the list box should exactly correspond to those from the
578         // dictionary. Thus:
579         aNewReplacePB.Enable(sal_False);
580         aDeletePB    .Enable( sal_True && !IsDicReadonly_Impl() );
581     }
582     return 0;
583 };
584 
585 // -----------------------------------------------------------------------
586 
IMPL_LINK(SvxEditDictionaryDialog,NewDelHdl,PushButton *,pBtn)587 IMPL_LINK(SvxEditDictionaryDialog, NewDelHdl, PushButton*, pBtn)
588 {
589     SvLBoxEntry* pEntry = aWordsLB.FirstSelected();
590 
591     if(pBtn == &aDeletePB)
592     {
593         DBG_ASSERT(pEntry, "keine Eintrag selektiert");
594         String aStr;
595 
596         aWordED.SetText(aStr);
597         aReplaceED.SetText(aStr);
598         aDeletePB.Disable();
599 
600         RemoveDictEntry(pEntry);    // remove entry from dic and list-box
601     }
602     if(pBtn == &aNewReplacePB || aNewReplacePB.IsEnabled())
603     {
604         SvLBoxEntry* _pEntry = aWordsLB.FirstSelected();
605         XubString aNewWord(aWordED.GetText());
606         String sEntry(aNewWord);
607         XubString aReplaceStr(aReplaceED.GetText());
608 
609         sal_Int16 nAddRes = DIC_ERR_UNKNOWN;
610         sal_uInt16 nPos = aAllDictsLB.GetSelectEntryPos();
611         if ( nPos != LISTBOX_ENTRY_NOTFOUND && aNewWord.Len() > 0)
612         {
613             DBG_ASSERT(nPos < aDics.getLength(), "invalid dictionary index");
614             Reference< XDictionary >  xDic( aDics.getConstArray()[ nPos ], UNO_QUERY );
615             if (xDic.is())
616             {
617                 // make changes in dic
618 
619                 //! ...IsVisible should reflect wether the dictionary is a negativ
620                 //! or not (hopefully...)
621                 sal_Bool bIsNegEntry = aReplaceFT.IsVisible();
622                 ::rtl::OUString aRplcText;
623                 if(bIsNegEntry)
624                     aRplcText = aReplaceStr;
625 
626                 if (_pEntry) // entry selected in aWordsLB ie action = modify entry
627                     xDic->remove( aWordsLB.GetEntryText( _pEntry, 0 ) );
628                 // if remove has failed the following add should fail too
629                 // and thus a warning message should be triggered...
630 
631                 Reference<XDictionary> aXDictionary(xDic, UNO_QUERY);
632                 nAddRes = linguistic::AddEntryToDic( aXDictionary,
633                             aNewWord, bIsNegEntry,
634                             aRplcText, SvxLocaleToLanguage( xDic->getLocale() ), sal_False );
635             }
636         }
637         if (DIC_ERR_NONE != nAddRes)
638             SvxDicError( this, nAddRes );
639 
640         if(DIC_ERR_NONE == nAddRes && sEntry.Len())
641         {
642             // insert new entry in list-box etc...
643 
644             aWordsLB.SetUpdateMode(sal_False);
645             sal_uInt16 _nPos = USHRT_MAX;
646 
647             if(aReplaceFT.IsVisible())
648             {
649                 sEntry += '\t';
650                 sEntry += aReplaceStr;
651             }
652 
653             SvLBoxEntry* pNewEntry = NULL;
654             if(_pEntry) // entry selected in aWordsLB ie action = modify entry
655             {
656                 aWordsLB.SetEntryText( sEntry, _pEntry );
657                 pNewEntry = _pEntry;
658             }
659             else
660             {
661                 _nPos = GetLBInsertPos( aNewWord );
662                 SvLBoxEntry* pInsEntry = aWordsLB.InsertEntry(sEntry, 0, sal_False,
663                             _nPos == USHRT_MAX ? LIST_APPEND : (sal_uInt32)_nPos);
664                 pNewEntry = pInsEntry;
665             }
666 
667             aWordsLB.MakeVisible( pNewEntry );
668             aWordsLB.SetUpdateMode(sal_True);
669             // falls der Request aus dem ReplaceEdit kam, dann Focus in das ShortEdit setzen
670             if(aReplaceED.HasFocus())
671                 aWordED.GrabFocus();
672         }
673     }
674     else
675     {
676         // das kann nur ein Enter in einem der beiden Edit-Felder sein und das
677         // bedeutet EndDialog() - muss im KeyInput ausgewertet werden
678         return 0;
679     }
680     ModifyHdl(&aWordED);
681     return 1;
682 }
683 
684 // -----------------------------------------------------------------------
685 
IMPL_LINK(SvxEditDictionaryDialog,ModifyHdl,Edit *,pEdt)686 IMPL_LINK(SvxEditDictionaryDialog, ModifyHdl, Edit*, pEdt)
687 {
688     SvLBoxEntry* pFirstSel = aWordsLB.FirstSelected();
689     String rEntry = pEdt->GetText();
690 
691     xub_StrLen nWordLen=rEntry.Len();
692     const String& rRepString = aReplaceED.GetText();
693 
694     sal_Bool bEnableNewReplace  = sal_False;
695     sal_Bool bEnableDelete      = sal_False;
696     String aNewReplaceText  = sNew;
697 
698     if(pEdt == &aWordED)
699     {
700         if(nWordLen>0)
701         {
702             sal_Bool bFound = sal_False;
703             sal_Bool bTmpSelEntry=sal_False;
704             CDE_RESULT eCmpRes = CDE_DIFFERENT;
705 
706             for(sal_uInt16 i = 0; i < aWordsLB.GetEntryCount(); i++)
707             {
708                 SvLBoxEntry*  pEntry = aWordsLB.GetEntry( i );
709                 String aTestStr( aWordsLB.GetEntryText(pEntry, 0) );
710                 eCmpRes = cmpDicEntry_Impl( rEntry, aTestStr );
711                 if(CDE_DIFFERENT != eCmpRes)
712                 {
713                     if(rRepString.Len())
714                         bFirstSelect = sal_True;
715                     bDoNothing=sal_True;
716                     aWordsLB.SetCurEntry(pEntry);
717                     bDoNothing=sal_False;
718                     pFirstSel = pEntry;
719                     aReplaceED.SetText(aWordsLB.GetEntryText(pEntry, 1));
720 
721                     if (CDE_SIMILAR == eCmpRes)
722                     {
723                         aNewReplaceText = sModify;
724                         bEnableNewReplace = sal_True;
725                     }
726                     bFound= sal_True;
727                     break;
728                 }
729                 else if(getNormDicEntry_Impl(aTestStr).Search(
730                             getNormDicEntry_Impl( rEntry ) ) == 0
731                         && !bTmpSelEntry)
732                 {
733                     bDoNothing=sal_True;
734                     aWordsLB.MakeVisible(pEntry);
735                     bDoNothing=sal_False;
736                     bTmpSelEntry=sal_True;
737 
738                     aNewReplaceText = sNew;
739                     bEnableNewReplace = sal_True;
740                 }
741             }
742 
743             if(!bFound)
744             {
745                 aWordsLB.SelectAll(sal_False);
746                 pFirstSel = 0;
747 
748                 aNewReplaceText = sNew;
749                 bEnableNewReplace = sal_True;
750             }
751             bEnableDelete = CDE_DIFFERENT != eCmpRes;
752         }
753         else if(aWordsLB.GetEntryCount()>0)
754         {
755             SvLBoxEntry*  pEntry = aWordsLB.GetEntry( 0 );
756             bDoNothing=sal_True;
757             aWordsLB.MakeVisible(pEntry);
758             bDoNothing=sal_False;
759         }
760     }
761     else if(pEdt == &aReplaceED)
762     {
763         String aReplaceText;
764         String aWordText;
765         if (pFirstSel)  // a aWordsLB entry is selected
766         {
767             aWordText    = aWordsLB.GetEntryText( pFirstSel, 0 );
768             aReplaceText = aWordsLB.GetEntryText( pFirstSel, 1 );
769 
770             aNewReplaceText = sModify;
771             bEnableDelete = sal_True;
772         }
773         sal_Bool bIsChange =
774                 CDE_EQUAL != cmpDicEntry_Impl(aWordED.GetText(), aWordText)
775              || CDE_EQUAL != cmpDicEntry_Impl(aReplaceED.GetText(), aReplaceText);
776         if (aWordED.GetText().Len()  &&  bIsChange)
777             bEnableNewReplace = sal_True;
778     }
779 
780     aNewReplacePB.SetText( aNewReplaceText );
781     aNewReplacePB.Enable( bEnableNewReplace && !IsDicReadonly_Impl() );
782     aDeletePB    .Enable( bEnableDelete     && !IsDicReadonly_Impl() );
783 
784     return 0;
785 }
786 
787 //=========================================================
788 //SvxDictEdit
789 //=========================================================
KeyInput(const KeyEvent & rKEvt)790 void SvxDictEdit::KeyInput( const KeyEvent& rKEvt )
791 {
792     const KeyCode aKeyCode = rKEvt.GetKeyCode();
793     const sal_uInt16 nModifier = aKeyCode.GetModifier();
794     if( aKeyCode.GetCode() == KEY_RETURN )
795     {
796         //wird bei Enter nichts getan, dann doch die Basisklasse rufen
797         // um den Dialog zu schliessen
798         if(!nModifier && !aActionLink.Call(this))
799                  Edit::KeyInput(rKEvt);
800     }
801     else if(bSpaces || aKeyCode.GetCode() != KEY_SPACE)
802         Edit::KeyInput(rKEvt);
803 }
804 
805 
806