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