xref: /AOO41X/main/cui/source/dialogs/hangulhanjadlg.cxx (revision 2ee96f1cdb99d49425d866b1ec4c5567f37285e6)
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