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