1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_svx.hxx"
30 
31 #include "chinese_dictionarydialog.hxx"
32 #include "chinese_dictionarydialog.hrc"
33 #include "resid.hxx"
34 #include <cppuhelper/bootstrap.hxx>
35 #include <com/sun/star/i18n/TextConversionOption.hpp>
36 #include <com/sun/star/linguistic2/ConversionDictionaryType.hpp>
37 #include <com/sun/star/linguistic2/ConversionPropertyType.hpp>
38 #include <com/sun/star/linguistic2/XConversionDictionaryList.hpp>
39 #include <com/sun/star/linguistic2/XConversionPropertyType.hpp>
40 #include <com/sun/star/util/XFlushable.hpp>
41 #include <com/sun/star/lang/Locale.hpp>
42 // header for class HeaderBar
43 #include <svtools/headbar.hxx>
44 // header for define RET_OK
45 #include <vcl/msgbox.hxx>
46 // header for class SvtLinguConfigItem
47 #include <unotools/lingucfg.hxx>
48 #include <unotools/linguprops.hxx>
49 // header for class IntlWrapper
50 #include <unotools/intlwrapper.hxx>
51 #ifndef _UNOTOOLS_PROCESSFACTORY_HXX
52 #include <comphelper/processfactory.hxx>
53 #endif
54 // header for class Application
55 #include <vcl/svapp.hxx>
56 #ifndef _SVX_HELPID_HRC
57 #include "helpid.hrc"
58 #endif
59 
60 //disable compiler warning C4355: 'this' : used in base member initializer list
61 #ifdef _MSC_VER
62 #  pragma warning (disable : 4355)
63 #endif
64 
65 //.............................................................................
66 namespace textconversiondlgs
67 {
68 //.............................................................................
69 
70 using namespace ::com::sun::star;
71 using namespace ::com::sun::star::uno;
72 
73 #define HEADER_BAR_BITS ( HIB_LEFT | HIB_VCENTER | HIB_CLICKABLE | HIB_FIXED | HIB_FIXEDPOS )
74 
75 DictionaryList::DictionaryList( Window* pParent, const ResId& rResId)
76     : SvHeaderTabListBox( pParent, rResId )
77     , m_xDictionary(0)
78     , m_pHeaderBar(0)
79     , m_pPropertyTypeNameListBox(0)
80     , m_aToBeDeleted()
81     , m_nSortColumnIndex(0)
82 {
83 }
84 
85 DictionaryList::DictionaryList( Window* pParent )
86     : SvHeaderTabListBox( pParent, 0 )
87     , m_xDictionary(0)
88     , m_pHeaderBar(0)
89     , m_pPropertyTypeNameListBox(0)
90     , m_aToBeDeleted()
91     , m_nSortColumnIndex(0)
92 {
93 }
94 
95 String DictionaryList::getPropertyTypeName( sal_Int16 nConversionPropertyType ) const
96 {
97     if(!m_pPropertyTypeNameListBox || !m_pPropertyTypeNameListBox->GetEntryCount())
98         return String();
99 
100     sal_uInt16 nPos = static_cast<sal_uInt16>( nConversionPropertyType )-1;
101     if(nPos<m_pPropertyTypeNameListBox->GetEntryCount())
102         return m_pPropertyTypeNameListBox->GetEntry(nPos);
103     return m_pPropertyTypeNameListBox->GetEntry(0);
104 }
105 
106 String DictionaryList::makeTabString( const DictionaryEntry& rEntry ) const
107 {
108     String aStr( rEntry.m_aTerm );
109     aStr += '\t';
110     aStr += String( rEntry.m_aMapping );
111     aStr += '\t';
112     aStr += getPropertyTypeName( rEntry.m_nConversionPropertyType );
113     return aStr;
114 }
115 
116 void DictionaryList::initDictionaryControl( const Reference< linguistic2::XConversionDictionary>& xDictionary
117                                            , ListBox* pPropertyTypeNameListBox )
118 {
119     SetStyle( WB_VSCROLL | WB_TABSTOP );
120     SetSelectionMode( SINGLE_SELECTION );
121     SetBorderStyle( WINDOW_BORDER_MONO );
122     SetHighlightRange();
123 
124     if(m_xDictionary.is())
125         return;
126 
127     m_xDictionary = xDictionary;
128     m_pPropertyTypeNameListBox = pPropertyTypeNameListBox;
129 }
130 
131 void DictionaryList::save()
132 {
133     if( !m_xDictionary.is() )
134         return;
135 
136     Reference< linguistic2::XConversionPropertyType > xPropertyType( m_xDictionary, uno::UNO_QUERY );
137 
138     sal_Int32 nN;
139     DictionaryEntry* pE;
140 
141     for( nN = m_aToBeDeleted.size(); nN--; )
142     {
143         pE = m_aToBeDeleted[nN];
144         m_xDictionary->removeEntry( pE->m_aTerm, pE->m_aMapping );
145     }
146     for( nN = GetRowCount(); nN--; )
147     {
148         pE = getEntryOnPos( nN );
149         if(pE->m_bNewEntry)
150         {
151             try
152             {
153                 m_xDictionary->addEntry( pE->m_aTerm, pE->m_aMapping );
154                 xPropertyType->setPropertyType( pE->m_aTerm, pE->m_aMapping, pE->m_nConversionPropertyType );
155             }
156             catch( uno::Exception& )
157             {
158 
159 			}
160         }
161     }
162     Reference< util::XFlushable > xFlush( m_xDictionary, uno::UNO_QUERY );
163     if( xFlush.is() )
164         xFlush->flush();
165 }
166 
167 void DictionaryList::deleteAll()
168 {
169     sal_Int32 nN;
170     for( nN = GetRowCount(); nN--; )
171         deleteEntryOnPos( nN  );
172     for( nN = m_aToBeDeleted.size(); nN--; )
173     {
174         DictionaryEntry* pE = m_aToBeDeleted[nN];
175         delete pE;
176     }
177     m_aToBeDeleted.clear();
178 }
179 
180 void DictionaryList::refillFromDictionary( sal_Int32 nTextConversionOptions )
181 {
182     deleteAll();
183 
184     if(!m_xDictionary.is())
185         return;
186 
187     Sequence< rtl::OUString > aLeftList(  m_xDictionary->getConversionEntries( linguistic2::ConversionDirection_FROM_LEFT ) );
188     sal_Int32 nCount = aLeftList.getLength();
189 
190     Reference< linguistic2::XConversionPropertyType > xPropertyType( m_xDictionary, uno::UNO_QUERY );
191 
192     rtl::OUString aLeft, aRight;
193     sal_Int16 nConversionPropertyType;
194 
195     for(sal_Int32 nN=0; nN<nCount; nN++)
196     {
197         aLeft  = aLeftList[nN];
198         Sequence< rtl::OUString > aRightList( m_xDictionary->getConversions(
199             aLeft, 0, aLeft.getLength()
200             , linguistic2::ConversionDirection_FROM_LEFT, nTextConversionOptions ) );
201 
202         if(aRightList.getLength()!=1)
203         {
204             OSL_ASSERT("The Chinese Translation Dictionary should have exactly one Mapping for each term.");
205             continue;
206         }
207 
208         aRight = aRightList[0];
209         nConversionPropertyType = linguistic2::ConversionPropertyType::OTHER;
210         if(xPropertyType.is())
211             nConversionPropertyType = xPropertyType->getPropertyType(aLeft, aRight);
212 
213         DictionaryEntry* pEntry = new DictionaryEntry( aLeft, aRight, nConversionPropertyType );
214         SvLBoxEntry* pLBEntry = InsertEntry( makeTabString( *pEntry ) );
215 	    pLBEntry->SetUserData( pEntry );
216     }
217 
218     if( GetEntryCount() > 0 )
219         SelectRow( 0 );
220 }
221 
222 DictionaryEntry* DictionaryList::getFirstSelectedEntry() const
223 {
224     DictionaryEntry* pRet=0;
225     for( sal_Int32 nN=GetRowCount(); nN--; )
226     {
227         if( IsRowSelected( nN ) )
228         {
229             pRet = getEntryOnPos( nN );
230             break;
231         }
232     }
233     return pRet;
234 }
235 
236 DictionaryEntry* DictionaryList::getEntryOnPos( sal_Int32 nPos ) const
237 {
238     DictionaryEntry* pEntry=0;
239     SvLBoxEntry* pLBEntry = GetEntryOnPos( nPos );
240     if(pLBEntry)
241         pEntry = (DictionaryEntry*)pLBEntry->GetUserData();
242     return pEntry;
243 }
244 
245 DictionaryEntry* DictionaryList::getTermEntry( const rtl::OUString& rTerm ) const
246 {
247     DictionaryEntry* pE = 0;
248     for( sal_Int32 nN=GetRowCount(); nN--; )
249     {
250         pE = getEntryOnPos( nN );
251         if( pE && rTerm.equals( pE->m_aTerm ) )
252             return pE;
253     }
254     return 0;
255 }
256 
257 bool DictionaryList::hasTerm( const rtl::OUString& rTerm ) const
258 {
259     return getTermEntry(rTerm) !=0 ;
260 }
261 
262 void DictionaryList::addEntry( const rtl::OUString& rTerm, const rtl::OUString& rMapping
263                               , sal_Int16 nConversionPropertyType, sal_uIntPtr nPos )
264 {
265     if( hasTerm( rTerm ) )
266         return;
267 
268     DictionaryEntry* pEntry = new DictionaryEntry( rTerm, rMapping, nConversionPropertyType, sal_True );
269     SvLBoxEntry* pLBEntry = InsertEntryToColumn( makeTabString( *pEntry ), nPos );
270 	pLBEntry->SetUserData( pEntry );
271     SelectRow( GetEntryPos( pLBEntry ) );
272 }
273 
274 void DictionaryList::deleteEntryOnPos( sal_Int32 nPos  )
275 {
276     SvLBoxEntry* pLBEntry = GetEntryOnPos( nPos );
277     DictionaryEntry* pEntry = getEntryOnPos( nPos );
278     if( pLBEntry )
279         RemoveParentKeepChilds( pLBEntry );
280     if( pEntry )
281     {
282         if( pEntry->m_bNewEntry )
283             delete pEntry;
284         else
285             m_aToBeDeleted.push_back( pEntry );
286     }
287 }
288 
289 sal_uIntPtr DictionaryList::deleteEntries( const rtl::OUString& rTerm )
290 {
291     sal_uIntPtr nPos = LIST_APPEND;
292     for( sal_Int32 nN=GetRowCount(); nN--; )
293     {
294         DictionaryEntry* pCurEntry = getEntryOnPos( nN );
295         if( rTerm.equals( pCurEntry->m_aTerm ) )
296         {
297             nPos = nN;
298             SvLBoxEntry* pCurLBEntry = GetEntryOnPos( nN );
299             RemoveParentKeepChilds( pCurLBEntry );
300             if( pCurEntry->m_bNewEntry )
301                 delete pCurEntry;
302             else
303                 m_aToBeDeleted.push_back( pCurEntry );
304         }
305     }
306     return nPos;
307 }
308 
309 DictionaryList::~DictionaryList()
310 {
311 }
312 
313 void DictionaryList::activate( HeaderBar* pHeaderBar )
314 {
315     if(!m_pHeaderBar)
316     {
317         m_pHeaderBar = pHeaderBar;
318 
319         Point aPos = GetPosPixel();
320         Size  aSize = GetSizePixel();
321 	    Size aHeadSize = pHeaderBar->GetSizePixel();
322 
323         aPos.Y() += aHeadSize.Height();
324         SetPosSizePixel( aPos, Size( aSize.Width(), aSize.Height() - aHeadSize.Height() ) );
325 	    InitHeaderBar( pHeaderBar );
326     }
327     Show();
328 }
329 
330 HeaderBar* DictionaryList::createHeaderBar( const String& rColumn1, const String& rColumn2, const String& rColumn3
331                   , long nWidth1, long nWidth2, long nWidth3 )
332 {
333     HeaderBar* pHeaderBar = new HeaderBar( Control::GetParent(), WB_BUTTONSTYLE | WB_BOTTOMBORDER );
334     pHeaderBar->SetPosSizePixel( GetPosPixel(), pHeaderBar->CalcWindowSizePixel() );
335 
336 	HeaderBarItemBits nBits = HEADER_BAR_BITS;
337     pHeaderBar->InsertItem( 1, rColumn1, nWidth1, nBits | HIB_UPARROW );
338 	pHeaderBar->InsertItem( 2, rColumn2, nWidth2, nBits );
339 	pHeaderBar->InsertItem( 3, rColumn3, nWidth3, nBits );
340 
341     pHeaderBar->Show();
342     return pHeaderBar;
343 }
344 
345 void DictionaryList::Resize()
346 {
347 	SvHeaderTabListBox::Resize();
348     Size aBoxSize = GetOutputSizePixel();
349 
350 	if ( !aBoxSize.Width() )
351 		return;
352 
353    	Size aBarSize = m_pHeaderBar->GetSizePixel();
354     aBarSize.Width() = GetSizePixel().Width();
355 	m_pHeaderBar->SetSizePixel( aBarSize );
356 }
357 
358 void DictionaryList::sortByColumn( sal_uInt16 nSortColumnIndex, bool bSortAtoZ )
359 {
360     m_nSortColumnIndex=nSortColumnIndex;
361     if( nSortColumnIndex<3 )
362     {
363 		if(bSortAtoZ)
364 			GetModel()->SetSortMode(SortAscending);
365 		else
366 			GetModel()->SetSortMode(SortDescending);
367 
368 		GetModel()->SetCompareHdl( LINK( this, DictionaryList, CompareHdl));
369 		GetModel()->Resort();
370 	}
371 	else
372 		GetModel()->SetSortMode(SortNone);
373 }
374 
375 sal_uInt16 DictionaryList::getSortColumn() const
376 {
377     return m_nSortColumnIndex;
378 }
379 
380 IMPL_LINK( DictionaryList, CompareHdl, SvSortData*, pData )
381 {
382 	SvLBoxEntry* pLeft = (SvLBoxEntry*)(pData->pLeft );
383 	SvLBoxEntry* pRight = (SvLBoxEntry*)(pData->pRight );
384 	return (long) ColumnCompare(pLeft,pRight);
385 }
386 
387 StringCompare DictionaryList::ColumnCompare( SvLBoxEntry* pLeft, SvLBoxEntry* pRight )
388 {
389 	StringCompare eCompare=COMPARE_EQUAL;
390 
391 	SvLBoxItem* pLeftItem = getItemAtColumn( pLeft, m_nSortColumnIndex );
392 	SvLBoxItem* pRightItem = getItemAtColumn( pRight, m_nSortColumnIndex );
393 
394 	if(pLeftItem != NULL && pRightItem != NULL)
395 	{
396 		sal_uInt16 nLeftKind=pLeftItem->IsA();
397 		sal_uInt16 nRightKind=pRightItem->IsA();
398 
399 		if(nRightKind == SV_ITEM_ID_LBOXSTRING &&
400 			nLeftKind == SV_ITEM_ID_LBOXSTRING )
401 		{
402 			IntlWrapper aIntlWrapper( ::comphelper::getProcessServiceFactory(), Application::GetSettings().GetLocale() );
403 			const CollatorWrapper* pCollator = aIntlWrapper.getCaseCollator();
404 
405 			eCompare=(StringCompare)pCollator->compareString( ((SvLBoxString*)pLeftItem)->GetText(),
406 									((SvLBoxString*)pRightItem)->GetText());
407 
408 			if(eCompare==COMPARE_EQUAL)
409                 eCompare=COMPARE_LESS;
410 		}
411 	}
412 	return eCompare;
413 }
414 
415 SvLBoxItem* DictionaryList::getItemAtColumn( SvLBoxEntry* pEntry, sal_uInt16 nColumn ) const
416 {
417 	SvLBoxItem* pItem = NULL;
418     if( pEntry )
419 	{
420 		sal_uInt16 nCount = pEntry->ItemCount();
421 		nColumn++;
422 		if( nTreeFlags & TREEFLAG_CHKBTN )
423             nColumn++;
424        	if( nColumn < nCount )
425 			pItem = pEntry->GetItem( nColumn );
426 	}
427 	return pItem;
428 }
429 
430 //-----------------------------------------------------------------------------
431 //-----------------------------------------------------------------------------
432 //-----------------------------------------------------------------------------
433 
434 DictionaryEntry::DictionaryEntry( const rtl::OUString& rTerm, const rtl::OUString& rMapping
435                     , sal_Int16 nConversionPropertyType
436                     , sal_Bool bNewEntry )
437         : m_aTerm( rTerm )
438         , m_aMapping( rMapping )
439         , m_nConversionPropertyType( nConversionPropertyType )
440         , m_bNewEntry( bNewEntry )
441 {
442     if( m_nConversionPropertyType == 0 )
443         m_nConversionPropertyType = 1;
444 }
445 
446 DictionaryEntry::~DictionaryEntry()
447 {
448 }
449 
450 bool DictionaryEntry::operator==( const DictionaryEntry& rE ) const
451 {
452     return m_aTerm == rE.m_aTerm
453             && m_aMapping == rE.m_aMapping
454             && m_nConversionPropertyType == rE.m_nConversionPropertyType;
455 }
456 
457 //-----------------------------------------------------------------------------
458 //-----------------------------------------------------------------------------
459 //-----------------------------------------------------------------------------
460 
461 ChineseDictionaryDialog::ChineseDictionaryDialog( Window* pParent )
462     : ModalDialog( pParent, TextConversionDlgs_ResId( DLG_CHINESEDICTIONARY ) )
463     , m_nTextConversionOptions( i18n::TextConversionOption::NONE )
464     , m_aRB_To_Simplified( this, TextConversionDlgs_ResId( RB_TO_SIMPLIFIED ) )
465     , m_aRB_To_Traditional( this, TextConversionDlgs_ResId( RB_TO_TRADITIONAL ) )
466     , m_aCB_Reverse( this, TextConversionDlgs_ResId( CB_REVERSE ) )
467     , m_aFT_Term( this, TextConversionDlgs_ResId( FT_TERM ) )
468     , m_aED_Term( this, TextConversionDlgs_ResId( ED_TERM ) )
469     , m_aFT_Mapping( this, TextConversionDlgs_ResId( FT_MAPPING ) )
470     , m_aED_Mapping( this, TextConversionDlgs_ResId( ED_MAPPING ) )
471     , m_aFT_Property( this, TextConversionDlgs_ResId( FT_PROPERTY ) )
472     , m_aLB_Property( this, TextConversionDlgs_ResId( LB_PROPERTY ) )
473     , m_pHeaderBar( 0 )
474     , m_aCT_DictionaryToSimplified( this, TextConversionDlgs_ResId( CT_MAPPINGLIST ) )
475     , m_aCT_DictionaryToTraditional( this )
476     , m_aPB_Add( this, TextConversionDlgs_ResId( PB_ADD ) )
477     , m_aPB_Modify( this, TextConversionDlgs_ResId( PB_MODIFY ) )
478     , m_aPB_Delete( this, TextConversionDlgs_ResId( PB_DELETE ) )
479     , m_aFL_Bottomline( this, TextConversionDlgs_ResId( FL_BOTTOMLINE ) )
480     , m_aBP_OK( this, TextConversionDlgs_ResId( PB_OK ) )
481     , m_aBP_Cancel( this, TextConversionDlgs_ResId( PB_CANCEL ) )
482     , m_aBP_Help( this, TextConversionDlgs_ResId( PB_HELP ) )
483     , m_xContext( 0 )
484     , m_xFactory( 0 )
485 {
486     FreeResource();
487 
488     m_aRB_To_Simplified.SetHelpId( HID_SVX_CHINESE_DICTIONARY_RB_CONVERSION_TO_SIMPLIFIED );
489     m_aRB_To_Traditional.SetHelpId( HID_SVX_CHINESE_DICTIONARY_RB_CONVERSION_TO_TRADITIONAL );
490 
491     m_aCB_Reverse.SetHelpId( HID_SVX_CHINESE_DICTIONARY_CB_REVERSE );
492 
493     m_aCT_DictionaryToSimplified.SetHelpId( HID_SVX_CHINESE_DICTIONARY_LB_TO_SIMPLIFIED );
494     m_aCT_DictionaryToTraditional.SetHelpId( HID_SVX_CHINESE_DICTIONARY_LB_TO_TRADITIONAL );
495 
496     SvtLinguConfig	aLngCfg;
497     sal_Bool bValue = sal_Bool();
498     Any aAny( aLngCfg.GetProperty( rtl::OUString::createFromAscii( UPN_IS_REVERSE_MAPPING ) ) );
499 	if( aAny >>= bValue )
500 	    m_aCB_Reverse.Check( bValue );
501 
502     m_aLB_Property.SetDropDownLineCount( m_aLB_Property.GetEntryCount() );
503     m_aLB_Property.SelectEntryPos(0);
504 
505     Reference< linguistic2::XConversionDictionary > xDictionary_To_Simplified(0);
506     Reference< linguistic2::XConversionDictionary > xDictionary_To_Traditional(0);
507     //get dictionaries
508     {
509         if(!m_xContext.is())
510             m_xContext = Reference< XComponentContext >( ::cppu::defaultBootstrap_InitialComponentContext() );
511         if(m_xContext.is())
512             m_xFactory = Reference< lang::XMultiComponentFactory >( m_xContext->getServiceManager() );
513         if(m_xFactory.is())
514         {
515             Reference< linguistic2::XConversionDictionaryList > xDictionaryList(
516                                 m_xFactory->createInstanceWithContext(
517                                     rtl::OUString::createFromAscii("com.sun.star.linguistic2.ConversionDictionaryList")
518                                     , m_xContext), uno::UNO_QUERY);
519             if( xDictionaryList.is() )
520             {
521                 Reference< container::XNameContainer > xContainer( xDictionaryList->getDictionaryContainer() );
522                 if(xContainer.is())
523                 {
524                     try
525                     {
526                         rtl::OUString aNameTo_Simplified( rtl::OUString::createFromAscii("ChineseT2S") );
527                         rtl::OUString aNameTo_Traditional( rtl::OUString::createFromAscii("ChineseS2T") );
528                         lang::Locale aLocale;
529                         aLocale.Language = rtl::OUString::createFromAscii("zh");
530 
531                         if( xContainer->hasByName( aNameTo_Simplified ) )
532 	                        xDictionary_To_Simplified = Reference< linguistic2::XConversionDictionary >(
533                                     xContainer->getByName( aNameTo_Simplified ), UNO_QUERY );
534                         else
535                         {
536                             aLocale.Country = rtl::OUString::createFromAscii("TW");
537                             xDictionary_To_Simplified = Reference< linguistic2::XConversionDictionary >(
538                                     xDictionaryList->addNewDictionary( aNameTo_Simplified
539                                     , aLocale, linguistic2::ConversionDictionaryType::SCHINESE_TCHINESE
540                                         ), UNO_QUERY );
541                         }
542 						if (xDictionary_To_Simplified.is())
543 							xDictionary_To_Simplified->setActive( sal_True );
544 
545 
546                         if( xContainer->hasByName( aNameTo_Traditional ) )
547 	                        xDictionary_To_Traditional = Reference< linguistic2::XConversionDictionary >(
548                                     xContainer->getByName( aNameTo_Traditional ), UNO_QUERY );
549                         else
550                         {
551                             aLocale.Country = rtl::OUString::createFromAscii("CN");
552                             xDictionary_To_Traditional = Reference< linguistic2::XConversionDictionary >(
553                                     xDictionaryList->addNewDictionary( aNameTo_Traditional
554                                     , aLocale, linguistic2::ConversionDictionaryType::SCHINESE_TCHINESE
555                                         ), UNO_QUERY );
556                         }
557 						if (xDictionary_To_Traditional.is())
558 							xDictionary_To_Traditional->setActive( sal_True );
559 
560                     }
561                     catch( uno::Exception& )
562                     {
563                     }
564                 }
565             }
566         }
567     }
568 
569     //init HeaderBar and set tabs
570     {
571         String aColumn1( OutputDevice::GetNonMnemonicString( m_aFT_Term.GetText() ) );
572         String aColumn2( OutputDevice::GetNonMnemonicString( m_aFT_Mapping.GetText() ) );
573         String aColumn3( OutputDevice::GetNonMnemonicString( m_aFT_Property.GetText() ) );
574 
575         long nWidth1 = m_aED_Mapping.GetPosPixel().X() - m_aED_Term.GetPosPixel().X();
576         long nWidth2 = m_aLB_Property.GetPosPixel().X() - m_aED_Mapping.GetPosPixel().X();
577         long nWidth3 = m_aLB_Property.GetSizePixel().Width();
578 
579         m_pHeaderBar = m_aCT_DictionaryToSimplified.createHeaderBar( aColumn1, aColumn2, aColumn3, nWidth1, nWidth2, nWidth3 );
580         if(m_pHeaderBar)
581             m_pHeaderBar->SetHelpId( HID_SVX_CHINESE_DICTIONARY_LB_HEADER );
582 
583         long pTabs[] = { 3, 0, nWidth1, nWidth1 + nWidth2 };
584 	    m_aCT_DictionaryToSimplified.SetTabs( &pTabs[0], MAP_PIXEL );
585         m_aCT_DictionaryToTraditional.SetTabs( &pTabs[0], MAP_PIXEL );
586     }
587 
588     //init dictionary controls
589     m_aCT_DictionaryToTraditional.SetPosPixel( m_aCT_DictionaryToSimplified.GetPosPixel() );
590     m_aCT_DictionaryToTraditional.SetSizePixel( m_aCT_DictionaryToSimplified.GetSizePixel() );
591 
592     m_aCT_DictionaryToSimplified.initDictionaryControl( xDictionary_To_Simplified, &m_aLB_Property );
593     m_aCT_DictionaryToTraditional.initDictionaryControl( xDictionary_To_Traditional, &m_aLB_Property );
594 
595     //
596     updateAfterDirectionChange();
597 
598     //set hdl
599     if(m_pHeaderBar)
600         m_pHeaderBar->SetSelectHdl( LINK( this, ChineseDictionaryDialog, HeaderBarClick ) );
601 
602     m_aED_Term.SetModifyHdl( LINK( this, ChineseDictionaryDialog, EditFieldsHdl ) );
603     m_aED_Mapping.SetModifyHdl( LINK( this, ChineseDictionaryDialog, EditFieldsHdl ) );
604     m_aLB_Property.SetSelectHdl( LINK( this, ChineseDictionaryDialog, EditFieldsHdl ) );
605 
606     m_aRB_To_Simplified.SetClickHdl( LINK( this, ChineseDictionaryDialog, DirectionHdl ) );
607     m_aRB_To_Traditional.SetClickHdl( LINK( this, ChineseDictionaryDialog, DirectionHdl ) );
608 
609     m_aCT_DictionaryToSimplified.SetSelectHdl( LINK( this, ChineseDictionaryDialog, MappingSelectHdl ));
610     m_aCT_DictionaryToTraditional.SetSelectHdl( LINK( this, ChineseDictionaryDialog, MappingSelectHdl ));
611 
612     m_aPB_Add.SetClickHdl( LINK( this, ChineseDictionaryDialog, AddHdl ) );
613     m_aPB_Modify.SetClickHdl( LINK( this, ChineseDictionaryDialog, ModifyHdl ) );
614     m_aPB_Delete.SetClickHdl( LINK( this, ChineseDictionaryDialog, DeleteHdl ) );
615 }
616 
617 ChineseDictionaryDialog::~ChineseDictionaryDialog()
618 {
619     m_xContext=0;
620     m_xFactory=0;
621     delete m_pHeaderBar;
622 }
623 
624 void ChineseDictionaryDialog::setDirectionAndTextConversionOptions( bool bDirectionToSimplified, sal_Int32 nTextConversionOptions /*i18n::TextConversionOption*/ )
625 {
626     if( bDirectionToSimplified == bool(m_aRB_To_Simplified.IsChecked())
627         && nTextConversionOptions == m_nTextConversionOptions )
628         return;
629 
630     m_nTextConversionOptions = nTextConversionOptions;
631 
632     if( bDirectionToSimplified )
633         m_aRB_To_Simplified.Check();
634     else
635         m_aRB_To_Traditional.Check();
636     updateAfterDirectionChange();
637 }
638 
639 IMPL_LINK( ChineseDictionaryDialog, DirectionHdl, void*, EMPTYARG )
640 {
641     updateAfterDirectionChange();
642     return 0;
643 }
644 
645 void ChineseDictionaryDialog::updateAfterDirectionChange()
646 {
647     Reference< linguistic2::XConversionDictionary > xDictionary(0);
648 
649     if( m_aRB_To_Simplified.IsChecked() )
650     {
651         m_aCT_DictionaryToSimplified.activate( m_pHeaderBar );
652         m_aCT_DictionaryToTraditional.Hide();
653         xDictionary = m_aCT_DictionaryToSimplified.m_xDictionary;
654     }
655     else
656     {
657         m_aCT_DictionaryToTraditional.activate( m_pHeaderBar );
658         m_aCT_DictionaryToSimplified.Hide();
659         xDictionary = m_aCT_DictionaryToTraditional.m_xDictionary;
660     }
661 
662     updateButtons();
663 }
664 
665 IMPL_LINK( ChineseDictionaryDialog, EditFieldsHdl, Control*, EMPTYARG )
666 {
667     updateButtons();
668     return 0;
669 }
670 IMPL_LINK( ChineseDictionaryDialog, MappingSelectHdl, void*, EMPTYARG )
671 {
672     DictionaryEntry* pE = getActiveDictionary().getFirstSelectedEntry();
673     if(pE)
674     {
675         m_aED_Term.SetText( pE->m_aTerm );
676         m_aED_Mapping.SetText( pE->m_aMapping );
677         sal_Int16 nPos = pE->m_nConversionPropertyType-1;
678         if( nPos<0 || nPos>=m_aLB_Property.GetEntryCount() )
679             nPos=0;
680         if( m_aLB_Property.GetEntryCount() )
681             m_aLB_Property.SelectEntryPos(nPos);
682     }
683 
684     updateButtons();
685     return 0;
686 }
687 
688 bool ChineseDictionaryDialog::isEditFieldsHaveContent() const
689 {
690     return m_aED_Term.GetText().Len() && m_aED_Mapping.GetText().Len();
691 }
692 
693 bool ChineseDictionaryDialog::isEditFieldsContentEqualsSelectedListContent() const
694 {
695     DictionaryEntry* pE = getActiveDictionary().getFirstSelectedEntry();
696     if( pE )
697     {
698         if( pE->m_aTerm != rtl::OUString( m_aED_Term.GetText() ) )
699             return false;
700         if( pE->m_aMapping != rtl::OUString( m_aED_Mapping.GetText() ) )
701             return false;
702         if( pE->m_nConversionPropertyType != m_aLB_Property.GetSelectEntryPos()+1 )
703             return false;
704         return true;
705     }
706     return false;
707 }
708 
709 const DictionaryList& ChineseDictionaryDialog::getActiveDictionary() const
710 {
711     if( m_aRB_To_Traditional.IsChecked() )
712         return m_aCT_DictionaryToTraditional;
713     return m_aCT_DictionaryToSimplified;
714 }
715 
716 DictionaryList& ChineseDictionaryDialog::getActiveDictionary()
717 {
718     if( m_aRB_To_Traditional.IsChecked() )
719         return m_aCT_DictionaryToTraditional;
720     return m_aCT_DictionaryToSimplified;
721 }
722 
723 const DictionaryList& ChineseDictionaryDialog::getReverseDictionary() const
724 {
725     if( m_aRB_To_Traditional.IsChecked() )
726         return m_aCT_DictionaryToSimplified;
727     return m_aCT_DictionaryToTraditional;
728 }
729 
730 DictionaryList& ChineseDictionaryDialog::getReverseDictionary()
731 {
732     if( m_aRB_To_Traditional.IsChecked() )
733         return m_aCT_DictionaryToSimplified;
734     return m_aCT_DictionaryToTraditional;
735 }
736 
737 void ChineseDictionaryDialog::updateButtons()
738 {
739     bool bAdd = isEditFieldsHaveContent() && !getActiveDictionary().hasTerm( m_aED_Term.GetText() );
740     m_aPB_Add.Enable( bAdd );
741 
742     m_aPB_Delete.Enable( !bAdd && getActiveDictionary().GetSelectedRowCount()>0 );
743 
744 //    DictionaryEntry* pFirstSelectedEntry = getActiveDictionary().getFirstSelectedEntry();
745 
746     bool bModify = false;
747     {
748         DictionaryEntry* pFirstSelectedEntry = getActiveDictionary().getFirstSelectedEntry();
749         bModify = !bAdd && getActiveDictionary().GetSelectedRowCount()==1
750                         && pFirstSelectedEntry && pFirstSelectedEntry->m_aTerm.equals( m_aED_Term.GetText() );
751         if( bModify && isEditFieldsContentEqualsSelectedListContent() )
752             bModify = false;
753     }
754     m_aPB_Modify.Enable( bModify );
755 }
756 
757 IMPL_LINK( ChineseDictionaryDialog, AddHdl, void*, EMPTYARG )
758 {
759     if( !isEditFieldsHaveContent() )
760         return 0;
761 
762     sal_Int16 nConversionPropertyType = m_aLB_Property.GetSelectEntryPos()+1;
763 
764     getActiveDictionary().addEntry( m_aED_Term.GetText(), m_aED_Mapping.GetText(), nConversionPropertyType );
765 
766     if( m_aCB_Reverse.IsChecked() )
767     {
768         getReverseDictionary().deleteEntries( m_aED_Mapping.GetText() );
769         getReverseDictionary().addEntry( m_aED_Mapping.GetText(), m_aED_Term.GetText(), nConversionPropertyType );
770     }
771 
772     updateButtons();
773     return 0;
774 }
775 IMPL_LINK( ChineseDictionaryDialog, ModifyHdl, void*, EMPTYARG )
776 {
777     rtl::OUString aTerm( m_aED_Term.GetText() );
778     rtl::OUString aMapping( m_aED_Mapping.GetText() );
779     sal_Int16 nConversionPropertyType = m_aLB_Property.GetSelectEntryPos()+1;
780 
781     DictionaryList& rActive  = getActiveDictionary();
782     DictionaryList& rReverse = getReverseDictionary();
783 
784     DictionaryEntry* pE = rActive.getFirstSelectedEntry();
785     if( pE->m_aTerm != aTerm )
786         return 0;
787 
788     if( pE )
789     {
790         if( pE->m_aMapping != aMapping || pE->m_nConversionPropertyType != nConversionPropertyType )
791         {
792             if( m_aCB_Reverse.IsChecked() )
793             {
794                 sal_uIntPtr nPos = rReverse.deleteEntries( pE->m_aMapping );
795                 nPos = rReverse.deleteEntries( aMapping );
796                 rReverse.addEntry( aMapping, aTerm, nConversionPropertyType, nPos );
797             }
798 
799             sal_uIntPtr nPos = rActive.deleteEntries( aTerm );
800             rActive.addEntry( aTerm, aMapping, nConversionPropertyType, nPos );
801         }
802     }
803 
804     updateButtons();
805     return 0;
806 }
807 
808 IMPL_LINK( ChineseDictionaryDialog, DeleteHdl, void*, EMPTYARG )
809 {
810     DictionaryList& rActive  = getActiveDictionary();
811     DictionaryList& rReverse = getReverseDictionary();
812 
813     if( rActive.GetSelectedRowCount()>0)
814     {
815         DictionaryEntry* pEntry;
816 
817         rtl::OUString aMapping;
818         for( sal_Int32 nN=rActive.GetRowCount(); nN--; )
819         {
820             if( rActive.IsRowSelected( nN ) )
821             {
822                 pEntry = rActive.getEntryOnPos( nN );
823                 if(pEntry)
824                 {
825                     aMapping = pEntry->m_aMapping;
826                     rActive.deleteEntryOnPos( nN );
827                     if( m_aCB_Reverse.IsChecked() )
828                         rReverse.deleteEntries( aMapping  );
829                 }
830                 break;
831             }
832         }
833     }
834 
835     updateButtons();
836     return 0;
837 }
838 
839 short ChineseDictionaryDialog::Execute()
840 {
841     sal_Int32 nTextConversionOptions = m_nTextConversionOptions;
842     if(m_nTextConversionOptions | i18n::TextConversionOption::USE_CHARACTER_VARIANTS )
843         nTextConversionOptions = nTextConversionOptions^i18n::TextConversionOption::USE_CHARACTER_VARIANTS ;
844 
845     m_aCT_DictionaryToSimplified.refillFromDictionary( nTextConversionOptions );
846     m_aCT_DictionaryToTraditional.refillFromDictionary( m_nTextConversionOptions );
847 
848     short nRet = ModalDialog::Execute();
849 
850     if( nRet == RET_OK )
851     {
852         //save settings to configuration
853         SvtLinguConfig	aLngCfg;
854         Any aAny;
855 	    aAny <<= sal_Bool( !!m_aCB_Reverse.IsChecked() );
856 	    aLngCfg.SetProperty( rtl::OUString::createFromAscii( UPN_IS_REVERSE_MAPPING ), aAny );
857 
858         m_aCT_DictionaryToSimplified.save();
859         m_aCT_DictionaryToTraditional.save();
860     }
861 
862     m_aCT_DictionaryToSimplified.deleteAll();
863     m_aCT_DictionaryToTraditional.deleteAll();
864 
865     return nRet;
866 }
867 
868 IMPL_LINK( ChineseDictionaryDialog, HeaderBarClick, void*, EMPTYARG )
869 {
870 	if(m_pHeaderBar)
871     {
872 	    sal_uInt16 nId = m_pHeaderBar->GetCurItemId();
873         HeaderBarItemBits nBits = m_pHeaderBar->GetItemBits(nId);
874 	    if( nBits & HIB_CLICKABLE )
875 	    {
876             //set new arrow positions in headerbar
877             m_pHeaderBar->SetItemBits( getActiveDictionary().getSortColumn()+1, HEADER_BAR_BITS );
878             if( nBits & HIB_UPARROW )
879                 m_pHeaderBar->SetItemBits( nId, HEADER_BAR_BITS | HIB_DOWNARROW );
880             else
881                 m_pHeaderBar->SetItemBits( nId, HEADER_BAR_BITS | HIB_UPARROW );
882 
883             //sort lists
884             nBits = m_pHeaderBar->GetItemBits(nId);
885             bool bSortAtoZ = nBits & HIB_UPARROW;
886             getActiveDictionary().sortByColumn(nId-1,bSortAtoZ);
887             getReverseDictionary().sortByColumn(nId-1,bSortAtoZ);
888 	    }
889     }
890 	return 0;
891 }
892 
893 //.............................................................................
894 } //end namespace
895 //.............................................................................
896