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