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