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 <svx/dialogs.hrc>
32 :
33 : #include <linguistic/misc.hxx>
34 : #include <cuires.hrc>
35 : #include "optdict.hxx"
36 : #include <dialmgr.hxx>
37 : #include <svx/svxerr.hxx>
38 :
39 : using namespace ::com::sun::star;
40 : using namespace ::com::sun::star::uno;
41 : using namespace ::com::sun::star::linguistic2;
42 :
43 : // static ----------------------------------------------------------------
44 :
45 : static const short NOACTDICT = -1;
46 :
47 : static long nStaticTabs[]=
48 : {
49 : 2,10,71,120
50 : };
51 :
52 : // static function -------------------------------------------------------
53 :
54 0 : static OUString getNormDicEntry_Impl(const OUString &rText)
55 : {
56 0 : OUString aTmp(comphelper::string::stripEnd(rText, '.'));
57 : // non-standard hyphenation
58 0 : if (aTmp.indexOf('[') > -1)
59 : {
60 0 : OUStringBuffer aTmp2 ( aTmp.getLength() );
61 0 : bool bSkip = false;
62 0 : for (sal_Int32 i = 0; i < aTmp.getLength(); i++)
63 : {
64 0 : sal_Unicode cTmp = aTmp[i];
65 0 : if (cTmp == '[')
66 0 : bSkip = true;
67 0 : else if (!bSkip)
68 0 : aTmp2.append( cTmp );
69 0 : else if (cTmp == ']')
70 0 : bSkip = false;
71 : }
72 0 : aTmp = aTmp2.makeStringAndClear();
73 : }
74 0 : return comphelper::string::remove(aTmp, '=');
75 : }
76 :
77 : // Compare Dictionary Entry result
78 : enum CDE_RESULT { CDE_EQUAL, CDE_SIMILAR, CDE_DIFFERENT };
79 :
80 0 : static CDE_RESULT cmpDicEntry_Impl( const OUString &rText1, const OUString &rText2 )
81 : {
82 0 : CDE_RESULT eRes = CDE_DIFFERENT;
83 :
84 0 : if (rText1 == rText2)
85 0 : eRes = CDE_EQUAL;
86 : else
87 : { // similar = equal up to trailing '.' and hyphenation positions
88 : // marked with '=' and '[' + alternative spelling pattern + ']'
89 0 : if (getNormDicEntry_Impl( rText1 ) == getNormDicEntry_Impl( rText2 ))
90 0 : eRes = CDE_SIMILAR;
91 : }
92 :
93 0 : return eRes;
94 : }
95 :
96 : // class SvxNewDictionaryDialog -------------------------------------------
97 :
98 0 : SvxNewDictionaryDialog::SvxNewDictionaryDialog( vcl::Window* pParent,
99 : Reference< XSpellChecker1 > &xSpl ) :
100 :
101 : ModalDialog( pParent, "OptNewDictionaryDialog" , "cui/ui/optnewdictionarydialog.ui" ),
102 :
103 0 : xSpell( xSpl )
104 : {
105 0 : get(pNameEdit,"nameedit");
106 0 : get(pLanguageLB,"language");
107 0 : get(pExceptBtn,"except");
108 0 : get(pOKBtn,"ok");
109 : // install handler
110 : pNameEdit->SetModifyHdl(
111 0 : LINK( this, SvxNewDictionaryDialog, ModifyHdl_Impl ) );
112 0 : pOKBtn->SetClickHdl( LINK( this, SvxNewDictionaryDialog, OKHdl_Impl ) );
113 :
114 : // display languages
115 0 : pLanguageLB->SetLanguageList( LANG_LIST_ALL, true, true );
116 0 : pLanguageLB->SelectEntryPos(0);
117 0 : }
118 :
119 :
120 :
121 0 : IMPL_LINK_NOARG(SvxNewDictionaryDialog, OKHdl_Impl)
122 : {
123 0 : OUString sDict = comphelper::string::stripEnd(pNameEdit->GetText(), ' ');
124 : // add extension for personal dictionaries
125 0 : sDict += ".dic";
126 :
127 0 : Reference< XSearchableDictionaryList > xDicList( SvxGetDictionaryList() );
128 :
129 0 : Sequence< Reference< XDictionary > > aDics;
130 0 : if (xDicList.is())
131 0 : aDics = xDicList->getDictionaries();
132 0 : const Reference< XDictionary > *pDic = aDics.getConstArray();
133 0 : sal_Int32 nCount = aDics.getLength();
134 :
135 0 : bool bFound = false;
136 : sal_Int32 i;
137 0 : for (i = 0; !bFound && i < nCount; ++i )
138 0 : if ( sDict.equalsIgnoreAsciiCase( pDic[i]->getName()) )
139 0 : bFound = true;
140 :
141 0 : if ( bFound )
142 : {
143 : // duplicate names?
144 0 : MessageDialog(this, CUI_RESSTR(RID_SVXSTR_OPT_DOUBLE_DICTS), VCL_MESSAGE_INFO).Execute();
145 0 : pNameEdit->GrabFocus();
146 0 : return 0;
147 : }
148 :
149 : // create and add
150 0 : sal_uInt16 nLang = pLanguageLB->GetSelectLanguage();
151 : try
152 : {
153 : // create new dictionary
154 0 : DictionaryType eType = pExceptBtn->IsChecked() ?
155 0 : DictionaryType_NEGATIVE : DictionaryType_POSITIVE;
156 0 : if (xDicList.is())
157 : {
158 0 : lang::Locale aLocale( LanguageTag::convertToLocale(nLang) );
159 0 : OUString aURL( linguistic::GetWritableDictionaryURL( sDict ) );
160 0 : xNewDic = Reference< XDictionary > (
161 0 : xDicList->createDictionary( sDict, aLocale, eType, aURL ) , UNO_QUERY );
162 0 : xNewDic->setActive( sal_True );
163 : }
164 : DBG_ASSERT(xNewDic.is(), "NULL pointer");
165 : }
166 0 : catch(...)
167 : {
168 0 : xNewDic = NULL;
169 :
170 : // error: couldn't create new dictionary
171 : SfxErrorContext aContext( ERRCTX_SVX_LINGU_DICTIONARY, OUString(),
172 0 : this, RID_SVXERRCTX, &CUI_MGR() );
173 : ErrorHandler::HandleError( *new StringErrorInfo(
174 0 : ERRCODE_SVX_LINGU_DICT_NOTWRITEABLE, sDict ) );
175 :
176 0 : EndDialog( RET_CANCEL );
177 : }
178 :
179 0 : if (xDicList.is() && xNewDic.is())
180 : {
181 0 : xDicList->addDictionary( Reference< XDictionary > ( xNewDic, UNO_QUERY ) );
182 :
183 : // refresh list of dictionaries
184 : //! dictionaries may have been added/removed elsewhere too.
185 0 : aDics = xDicList->getDictionaries();
186 : }
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 ( !pNameEdit->GetText().isEmpty() )
198 0 : pOKBtn->Enable();
199 : else
200 0 : pOKBtn->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 : extern "C" SAL_DLLPUBLIC_EXPORT vcl::Window* SAL_CALL makeSvxDictEdit(vcl::Window *pParent, VclBuilder::stringmap&)
212 : {
213 0 : WinBits nWinStyle = WB_LEFT|WB_VCENTER|WB_BORDER|WB_3DLOOK;
214 0 : SvxDictEdit *pEdit = new SvxDictEdit(pParent, nWinStyle);
215 0 : return pEdit;
216 : };
217 :
218 0 : SvxEditDictionaryDialog::SvxEditDictionaryDialog(
219 : vcl::Window* pParent,
220 : const OUString& rName,
221 : Reference< XSpellChecker1 > &xSpl ) :
222 :
223 : ModalDialog( pParent, "EditDictionaryDialog" ,"cui/ui/editdictionarydialog.ui" ),
224 :
225 0 : sModify (CUI_RESSTR(STR_MODIFY)),
226 : aDecoView ( this),
227 : xSpell ( xSpl ),
228 : nOld ( NOACTDICT ),
229 : bFirstSelect (true),
230 : bDoNothing (false),
231 0 : bDicIsReadonly (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(true);
298 0 : pWordED->SetSpaces(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 : 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 = 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 = 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 : 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 : MessageDialog aBox(this, CUI_RES( RID_SVXSTR_CONFIRM_SET_LANGUAGE), VCL_MESSAGE_QUESTION, VCL_BUTTONS_YES_NO);
454 0 : OUString sTxt(aBox.get_primary_text());
455 0 : sTxt = sTxt.replaceFirst( "%1", pAllDictsLB->GetSelectEntry() );
456 0 : aBox.set_primary_text(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 = 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 : 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 : OUString rEntry = pEdt->GetText();
679 :
680 0 : sal_Int32 nWordLen = rEntry.getLength();
681 0 : const OUString& rRepString = pReplaceED->GetText();
682 :
683 0 : bool bEnableNewReplace = false;
684 0 : bool bEnableDelete = false;
685 0 : OUString aNewReplaceText = sNew;
686 :
687 0 : if(pEdt == pWordED)
688 : {
689 0 : if(nWordLen>0)
690 : {
691 0 : bool bFound = false;
692 0 : bool bTmpSelEntry=false;
693 0 : CDE_RESULT eCmpRes = CDE_DIFFERENT;
694 :
695 0 : for(sal_uLong i = 0; i < pWordsLB->GetEntryCount(); i++)
696 : {
697 0 : SvTreeListEntry* pEntry = pWordsLB->GetEntry( i );
698 0 : OUString aTestStr( pWordsLB->GetEntryText(pEntry, 0) );
699 0 : eCmpRes = cmpDicEntry_Impl( rEntry, aTestStr );
700 0 : if(CDE_DIFFERENT != eCmpRes)
701 : {
702 0 : if(!rRepString.isEmpty())
703 0 : bFirstSelect = true;
704 0 : bDoNothing=true;
705 0 : pWordsLB->SetCurEntry(pEntry);
706 0 : bDoNothing=false;
707 0 : pReplaceED->SetText(pWordsLB->GetEntryText(pEntry, 1));
708 :
709 0 : if (CDE_SIMILAR == eCmpRes)
710 : {
711 0 : aNewReplaceText = sModify;
712 0 : bEnableNewReplace = true;
713 : }
714 0 : bFound= true;
715 0 : break;
716 : }
717 0 : else if(getNormDicEntry_Impl(aTestStr).indexOf(
718 0 : getNormDicEntry_Impl( rEntry ) ) == 0
719 0 : && !bTmpSelEntry)
720 : {
721 0 : bDoNothing=true;
722 0 : pWordsLB->MakeVisible(pEntry);
723 0 : bDoNothing=false;
724 0 : bTmpSelEntry=true;
725 :
726 0 : aNewReplaceText = sNew;
727 0 : bEnableNewReplace = true;
728 : }
729 0 : }
730 :
731 0 : if(!bFound)
732 : {
733 0 : pWordsLB->SelectAll(false);
734 :
735 0 : aNewReplaceText = sNew;
736 0 : bEnableNewReplace = true;
737 : }
738 0 : bEnableDelete = CDE_DIFFERENT != eCmpRes;
739 : }
740 0 : else if(pWordsLB->GetEntryCount()>0)
741 : {
742 0 : SvTreeListEntry* pEntry = pWordsLB->GetEntry( 0 );
743 0 : bDoNothing=true;
744 0 : pWordsLB->MakeVisible(pEntry);
745 0 : bDoNothing=false;
746 : }
747 : }
748 0 : else if(pEdt == pReplaceED)
749 : {
750 0 : OUString aReplaceText;
751 0 : OUString aWordText;
752 0 : SvTreeListEntry* pFirstSel = pWordsLB->FirstSelected();
753 0 : if (pFirstSel) // a pWordsLB entry is selected
754 : {
755 0 : aWordText = pWordsLB->GetEntryText( pFirstSel, 0 );
756 0 : aReplaceText = pWordsLB->GetEntryText( pFirstSel, 1 );
757 :
758 0 : aNewReplaceText = sModify;
759 0 : bEnableDelete = true;
760 : }
761 : bool bIsChange =
762 0 : CDE_EQUAL != cmpDicEntry_Impl(pWordED->GetText(), aWordText)
763 0 : || CDE_EQUAL != cmpDicEntry_Impl(pReplaceED->GetText(), aReplaceText);
764 0 : if (!pWordED->GetText().isEmpty() && bIsChange)
765 0 : bEnableNewReplace = true;
766 : }
767 :
768 0 : pNewReplacePB->SetText( aNewReplaceText );
769 0 : pNewReplacePB->Enable( bEnableNewReplace && !IsDicReadonly_Impl() );
770 0 : pDeletePB->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 vcl::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: */
|