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