xref: /AOO41X/main/cui/source/dialogs/hangulhanjadlg.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
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_cui.hxx"
30 
31 #include "hangulhanjadlg.hxx"
32 #include "hangulhanjadlg.hrc"
33 #include "commonlingui.hxx"
34 #include <dialmgr.hxx>
35 
36 #include <cuires.hrc>
37 #include "helpid.hrc"
38 
39 #include <algorithm>
40 #include <tools/urlobj.hxx>
41 #include <vcl/controllayout.hxx>
42 #include <vcl/msgbox.hxx>
43 #include <unotools/lingucfg.hxx>
44 #include <unotools/linguprops.hxx>
45 #include <com/sun/star/linguistic2/ConversionDictionaryType.hpp>
46 #include <com/sun/star/linguistic2/ConversionDirection.hdl>
47 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
48 #include <com/sun/star/i18n/TextConversionOption.hdl>
49 #include <com/sun/star/util/XFlushable.hpp>
50 
51 #include <comphelper/processfactory.hxx>
52 
53 #define HHC editeng::HangulHanjaConversion
54 #define LINE_CNT        static_cast< sal_uInt16 >(2)
55 
56 //.............................................................................
57 namespace svx
58 {
59 //.............................................................................
60 /*
61 	using HangulHanjaConversion::eSimpleConversion;
62 	using HangulHanjaConversion::eHangulBracketed;
63 	using HangulHanjaConversion::eHanjaBracketed;
64 	using HangulHanjaConversion::eRubyHanjaAbove;
65 	using HangulHanjaConversion::eRubyHanjaBelow;
66 	using HangulHanjaConversion::eRubyHangulAbove;
67 	using HangulHanjaConversion::eRubyHangulBelow;
68 */
69 	using namespace ::com::sun::star;
70 	using namespace ::com::sun::star::uno;
71 	using namespace ::com::sun::star::linguistic2;
72 	using namespace ::com::sun::star::lang;
73 	using namespace ::com::sun::star::container;
74 	using ::rtl::OUString;
75 
76 	//-------------------------------------------------------------------------
77 	namespace
78 	{
79 		class FontSwitch
80 		{
81 		private:
82 			OutputDevice& m_rDev;
83 
84 		public:
85 			inline FontSwitch( OutputDevice& _rDev, const Font& _rTemporaryFont )
86 				:m_rDev( _rDev )
87 			{
88 				m_rDev.Push( PUSH_FONT );
89 				m_rDev.SetFont( _rTemporaryFont );
90 			}
91 			inline ~FontSwitch( )
92 			{
93 				m_rDev.Pop( );
94 			}
95 		};
96 	}
97 
98 	//=========================================================================
99 	//= PseudoRubyText
100 	//=========================================================================
101 	/** a class which allows to draw two texts in a pseudo-ruby way (which basically
102 		means one text above or below the other, and a little bit smaller)
103 	*/
104 	class PseudoRubyText
105 	{
106 	public:
107 		enum RubyPosition
108 		{
109 			eAbove, eBelow
110 		};
111 
112 	protected:
113 		const String		m_sPrimaryText;
114 		const String		m_sSecondaryText;
115 		const RubyPosition	m_ePosition;
116 
117 	public:
118 		PseudoRubyText( const String& _rPrimary, const String& _rSecondary, const RubyPosition _ePosition );
119 
120 	public:
121 		void Paint( OutputDevice& _rDevice, const Rectangle& _rRect, sal_uInt16 _nTextStyle,
122 			Rectangle* _pPrimaryLocation = NULL, Rectangle* _pSecondaryLocation = NULL,
123 			::vcl::ControlLayoutData* _pLayoutData = NULL );
124 	};
125 
126 	//-------------------------------------------------------------------------
127 	PseudoRubyText::PseudoRubyText( const String& _rPrimary, const String& _rSecondary, const RubyPosition _ePosition )
128 		:m_sPrimaryText( _rPrimary )
129 		,m_sSecondaryText( _rSecondary )
130 		,m_ePosition( _ePosition )
131 	{
132 	}
133 
134 	//-------------------------------------------------------------------------
135 	void PseudoRubyText::Paint( OutputDevice& _rDevice, const Rectangle& _rRect, sal_uInt16 _nTextStyle,
136 		Rectangle* _pPrimaryLocation, Rectangle* _pSecondaryLocation, ::vcl::ControlLayoutData* _pLayoutData )
137 	{
138 		bool			bLayoutOnly	 = NULL != _pLayoutData;
139 		MetricVector*	pTextMetrics = bLayoutOnly ? &_pLayoutData->m_aUnicodeBoundRects : NULL;
140 		String*			pDisplayText = bLayoutOnly ? &_pLayoutData->m_aDisplayText		 : NULL;
141 
142 		Size aPlaygroundSize( _rRect.GetSize() );
143 
144 		// the font for the secondary text:
145 		Font aSmallerFont( _rDevice.GetFont() );
146 		// heuristic: 80% of the original size
147 		aSmallerFont.SetHeight( (long)( 0.8 * aSmallerFont.GetHeight() ) );
148 
149 		// let's calculate the size of our two texts
150 		Rectangle aPrimaryRect = _rDevice.GetTextRect( _rRect, m_sPrimaryText, _nTextStyle );
151 		Rectangle aSecondaryRect;
152 		{
153 			FontSwitch aFontRestore( _rDevice, aSmallerFont );
154 			aSecondaryRect = _rDevice.GetTextRect( _rRect, m_sSecondaryText, _nTextStyle );
155 		}
156 
157 		// position these rectangles properly
158 		// x-axis:
159 		sal_Int32 nCombinedWidth = ::std::max( aSecondaryRect.GetWidth(), aPrimaryRect.GetWidth() );
160 			// the rectangle where both texts will reside is as high as possible, and as wide as the
161 			// widest of both text rects
162 		aPrimaryRect.Left() = aSecondaryRect.Left() = _rRect.Left();
163 		aPrimaryRect.Right() = aSecondaryRect.Right() = _rRect.Left() + nCombinedWidth;
164 		if ( TEXT_DRAW_RIGHT & _nTextStyle )
165 		{
166 			// move the rectangles to the right
167 			aPrimaryRect.Move( aPlaygroundSize.Width() - nCombinedWidth, 0 );
168 			aSecondaryRect.Move( aPlaygroundSize.Width() - nCombinedWidth, 0 );
169 		}
170 		else if ( TEXT_DRAW_CENTER & _nTextStyle )
171 		{
172 			// center the rectangles
173 			aPrimaryRect.Move( ( aPlaygroundSize.Width() - nCombinedWidth ) / 2, 0 );
174 			aSecondaryRect.Move( ( aPlaygroundSize.Width() - nCombinedWidth ) / 2, 0 );
175 		}
176 
177 		// y-axis:
178 		sal_Int32 nCombinedHeight = aPrimaryRect.GetHeight() + aSecondaryRect.GetHeight();
179 		// align to the top, for the moment
180 		aPrimaryRect.Move( 0, _rRect.Top() - aPrimaryRect.Top() );
181 		aSecondaryRect.Move( 0, aPrimaryRect.Top() + aPrimaryRect.GetHeight() - aSecondaryRect.Top() );
182 		if ( TEXT_DRAW_BOTTOM & _nTextStyle )
183 		{
184 			// move the rects to the bottom
185 			aPrimaryRect.Move( 0, aPlaygroundSize.Height() - nCombinedHeight );
186 			aSecondaryRect.Move( 0, aPlaygroundSize.Height() - nCombinedHeight );
187 		}
188 		else if ( TEXT_DRAW_VCENTER & _nTextStyle )
189 		{
190 			// move the rects to the bottom
191 			aPrimaryRect.Move( 0, ( aPlaygroundSize.Height() - nCombinedHeight ) / 2 );
192 			aSecondaryRect.Move( 0, ( aPlaygroundSize.Height() - nCombinedHeight ) / 2 );
193 		}
194 
195 		// 'til here, everything we did assumes that the secondary text is painted _below_ the primary
196 		// text. If this isn't the case, we need to correct the rectangles
197 		if ( eAbove == m_ePosition )
198 		{
199 			sal_Int32 nVertDistance = aSecondaryRect.Top() - aPrimaryRect.Top();
200 			aSecondaryRect.Move( 0, -nVertDistance );
201 			aPrimaryRect.Move( 0, nCombinedHeight - nVertDistance );
202 		}
203 
204 		// now draw the texts
205 		// as we already calculated the precise rectangles for the texts, we don't want to
206 		// use the alignment flags given - within it's rect, every text is centered
207 		sal_uInt16 nDrawTextStyle( _nTextStyle );
208 		nDrawTextStyle &= ~( TEXT_DRAW_RIGHT | TEXT_DRAW_LEFT | TEXT_DRAW_BOTTOM | TEXT_DRAW_TOP );
209 		nDrawTextStyle |= TEXT_DRAW_CENTER | TEXT_DRAW_VCENTER;
210 
211 		_rDevice.DrawText( aPrimaryRect, m_sPrimaryText, nDrawTextStyle, pTextMetrics, pDisplayText );
212 		{
213 			FontSwitch aFontRestore( _rDevice, aSmallerFont );
214 			_rDevice.DrawText( aSecondaryRect, m_sSecondaryText, nDrawTextStyle, pTextMetrics, pDisplayText );
215 		}
216 
217 		// outta here
218 		if ( _pPrimaryLocation )
219 			*_pPrimaryLocation = aPrimaryRect;
220 		if ( _pSecondaryLocation )
221 			*_pSecondaryLocation = aSecondaryRect;
222 	}
223 
224 	//=========================================================================
225 	//= RubyRadioButton
226 	//=========================================================================
227 	class RubyRadioButton	:public RadioButton
228 							,protected PseudoRubyText
229 	{
230 		using svx::PseudoRubyText::Paint;
231 
232 	public:
233 		RubyRadioButton(
234 			Window* _pParent,
235 			const ResId& _rId,			// the text in the resource will be taken as primary text
236 			const String& _rSecondary,	// this will be the secondary text which will be printed somewhat smaller
237 			const PseudoRubyText::RubyPosition _ePosition );
238 
239 	protected:
240 		virtual void	Paint( const Rectangle& _rRect );
241 	};
242 
243 	//-------------------------------------------------------------------------
244 	RubyRadioButton::RubyRadioButton( Window* _pParent, const ResId& _rId,
245 		const String& _rSecondary, const PseudoRubyText::RubyPosition _ePosition )
246 		:RadioButton( _pParent, _rId )
247 		,PseudoRubyText( RadioButton::GetText(), _rSecondary, _ePosition )
248 	{
249 	}
250 
251 	//-------------------------------------------------------------------------
252 	void RubyRadioButton::Paint( const Rectangle& )
253 	{
254 		HideFocus();
255 
256 		// calculate the size of the radio image - we're to paint our text _after_ this image
257 		DBG_ASSERT( !GetModeRadioImage(), "RubyRadioButton::Paint: images not supported!" );
258 		Size aImageSize = GetRadioImage( GetSettings(), 0 ).GetSizePixel();
259 		aImageSize.Width()  = CalcZoom( aImageSize.Width() );
260 		aImageSize.Height()  = CalcZoom( aImageSize.Height() );
261 
262 		Rectangle aOverallRect( Point( 0, 0 ), GetOutputSizePixel() );
263 		aOverallRect.Left() += aImageSize.Width() + 4;	// 4 is the separator between the image and the text
264 		// inflate the rect a little bit (because the VCL radio button does the same)
265 		Rectangle aTextRect( aOverallRect );
266 		++aTextRect.Left(); --aTextRect.Right();
267 		++aTextRect.Top(); --aTextRect.Bottom();
268 
269 		// calculate the text flags for the painting
270 		sal_uInt16 nTextStyle = TEXT_DRAW_MNEMONIC;
271 		WinBits nStyle = GetStyle( );
272 
273 		// the horizontal alignment
274 		if ( nStyle & WB_RIGHT )
275 			nTextStyle |= TEXT_DRAW_RIGHT;
276 		else if ( nStyle & WB_CENTER )
277 			nTextStyle |= TEXT_DRAW_CENTER;
278 		else
279 			nTextStyle |= TEXT_DRAW_LEFT;
280 		// the vertical alignment
281 		if ( nStyle & WB_BOTTOM )
282 			nTextStyle |= TEXT_DRAW_BOTTOM;
283 		else if ( nStyle & WB_VCENTER )
284 			nTextStyle |= TEXT_DRAW_VCENTER;
285 		else
286 			nTextStyle |= TEXT_DRAW_TOP;
287 		// mnemonics
288 		if ( 0 == ( nStyle & WB_NOLABEL ) )
289 			nTextStyle |= TEXT_DRAW_MNEMONIC;
290 
291 		// paint the ruby text
292 		Rectangle aPrimaryTextLocation, aSecondaryTextLocation;
293 		PseudoRubyText::Paint( *this, aTextRect, nTextStyle, &aPrimaryTextLocation, &aSecondaryTextLocation );
294 
295 		// the focus rectangle is to be painted around both texts
296 		Rectangle aCombinedRect( aPrimaryTextLocation );
297 		aCombinedRect.Union( aSecondaryTextLocation );
298 		SetFocusRect( aCombinedRect );
299 
300 		// let the base class paint the radio button
301 		// for this, give it the proper location to paint the image (vertically centered, relative to our text)
302 		Rectangle aImageLocation( Point( 0, 0 ), aImageSize );
303 		sal_Int32 nTextHeight = aSecondaryTextLocation.Bottom() - aPrimaryTextLocation.Top();
304 		aImageLocation.Top() = aPrimaryTextLocation.Top() + ( nTextHeight - aImageSize.Height() ) / 2;
305 		aImageLocation.Bottom() = aImageLocation.Top() + aImageSize.Height();
306 		SetStateRect( aImageLocation );
307 		DrawRadioButtonState( );
308 
309 		// mouse clicks should be recognized in a rect which is one pixel larger in each direction, plus
310 		// includes the image
311 		aCombinedRect.Left() = aImageLocation.Left(); ++aCombinedRect.Right();
312 		--aCombinedRect.Top(); ++aCombinedRect.Bottom();
313 		SetMouseRect( aCombinedRect );
314 
315 		// paint the focus rect, if necessary
316 		if ( HasFocus() )
317 			ShowFocus( aTextRect );
318 	}
319 
320     //=========================================================================
321 	//= SuggestionSet
322 	//=========================================================================
323 	//-------------------------------------------------------------------------
324 
325     SuggestionSet::SuggestionSet( Window* pParent )
326                     : ValueSet( pParent, pParent->GetStyle() | WB_BORDER )
327 
328     {
329     }
330 
331     SuggestionSet::~SuggestionSet()
332     {
333         ClearSet();
334     }
335 
336     void SuggestionSet::UserDraw( const UserDrawEvent& rUDEvt )
337     {
338         OutputDevice*  pDev = rUDEvt.GetDevice();
339         Rectangle aRect = rUDEvt.GetRect();
340         sal_uInt16  nItemId = rUDEvt.GetItemId();
341 
342         String sText = *static_cast< String* >( GetItemData( nItemId ) );
343         pDev->DrawText( aRect, sText, TEXT_DRAW_CENTER | TEXT_DRAW_VCENTER );
344     }
345 
346     void SuggestionSet::ClearSet()
347     {
348         sal_uInt16 i, nCount = GetItemCount();
349         for ( i = 0; i < nCount; ++i )
350             delete static_cast< String* >( GetItemData(i) );
351         Clear();
352     }
353 
354     //=========================================================================
355 	//= SuggestionDisplay
356 	//=========================================================================
357 	//-------------------------------------------------------------------------
358 
359     SuggestionDisplay::SuggestionDisplay( Window* pParent, const ResId& rResId )
360         : Control( pParent, rResId )
361         , m_bDisplayListBox(true)
362         , m_aValueSet(this)
363         , m_aListBox(this,GetStyle() | WB_BORDER )
364         , m_bInSelectionUpdate(false)
365     {
366         m_aValueSet.SetSelectHdl( LINK( this, SuggestionDisplay, SelectSuggestionHdl ) );
367         m_aListBox.SetSelectHdl( LINK( this, SuggestionDisplay, SelectSuggestionHdl ) );
368 
369         m_aValueSet.SetLineCount( LINE_CNT );
370         m_aValueSet.SetStyle( m_aValueSet.GetStyle() | WB_ITEMBORDER | WB_FLATVALUESET | WB_VSCROLL );
371         m_aValueSet.SetBorderStyle( WINDOW_BORDER_MONO );
372         String aOneCharacter(RTL_CONSTASCII_STRINGPARAM("AU"));
373         long nItemWidth = 2*GetTextWidth( aOneCharacter );
374         m_aValueSet.SetItemWidth( nItemWidth );
375 
376         Point aPos(0,0);
377         Size aSize(GetSizePixel());
378         m_aValueSet.SetSizePixel(aSize);
379         m_aListBox.SetSizePixel(aSize);
380 
381         implUpdateDisplay();
382     }
383 
384     SuggestionDisplay::~SuggestionDisplay()
385     {
386     }
387 
388     void SuggestionDisplay::implUpdateDisplay()
389     {
390         bool bShowBox = IsVisible() && m_bDisplayListBox;
391         bool bShowSet = IsVisible() && !m_bDisplayListBox;
392 
393         m_aListBox.Show(bShowBox);
394         m_aValueSet.Show(bShowSet);
395     }
396 
397     void SuggestionDisplay::StateChanged( StateChangedType nStateChange )
398     {
399         if( STATE_CHANGE_VISIBLE == nStateChange )
400             implUpdateDisplay();
401     }
402 
403     Control& SuggestionDisplay::implGetCurrentControl()
404     {
405         if( m_bDisplayListBox )
406             return m_aListBox;
407         return m_aValueSet;
408     }
409 
410     void SuggestionDisplay::KeyInput( const KeyEvent& rKEvt )
411     {
412         implGetCurrentControl().KeyInput( rKEvt );
413     }
414     void SuggestionDisplay::KeyUp( const KeyEvent& rKEvt )
415     {
416         implGetCurrentControl().KeyUp( rKEvt );
417     }
418     void SuggestionDisplay::Activate()
419     {
420         implGetCurrentControl().Activate();
421     }
422     void SuggestionDisplay::Deactivate()
423     {
424         implGetCurrentControl().Deactivate();
425     }
426     void SuggestionDisplay::GetFocus()
427     {
428         implGetCurrentControl().GetFocus();
429     }
430 	void SuggestionDisplay::LoseFocus()
431     {
432         implGetCurrentControl().LoseFocus();
433     }
434     void SuggestionDisplay::Command( const CommandEvent& rCEvt )
435     {
436         implGetCurrentControl().Command( rCEvt );
437     }
438 
439     void SuggestionDisplay::DisplayListBox( bool bDisplayListBox )
440     {
441         if( m_bDisplayListBox != bDisplayListBox )
442         {
443             Control& rOldControl = implGetCurrentControl();
444             sal_Bool bHasFocus = rOldControl.HasFocus();
445 
446             m_bDisplayListBox = bDisplayListBox;
447 
448             if( bHasFocus )
449             {
450                 Control& rNewControl = implGetCurrentControl();
451                 rNewControl.GrabFocus();
452             }
453 
454             implUpdateDisplay();
455         }
456     }
457 
458     IMPL_LINK( SuggestionDisplay, SelectSuggestionHdl, Control*, pControl )
459     {
460         if( m_bInSelectionUpdate )
461             return 0L;
462 
463         m_bInSelectionUpdate = true;
464         if(pControl==&m_aListBox)
465         {
466             sal_uInt16 nPos = m_aListBox.GetSelectEntryPos();
467             m_aValueSet.SelectItem( nPos+1 ); //itemid == pos+1 (id 0 has special meaning)
468         }
469         else
470         {
471             sal_uInt16 nPos = m_aValueSet.GetSelectItemId()-1; //itemid == pos+1 (id 0 has special meaning)
472             m_aListBox.SelectEntryPos( nPos );
473         }
474         m_bInSelectionUpdate = false;
475         m_aSelectLink.Call(this);
476         return 0L;
477     }
478 
479     void SuggestionDisplay::SetSelectHdl( const Link& rLink )
480     {
481         m_aSelectLink = rLink;
482     }
483     void SuggestionDisplay::Clear()
484     {
485         m_aListBox.Clear();
486         m_aValueSet.Clear();
487     }
488     void SuggestionDisplay::InsertEntry( const XubString& rStr )
489     {
490         sal_uInt16 nItemId = m_aListBox.InsertEntry( rStr ) + 1; //itemid == pos+1 (id 0 has special meaning)
491         m_aValueSet.InsertItem( nItemId );
492         String* pItemData = new String(rStr);
493         m_aValueSet.SetItemData( nItemId, pItemData );
494     }
495     void SuggestionDisplay::SelectEntryPos( sal_uInt16 nPos )
496     {
497         m_aListBox.SelectEntryPos( nPos );
498         m_aValueSet.SelectItem( nPos+1 ); //itemid == pos+1 (id 0 has special meaning)
499     }
500     sal_uInt16 SuggestionDisplay::GetEntryCount() const
501     {
502         return m_aListBox.GetEntryCount();
503     }
504     XubString SuggestionDisplay::GetEntry( sal_uInt16 nPos ) const
505     {
506         return m_aListBox.GetEntry( nPos );
507     }
508     XubString SuggestionDisplay::GetSelectEntry() const
509     {
510         return m_aListBox.GetSelectEntry();
511     }
512     void SuggestionDisplay::SetHelpIds()
513     {
514         this->SetHelpId( HID_HANGULDLG_SUGGESTIONS );
515         m_aValueSet.SetHelpId( HID_HANGULDLG_SUGGESTIONS_GRID );
516         m_aListBox.SetHelpId( HID_HANGULDLG_SUGGESTIONS_LIST );
517     }
518 
519     //=========================================================================
520 	//= HangulHanjaConversionDialog
521 	//=========================================================================
522 	//-------------------------------------------------------------------------
523     HangulHanjaConversionDialog::HangulHanjaConversionDialog( Window* _pParent, HHC::ConversionDirection _ePrimaryDirection )
524 		:ModalDialog( _pParent, CUI_RES( RID_SVX_MDLG_HANGULHANJA ) )
525 		,m_pPlayground( new SvxCommonLinguisticControl( this ) )
526 		,m_aFind			( m_pPlayground.get(), CUI_RES( PB_FIND ) )
527 		,m_aSuggestions		( m_pPlayground.get(), CUI_RES( CTL_SUGGESTIONS ) )
528 		,m_aFormat			( m_pPlayground.get(), CUI_RES( FT_FORMAT ) )
529 		,m_aSimpleConversion( m_pPlayground.get(), CUI_RES( RB_SIMPLE_CONVERSION ) )
530 		,m_aHangulBracketed	( m_pPlayground.get(), CUI_RES( RB_HANJA_HANGUL_BRACKETED ) )
531 		,m_aHanjaBracketed	( m_pPlayground.get(), CUI_RES( RB_HANGUL_HANJA_BRACKETED ) )
532 		,m_aConversion		( m_pPlayground.get(), CUI_RES( FT_CONVERSION ) )
533 		,m_aHangulOnly		( m_pPlayground.get(), CUI_RES( CB_HANGUL_ONLY ) )
534 		,m_aHanjaOnly		( m_pPlayground.get(), CUI_RES( CB_HANJA_ONLY ) )
535 		,m_aReplaceByChar	( m_pPlayground.get(), CUI_RES( CB_REPLACE_BY_CHARACTER ) )
536 		,m_pIgnoreNonPrimary( NULL )
537 		,m_bDocumentMode( true )
538 	{
539 		// special creation of the 4 pseudo-ruby radio buttons
540 		String sSecondaryHangul( CUI_RES( STR_HANGUL ) );
541 		String sSecondaryHanja( CUI_RES( STR_HANJA ) );
542 		m_pHanjaAbove.reset( new RubyRadioButton( m_pPlayground.get(), CUI_RES( RB_HANGUL_HANJA_ABOVE ), sSecondaryHanja, PseudoRubyText::eAbove ) );
543 		m_pHanjaBelow.reset( new RubyRadioButton( m_pPlayground.get(), CUI_RES( RB_HANGUL_HANJA_BELOW ), sSecondaryHanja, PseudoRubyText::eBelow ) );
544 		m_pHangulAbove.reset( new RubyRadioButton( m_pPlayground.get(), CUI_RES( RB_HANJA_HANGUL_ABOVE ), sSecondaryHangul, PseudoRubyText::eAbove ) );
545 		m_pHangulBelow.reset( new RubyRadioButton( m_pPlayground.get(), CUI_RES( RB_HANJA_HANGUL_BELOW ), sSecondaryHangul, PseudoRubyText::eBelow ) );
546 
547 		// since these 4 buttons are not created within the other members, they have a wrong initial Z-Order
548 		// correct this
549 		m_pHanjaAbove->SetZOrder( &m_aHanjaBracketed, WINDOW_ZORDER_BEHIND );
550 		m_pHanjaBelow->SetZOrder( m_pHanjaAbove.get(), WINDOW_ZORDER_BEHIND );
551 		m_pHangulAbove->SetZOrder( m_pHanjaBelow.get(), WINDOW_ZORDER_BEHIND );
552 		m_pHangulBelow->SetZOrder( m_pHangulAbove.get(), WINDOW_ZORDER_BEHIND );
553 
554 		// VCL automatically sets the WB_GROUP bit, if the previous sibling (at the moment of creation)
555 		// is no radion button
556 		m_pHanjaAbove->SetStyle( m_pHanjaAbove->GetStyle() & ~WB_GROUP );
557 
558 		// the "Find" button and the word input control may not have the proper distance/extensions
559 		// -> correct this
560 		Point aDistance = LogicToPixel( Point( 3, 0 ), MAP_APPFONT );
561 		sal_Int32 nTooLargeByPixels =
562 			// right margin of the word input control
563 			(	m_pPlayground->GetWordInputControl().GetPosPixel().X()
564 			+	m_pPlayground->GetWordInputControl().GetSizePixel().Width()
565 			)
566 			// minus left margin of the find button
567 			-	m_aFind.GetPosPixel().X()
568 			// plus desired distance between the both
569 			+	aDistance.X();
570 		// make the word input control smaller
571 		Size aSize = m_pPlayground->GetWordInputControl().GetSizePixel();
572 		aSize.Width() -= nTooLargeByPixels;
573 		m_pPlayground->GetWordInputControl().SetSizePixel( aSize );
574 
575 		// additionall, the playground is not wide enough (in it's default size)
576 		sal_Int32 nEnlargeWidth = 0;
577 		{
578 			FixedText aBottomAnchor( m_pPlayground.get(), CUI_RES( FT_RESIZE_ANCHOR ) );
579 			Point aAnchorPos = aBottomAnchor.GetPosPixel();
580 
581 			nEnlargeWidth = aAnchorPos.X() - m_pPlayground->GetActionButtonsLocation().X();
582 		}
583 		m_pPlayground->Enlarge( nEnlargeWidth, 0 );
584 
585 		// insert our controls into the z-order of the playground
586 		m_pPlayground->InsertControlGroup( m_aFind, m_aFind, SvxCommonLinguisticControl::eLeftRightWords );
587 		m_pPlayground->InsertControlGroup( m_aSuggestions, m_aHanjaOnly, SvxCommonLinguisticControl::eSuggestionLabel );
588 		m_pPlayground->InsertControlGroup( m_aReplaceByChar, m_aReplaceByChar, SvxCommonLinguisticControl::eActionButtons );
589 
590 		m_pPlayground->SetButtonHandler( SvxCommonLinguisticControl::eClose, LINK( this, HangulHanjaConversionDialog, OnClose ) );
591 		m_pPlayground->GetWordInputControl().SetModifyHdl( LINK( this,  HangulHanjaConversionDialog, OnSuggestionModified ) );
592 		m_aSuggestions.SetSelectHdl( LINK( this,  HangulHanjaConversionDialog, OnSuggestionSelected ) );
593 
594         m_aReplaceByChar.SetClickHdl( LINK( this, HangulHanjaConversionDialog, ClickByCharacterHdl ) );
595 
596 		m_aHangulOnly.SetClickHdl( LINK( this,  HangulHanjaConversionDialog, OnConversionDirectionClicked ) );
597 		m_aHanjaOnly.SetClickHdl(  LINK( this,  HangulHanjaConversionDialog, OnConversionDirectionClicked ) );
598 
599 		m_pPlayground->SetButtonHandler( SvxCommonLinguisticControl::eOptions,
600 										LINK( this, HangulHanjaConversionDialog, OnOption ) );
601 		m_pPlayground->GetButton( SvxCommonLinguisticControl::eOptions )->Show();
602 //		m_pPlayground->EnableButton( SvxCommonLinguisticControl::eOptions, true );
603 
604 		if ( editeng::HangulHanjaConversion::eHangulToHanja == _ePrimaryDirection )
605 		{
606 //			m_aHanjaOnly.Enable( sal_False );
607 			m_pIgnoreNonPrimary = &m_aHangulOnly;
608 		}
609 		else
610 		{
611 //			m_aHangulOnly.Enable( sal_False );
612 			m_pIgnoreNonPrimary = &m_aHanjaOnly;
613 		}
614 //        m_pIgnoreNonPrimary->Check();
615 
616 		// initial focus
617 		FocusSuggestion( );
618 
619 		// initial control values
620 		m_aSimpleConversion.Check();
621 
622         m_pPlayground->GetButton(SvxCommonLinguisticControl::eClose     )->SetHelpId(HID_HANGULDLG_BUTTON_CLOSE    );
623         m_pPlayground->GetButton(SvxCommonLinguisticControl::eIgnore    )->SetHelpId(HID_HANGULDLG_BUTTON_IGNORE   );
624         m_pPlayground->GetButton(SvxCommonLinguisticControl::eIgnoreAll )->SetHelpId(HID_HANGULDLG_BUTTON_IGNOREALL);
625         m_pPlayground->GetButton(SvxCommonLinguisticControl::eChange    )->SetHelpId(HID_HANGULDLG_BUTTON_CHANGE   );
626         m_pPlayground->GetButton(SvxCommonLinguisticControl::eChangeAll )->SetHelpId(HID_HANGULDLG_BUTTON_CHANGEALL);
627 		m_pPlayground->GetButton(SvxCommonLinguisticControl::eOptions   )->SetHelpId(HID_HANGULDLG_BUTTON_OPTIONS  );
628         m_pPlayground->GetWordInputControl().SetHelpId(HID_HANGULDLG_EDIT_NEWWORD);
629 
630         FreeResource();
631 
632         m_aSuggestions.SetHelpIds();
633 	}
634 
635 	//-------------------------------------------------------------------------
636 	HangulHanjaConversionDialog::~HangulHanjaConversionDialog( )
637 	{
638 	}
639 
640 	//-------------------------------------------------------------------------
641 	void HangulHanjaConversionDialog::FillSuggestions( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& _rSuggestions )
642 	{
643 		m_aSuggestions.Clear();
644 
645 		const ::rtl::OUString* pSuggestions = _rSuggestions.getConstArray();
646 		const ::rtl::OUString* pSuggestionsEnd = _rSuggestions.getConstArray() + _rSuggestions.getLength();
647 		while ( pSuggestions != pSuggestionsEnd )
648 			m_aSuggestions.InsertEntry( *pSuggestions++ );
649 
650 		// select the first suggestion, and fill in the suggestion edit field
651 		String sFirstSuggestion;
652 		if ( m_aSuggestions.GetEntryCount() )
653 		{
654 			sFirstSuggestion = m_aSuggestions.GetEntry( 0 );
655 			m_aSuggestions.SelectEntryPos( 0 );
656 		}
657 		m_pPlayground->GetWordInputControl().SetText( sFirstSuggestion );
658 		m_pPlayground->GetWordInputControl().SaveValue();
659 		OnSuggestionModified( &m_pPlayground->GetWordInputControl() );
660 	}
661 
662     //-------------------------------------------------------------------------
663 	void HangulHanjaConversionDialog::SetOptionsChangedHdl( const Link& _rHdl )
664 	{
665 		m_aOptionsChangedLink = _rHdl;
666 	}
667 
668 	//-------------------------------------------------------------------------
669 	void HangulHanjaConversionDialog::SetIgnoreHdl( const Link& _rHdl )
670 	{
671 		m_pPlayground->SetButtonHandler( SvxCommonLinguisticControl::eIgnore, _rHdl );
672 	}
673 
674 	//-------------------------------------------------------------------------
675 	void HangulHanjaConversionDialog::SetIgnoreAllHdl( const Link& _rHdl )
676 	{
677 		m_pPlayground->SetButtonHandler( SvxCommonLinguisticControl::eIgnoreAll, _rHdl );
678 	}
679 
680 	//-------------------------------------------------------------------------
681 	void HangulHanjaConversionDialog::SetChangeHdl( const Link& _rHdl )
682 	{
683 		m_pPlayground->SetButtonHandler( SvxCommonLinguisticControl::eChange, _rHdl );
684 	}
685 
686 	//-------------------------------------------------------------------------
687 	void HangulHanjaConversionDialog::SetChangeAllHdl( const Link& _rHdl )
688 	{
689 		m_pPlayground->SetButtonHandler( SvxCommonLinguisticControl::eChangeAll, _rHdl );
690 	}
691 
692 	//-------------------------------------------------------------------------
693 	void HangulHanjaConversionDialog::SetFindHdl( const Link& _rHdl )
694 	{
695 		m_aFind.SetClickHdl( _rHdl );
696 	}
697 
698 	//-------------------------------------------------------------------------
699 	void HangulHanjaConversionDialog::SetConversionFormatChangedHdl( const Link& _rHdl )
700 	{
701 		m_aSimpleConversion.SetClickHdl( _rHdl );
702 		m_aHangulBracketed.SetClickHdl( _rHdl );
703 		m_aHanjaBracketed.SetClickHdl( _rHdl );
704 		m_pHanjaAbove->SetClickHdl( _rHdl );
705 		m_pHanjaBelow->SetClickHdl( _rHdl );
706 		m_pHangulAbove->SetClickHdl( _rHdl );
707 		m_pHangulBelow->SetClickHdl( _rHdl );
708 	}
709 
710 	//-------------------------------------------------------------------------
711 	void HangulHanjaConversionDialog::SetClickByCharacterHdl( const Link& _rHdl )
712 	{
713         m_aClickByCharacterLink = _rHdl;
714 	}
715 
716 	//-------------------------------------------------------------------------
717 	IMPL_LINK( HangulHanjaConversionDialog, OnSuggestionSelected, void*, EMPTYARG )
718 	{
719 		m_pPlayground->GetWordInputControl().SetText( m_aSuggestions.GetSelectEntry() );
720 		OnSuggestionModified( NULL );
721 		return 0L;
722 	}
723 
724 	//-------------------------------------------------------------------------
725 	IMPL_LINK( HangulHanjaConversionDialog, OnSuggestionModified, void*, EMPTYARG )
726 	{
727 		m_aFind.Enable( m_pPlayground->GetWordInputControl().GetSavedValue() != m_pPlayground->GetWordInputControl().GetText() );
728 
729 		bool bSameLen = m_pPlayground->GetWordInputControl().GetText().Len() == m_pPlayground->GetCurrentText().Len();
730 		m_pPlayground->EnableButton( SvxCommonLinguisticControl::eChange, m_bDocumentMode && bSameLen );
731 		m_pPlayground->EnableButton( SvxCommonLinguisticControl::eChangeAll, m_bDocumentMode && bSameLen );
732 
733 		return 0L;
734 	}
735 
736     //-------------------------------------------------------------------------
737 	IMPL_LINK( HangulHanjaConversionDialog, ClickByCharacterHdl, CheckBox *, pBox )
738     {
739         m_aClickByCharacterLink.Call(pBox);
740 
741         bool bByCharacter = pBox->IsChecked();
742         m_aSuggestions.DisplayListBox( !bByCharacter );
743 
744         return 0L;
745     }
746 
747 	//-------------------------------------------------------------------------
748 	IMPL_LINK( HangulHanjaConversionDialog, OnConversionDirectionClicked, CheckBox *, pBox )
749 	{
750 		CheckBox *pOtherBox = 0;
751 		if (pBox == &m_aHangulOnly)
752 			pOtherBox = &m_aHanjaOnly;
753 		else if (pBox == &m_aHanjaOnly)
754 			pOtherBox = &m_aHangulOnly;
755 		if (pBox && pOtherBox)
756 		{
757 			sal_Bool bBoxChecked = pBox->IsChecked();
758 			if (bBoxChecked)
759 				pOtherBox->Check( sal_False );
760 			pOtherBox->Enable( !bBoxChecked );
761 		}
762 
763 		return 0L;
764 	}
765 
766 	//-------------------------------------------------------------------------
767 	IMPL_LINK( HangulHanjaConversionDialog, OnClose, void*, EMPTYARG )
768 	{
769 		Close();
770 		return 0L;
771 	}
772 
773 	IMPL_LINK( HangulHanjaConversionDialog, OnOption, void*, EMPTYARG )
774 	{
775 		HangulHanjaOptionsDialog		aOptDlg( this );
776 		aOptDlg.Execute();
777         m_aOptionsChangedLink.Call(this);
778 		return 0L;
779 	}
780 
781 	//-------------------------------------------------------------------------
782 	String HangulHanjaConversionDialog::GetCurrentString( ) const
783 	{
784 		return m_pPlayground->GetCurrentText( );
785 	}
786 
787 	//-------------------------------------------------------------------------
788 	void HangulHanjaConversionDialog::FocusSuggestion( )
789 	{
790 		m_pPlayground->GetWordInputControl().GrabFocus();
791 	}
792 
793 	//-------------------------------------------------------------------------
794 	namespace
795 	{
796 		void lcl_modifyWindowStyle( Window* _pWin, WinBits _nSet, WinBits _nReset )
797 		{
798 			DBG_ASSERT( 0 == ( _nSet & _nReset ), "lcl_modifyWindowStyle: set _and_ reset the same bit?" );
799 			if ( _pWin )
800 				_pWin->SetStyle( ( _pWin->GetStyle() | _nSet ) & ~_nReset );
801 		}
802 	}
803 
804 	//-------------------------------------------------------------------------
805 	void HangulHanjaConversionDialog::SetCurrentString( const String& _rNewString,
806 		const Sequence< ::rtl::OUString >& _rSuggestions, bool _bOriginatesFromDocument )
807 	{
808 		m_pPlayground->SetCurrentText( _rNewString );
809 
810 		bool bOldDocumentMode = m_bDocumentMode;
811 		m_bDocumentMode = _bOriginatesFromDocument;	// before FillSuggestions!
812 		FillSuggestions( _rSuggestions );
813 
814 		m_pPlayground->EnableButton( SvxCommonLinguisticControl::eIgnoreAll, m_bDocumentMode );
815 			// all other buttons have been implicitly enabled or disabled during filling in the suggestions
816 
817 		// switch the def button depending if we're working for document text
818 		if ( bOldDocumentMode != m_bDocumentMode )
819 		{
820 			Window* pOldDefButton = NULL;
821 			Window* pNewDefButton = NULL;
822 			if ( m_bDocumentMode )
823 			{
824 				pOldDefButton = &m_aFind;
825 				pNewDefButton = m_pPlayground->GetButton( SvxCommonLinguisticControl::eChange );
826 			}
827 			else
828 			{
829 				pOldDefButton = m_pPlayground->GetButton( SvxCommonLinguisticControl::eChange );
830 				pNewDefButton = &m_aFind;
831 			}
832 
833 			DBG_ASSERT( WB_DEFBUTTON == ( pOldDefButton->GetStyle( ) & WB_DEFBUTTON ),
834 				"HangulHanjaConversionDialog::SetCurrentString: wrong previous default button (1)!" );
835 			DBG_ASSERT( 0 == ( pNewDefButton->GetStyle( ) & WB_DEFBUTTON ),
836 				"HangulHanjaConversionDialog::SetCurrentString: wrong previous default button (2)!" );
837 
838 			lcl_modifyWindowStyle( pOldDefButton, 0, WB_DEFBUTTON );
839 			lcl_modifyWindowStyle( pNewDefButton, WB_DEFBUTTON, 0 );
840 
841 			// give the focus to the new def button temporarily - VCL is somewhat peculiar
842 			// in recognizing a new default button
843 			sal_uInt32 nSaveFocusId = Window::SaveFocus();
844 			pNewDefButton->GrabFocus();
845 			Window::EndSaveFocus( nSaveFocusId );
846 		}
847 	}
848 
849 	//-------------------------------------------------------------------------
850 	String HangulHanjaConversionDialog::GetCurrentSuggestion( ) const
851 	{
852 		return m_pPlayground->GetWordInputControl().GetText();
853 	}
854 
855 	//-------------------------------------------------------------------------
856 	void HangulHanjaConversionDialog::SetByCharacter( sal_Bool _bByCharacter )
857 	{
858 		m_aReplaceByChar.Check( _bByCharacter );
859 		m_aSuggestions.DisplayListBox( !_bByCharacter );
860 	}
861 
862 	//-------------------------------------------------------------------------
863 	void HangulHanjaConversionDialog::SetConversionDirectionState(
864 			sal_Bool _bTryBothDirections,
865 			HHC::ConversionDirection _ePrimaryConversionDirection )
866 	{
867 		// default state: try both direction
868 		m_aHangulOnly.Check( sal_False );
869 		m_aHangulOnly.Enable( sal_True );
870 		m_aHanjaOnly.Check( sal_False );
871 		m_aHanjaOnly.Enable( sal_True );
872 
873 		if (!_bTryBothDirections)
874 		{
875 			CheckBox *pBox = _ePrimaryConversionDirection == HHC::eHangulToHanja?
876 									&m_aHangulOnly : &m_aHanjaOnly;
877 			pBox->Check( sal_True );
878 			OnConversionDirectionClicked( pBox );
879 		}
880 	}
881 
882 	//-------------------------------------------------------------------------
883 	sal_Bool HangulHanjaConversionDialog::GetUseBothDirections( ) const
884 	{
885 //		DBG_ASSERT( m_pIgnoreNonPrimary, "HangulHanjaConversionDialog::GetUseBothDirections: where's the check box pointer?" );
886 //		return m_pIgnoreNonPrimary ? !m_pIgnoreNonPrimary->IsChecked( ) : sal_True;
887 		return !m_aHangulOnly.IsChecked() && !m_aHanjaOnly.IsChecked();
888 	}
889 
890 	//-------------------------------------------------------------------------
891 	HHC::ConversionDirection HangulHanjaConversionDialog::GetDirection(
892 			HHC::ConversionDirection eDefaultDirection ) const
893 	{
894 		HHC::ConversionDirection eDirection = eDefaultDirection;
895 		if (m_aHangulOnly.IsChecked() && !m_aHanjaOnly.IsChecked())
896 			eDirection = HHC::eHangulToHanja;
897 		else if (!m_aHangulOnly.IsChecked() && m_aHanjaOnly.IsChecked())
898 			eDirection = HHC::eHanjaToHangul;
899 		return eDirection;
900 	}
901 
902 	//-------------------------------------------------------------------------
903     void HangulHanjaConversionDialog::SetConversionFormat( HHC::ConversionFormat _eType )
904 	{
905 		switch ( _eType )
906 		{
907             case HHC::eSimpleConversion: m_aSimpleConversion.Check(); break;
908             case HHC::eHangulBracketed: m_aHangulBracketed.Check(); break;
909             case HHC::eHanjaBracketed:  m_aHanjaBracketed.Check(); break;
910             case HHC::eRubyHanjaAbove:  m_pHanjaAbove->Check(); break;
911             case HHC::eRubyHanjaBelow:  m_pHanjaBelow->Check(); break;
912             case HHC::eRubyHangulAbove: m_pHangulAbove->Check(); break;
913             case HHC::eRubyHangulBelow: m_pHangulBelow->Check(); break;
914 		default:
915 			DBG_ERROR( "HangulHanjaConversionDialog::SetConversionFormat: unknown type!" );
916 		}
917 	}
918 
919 	//-------------------------------------------------------------------------
920     HHC::ConversionFormat HangulHanjaConversionDialog::GetConversionFormat( ) const
921 	{
922 		if ( m_aSimpleConversion.IsChecked() )
923             return HHC::eSimpleConversion;
924 		if ( m_aHangulBracketed.IsChecked() )
925             return HHC::eHangulBracketed;
926 		if ( m_aHanjaBracketed.IsChecked() )
927             return HHC::eHanjaBracketed;
928 		if ( m_pHanjaAbove->IsChecked() )
929             return HHC::eRubyHanjaAbove;
930 		if ( m_pHanjaBelow->IsChecked() )
931             return HHC::eRubyHanjaBelow;
932 		if ( m_pHangulAbove->IsChecked() )
933             return HHC::eRubyHangulAbove;
934 		if ( m_pHangulBelow->IsChecked() )
935             return HHC::eRubyHangulBelow;
936 
937 		DBG_ERROR( "HangulHanjaConversionDialog::GetConversionFormat: no radio checked?" );
938         return HHC::eSimpleConversion;
939 	}
940 
941     //-------------------------------------------------------------------------
942     void HangulHanjaConversionDialog::EnableRubySupport( sal_Bool bVal )
943     {
944         m_pHanjaAbove->Enable( bVal );
945         m_pHanjaBelow->Enable( bVal );
946         m_pHangulAbove->Enable( bVal );
947         m_pHangulBelow->Enable( bVal );
948     }
949 
950 
951 	//=========================================================================
952 	//= HangulHanjaOptionsDialog
953 	//=========================================================================
954 	//-------------------------------------------------------------------------
955 
956 	void HangulHanjaOptionsDialog::Init( void )
957 	{
958         if( !m_xConversionDictionaryList.is() )
959         {
960             Reference< XMultiServiceFactory > xMgr( ::comphelper::getProcessServiceFactory() );
961 		    if( xMgr.is() )
962 		    {
963 			    m_xConversionDictionaryList = Reference< XConversionDictionaryList >( xMgr->createInstance(
964 				    OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.linguistic2.ConversionDictionaryList")) ),
965 				    UNO_QUERY );
966 		    }
967         }
968 
969 		m_aDictList.clear();
970         m_aDictsLB.Clear();
971 
972 		if( m_xConversionDictionaryList.is() )
973 		{
974 			Reference< XNameContainer >	xNameCont = m_xConversionDictionaryList->getDictionaryContainer();
975 			Reference< XNameAccess >	xNameAccess = Reference< XNameAccess >( xNameCont, UNO_QUERY );
976 			if( xNameAccess.is() )
977 			{
978 				Sequence< ::rtl::OUString >		aDictNames( xNameAccess->getElementNames() );
979 
980 				const ::rtl::OUString*			pDic = aDictNames.getConstArray();
981 				sal_Int32						nCount = aDictNames.getLength();
982 
983 				sal_Int32						i;
984 				for( i = 0 ; i < nCount ; ++i )
985 				{
986 					Any									aAny( xNameAccess->getByName( pDic[ i ] ) );
987 					Reference< XConversionDictionary >	xDic;
988 					if( ( aAny >>= xDic ) && xDic.is() )
989                     {
990                         if( LANGUAGE_KOREAN == SvxLocaleToLanguage( xDic->getLocale() ) )
991                         {
992                             m_aDictList.push_back( xDic );
993                             AddDict( xDic->getName(), xDic->isActive() );
994                         }
995                     }
996 				}
997 			}
998 		}
999 	}
1000 
1001 	IMPL_LINK( HangulHanjaOptionsDialog, OkHdl, void*, EMPTYARG )
1002 	{
1003 		sal_uInt32				nCnt = m_aDictList.size();
1004 		sal_uInt32				n = 0;
1005 		sal_uInt32				nActiveDics = 0;
1006 	    Sequence< OUString >	aActiveDics;
1007 
1008 		aActiveDics.realloc( nCnt );
1009 		OUString*				pActActiveDic = aActiveDics.getArray();
1010 
1011 		while( nCnt )
1012 		{
1013             Reference< XConversionDictionary >	xDict = m_aDictList[ n ];
1014 			SvLBoxEntry*						pEntry = m_aDictsLB.SvTreeListBox::GetEntry( n );
1015 
1016 			DBG_ASSERT( xDict.is(), "-HangulHanjaOptionsDialog::OkHdl(): someone is evaporated..." );
1017 			DBG_ASSERT( pEntry, "-HangulHanjaOptionsDialog::OkHdl(): no one there in list?" );
1018 
1019 			bool	bActive = m_aDictsLB.GetCheckButtonState( pEntry ) == SV_BUTTON_CHECKED;
1020 			xDict->setActive( bActive );
1021             Reference< util::XFlushable > xFlush( xDict, uno::UNO_QUERY );
1022             if( xFlush.is() )
1023                 xFlush->flush();
1024 
1025 			if( bActive )
1026 			{
1027 				pActActiveDic[ nActiveDics ] = xDict->getName();
1028 				++nActiveDics;
1029 			}
1030 
1031 			++n;
1032 			--nCnt;
1033 		}
1034 
1035 		// save configuration
1036 		aActiveDics.realloc( nActiveDics );
1037 		Any				aTmp;
1038 		SvtLinguConfig	aLngCfg;
1039 		aTmp <<= aActiveDics;
1040 		aLngCfg.SetProperty( UPH_ACTIVE_CONVERSION_DICTIONARIES, aTmp );
1041 
1042 		aTmp <<= bool( m_aIgnorepostCB.IsChecked() );
1043 		aLngCfg.SetProperty( UPH_IS_IGNORE_POST_POSITIONAL_WORD, aTmp );
1044 
1045 		aTmp <<= bool( m_aShowrecentlyfirstCB.IsChecked() );
1046 		aLngCfg.SetProperty( UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST, aTmp );
1047 
1048 		aTmp <<= bool( m_aAutoreplaceuniqueCB.IsChecked() );
1049 		aLngCfg.SetProperty( UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES, aTmp );
1050 
1051 		EndDialog( RET_OK );
1052 		return 0;
1053 	}
1054 
1055 	IMPL_LINK( HangulHanjaOptionsDialog, DictsLB_SelectHdl, void*, EMPTYARG )
1056 	{
1057 		bool	bSel = m_aDictsLB.FirstSelected() != NULL;
1058 
1059 		m_aEditPB.Enable( bSel );
1060 		m_aDeletePB.Enable( bSel );
1061 
1062 		return 0;
1063 	}
1064 
1065 	IMPL_LINK( HangulHanjaOptionsDialog, NewDictHdl, void*, EMPTYARG )
1066 	{
1067 		String						aName;
1068 		HangulHanjaNewDictDialog	aNewDlg( this );
1069 		aNewDlg.Execute();
1070 		if( aNewDlg.GetName( aName ) )
1071 		{
1072 			if( m_xConversionDictionaryList.is() )
1073 			{
1074 				try
1075 				{
1076                     Reference< XConversionDictionary >	xDic =
1077                         m_xConversionDictionaryList->addNewDictionary( aName, SvxCreateLocale( LANGUAGE_KOREAN ), ConversionDictionaryType::HANGUL_HANJA );
1078 
1079                     if( xDic.is() )
1080                     {
1081                         //adapt local caches:
1082                         m_aDictList.push_back( xDic );
1083                         AddDict( xDic->getName(), xDic->isActive() );
1084                     }
1085 				}
1086 				catch( const ElementExistException& )
1087 				{
1088 				}
1089 				catch( const NoSupportException& )
1090 				{
1091 				}
1092 			}
1093 		}
1094 
1095 		return 0L;
1096 	}
1097 
1098 	IMPL_LINK( HangulHanjaOptionsDialog, EditDictHdl, void*, EMPTYARG )
1099 	{
1100 		SvLBoxEntry*	pEntry = m_aDictsLB.FirstSelected();
1101 		DBG_ASSERT( pEntry, "+HangulHanjaEditDictDialog::EditDictHdl(): call of edit should not be possible with no selection!" );
1102 		if( pEntry )
1103 		{
1104 			HangulHanjaEditDictDialog	aEdDlg( this, m_aDictList, m_aDictsLB.GetSelectEntryPos() );
1105 			aEdDlg.Execute();
1106 		}
1107 		return 0L;
1108 	}
1109 
1110 	IMPL_LINK( HangulHanjaOptionsDialog, DeleteDictHdl, void*, EMPTYARG )
1111 	{
1112         sal_uInt16 nSelPos = m_aDictsLB.GetSelectEntryPos();
1113 		if( nSelPos != LISTBOX_ENTRY_NOTFOUND )
1114 		{
1115             Reference< XConversionDictionary >	xDic( m_aDictList[ nSelPos ] );
1116 			if( m_xConversionDictionaryList.is() && xDic.is() )
1117 			{
1118 				Reference< XNameContainer >		xNameCont = m_xConversionDictionaryList->getDictionaryContainer();
1119 				if( xNameCont.is() )
1120 				{
1121 					try
1122 					{
1123 						xNameCont->removeByName( xDic->getName() );
1124 
1125                         //adapt local caches:
1126                         HHDictList::iterator aIter(m_aDictList.begin());
1127                         m_aDictList.erase(aIter+nSelPos );
1128                         m_aDictsLB.RemoveEntry( nSelPos );
1129 					}
1130 					catch( const ElementExistException& )
1131 					{
1132 					}
1133 					catch( const NoSupportException& )
1134 					{
1135 					}
1136 				}
1137 			}
1138 		}
1139 
1140 		return 0L;
1141 	}
1142 
1143 	HangulHanjaOptionsDialog::HangulHanjaOptionsDialog( Window* _pParent )
1144 		:ModalDialog			( _pParent, CUI_RES( RID_SVX_MDLG_HANGULHANJA_OPT ) )
1145 		,m_aUserdefdictFT		( this, CUI_RES( FT_USERDEFDICT ) )
1146 		,m_aDictsLB				( this, CUI_RES( LB_DICTS ) )
1147 		,m_aOptionsFL			( this, CUI_RES( FL_OPTIONS ) )
1148 		,m_aIgnorepostCB		( this, CUI_RES( CB_IGNOREPOST ) )
1149 		,m_aShowrecentlyfirstCB	( this, CUI_RES( CB_SHOWRECENTLYFIRST ) )
1150 		,m_aAutoreplaceuniqueCB	( this, CUI_RES( CB_AUTOREPLACEUNIQUE ) )
1151 		,m_aNewPB				( this, CUI_RES( PB_HHO_NEW ) )
1152 		,m_aEditPB				( this, CUI_RES( PB_HHO_EDIT ) )
1153 		,m_aDeletePB			( this, CUI_RES( PB_HHO_DELETE ) )
1154 		,m_aOkPB				( this, CUI_RES( PB_HHO_OK ) )
1155 		,m_aCancelPB			( this, CUI_RES( PB_HHO_CANCEL ) )
1156 		,m_aHelpPB				( this, CUI_RES( PB_HHO_HELP ) )
1157 
1158 		,m_pCheckButtonData		( NULL )
1159         ,m_xConversionDictionaryList( NULL )
1160 	{
1161 		m_aDictsLB.SetStyle( m_aDictsLB.GetStyle() | WB_CLIPCHILDREN | WB_HSCROLL | WB_FORCE_MAKEVISIBLE );
1162 		m_aDictsLB.SetSelectionMode( SINGLE_SELECTION );
1163 		m_aDictsLB.SetHighlightRange();
1164 //		m_aDictsLB.SetHelpId( xxx );
1165 		m_aDictsLB.SetSelectHdl( LINK( this, HangulHanjaOptionsDialog, DictsLB_SelectHdl ) );
1166 		m_aDictsLB.SetDeselectHdl( LINK( this, HangulHanjaOptionsDialog, DictsLB_SelectHdl ) );
1167 
1168 		m_aOkPB.SetClickHdl( LINK( this, HangulHanjaOptionsDialog, OkHdl ) );
1169 		m_aNewPB.SetClickHdl( LINK( this, HangulHanjaOptionsDialog, NewDictHdl ) );
1170 		m_aEditPB.SetClickHdl( LINK( this, HangulHanjaOptionsDialog, EditDictHdl ) );
1171 		m_aDeletePB.SetClickHdl( LINK( this, HangulHanjaOptionsDialog, DeleteDictHdl ) );
1172 
1173 		FreeResource();
1174 
1175 		SvtLinguConfig	aLngCfg;
1176 		Any				aTmp;
1177 		bool			bVal = bool();
1178 		aTmp = aLngCfg.GetProperty( UPH_IS_IGNORE_POST_POSITIONAL_WORD );
1179 		if( aTmp >>= bVal )
1180 			m_aIgnorepostCB.Check( bVal );
1181 
1182 		aTmp = aLngCfg.GetProperty( UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST );
1183 		if( aTmp >>= bVal )
1184 			m_aShowrecentlyfirstCB.Check( bVal );
1185 
1186 		aTmp = aLngCfg.GetProperty( UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES );
1187 		if( aTmp >>= bVal )
1188 			m_aAutoreplaceuniqueCB.Check( bVal );
1189 
1190 		Init();
1191 	}
1192 
1193 	HangulHanjaOptionsDialog::~HangulHanjaOptionsDialog()
1194 	{
1195 		SvLBoxEntry*	pEntry = m_aDictsLB.First();
1196 		String*			pDel;
1197 		while( pEntry )
1198 		{
1199 			pDel = ( String* ) pEntry->GetUserData();
1200 			if( pDel )
1201 				delete pDel;
1202 			pEntry = m_aDictsLB.Next( pEntry );
1203 		}
1204 
1205 		if( m_pCheckButtonData )
1206 			delete m_pCheckButtonData;
1207 	}
1208 
1209 	void HangulHanjaOptionsDialog::AddDict( const String& _rName, bool _bChecked )
1210 	{
1211 		SvLBoxEntry*	pEntry = m_aDictsLB.SvTreeListBox::InsertEntry( _rName );
1212 		m_aDictsLB.SetCheckButtonState( pEntry, _bChecked? SV_BUTTON_CHECKED : SV_BUTTON_UNCHECKED );
1213 		pEntry->SetUserData( new String( _rName ) );
1214 	}
1215 
1216 	//=========================================================================
1217 	//= HangulHanjaNewDictDialog
1218 	//=========================================================================
1219 	//-------------------------------------------------------------------------
1220 
1221 	IMPL_LINK( HangulHanjaNewDictDialog, OKHdl, void*, EMPTYARG )
1222 	{
1223 		String	aName( m_aDictNameED.GetText() );
1224 
1225 		aName.EraseTrailingChars();
1226 		m_bEntered = aName.Len() > 0;
1227 		if( m_bEntered )
1228 			m_aDictNameED.SetText( aName );		// do this in case of trailing chars have been deleted
1229 
1230 		EndDialog( RET_OK );
1231 		return 0;
1232 	}
1233 
1234 	IMPL_LINK( HangulHanjaNewDictDialog, ModifyHdl, void*, EMPTYARG )
1235 	{
1236 		String	aName( m_aDictNameED.GetText() );
1237 
1238 		aName.EraseTrailingChars();
1239 		m_aOkBtn.Enable( aName.Len() > 0 );
1240 
1241 		return 0;
1242 	}
1243 
1244 	HangulHanjaNewDictDialog::HangulHanjaNewDictDialog( Window* _pParent )
1245 		:ModalDialog	( _pParent, CUI_RES( RID_SVX_MDLG_HANGULHANJA_NEWDICT ) )
1246 		,m_aNewDictFL	( this, CUI_RES( FL_NEWDICT ) )
1247 		,m_aDictNameFT	( this, CUI_RES( FT_DICTNAME ) )
1248 		,m_aDictNameED	( this, CUI_RES( ED_DICTNAME ) )
1249 		,m_aOkBtn		( this, CUI_RES( PB_NEWDICT_OK ) )
1250 		,m_aCancelBtn	( this, CUI_RES( PB_NEWDICT_ESC ) )
1251 		,m_aHelpBtn		( this, CUI_RES( PB_NEWDICT_HLP ) )
1252 
1253 		,m_bEntered		( false )
1254 	{
1255 		m_aOkBtn.SetClickHdl( LINK( this, HangulHanjaNewDictDialog, OKHdl ) );
1256 
1257 		m_aDictNameED.SetModifyHdl( LINK( this, HangulHanjaNewDictDialog, ModifyHdl ) );
1258 
1259 		FreeResource();
1260 	}
1261 
1262 	HangulHanjaNewDictDialog::~HangulHanjaNewDictDialog()
1263 	{
1264 	}
1265 
1266 	bool HangulHanjaNewDictDialog::GetName( String& _rRetName ) const
1267 	{
1268 		if( m_bEntered )
1269 		{
1270 			_rRetName = m_aDictNameED.GetText();
1271 			_rRetName.EraseTrailingChars();
1272 		}
1273 
1274 		return m_bEntered;
1275 	}
1276 
1277 	//=========================================================================
1278 	//= HangulHanjaEditDictDialog
1279 	//=========================================================================
1280 	//-------------------------------------------------------------------------
1281 
1282 	class SuggestionList
1283 	{
1284 	private:
1285 	protected:
1286 		sal_uInt16			m_nSize;
1287 		String**			m_ppElements;
1288 		sal_uInt16			m_nNumOfEntries;
1289 		sal_uInt16			m_nAct;
1290 
1291 		const String*		_Next( void );
1292 	public:
1293 							SuggestionList( sal_uInt16 _nNumOfElements );
1294 		virtual				~SuggestionList();
1295 
1296 		bool				Set( const String& _rElement, sal_uInt16 _nNumOfElement );
1297 		bool				Reset( sal_uInt16 _nNumOfElement );
1298 		const String*		Get( sal_uInt16 _nNumOfElement ) const;
1299 		void				Clear( void );
1300 
1301 		const String*		First( void );
1302 		const String*		Next( void );
1303 
1304 		inline sal_uInt16	GetCount( void ) const;
1305 	};
1306 
1307 	inline sal_uInt16 SuggestionList::GetCount( void ) const
1308 	{
1309 		return m_nNumOfEntries;
1310 	}
1311 
1312 	SuggestionList::SuggestionList( sal_uInt16 _nNumOfElements )
1313 	{
1314 		if( !_nNumOfElements )
1315 			_nNumOfElements = 1;
1316 
1317 		m_nSize = _nNumOfElements;
1318 
1319 		m_ppElements = new String*[ m_nSize ];
1320 		m_nAct = m_nNumOfEntries = 0;
1321 
1322 		String**	ppNull = m_ppElements;
1323 		sal_uInt16	n = _nNumOfElements;
1324 		while( n )
1325 		{
1326 			*ppNull = NULL;
1327 			++ppNull;
1328 			--n;
1329 		}
1330 	}
1331 
1332 	SuggestionList::~SuggestionList()
1333 	{
1334 		Clear();
1335 	}
1336 
1337 	bool SuggestionList::Set( const String& _rElement, sal_uInt16 _nNumOfElement )
1338 	{
1339 		bool	bRet = _nNumOfElement < m_nSize;
1340 		if( bRet )
1341 		{
1342 			String**	ppElem = m_ppElements + _nNumOfElement;
1343 			if( *ppElem )
1344 				**ppElem = _rElement;
1345 			else
1346 			{
1347 				*ppElem = new String( _rElement );
1348 				++m_nNumOfEntries;
1349 			}
1350 		}
1351 
1352 		return bRet;
1353 	}
1354 
1355 	bool SuggestionList::Reset( sal_uInt16 _nNumOfElement )
1356 	{
1357 		bool	bRet = _nNumOfElement < m_nSize;
1358 		if( bRet )
1359 		{
1360 			String**	ppElem = m_ppElements + _nNumOfElement;
1361 			if( *ppElem )
1362 			{
1363 				delete *ppElem;
1364 				*ppElem = NULL;
1365 				--m_nNumOfEntries;
1366 			}
1367 		}
1368 
1369 		return bRet;
1370 	}
1371 
1372 	const String* SuggestionList::Get( sal_uInt16 _nNumOfElement ) const
1373 	{
1374 		const String*	pRet;
1375 
1376 		if( _nNumOfElement < m_nSize )
1377 			pRet = m_ppElements[ _nNumOfElement ];
1378 		else
1379 			pRet = NULL;
1380 
1381 		return pRet;
1382 	}
1383 
1384 	void SuggestionList::Clear( void )
1385 	{
1386 		if( m_nNumOfEntries )
1387 		{
1388 			String**	ppDel = m_ppElements;
1389 			sal_uInt16	nCnt = m_nSize;
1390 			while( nCnt )
1391 			{
1392 				if( *ppDel )
1393 				{
1394 					delete *ppDel;
1395 					*ppDel = NULL;
1396 				}
1397 
1398 				++ppDel;
1399 				--nCnt;
1400 			}
1401 
1402 			m_nNumOfEntries = m_nAct = 0;
1403 		}
1404 	}
1405 
1406 	const String* SuggestionList::_Next( void )
1407 	{
1408 		const String*	pRet = NULL;
1409 		while( m_nAct < m_nSize && !pRet )
1410 		{
1411 			pRet = m_ppElements[ m_nAct ];
1412 			if( !pRet )
1413 				++m_nAct;
1414 		}
1415 
1416 		return pRet;
1417 	}
1418 
1419 	const String* SuggestionList::First( void )
1420 	{
1421 		m_nAct = 0;
1422 		return _Next();
1423 	}
1424 
1425 	const String* SuggestionList::Next( void )
1426 	{
1427 		const String*	pRet;
1428 
1429 		if( m_nAct < m_nNumOfEntries )
1430 		{
1431 			++m_nAct;
1432 			pRet = _Next();
1433 		}
1434 		else
1435 			pRet = NULL;
1436 
1437 		return pRet;
1438 	}
1439 
1440 
1441 	bool SuggestionEdit::ShouldScroll( bool _bUp ) const
1442 	{
1443 		bool	bRet = false;
1444 
1445 		if( _bUp )
1446 		{
1447 			if( !m_pPrev )
1448 				bRet = m_rScrollBar.GetThumbPos() > m_rScrollBar.GetRangeMin();
1449 		}
1450 		else
1451 		{
1452 			if( !m_pNext )
1453 				bRet = m_rScrollBar.GetThumbPos() < ( m_rScrollBar.GetRangeMax() - 4 );
1454 		}
1455 
1456 		return bRet;
1457 	}
1458 
1459 	void SuggestionEdit::DoJump( bool _bUp )
1460 	{
1461 		const Link& 	rLoseFocusHdl = GetLoseFocusHdl();
1462 		if( rLoseFocusHdl.IsSet() )
1463 			rLoseFocusHdl.Call( this );
1464 		m_rScrollBar.SetThumbPos( m_rScrollBar.GetThumbPos() + ( _bUp? -1 : 1 ) );
1465 
1466 		( static_cast< HangulHanjaEditDictDialog* >( GetParent() ) )->UpdateScrollbar();
1467 	}
1468 
1469 	SuggestionEdit::SuggestionEdit( Window* pParent, const ResId& rResId,
1470 		ScrollBar& _rScrollBar, SuggestionEdit* _pPrev, SuggestionEdit* _pNext  )
1471 		:Edit( pParent, rResId )
1472 		,m_pPrev( _pPrev )
1473 		,m_pNext( _pNext )
1474 		,m_rScrollBar( _rScrollBar )
1475 	{
1476 	}
1477 
1478 	SuggestionEdit::~SuggestionEdit()
1479 	{
1480 	}
1481 
1482 	long SuggestionEdit::PreNotify( NotifyEvent& rNEvt )
1483 	{
1484 		long	nHandled = 0;
1485 		if( rNEvt.GetType() == EVENT_KEYINPUT )
1486 		{
1487 			const KeyEvent*				pKEvt = rNEvt.GetKeyEvent();
1488 			const KeyCode&				rKeyCode = pKEvt->GetKeyCode();
1489 			sal_uInt16						nMod = rKeyCode.GetModifier();
1490 			sal_uInt16						nCode = rKeyCode.GetCode();
1491 			if( nCode == KEY_TAB && ( !nMod || KEY_SHIFT == nMod ) )
1492 			{
1493 				bool		bUp = KEY_SHIFT == nMod;
1494 				if( ShouldScroll( bUp ) )
1495 				{
1496 					DoJump( bUp );
1497 					SetSelection( Selection( 0, SELECTION_MAX ) );
1498 						// Tab-travel doesn't really happen, so emulate it by setting a selection manually
1499 					nHandled = 1;
1500 				}
1501 			}
1502 			else if( KEY_UP == nCode || KEY_DOWN == nCode )
1503 			{
1504 				bool		bUp = KEY_UP == nCode;
1505 				if( ShouldScroll( bUp ) )
1506 				{
1507 					DoJump( bUp );
1508 					nHandled = 1;
1509 				}
1510 				else if( bUp )
1511 				{
1512 					if( m_pPrev )
1513 					{
1514 						m_pPrev->GrabFocus();
1515 						nHandled = 1;
1516 					}
1517 				}
1518 				else if( m_pNext )
1519 				{
1520 					m_pNext->GrabFocus();
1521 					nHandled = 1;
1522 				}
1523 			}
1524 		}
1525 
1526 		if( !nHandled )
1527 			nHandled = Edit::PreNotify( rNEvt );
1528 		return nHandled;
1529 	}
1530 
1531 
1532 	namespace
1533 	{
1534 		bool GetConversions(	Reference< XConversionDictionary >	_xDict,
1535 								const OUString& _rOrg,
1536 								Sequence< OUString >& _rEntries )
1537 		{
1538 			bool	bRet = false;
1539 			if( _xDict.is() && _rOrg.getLength() )
1540 			{
1541 				try
1542 				{
1543 					_rEntries = _xDict->getConversions(	_rOrg,
1544 														0,
1545 														_rOrg.getLength(),
1546 														ConversionDirection_FROM_LEFT,
1547 														::com::sun::star::i18n::TextConversionOption::NONE );
1548 					bRet = _rEntries.getLength() > 0;
1549 				}
1550 				catch( const IllegalArgumentException& )
1551 				{
1552 				}
1553 			}
1554 
1555 			return bRet;
1556 		}
1557 	}
1558 
1559 
1560 	IMPL_LINK( HangulHanjaEditDictDialog, ScrollHdl, void*, EMPTYARG )
1561 	{
1562 		UpdateScrollbar();
1563 
1564 		return 0;
1565 	}
1566 
1567 	IMPL_LINK( HangulHanjaEditDictDialog, OriginalModifyHdl, void*, EMPTYARG )
1568 	{
1569         m_bModifiedOriginal = true;
1570 		m_aOriginal = m_aOriginalLB.GetText();
1571 		m_aOriginal.EraseTrailingChars();
1572 
1573         UpdateSuggestions();
1574 		UpdateButtonStates();
1575 
1576 		return 0;
1577 	}
1578 
1579 	IMPL_LINK( HangulHanjaEditDictDialog, EditModifyHdl1, Edit*, pEdit )
1580 	{
1581 		EditModify( pEdit, 0 );
1582 		return 0;
1583 	}
1584 
1585 	IMPL_LINK( HangulHanjaEditDictDialog, EditModifyHdl2, Edit*, pEdit )
1586 	{
1587 		EditModify( pEdit, 1 );
1588 		return 0;
1589 	}
1590 
1591 	IMPL_LINK( HangulHanjaEditDictDialog, EditModifyHdl3, Edit*, pEdit )
1592 	{
1593 		EditModify( pEdit, 2 );
1594 		return 0;
1595 	}
1596 
1597 	IMPL_LINK( HangulHanjaEditDictDialog, EditModifyHdl4, Edit*, pEdit )
1598 	{
1599 		EditModify( pEdit, 3 );
1600 		return 0;
1601 	}
1602 
1603     IMPL_LINK( HangulHanjaEditDictDialog, BookLBSelectHdl, void*, EMPTYARG )
1604 	{
1605 		InitEditDictDialog( m_aBookLB.GetSelectEntryPos() );
1606 		return 0;
1607 	}
1608 
1609 	IMPL_LINK( HangulHanjaEditDictDialog, NewPBPushHdl, void*, EMPTYARG )
1610 	{
1611 		DBG_ASSERT( m_pSuggestions, "-HangulHanjaEditDictDialog::NewPBPushHdl(): no suggestions... search in hell..." );
1612 		Reference< XConversionDictionary >	xDict = m_rDictList[ m_nCurrentDict ];
1613 		if( xDict.is() && m_pSuggestions )
1614 		{
1615 			//delete old entry
1616 			bool bRemovedSomething = DeleteEntryFromDictionary( m_aOriginal, xDict );
1617 
1618 			OUString				aLeft( m_aOriginal );
1619 			const String*			pRight = m_pSuggestions->First();
1620             bool bAddedSomething = false;
1621 			while( pRight )
1622 			{
1623 				try
1624 				{
1625 					//add new entry
1626 					xDict->addEntry( aLeft, *pRight );
1627                     bAddedSomething = true;
1628 				}
1629 				catch( const IllegalArgumentException& )
1630 				{
1631 				}
1632 				catch( const ElementExistException& )
1633 				{
1634 				}
1635 
1636 				pRight = m_pSuggestions->Next();
1637 			}
1638 
1639             if(bAddedSomething||bRemovedSomething)
1640     		    InitEditDictDialog( m_nCurrentDict );
1641 		}
1642 		else
1643 		{
1644 			DBG_WARNING( "+HangulHanjaEditDictDialog::NewPBPushHdl(): dictionary faded away..." );
1645 		}
1646 		return 0;
1647 	}
1648 
1649 	bool HangulHanjaEditDictDialog::DeleteEntryFromDictionary( const OUString&, const Reference< XConversionDictionary >& xDict  )
1650 	{
1651 		bool bRemovedSomething = false;
1652 		if( xDict.is() )
1653 		{
1654 			OUString				aOrg( m_aOriginal );
1655 			Sequence< OUString >	aEntries;
1656             GetConversions( xDict, m_aOriginal, aEntries );
1657 
1658 			sal_uInt32	n = aEntries.getLength();
1659 			OUString*	pEntry = aEntries.getArray();
1660 			while( n )
1661 			{
1662 				try
1663 				{
1664 					xDict->removeEntry( aOrg, *pEntry );
1665                     bRemovedSomething = true;
1666 				}
1667 				catch( const NoSuchElementException& )
1668 				{	// can not be...
1669 				}
1670 
1671 				++pEntry;
1672 				--n;
1673 			}
1674 		}
1675 		return bRemovedSomething;
1676 	}
1677 
1678 	IMPL_LINK( HangulHanjaEditDictDialog, DeletePBPushHdl, void*, EMPTYARG )
1679 	{
1680 		if( DeleteEntryFromDictionary( m_aOriginal, m_rDictList[ m_nCurrentDict ] ) )
1681         {
1682             m_aOriginal.Erase();
1683             m_bModifiedOriginal = true;
1684             InitEditDictDialog( m_nCurrentDict );
1685         }
1686 		return 0;
1687 	}
1688 
1689 	void HangulHanjaEditDictDialog::InitEditDictDialog( sal_uInt32 _nSelDict )
1690 	{
1691         if( m_pSuggestions )
1692 		    m_pSuggestions->Clear();
1693 
1694 		if( m_nCurrentDict != _nSelDict )
1695 		{
1696 			m_nCurrentDict = _nSelDict;
1697 			m_aOriginal.Erase();
1698             m_bModifiedOriginal = true;
1699 		}
1700 
1701 		UpdateOriginalLB();
1702 
1703 		m_aOriginalLB.SetText( m_aOriginal.Len()? m_aOriginal : m_aEditHintText, Selection( 0, SELECTION_MAX ) );
1704 		m_aOriginalLB.GrabFocus();
1705 
1706         UpdateSuggestions();
1707 		UpdateButtonStates();
1708 	}
1709 
1710 	void HangulHanjaEditDictDialog::UpdateOriginalLB( void )
1711 	{
1712 		m_aOriginalLB.Clear();
1713 		Reference< XConversionDictionary >	xDict = m_rDictList[ m_nCurrentDict ];
1714 		if( xDict.is() )
1715 		{
1716 			Sequence< OUString >	aEntries = xDict->getConversionEntries( ConversionDirection_FROM_LEFT );
1717 			sal_uInt32				n = aEntries.getLength();
1718 			OUString*				pEntry = aEntries.getArray();
1719 			while( n )
1720 			{
1721 				m_aOriginalLB.InsertEntry( *pEntry );
1722 
1723 				++pEntry;
1724 				--n;
1725 			}
1726 		}
1727 		else
1728 		{
1729 			DBG_WARNING( "+HangulHanjaEditDictDialog::UpdateOriginalLB(): dictionary faded away..." );
1730 		}
1731 	}
1732 
1733     void HangulHanjaEditDictDialog::UpdateButtonStates()
1734     {
1735         bool bHaveValidOriginalString = m_aOriginal.Len() && m_aOriginal != m_aEditHintText;
1736         bool bNew = bHaveValidOriginalString && m_pSuggestions && m_pSuggestions->GetCount() > 0;
1737         bNew = bNew && (m_bModifiedSuggestions || m_bModifiedOriginal);
1738 
1739         m_aNewPB.Enable( bNew );
1740         m_aDeletePB.Enable( !m_bModifiedOriginal && bHaveValidOriginalString );
1741     }
1742 
1743 	void HangulHanjaEditDictDialog::UpdateSuggestions( void )
1744 	{
1745         Sequence< OUString > aEntries;
1746         bool bFound = GetConversions( m_rDictList[ m_nCurrentDict ], m_aOriginal, aEntries );
1747 		if( bFound )
1748 		{
1749             m_bModifiedOriginal = false;
1750 
1751 			if( m_pSuggestions )
1752 			    m_pSuggestions->Clear();
1753 
1754             //fill found entries into boxes
1755 		    sal_uInt32 nCnt = aEntries.getLength();
1756 		    sal_uInt32 n = 0;
1757 		    if( nCnt )
1758 		    {
1759 			    if( !m_pSuggestions )
1760 				    m_pSuggestions = new SuggestionList( MAXNUM_SUGGESTIONS );
1761 
1762 			    const OUString* pSugg = aEntries.getConstArray();
1763 			    while( nCnt )
1764 			    {
1765 				    m_pSuggestions->Set( pSugg[ n ], sal_uInt16( n ) );
1766 				    ++n;
1767 				    --nCnt;
1768 			    }
1769 		    }
1770             m_bModifiedSuggestions=false;
1771 		}
1772 
1773         m_aScrollSB.SetThumbPos( 0 );
1774 		UpdateScrollbar();				// will force edits to be filled new
1775 	}
1776 
1777 	void HangulHanjaEditDictDialog::SetEditText( Edit& _rEdit, sal_uInt16 _nEntryNum )
1778 	{
1779 		String	aStr;
1780 		if( m_pSuggestions )
1781 		{
1782 			const String*	p = m_pSuggestions->Get( _nEntryNum );
1783 			if( p )
1784 				aStr = *p;
1785 		}
1786 
1787 		_rEdit.SetText( aStr );
1788 	}
1789 
1790 	void HangulHanjaEditDictDialog::EditModify( Edit* _pEdit, sal_uInt8 _nEntryOffset )
1791 	{
1792         m_bModifiedSuggestions = true;
1793 
1794         String	aTxt( _pEdit->GetText() );
1795         sal_uInt16 nEntryNum = m_nTopPos + _nEntryOffset;
1796         if( aTxt.Len() == 0 )
1797 		{
1798             //reset suggestion
1799             if( m_pSuggestions )
1800 			    m_pSuggestions->Reset( nEntryNum );
1801         }
1802         else
1803         {
1804             //set suggestion
1805             if( !m_pSuggestions )
1806 			    m_pSuggestions = new SuggestionList( MAXNUM_SUGGESTIONS );
1807 		    m_pSuggestions->Set( aTxt, nEntryNum );
1808         }
1809 
1810         UpdateButtonStates();
1811 	}
1812 
1813 	HangulHanjaEditDictDialog::HangulHanjaEditDictDialog( Window* _pParent, HHDictList& _rDictList, sal_uInt32 _nSelDict )
1814 		:ModalDialog			( _pParent, CUI_RES( RID_SVX_MDLG_HANGULHANJA_EDIT ) )
1815 		,m_aEditHintText		( CUI_RES( STR_EDITHINT ) )
1816 		,m_rDictList			( _rDictList )
1817 		,m_nCurrentDict			( 0xFFFFFFFF )
1818 		,m_pSuggestions			( NULL )
1819 		,m_aBookFT				( this, CUI_RES( FT_BOOK ) )
1820 		,m_aBookLB				( this, CUI_RES( LB_BOOK ) )
1821 		,m_aOriginalFT			( this, CUI_RES( FT_ORIGINAL ) )
1822 		,m_aOriginalLB			( this, CUI_RES( LB_ORIGINAL ) )
1823 		,m_aSuggestionsFT		( this, CUI_RES( FT_SUGGESTIONS ) )
1824 		,m_aEdit1				( this, CUI_RES( ED_1 ), m_aScrollSB, NULL, &m_aEdit2 )
1825 		,m_aEdit2				( this, CUI_RES( ED_2 ), m_aScrollSB, &m_aEdit1, &m_aEdit3 )
1826 		,m_aEdit3				( this, CUI_RES( ED_3 ), m_aScrollSB, &m_aEdit2, &m_aEdit4 )
1827 		,m_aEdit4				( this, CUI_RES( ED_4 ), m_aScrollSB, &m_aEdit3, NULL )
1828 		,m_aScrollSB			( this, CUI_RES( SB_SCROLL ) )
1829 		,m_aNewPB				( this, CUI_RES( PB_HHE_NEW ) )
1830 		,m_aDeletePB			( this, CUI_RES( PB_HHE_DELETE ) )
1831 		,m_aHelpPB				( this, CUI_RES( PB_HHE_HELP ) )
1832 		,m_aClosePB				( this, CUI_RES( PB_HHE_CLOSE ) )
1833 		,m_nTopPos				( 0 )
1834 		,m_bModifiedSuggestions ( false )
1835 		,m_bModifiedOriginal    ( false )
1836 	{
1837 		m_aOriginalLB.SetModifyHdl( LINK( this, HangulHanjaEditDictDialog, OriginalModifyHdl ) );
1838 
1839 		m_aNewPB.SetClickHdl( LINK( this, HangulHanjaEditDictDialog, NewPBPushHdl ) );
1840 		m_aNewPB.Enable( false );
1841 
1842 		m_aDeletePB.SetClickHdl( LINK( this, HangulHanjaEditDictDialog, DeletePBPushHdl ) );
1843 
1844 		m_aDeletePB.Enable( false );
1845 
1846 	#if( MAXNUM_SUGGESTIONS <= 4 )
1847 		#error number of suggestions should not under-run the value of 5
1848 	#endif
1849 
1850 		Link	aScrLk( LINK( this, HangulHanjaEditDictDialog, ScrollHdl ) );
1851 		m_aScrollSB.SetScrollHdl( aScrLk );
1852 		m_aScrollSB.SetEndScrollHdl( aScrLk );
1853 		m_aScrollSB.SetRangeMin( 0 );
1854 		m_aScrollSB.SetRangeMax( MAXNUM_SUGGESTIONS );
1855 		m_aScrollSB.SetPageSize( 4 );		// because we have 4 edits / page
1856 		m_aScrollSB.SetVisibleSize( 4 );
1857 
1858 		m_aEdit1.SetModifyHdl( LINK( this, HangulHanjaEditDictDialog, EditModifyHdl1 ) );
1859 		m_aEdit2.SetModifyHdl( LINK( this, HangulHanjaEditDictDialog, EditModifyHdl2 ) );
1860 		m_aEdit3.SetModifyHdl( LINK( this, HangulHanjaEditDictDialog, EditModifyHdl3 ) );
1861 		m_aEdit4.SetModifyHdl( LINK( this, HangulHanjaEditDictDialog, EditModifyHdl4 ) );
1862 
1863 		m_aBookLB.SetSelectHdl( LINK( this, HangulHanjaEditDictDialog, BookLBSelectHdl ) );
1864 		sal_uInt32	nDictCnt = m_rDictList.size();
1865 		for( sal_uInt32 n = 0 ; n < nDictCnt ; ++n )
1866         {
1867             Reference< XConversionDictionary >	xDic( m_rDictList[n] );
1868             String aName;
1869             if(xDic.is())
1870                 aName = xDic->getName();
1871             m_aBookLB.InsertEntry( aName );
1872         }
1873 		m_aBookLB.SelectEntryPos( sal_uInt16( _nSelDict ) );
1874 
1875 		FreeResource();
1876 
1877 		InitEditDictDialog( _nSelDict );
1878 	}
1879 
1880 	HangulHanjaEditDictDialog::~HangulHanjaEditDictDialog()
1881 	{
1882 		if( m_pSuggestions )
1883 			delete m_pSuggestions;
1884 	}
1885 
1886 	void HangulHanjaEditDictDialog::UpdateScrollbar( void )
1887 	{
1888 		sal_uInt16	nPos = sal_uInt16( m_aScrollSB.GetThumbPos() );
1889 		m_nTopPos = nPos;
1890 
1891 		SetEditText( m_aEdit1, nPos++ );
1892 		SetEditText( m_aEdit2, nPos++ );
1893 		SetEditText( m_aEdit3, nPos++ );
1894 		SetEditText( m_aEdit4, nPos );
1895 	}
1896 
1897 //.............................................................................
1898 }	// namespace svx
1899 //.............................................................................
1900