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