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