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